Skip to content

Commit 5f07a1a

Browse files
Tests merge-cells add-rows and fix for merge cells (#36)
* tests for context menu options * tests for context menu options, version update * format
1 parent cdf0211 commit 5f07a1a

6 files changed

Lines changed: 137 additions & 8 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-spread-sheet-excel",
3-
"version": "3.1.5",
3+
"version": "3.1.6",
44
"description": "A quick example of rendering large number of input boxes in table using React JS, React Spread-sheet (Excel sheet)",
55
"keywords": [
66
"React spreadsheet",

src/lib/list/__tests__/index.test.tsx

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,4 +283,109 @@ describe("index tests", () => {
283283
fireEvent.click(screen.getByTestId(`sheet-table-content`));
284284
expect(screen.queryByText("Cut")).not.toBeInTheDocument();
285285
});
286+
287+
test("Add row and undo, redo", () => {
288+
render(<List data={generateDummyContent(10, 2)} autoAddAdditionalRows={false} />);
289+
expect(store.getState().data.length).toBe(10);
290+
mockAllIsIntersecting(true);
291+
fireEvent.contextMenu(screen.getByTestId(`0-0`));
292+
const addRow = screen.getByText("Add Row");
293+
expect(addRow).toBeInTheDocument();
294+
fireEvent.mouseEnter(addRow);
295+
expect(screen.getByText("Above")).toBeInTheDocument();
296+
expect(screen.getByText("Below")).toBeInTheDocument();
297+
fireEvent.click(screen.getByText("Above"));
298+
expect(store.getState().data.length).toBe(11);
299+
fireEvent.contextMenu(screen.getByTestId(`0-0`));
300+
fireEvent.mouseEnter(screen.getByText("Add Row"));
301+
fireEvent.click(screen.getByText("Below"));
302+
303+
expect(store.getState().data.length).toBe(12);
304+
305+
fireEvent.keyDown(screen.getByRole("table"), { code: "KeyZ", ctrlKey: true });
306+
expect(store.getState().data.length).toBe(11);
307+
fireEvent.keyDown(screen.getByRole("table"), { code: "KeyZ", ctrlKey: true, shiftKey: true });
308+
expect(store.getState().data.length).toBe(12);
309+
fireEvent.keyDown(screen.getByRole("table"), { code: "KeyZ", ctrlKey: true });
310+
fireEvent.keyDown(screen.getByRole("table"), { code: "KeyZ", ctrlKey: true });
311+
expect(store.getState().data.length).toBe(10);
312+
});
313+
314+
test("delete row and undo, redo", () => {
315+
render(<List data={generateDummyContent(10, 2)} autoAddAdditionalRows={false} />);
316+
expect(store.getState().data.length).toBe(10);
317+
mockAllIsIntersecting(true);
318+
fireEvent.contextMenu(screen.getByTestId(`0-0`));
319+
const deleteRow = screen.getByText("Delete Row");
320+
expect(deleteRow).toBeInTheDocument();
321+
fireEvent.click(deleteRow);
322+
expect(store.getState().data.length).toBe(9);
323+
fireEvent.keyDown(screen.getByRole("table"), { code: "KeyZ", ctrlKey: true });
324+
expect(store.getState().data.length).toBe(10);
325+
fireEvent.keyDown(screen.getByRole("table"), { code: "KeyZ", ctrlKey: true, shiftKey: true });
326+
expect(store.getState().data.length).toBe(9);
327+
});
328+
test("Add column and undo, redo", () => {
329+
render(<List data={generateDummyContent(10, 2)} autoAddAdditionalRows={false} />);
330+
expect(store.getState().data[0].length).toBe(2);
331+
mockAllIsIntersecting(true);
332+
fireEvent.contextMenu(screen.getByTestId(`0-0`));
333+
const addColumn = screen.getByText("Add Column");
334+
expect(addColumn).toBeInTheDocument();
335+
fireEvent.mouseEnter(addColumn);
336+
expect(screen.getByText("Right")).toBeInTheDocument();
337+
expect(screen.getByText("Left")).toBeInTheDocument();
338+
fireEvent.click(screen.getByText("Right"));
339+
expect(store.getState().data[0].length).toBe(3);
340+
341+
fireEvent.contextMenu(screen.getByTestId(`0-0`));
342+
fireEvent.mouseEnter(screen.getByText("Add Column"));
343+
fireEvent.click(screen.getByText("Left"));
344+
expect(store.getState().data[0].length).toBe(4);
345+
346+
fireEvent.keyDown(screen.getByRole("table"), { code: "KeyZ", ctrlKey: true });
347+
expect(store.getState().data[0].length).toBe(3);
348+
fireEvent.keyDown(screen.getByRole("table"), { code: "KeyZ", ctrlKey: true, shiftKey: true });
349+
expect(store.getState().data[0].length).toBe(4);
350+
fireEvent.keyDown(screen.getByRole("table"), { code: "KeyZ", ctrlKey: true });
351+
fireEvent.keyDown(screen.getByRole("table"), { code: "KeyZ", ctrlKey: true });
352+
expect(store.getState().data[0].length).toBe(2);
353+
});
354+
test("delete column and undo, redo", () => {
355+
render(<List data={generateDummyContent(10, 2)} autoAddAdditionalRows={false} />);
356+
expect(store.getState().data[0].length).toBe(2);
357+
mockAllIsIntersecting(true);
358+
fireEvent.contextMenu(screen.getByTestId(`0-0`));
359+
const deleteColumn = screen.getByText("Delete Column");
360+
expect(deleteColumn).toBeInTheDocument();
361+
fireEvent.click(deleteColumn);
362+
expect(store.getState().data[0].length).toBe(1);
363+
364+
fireEvent.keyDown(screen.getByRole("table"), { code: "KeyZ", ctrlKey: true });
365+
expect(store.getState().data[0].length).toBe(2);
366+
fireEvent.keyDown(screen.getByRole("table"), { code: "KeyZ", ctrlKey: true, shiftKey: true });
367+
expect(store.getState().data[0].length).toBe(1);
368+
});
369+
test("merge cells", async () => {
370+
const user = userEvent.setup();
371+
render(<List data={generateDummyContent(10, 2)} autoAddAdditionalRows={false} />);
372+
mockAllIsIntersecting(true);
373+
expect(screen.getAllByRole("textbox").length).toBe(21); //one common input from tools
374+
await user.click(screen.getByTestId(`${0}-${0}`));
375+
await user.keyboard("{Meta>}");
376+
await user.click(screen.getByTestId(`${0}-${1}`));
377+
await user.click(screen.getByTestId(`${1}-${0}`));
378+
await user.click(screen.getByTestId(`${1}-${1}`));
379+
await user.keyboard("{/Meta}");
380+
await waitFor(() => {
381+
expect(store.getState().selected.length).toBe(4);
382+
});
383+
fireEvent.contextMenu(screen.getByTestId(`0-0`));
384+
fireEvent.click(screen.getByText("Merge cells"));
385+
expect(store.getState().selected.length).toBe(1);
386+
expect(screen.getAllByRole("textbox").length).toBe(18); //one common input from tools
387+
fireEvent.contextMenu(screen.getByTestId(`0-0`));
388+
fireEvent.click(screen.getByText("Merge cells"));
389+
expect(screen.getAllByRole("textbox").length).toBe(18); //one common input from tools
390+
});
286391
});

src/lib/list/tools/__tests__/tools.test.tsx

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React, { act } from "react";
22
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
33
import { store } from "../../../store";
4-
import { addData, selectOneCell } from "../../../reducer";
4+
import { addData, selectCellsDrag, selectOneCell } from "../../../reducer";
55
import { generateDummyContent } from "../../utils";
66
import Tools from "../tools";
77

@@ -147,3 +147,23 @@ test("Undo redo", async () => {
147147
expect(onChange).toHaveBeenCalled();
148148
expect(onChange).toHaveBeenCalledTimes(3);
149149
});
150+
151+
test("merge cells tools", async () => {
152+
const changeStyle = jest.fn();
153+
const onChange = jest.fn();
154+
render(<Tools changeStyle={changeStyle} onChange={onChange} />);
155+
act(() => {
156+
store.dispatch(selectOneCell, { payload: { i: 0, j: 0 } });
157+
});
158+
act(() => {
159+
store.dispatch(selectCellsDrag, { payload: { i: 1, j: 1 } });
160+
});
161+
162+
await waitFor(() => {
163+
expect(store.getState().selected.length).toBe(4);
164+
});
165+
fireEvent.click(screen.getByTestId(`merge`));
166+
expect(store.getState().selected.length).toBe(1);
167+
expect(store.getState().data[0][0].rowSpan).toBe(2);
168+
expect(store.getState().data[0][0].colSpan).toBe(2);
169+
});

src/lib/list/tools/tools.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ const Tools = ({
5353
}, 200);
5454
};
5555
const onValChange = (e: { target: { value: string } }) => {
56-
dispatch(changeData, { payload: { value: e.target.value || "", i: i, j: j } });
56+
dispatch(changeData, { payload: { value: e.target.value, i: i, j: j } });
5757
onChange && onChange(i, j, e.target.value);
5858
};
5959
return (
@@ -240,7 +240,10 @@ const Tools = ({
240240
<button
241241
className={rowSpan ? "text-style-btn-active" : ""}
242242
data-testid="merge"
243-
onClick={() => dispatch(mergeCells)}
243+
onClick={() => {
244+
dispatch(mergeCells);
245+
onChange && onChange();
246+
}}
244247
>
245248
<Icons type="merge" />
246249
</button>

src/lib/reducer.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -342,12 +342,12 @@ const actions: DispatcherActions = {
342342
if (data[cellForMerge[0]][cellForMerge[1]].rowSpan) {
343343
for (
344344
let i = cellForMerge[0];
345-
i <= cellForMerge[0] + (data[cellForMerge[0]][cellForMerge[1]].rowSpan || 0);
345+
i < cellForMerge[0] + (data[cellForMerge[0]][cellForMerge[1]].rowSpan || 0);
346346
i++
347347
) {
348348
for (
349349
let j = cellForMerge[1];
350-
j <= cellForMerge[1] + (data[cellForMerge[0]][cellForMerge[1]].colSpan || 0);
350+
j < cellForMerge[1] + (data[cellForMerge[0]][cellForMerge[1]].colSpan || 0);
351351
j++
352352
) {
353353
undo.push({ i: i, j: j, data: { ...state.data[i][j] } });

todo.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ Locale - translations.
1919
Improve tests
2020
More events - on select, on bulk change, onUndo, onRedo, onScroll(which should help to add more data)
2121
Custom tools - onClick should respond with all selected cell data
22-
Resize rows
22+
custom options in menu
23+
!!Resize rows
2324
Multiple selection with cntrl key
2425
Readonly should disable all updates and support merged cells
2526

26-
!!complete pending tests
27+
Tool tip for tools

0 commit comments

Comments
 (0)