forked from TypeCellOS/BlockNote
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTableExtension.test.ts
More file actions
126 lines (106 loc) · 3.33 KB
/
TableExtension.test.ts
File metadata and controls
126 lines (106 loc) · 3.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import { TextSelection } from "prosemirror-state";
import { CellSelection } from "prosemirror-tables";
import { afterAll, beforeAll, beforeEach, describe, expect, it } from "vitest";
import { BlockNoteEditor } from "../../editor/BlockNoteEditor.js";
import type { PartialBlock } from "../defaultBlocks.js";
/**
* @vitest-environment jsdom
*/
function pressEnter(editor: BlockNoteEditor) {
const view = editor.prosemirrorView;
const event = new KeyboardEvent("keydown", { key: "Enter" });
view.someProp("handleKeyDown", (f) => f(view, event));
}
const testDocument: PartialBlock[] = [
{
id: "table-0",
type: "table",
content: {
type: "tableContent",
rows: [
{ cells: ["Cell 1", "Cell 2", "Cell 3"] },
{ cells: ["Cell 4", "Cell 5", "Cell 6"] },
{ cells: ["Cell 7", "Cell 8", "Cell 9"] },
],
},
},
];
describe("Table Enter keyboard shortcut", () => {
let editor: BlockNoteEditor;
const div = document.createElement("div");
beforeAll(() => {
editor = BlockNoteEditor.create();
editor.mount(div);
});
afterAll(() => {
editor._tiptapEditor.destroy();
editor = undefined as any;
});
beforeEach(() => {
editor.replaceBlocks(editor.document, testDocument);
});
function posInCell(cellText: string): number {
const view = editor.prosemirrorView;
let pos = -1;
view.state.doc.descendants((node, nodePos) => {
if (pos === -1 && node.isText && node.text === cellText) {
pos = nodePos;
}
return true;
});
if (pos === -1) {
throw new Error(`Cell with text "${cellText}" not found`);
}
return pos;
}
function setCursorInCell(cellText: string, offset = 1) {
const pos = posInCell(cellText);
editor.transact((tr) =>
tr.setSelection(TextSelection.create(tr.doc, pos + offset)),
);
}
it("moves the selection to the cell below", () => {
setCursorInCell("Cell 5");
pressEnter(editor);
const parentText =
editor.prosemirrorView.state.selection.$head.parent.textContent;
expect(parentText).toBe("Cell 8");
});
it("does not crash and is a no-op on the last row", () => {
setCursorInCell("Cell 8");
const before = editor.document;
expect(() => pressEnter(editor)).not.toThrow();
expect(editor.document).toStrictEqual(before);
});
it("does not crash with a (non-empty) text selection in the last row", () => {
const start = posInCell("Cell 8");
editor.transact((tr) =>
tr.setSelection(TextSelection.create(tr.doc, start, start + 4)),
);
const before = editor.document;
expect(() => pressEnter(editor)).not.toThrow();
expect(editor.document).toStrictEqual(before);
});
it("does not crash with a multi-cell selection", () => {
const view = editor.prosemirrorView;
const cellPositions: number[] = [];
view.state.doc.descendants((node, pos) => {
if (node.type.name === "tableCell" || node.type.name === "tableHeader") {
cellPositions.push(pos);
}
return true;
});
editor.transact((tr) =>
tr.setSelection(
CellSelection.create(
tr.doc,
cellPositions[0],
cellPositions[1],
) as any,
),
);
const before = editor.document;
expect(() => pressEnter(editor)).not.toThrow();
expect(editor.document).toStrictEqual(before);
});
});