vitest-prosemirror 0.2.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,6 +8,13 @@ export declare interface CustomMatchers<R = unknown> {
8
8
  toEqualProseMirrorNode(expected: Node_2): R;
9
9
  }
10
10
 
11
+ export declare interface KeyboardModifiers {
12
+ altKey?: boolean;
13
+ ctrlKey?: boolean;
14
+ metaKey?: boolean;
15
+ shiftKey?: boolean;
16
+ }
17
+
11
18
  export declare interface Options {
12
19
  plugins: Array<Plugin_2>;
13
20
  }
@@ -17,9 +24,8 @@ export declare class ProseMirrorTester {
17
24
  get schema(): Schema;
18
25
  private readonly view;
19
26
  constructor(documentRoot: Node_2, options?: Partial<Options>);
20
- insertText(text: string): void;
27
+ insertText(text: string, modifiers?: KeyboardModifiers): void;
21
28
  selectText(selection: TesterSelection): void;
22
- shortcut(text: string): void;
23
29
  private getSelection;
24
30
  }
25
31
 
@@ -28,11 +34,6 @@ export declare type TesterSelection = "all" | "end" | "start" | {
28
34
  to: number;
29
35
  } | Selection_2 | number;
30
36
 
31
- /**
32
- * @public
33
- */
34
- export declare function trimProseMirrorNode(node: Node_2): Node_2;
35
-
36
37
  export { }
37
38
 
38
39
 
@@ -2,8 +2,6 @@ import { expect } from "vitest";
2
2
  import stringifyObject from "stringify-object";
3
3
  import { EditorState, AllSelection, TextSelection } from "prosemirror-state";
4
4
  import { EditorView } from "prosemirror-view";
5
- import { Keyboard } from "test-keyboard";
6
- import { Fragment } from "prosemirror-model";
7
5
  function getMarks(marks, origContent) {
8
6
  let content = `'${origContent}'`;
9
7
  for (const mark of [...marks].reverse()) {
@@ -53,8 +51,94 @@ function stringifyProseMirrorNode(node, indentation = "") {
53
51
  ${nextIndentation}` : content.length > 0 ? "\n" : "";
54
52
  const postfix = content.length > 0 ? `
55
53
  ${indentation}` : "";
56
- return `${indentation}${type}(${prefix}${content.join(joiner)}${postfix})`;
54
+ return `${indentation}${type}(${prefix}${content.join(joiner)},${postfix})`;
57
55
  }
56
+ function tokenizeKeyboardInput(input) {
57
+ const output = [];
58
+ let currentGroupOpener = null;
59
+ let group = "";
60
+ for (const char of input) {
61
+ if (currentGroupOpener !== null) {
62
+ if (["]", "}"].includes(char)) {
63
+ if (group.endsWith("\\") && char === matchingBrace(currentGroupOpener)) {
64
+ group = group.slice(0, -2) + char;
65
+ } else if (char === matchingBrace(currentGroupOpener)) {
66
+ if (group.length === 4 && group.startsWith("Key")) {
67
+ output.push(group.slice(3).toLowerCase());
68
+ } else {
69
+ output.push(group);
70
+ }
71
+ currentGroupOpener = null;
72
+ group = "";
73
+ } else {
74
+ group += char;
75
+ }
76
+ } else if (group === "" && currentGroupOpener === char) {
77
+ output.push(char);
78
+ currentGroupOpener = null;
79
+ group = "";
80
+ } else {
81
+ group += char;
82
+ }
83
+ } else if (["[", "{"].includes(char)) {
84
+ currentGroupOpener = char;
85
+ } else {
86
+ output.push(char);
87
+ }
88
+ }
89
+ output.forEach(assertSupported);
90
+ return output;
91
+ }
92
+ function assertSupported(character) {
93
+ if (/^\/.+/u.exec(character) || /.+>[\d]*\/?$/u.exec(character)) {
94
+ throw new Error("Unsupported keyboard input");
95
+ }
96
+ }
97
+ function matchingBrace(opener) {
98
+ return opener === "{" ? "}" : "]";
99
+ }
100
+ class KeyboardEventMock extends KeyboardEvent {
101
+ constructor(onPreventDefault, type, eventInitDict) {
102
+ super(type, eventInitDict);
103
+ this.onPreventDefault = onPreventDefault;
104
+ }
105
+ preventDefault() {
106
+ super.preventDefault();
107
+ this.onPreventDefault();
108
+ }
109
+ }
110
+ const _MutationObserverMock = class _MutationObserverMock {
111
+ constructor(callback) {
112
+ this.callback = callback;
113
+ this.target = void 0;
114
+ }
115
+ static createMutation(target, mutationRecords) {
116
+ const observer = _MutationObserverMock.activeObservers.get(target);
117
+ if (observer === void 0) {
118
+ return;
119
+ }
120
+ observer.callback(
121
+ mutationRecords,
122
+ observer
123
+ );
124
+ }
125
+ disconnect() {
126
+ if (this.target !== void 0) {
127
+ _MutationObserverMock.activeObservers.delete(this.target);
128
+ }
129
+ this.target = void 0;
130
+ }
131
+ observe(target) {
132
+ this.target = target;
133
+ _MutationObserverMock.activeObservers.set(target, this);
134
+ }
135
+ // eslint-disable-next-line @typescript-eslint/class-methods-use-this -- Mocking another method
136
+ takeRecords() {
137
+ return [];
138
+ }
139
+ };
140
+ _MutationObserverMock.activeObservers = /* @__PURE__ */ new Map();
141
+ let MutationObserverMock = _MutationObserverMock;
58
142
  class ProseMirrorTester {
59
143
  get doc() {
60
144
  return this.view.state.doc;
@@ -72,49 +156,109 @@ class ProseMirrorTester {
72
156
  doc: documentRoot,
73
157
  plugins: options.plugins ?? []
74
158
  });
159
+ global.MutationObserver = MutationObserverMock;
75
160
  this.view = new EditorView(element, {
76
161
  state
77
162
  });
78
163
  }
79
- insertText(text) {
80
- const keys = Keyboard.create({
81
- target: this.view.dom
82
- }).start();
83
- for (const character of text) {
84
- keys.char({ text: character, typing: true });
85
- if (this.view.someProp(
86
- "handleTextInput",
87
- (f) => f(
88
- this.view,
89
- this.view.state.selection.from,
90
- this.view.state.selection.from,
91
- character
164
+ insertText(text, modifiers) {
165
+ for (const key of tokenizeKeyboardInput(text)) {
166
+ const character = keyToChar(key);
167
+ let keydownPrevented = false;
168
+ this.view.dispatchEvent(
169
+ new KeyboardEventMock(
170
+ () => {
171
+ keydownPrevented = true;
172
+ },
173
+ "keydown",
174
+ {
175
+ bubbles: true,
176
+ charCode: character.charCodeAt(0),
177
+ key,
178
+ ...modifiers
179
+ }
92
180
  )
93
- ) !== true) {
94
- this.view.dispatch(
95
- this.view.state.tr.insertText(
96
- character,
97
- this.view.state.selection.from,
98
- this.view.state.selection.from
99
- )
100
- );
181
+ );
182
+ if (keydownPrevented) {
183
+ continue;
101
184
  }
185
+ this.view.dispatchEvent(
186
+ new KeyboardEvent("keypress", {
187
+ bubbles: true,
188
+ charCode: character.charCodeAt(0),
189
+ key,
190
+ keyCode: character.charCodeAt(0),
191
+ ...modifiers
192
+ })
193
+ );
194
+ const domNode = this.view.domAtPos(this.view.state.selection.from).node;
195
+ if (domNode.childNodes.length === 1 && domNode.firstChild instanceof HTMLBRElement && domNode.firstChild.classList.contains("ProseMirror-trailingBreak")) {
196
+ const brNode = domNode.firstChild;
197
+ const textNode = new Text(character);
198
+ domNode.removeChild(brNode);
199
+ domNode.appendChild(textNode);
200
+ MutationObserverMock.createMutation(this.view.dom, [
201
+ {
202
+ addedNodes: [textNode],
203
+ attributeName: null,
204
+ attributeNamespace: null,
205
+ nextSibling: brNode,
206
+ oldValue: null,
207
+ previousSibling: null,
208
+ removedNodes: [],
209
+ target: domNode,
210
+ type: "childList"
211
+ },
212
+ {
213
+ addedNodes: [],
214
+ attributeName: null,
215
+ attributeNamespace: null,
216
+ nextSibling: null,
217
+ oldValue: null,
218
+ previousSibling: textNode,
219
+ removedNodes: [brNode],
220
+ target: domNode,
221
+ type: "childList"
222
+ }
223
+ ]);
224
+ } else {
225
+ const target = findLastCharacterDataNode(domNode);
226
+ if (target === null) {
227
+ continue;
228
+ }
229
+ const oldValue = target.data;
230
+ const domOffset = this.view.state.selection.from - this.view.posAtDOM(target, 0);
231
+ target.data = target.data.slice(0, domOffset) + character + target.data.slice(domOffset);
232
+ MutationObserverMock.createMutation(this.view.dom, [
233
+ {
234
+ addedNodes: [],
235
+ attributeName: null,
236
+ attributeNamespace: null,
237
+ nextSibling: null,
238
+ oldValue,
239
+ previousSibling: null,
240
+ removedNodes: [],
241
+ target,
242
+ type: "characterData"
243
+ }
244
+ ]);
245
+ }
246
+ this.view.dispatchEvent(
247
+ new KeyboardEvent("keyup", {
248
+ bubbles: true,
249
+ charCode: character.charCodeAt(0),
250
+ key,
251
+ keyCode: character.charCodeAt(0),
252
+ ...modifiers
253
+ })
254
+ );
102
255
  }
103
- keys.end();
104
256
  }
105
257
  selectText(selection) {
106
258
  this.view.dispatch(
107
259
  this.view.state.tr.setSelection(this.getSelection(selection))
108
260
  );
109
261
  }
110
- shortcut(text) {
111
- Keyboard.create({
112
- batch: true,
113
- target: this.view.dom
114
- }).start().mod({ text: text.replace(/Enter$/u, "\n") }).forEach(({ event }) => {
115
- this.view.dispatchEvent(event);
116
- }).end();
117
- }
118
262
  getSelection(selection) {
119
263
  if (selection === "all") {
120
264
  return new AllSelection(this.doc);
@@ -139,24 +283,26 @@ class ProseMirrorTester {
139
283
  return TextSelection.near(this.doc.resolve(pos));
140
284
  }
141
285
  }
142
- function trimProseMirrorNode(node) {
143
- let start = 0;
144
- let end = node.children.length;
145
- for (const child of node.children) {
146
- if (child.type.name === "paragraph" && ["", "\n"].includes(child.textContent)) {
147
- start++;
148
- } else {
149
- break;
150
- }
286
+ function findLastCharacterDataNode(node) {
287
+ if (node instanceof CharacterData) {
288
+ return node;
151
289
  }
152
- for (const child of node.children.slice().reverse()) {
153
- if (child.type.name === "paragraph" && ["", "\n"].includes(child.textContent)) {
154
- end--;
155
- } else {
156
- break;
290
+ for (const child of Array.from(node.childNodes).reverse()) {
291
+ const textNode = findLastCharacterDataNode(child);
292
+ if (textNode !== null) {
293
+ return textNode;
157
294
  }
158
295
  }
159
- return node.copy(Fragment.from(node.children.slice(start, end)));
296
+ return null;
297
+ }
298
+ function keyToChar(key) {
299
+ if (key === "Enter") {
300
+ return "\n";
301
+ }
302
+ if (key === "Tab") {
303
+ return " ";
304
+ }
305
+ return key;
160
306
  }
161
307
  expect.extend({
162
308
  toEqualProseMirrorNode(received, expected) {
@@ -194,7 +340,6 @@ ${diffString}` : ""}`;
194
340
  }
195
341
  });
196
342
  export {
197
- ProseMirrorTester,
198
- trimProseMirrorNode
343
+ ProseMirrorTester
199
344
  };
200
345
  //# sourceMappingURL=vitest-prosemirror.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"vitest-prosemirror.js","sources":["../src/stringifyProseMirrorNode.ts","../src/ProseMirrorTester.ts","../src/trimProseMirrorNode.ts","../src/index.ts"],"sourcesContent":["import type { Mark, Node } from \"prosemirror-model\";\n\nimport stringifyObject from \"stringify-object\";\n\nfunction getMarks(marks: ReadonlyArray<Mark>, origContent: string): string {\n let content = `'${origContent}'`;\n\n for (const mark of [...marks].reverse()) {\n const hasAttrs = Object.keys(mark.attrs).length > 0;\n const items: Array<string> = [content];\n\n if (hasAttrs) {\n items.unshift(\n stringifyObject(mark.attrs, {\n indent: \" \",\n inlineCharacterLimit: 1000,\n }),\n );\n }\n\n content = `${mark.type.name}(${items.join(\", \")})`;\n }\n\n return content;\n}\n\nconst renamedTypes: Record<string, string> = {\n hardBreak: \"br\",\n heading: \"h\",\n horizontalRule: \"hr\",\n paragraph: \"p\",\n};\n\nexport function stringifyProseMirrorNode(node: Node, indentation = \"\"): string {\n const nextIndentation = `${indentation} `;\n\n if (node.type.name === \"text\") {\n return `${indentation}${getMarks(node.marks, node.text ?? \"\")}`;\n }\n\n const type = renamedTypes[node.type.name] ?? node.type.name;\n const content: Array<string> = [];\n const hasAttrs = Object.keys(node.attrs).length > 0;\n\n if (hasAttrs) {\n content.push(\n stringifyObject(node.attrs, { indent: \" \", inlineCharacterLimit: 1000 }),\n );\n }\n\n node.content.forEach((item) => {\n content.push(stringifyProseMirrorNode(item, nextIndentation));\n });\n\n if (\n !hasAttrs &&\n content.length === 1 &&\n node.content.firstChild?.type.name === \"text\"\n ) {\n return `${indentation}${type}(${stringifyProseMirrorNode(node.content.firstChild, \"\")})`;\n }\n\n const joiner = `,\\n`;\n const prefix = hasAttrs\n ? `\\n${nextIndentation}`\n : content.length > 0\n ? \"\\n\"\n : \"\";\n const postfix = content.length > 0 ? `\\n${indentation}` : \"\";\n\n return `${indentation}${type}(${prefix}${content.join(joiner)}${postfix})`;\n}\n","import type { Node, Schema } from \"prosemirror-model\";\n\nimport {\n AllSelection,\n EditorState,\n type Plugin,\n type Selection,\n TextSelection,\n} from \"prosemirror-state\";\nimport { EditorView } from \"prosemirror-view\";\nimport { Keyboard } from \"test-keyboard\";\n\nexport interface Options {\n plugins: Array<Plugin>;\n}\n\nexport type TesterSelection =\n | \"all\"\n | \"end\"\n | \"start\"\n | { from: number; to: number }\n | Selection\n | number;\n\nexport class ProseMirrorTester {\n public get doc(): Node {\n return this.view.state.doc;\n }\n\n public get schema(): Schema {\n return this.view.state.schema;\n }\n\n private readonly view: EditorView;\n\n public constructor(documentRoot: Node, options: Partial<Options> = {}) {\n if (typeof document === \"undefined\") {\n throw new Error(\"TODO\");\n }\n\n const element = document.createElement(\"div\");\n document.body.append(element);\n\n const state = EditorState.create({\n doc: documentRoot,\n plugins: options.plugins ?? [],\n });\n this.view = new EditorView(element, {\n state,\n });\n }\n\n public insertText(text: string): void {\n const keys = Keyboard.create({\n target: this.view.dom,\n }).start();\n\n for (const character of text) {\n keys.char({ text: character, typing: true });\n\n if (\n this.view.someProp(\"handleTextInput\", (f) =>\n f(\n this.view,\n this.view.state.selection.from,\n this.view.state.selection.from,\n character,\n ),\n ) !== true\n ) {\n this.view.dispatch(\n this.view.state.tr.insertText(\n character,\n this.view.state.selection.from,\n this.view.state.selection.from,\n ),\n );\n }\n }\n keys.end();\n }\n\n public selectText(selection: TesterSelection): void {\n this.view.dispatch(\n this.view.state.tr.setSelection(this.getSelection(selection)),\n );\n }\n\n public shortcut(text: string): void {\n Keyboard.create({\n batch: true,\n target: this.view.dom,\n })\n .start()\n .mod({ text: text.replace(/Enter$/u, \"\\n\") })\n .forEach(({ event }) => {\n this.view.dispatchEvent(event);\n })\n .end();\n }\n\n private getSelection(selection: TesterSelection): Selection {\n if (selection === \"all\") {\n return new AllSelection(this.doc);\n }\n\n if (\n typeof selection === \"object\" &&\n \"$anchor\" in selection &&\n \"$head\" in selection\n ) {\n return selection;\n }\n\n if (\n typeof selection === \"object\" &&\n \"from\" in selection &&\n \"to\" in selection\n ) {\n return TextSelection.between(\n this.doc.resolve(selection.from),\n this.doc.resolve(selection.to),\n );\n }\n\n let pos = 0;\n if (selection === \"start\") {\n pos = 0;\n } else if (selection === \"end\") {\n pos = this.doc.nodeSize - 2;\n } else {\n pos = selection;\n }\n\n return TextSelection.near(this.doc.resolve(pos));\n }\n}\n","import { Fragment, type Node } from \"prosemirror-model\";\n\n/**\n * @public\n */\nexport function trimProseMirrorNode(node: Node): Node {\n let start = 0;\n let end = node.children.length;\n for (const child of node.children) {\n if (\n child.type.name === \"paragraph\" &&\n [\"\", \"\\n\"].includes(child.textContent)\n ) {\n start++;\n } else {\n break;\n }\n }\n for (const child of node.children.slice().reverse()) {\n if (\n child.type.name === \"paragraph\" &&\n [\"\", \"\\n\"].includes(child.textContent)\n ) {\n end--;\n } else {\n break;\n }\n }\n return node.copy(Fragment.from(node.children.slice(start, end)));\n}\n","import type { Node } from \"prosemirror-model\";\n\nimport { expect } from \"vitest\";\n\nimport { stringifyProseMirrorNode } from \"./stringifyProseMirrorNode\";\n\nexport {\n type Options,\n ProseMirrorTester,\n type TesterSelection,\n} from \"./ProseMirrorTester\";\nexport { trimProseMirrorNode } from \"./trimProseMirrorNode\";\n\nexport interface CustomMatchers<R = unknown> {\n toEqualProseMirrorNode(expected: Node): R;\n}\n\n/* eslint-disable @typescript-eslint/no-empty-object-type, @typescript-eslint/no-explicit-any -- These are overridest for vitest matchers */\n\ndeclare module \"vitest\" {\n interface Assertion<T = any> extends CustomMatchers<T> {}\n interface AsymmetricMatchersContaining extends CustomMatchers {}\n}\n\n/* eslint-enable */\n\nexpect.extend({\n toEqualProseMirrorNode(received: Node, expected: Node) {\n const receivedDoc = `\\n${stringifyProseMirrorNode(received)}\\n`;\n const expectedDoc = `\\n${stringifyProseMirrorNode(expected)}\\n`;\n const pass = this.equals(receivedDoc, expectedDoc);\n const message = pass\n ? (): string =>\n `${this.utils.matcherHint(\".not.toEqualProsemirrorNode\")}\\n\\n` +\n `Expected value of document to not equal:\\n ${this.utils.printExpected(expectedDoc)}\\n` +\n `Actual:\\n ${this.utils.printReceived(receivedDoc)}`\n : (): string => {\n const diffString = this.utils.diff(expectedDoc, receivedDoc, {\n expand: this.expand ?? false,\n });\n return `${this.utils.matcherHint(\".toEqualProsemirrorNode\")}\\n\\nExpected value of document to equal:\\n${this.utils.printExpected(expectedDoc)}\\nActual:\\n${this.utils.printReceived(receivedDoc)}${diffString !== undefined ? `\\n\\nDifference:\\n\\n${diffString}` : \"\"}`;\n };\n return {\n message,\n pass,\n };\n },\n});\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"vitest-prosemirror.js","sources":["../src/stringifyProseMirrorNode.ts","../src/utils/keyboardInput.ts","../src/ProseMirrorTester.ts","../src/index.ts"],"sourcesContent":["import type { Mark, Node } from \"prosemirror-model\";\n\nimport stringifyObject from \"stringify-object\";\n\nfunction getMarks(marks: ReadonlyArray<Mark>, origContent: string): string {\n let content = `'${origContent}'`;\n\n for (const mark of [...marks].reverse()) {\n const hasAttrs = Object.keys(mark.attrs).length > 0;\n const items: Array<string> = [content];\n\n if (hasAttrs) {\n items.unshift(\n stringifyObject(mark.attrs, {\n indent: \" \",\n inlineCharacterLimit: 1000,\n }),\n );\n }\n\n content = `${mark.type.name}(${items.join(\", \")})`;\n }\n\n return content;\n}\n\nconst renamedTypes: Record<string, string> = {\n hardBreak: \"br\",\n heading: \"h\",\n horizontalRule: \"hr\",\n paragraph: \"p\",\n};\n\nexport function stringifyProseMirrorNode(node: Node, indentation = \"\"): string {\n const nextIndentation = `${indentation} `;\n\n if (node.type.name === \"text\") {\n return `${indentation}${getMarks(node.marks, node.text ?? \"\")}`;\n }\n\n const type = renamedTypes[node.type.name] ?? node.type.name;\n const content: Array<string> = [];\n const hasAttrs = Object.keys(node.attrs).length > 0;\n\n if (hasAttrs) {\n content.push(\n stringifyObject(node.attrs, { indent: \" \", inlineCharacterLimit: 1000 }),\n );\n }\n\n node.content.forEach((item) => {\n content.push(stringifyProseMirrorNode(item, nextIndentation));\n });\n\n if (\n !hasAttrs &&\n content.length === 1 &&\n node.content.firstChild?.type.name === \"text\"\n ) {\n return `${indentation}${type}(${stringifyProseMirrorNode(node.content.firstChild, \"\")})`;\n }\n\n const joiner = `,\\n`;\n const prefix = hasAttrs\n ? `\\n${nextIndentation}`\n : content.length > 0\n ? \"\\n\"\n : \"\";\n const postfix = content.length > 0 ? `\\n${indentation}` : \"\";\n\n return `${indentation}${type}(${prefix}${content.join(joiner)},${postfix})`;\n}\n","export function tokenizeKeyboardInput(input: string): Array<string> {\n const output = [];\n\n let currentGroupOpener: \"[\" | \"{\" | null = null;\n let group = \"\";\n for (const char of input) {\n if (currentGroupOpener !== null) {\n if ([\"]\", \"}\"].includes(char)) {\n if (\n group.endsWith(\"\\\\\") &&\n char === matchingBrace(currentGroupOpener)\n ) {\n group = group.slice(0, -2) + char;\n } else if (char === matchingBrace(currentGroupOpener)) {\n if (group.length === 4 && group.startsWith(\"Key\")) {\n output.push(group.slice(3).toLowerCase());\n } else {\n output.push(group);\n }\n currentGroupOpener = null;\n group = \"\";\n } else {\n group += char;\n }\n } else if (group === \"\" && currentGroupOpener === char) {\n output.push(char);\n currentGroupOpener = null;\n group = \"\";\n } else {\n group += char;\n }\n } else if ([\"[\", \"{\"].includes(char)) {\n currentGroupOpener = char as \"[\" | \"{\";\n } else {\n output.push(char);\n }\n }\n\n output.forEach(assertSupported);\n return output;\n}\n\nfunction assertSupported(character: string): never | void {\n if (/^\\/.+/u.exec(character) || /.+>[\\d]*\\/?$/u.exec(character)) {\n throw new Error(\"Unsupported keyboard input\");\n }\n}\n\nfunction matchingBrace(opener: \"[\" | \"{\"): \"]\" | \"}\" {\n return opener === \"{\" ? \"}\" : \"]\";\n}\n","import type { Node as ProseMirrorNode, Schema } from \"prosemirror-model\";\n\nimport {\n AllSelection,\n EditorState,\n type Plugin,\n type Selection,\n TextSelection,\n} from \"prosemirror-state\";\nimport { EditorView } from \"prosemirror-view\";\n\nimport { tokenizeKeyboardInput } from \"./utils/keyboardInput\";\n\nexport interface KeyboardModifiers {\n altKey?: boolean;\n ctrlKey?: boolean;\n metaKey?: boolean;\n shiftKey?: boolean;\n}\n\nexport interface Options {\n plugins: Array<Plugin>;\n}\n\nexport type TesterSelection =\n | \"all\"\n | \"end\"\n | \"start\"\n | { from: number; to: number }\n | Selection\n | number;\n\ntype UsableMutationRecord = Omit<\n MutationRecord,\n \"addedNodes\" | \"removedNodes\"\n> & {\n addedNodes: Array<Node>;\n removedNodes: Array<Node>;\n};\n\nclass KeyboardEventMock extends KeyboardEvent {\n private readonly onPreventDefault: () => void;\n\n public constructor(\n onPreventDefault: () => void,\n type: string,\n eventInitDict?: KeyboardEventInit,\n ) {\n super(type, eventInitDict);\n this.onPreventDefault = onPreventDefault;\n }\n public override preventDefault(): void {\n super.preventDefault();\n this.onPreventDefault();\n }\n}\n\nclass MutationObserverMock {\n private static readonly activeObservers: Map<Node, MutationObserverMock> =\n new Map<Node, MutationObserverMock>();\n\n private readonly callback: MutationCallback;\n private target: Node | undefined;\n\n public constructor(callback: MutationCallback) {\n this.callback = callback;\n this.target = undefined;\n }\n\n public static createMutation(\n target: Node,\n mutationRecords: Array<UsableMutationRecord>,\n ): void {\n const observer = MutationObserverMock.activeObservers.get(target);\n if (observer === undefined) {\n return;\n }\n observer.callback(\n mutationRecords as unknown as Array<MutationRecord>,\n observer,\n );\n }\n\n public disconnect(): void {\n if (this.target !== undefined) {\n MutationObserverMock.activeObservers.delete(this.target);\n }\n this.target = undefined;\n }\n\n public observe(target: Node): void {\n this.target = target;\n MutationObserverMock.activeObservers.set(target, this);\n }\n\n // eslint-disable-next-line @typescript-eslint/class-methods-use-this -- Mocking another method\n public takeRecords(): Array<MutationRecord> {\n return [];\n }\n}\n\nexport class ProseMirrorTester {\n public get doc(): ProseMirrorNode {\n return this.view.state.doc;\n }\n\n public get schema(): Schema {\n return this.view.state.schema;\n }\n\n private readonly view: EditorView;\n\n public constructor(\n documentRoot: ProseMirrorNode,\n options: Partial<Options> = {},\n ) {\n if (typeof document === \"undefined\") {\n throw new Error(\"TODO\");\n }\n\n const element = document.createElement(\"div\");\n document.body.append(element);\n\n const state = EditorState.create({\n doc: documentRoot,\n plugins: options.plugins ?? [],\n });\n\n global.MutationObserver = MutationObserverMock;\n\n this.view = new EditorView(element, {\n state,\n });\n }\n\n public insertText(text: string, modifiers?: KeyboardModifiers): void {\n for (const key of tokenizeKeyboardInput(text)) {\n const character = keyToChar(key);\n\n let keydownPrevented = false;\n this.view.dispatchEvent(\n new KeyboardEventMock(\n () => {\n keydownPrevented = true;\n },\n \"keydown\",\n {\n bubbles: true,\n charCode: character.charCodeAt(0),\n key,\n ...modifiers,\n },\n ),\n );\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- False positive due to the value being set in a callback\n if (keydownPrevented) {\n continue;\n }\n\n this.view.dispatchEvent(\n new KeyboardEvent(\"keypress\", {\n bubbles: true,\n charCode: character.charCodeAt(0),\n key,\n keyCode: character.charCodeAt(0),\n ...modifiers,\n }),\n );\n\n const domNode = this.view.domAtPos(this.view.state.selection.from).node;\n if (\n domNode.childNodes.length === 1 &&\n domNode.firstChild instanceof HTMLBRElement &&\n domNode.firstChild.classList.contains(\"ProseMirror-trailingBreak\")\n ) {\n const brNode = domNode.firstChild;\n const textNode = new Text(character);\n domNode.removeChild(brNode);\n domNode.appendChild(textNode);\n MutationObserverMock.createMutation(this.view.dom, [\n {\n addedNodes: [textNode],\n attributeName: null,\n attributeNamespace: null,\n nextSibling: brNode,\n oldValue: null,\n previousSibling: null,\n removedNodes: [],\n target: domNode,\n type: \"childList\",\n },\n {\n addedNodes: [],\n attributeName: null,\n attributeNamespace: null,\n nextSibling: null,\n oldValue: null,\n previousSibling: textNode,\n removedNodes: [brNode],\n target: domNode,\n type: \"childList\",\n },\n ]);\n } else {\n const target = findLastCharacterDataNode(domNode);\n if (target === null) {\n continue;\n }\n const oldValue = target.data;\n const domOffset =\n this.view.state.selection.from - this.view.posAtDOM(target, 0);\n target.data =\n target.data.slice(0, domOffset) +\n character +\n target.data.slice(domOffset);\n MutationObserverMock.createMutation(this.view.dom, [\n {\n addedNodes: [],\n attributeName: null,\n attributeNamespace: null,\n nextSibling: null,\n oldValue,\n previousSibling: null,\n removedNodes: [],\n target,\n type: \"characterData\",\n },\n ]);\n }\n\n this.view.dispatchEvent(\n new KeyboardEvent(\"keyup\", {\n bubbles: true,\n charCode: character.charCodeAt(0),\n key,\n keyCode: character.charCodeAt(0),\n ...modifiers,\n }),\n );\n }\n }\n\n public selectText(selection: TesterSelection): void {\n this.view.dispatch(\n this.view.state.tr.setSelection(this.getSelection(selection)),\n );\n }\n\n private getSelection(selection: TesterSelection): Selection {\n if (selection === \"all\") {\n return new AllSelection(this.doc);\n }\n\n if (\n typeof selection === \"object\" &&\n \"$anchor\" in selection &&\n \"$head\" in selection\n ) {\n return selection;\n }\n\n if (\n typeof selection === \"object\" &&\n \"from\" in selection &&\n \"to\" in selection\n ) {\n return TextSelection.between(\n this.doc.resolve(selection.from),\n this.doc.resolve(selection.to),\n );\n }\n\n let pos = 0;\n if (selection === \"start\") {\n pos = 0;\n } else if (selection === \"end\") {\n pos = this.doc.nodeSize - 2;\n } else {\n pos = selection;\n }\n\n return TextSelection.near(this.doc.resolve(pos));\n }\n}\n\nfunction findLastCharacterDataNode(node: Node): CharacterData | null {\n if (node instanceof CharacterData) {\n return node;\n }\n for (const child of Array.from(node.childNodes).reverse()) {\n const textNode = findLastCharacterDataNode(child);\n if (textNode !== null) {\n return textNode;\n }\n }\n return null;\n}\n\nfunction keyToChar(key: string): string {\n if (key === \"Enter\") {\n return \"\\n\";\n }\n if (key === \"Tab\") {\n return \"\\t\";\n }\n return key;\n}\n","import type { Node } from \"prosemirror-model\";\n\nimport { expect } from \"vitest\";\n\nimport { stringifyProseMirrorNode } from \"./stringifyProseMirrorNode\";\n\nexport {\n type KeyboardModifiers,\n type Options,\n ProseMirrorTester,\n type TesterSelection,\n} from \"./ProseMirrorTester\";\n\nexport interface CustomMatchers<R = unknown> {\n toEqualProseMirrorNode(expected: Node): R;\n}\n\n/* eslint-disable @typescript-eslint/no-empty-object-type, @typescript-eslint/no-explicit-any -- These are overridest for vitest matchers */\n\ndeclare module \"vitest\" {\n interface Assertion<T = any> extends CustomMatchers<T> {}\n interface AsymmetricMatchersContaining extends CustomMatchers {}\n}\n\n/* eslint-enable */\n\nexpect.extend({\n toEqualProseMirrorNode(received: Node, expected: Node) {\n const receivedDoc = `\\n${stringifyProseMirrorNode(received)}\\n`;\n const expectedDoc = `\\n${stringifyProseMirrorNode(expected)}\\n`;\n const pass = this.equals(receivedDoc, expectedDoc);\n const message = pass\n ? (): string =>\n `${this.utils.matcherHint(\".not.toEqualProsemirrorNode\")}\\n\\n` +\n `Expected value of document to not equal:\\n ${this.utils.printExpected(expectedDoc)}\\n` +\n `Actual:\\n ${this.utils.printReceived(receivedDoc)}`\n : (): string => {\n const diffString = this.utils.diff(expectedDoc, receivedDoc, {\n expand: this.expand ?? false,\n });\n return `${this.utils.matcherHint(\".toEqualProsemirrorNode\")}\\n\\nExpected value of document to equal:\\n${this.utils.printExpected(expectedDoc)}\\nActual:\\n${this.utils.printReceived(receivedDoc)}${diffString !== undefined ? `\\n\\nDifference:\\n\\n${diffString}` : \"\"}`;\n };\n return {\n message,\n pass,\n };\n },\n});\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vitest-prosemirror",
3
- "version": "0.2.2",
3
+ "version": "0.3.0",
4
4
  "description": "A plugin for Vitest that enables you to write tests using the ProseMirror editor",
5
5
  "keywords": [
6
6
  "vitest",
@@ -52,8 +52,7 @@
52
52
  "prosemirror-model": "^1.24.1",
53
53
  "prosemirror-state": "^1.4.3",
54
54
  "prosemirror-view": "^1.38.0",
55
- "stringify-object": "^5.0.0",
56
- "test-keyboard": "^2.0.7"
55
+ "stringify-object": "^5.0.0"
57
56
  },
58
57
  "devDependencies": {
59
58
  "@eslint-community/eslint-plugin-eslint-comments": "^4.4.0",