import {DetailsNode} from "@lexical/rich-text/LexicalDetailsNode";
import {EditorUiContext} from "../../../../ui/framework/core";
import {EditorUIManager} from "../../../../ui/framework/manager";
-import {turtle} from "@codemirror/legacy-modes/mode/turtle";
-
type TestEnv = {
readonly container: HTMLDivElement;
readonly innerHTML: string;
};
+/**
+ * @deprecated - Consider using `createTestContext` instead within the test case.
+ */
export function initializeUnitTest(
runTests: (testEnv: TestEnv) => void,
editorConfig: CreateEditorArgs = {namespace: 'test', theme: {}},
expect(shape.children).toMatchObject(expected);
}
+/**
+ * Expect a given prop within the JSON editor state structure to be the given value.
+ * Uses dot notation for the provided `propPath`. Example:
+ * 0.5.cat => First child, Sixth child, cat property
+ */
+export function expectEditorStateJSONPropToEqual(editor: LexicalEditor, propPath: string, expected: any) {
+ let currentItem: any = editor.getEditorState().toJSON().root;
+ let currentPath = [];
+ const pathParts = propPath.split('.');
+
+ for (const part of pathParts) {
+ currentPath.push(part);
+ const childAccess = Number.isInteger(Number(part)) && Array.isArray(currentItem.children);
+ const target = childAccess ? currentItem.children : currentItem;
+
+ if (typeof target[part] === 'undefined') {
+ throw new Error(`Could not resolve editor state at path ${currentPath.join('.')}`)
+ }
+ currentItem = target[part];
+ }
+
+ expect(currentItem).toBe(expected);
+}
+
function formatHtml(s: string): string {
return s.replace(/>\s+</g, '><').replace(/\s*\n\s*/g, ' ').trim();
}
-import {initializeUnitTest} from "lexical/__tests__/utils";
-import {SerializedLinkNode} from "@lexical/link";
+import {
+ createTestContext,
+ dispatchKeydownEventForNode, expectEditorStateJSONPropToEqual,
+ expectNodeShapeToMatch
+} from "lexical/__tests__/utils";
import {
$getRoot,
ParagraphNode,
- SerializedParagraphNode,
- SerializedTextNode,
TextNode
} from "lexical";
import {registerAutoLinks} from "../auto-links";
describe('Auto-link service tests', () => {
- initializeUnitTest((testEnv) => {
-
- test('space after link in text', async () => {
- const {editor} = testEnv;
-
- registerAutoLinks(editor);
- let pNode!: ParagraphNode;
-
- editor.update(() => {
- pNode = new ParagraphNode();
- const text = new TextNode('Some https://example.com?test=true text');
- pNode.append(text);
- $getRoot().append(pNode);
-
- text.select(34, 34);
- });
+ test('space after link in text', async () => {
+ const {editor} = createTestContext();
+ registerAutoLinks(editor);
+ let pNode!: ParagraphNode;
+
+ editor.updateAndCommit(() => {
+ pNode = new ParagraphNode();
+ const text = new TextNode('Some https://example.com?test=true text');
+ pNode.append(text);
+ $getRoot().append(pNode);
+
+ text.select(34, 34);
+ });
- editor.commitUpdates();
+ dispatchKeydownEventForNode(pNode, editor, ' ');
- const pDomEl = editor.getElementByKey(pNode.getKey());
- const event = new KeyboardEvent('keydown', {
- bubbles: true,
- cancelable: true,
- key: ' ',
- keyCode: 62,
- });
- pDomEl?.dispatchEvent(event);
+ expectEditorStateJSONPropToEqual(editor, '0.1.url', 'https://example.com?test=true');
+ expectEditorStateJSONPropToEqual(editor, '0.1.0.text', 'https://example.com?test=true');
+ });
- editor.commitUpdates();
+ test('space after link at end of line', async () => {
+ const {editor} = createTestContext();
+ registerAutoLinks(editor);
+ let pNode!: ParagraphNode;
- const paragraph = editor!.getEditorState().toJSON().root
- .children[0] as SerializedParagraphNode;
- expect(paragraph.children[1].type).toBe('link');
+ editor.updateAndCommit(() => {
+ pNode = new ParagraphNode();
+ const text = new TextNode('Some https://example.com?test=true');
+ pNode.append(text);
+ $getRoot().append(pNode);
- const link = paragraph.children[1] as SerializedLinkNode;
- expect(link.url).toBe('https://example.com?test=true');
- const linkText = link.children[0] as SerializedTextNode;
- expect(linkText.text).toBe('https://example.com?test=true');
+ text.selectEnd();
});
- test('enter after link in text', async () => {
- const {editor} = testEnv;
-
- registerAutoLinks(editor);
- let pNode!: ParagraphNode;
-
- editor.update(() => {
- pNode = new ParagraphNode();
- const text = new TextNode('Some https://example.com?test=true text');
- pNode.append(text);
- $getRoot().append(pNode);
+ dispatchKeydownEventForNode(pNode, editor, ' ');
- text.select(34, 34);
- });
+ expectNodeShapeToMatch(editor, [{type: 'paragraph', children: [
+ {text: 'Some '},
+ {type: 'link', children: [{text: 'https://example.com?test=true'}]}
+ ]}]);
+ expectEditorStateJSONPropToEqual(editor, '0.1.url', 'https://example.com?test=true');
+ });
- editor.commitUpdates();
+ test('enter after link in text', async () => {
+ const {editor} = createTestContext();
+ registerAutoLinks(editor);
+ let pNode!: ParagraphNode;
- const pDomEl = editor.getElementByKey(pNode.getKey());
- const event = new KeyboardEvent('keydown', {
- bubbles: true,
- cancelable: true,
- key: 'Enter',
- keyCode: 66,
- });
- pDomEl?.dispatchEvent(event);
+ editor.updateAndCommit(() => {
+ pNode = new ParagraphNode();
+ const text = new TextNode('Some https://example.com?test=true text');
+ pNode.append(text);
+ $getRoot().append(pNode);
- editor.commitUpdates();
+ text.select(34, 34);
+ });
- const paragraph = editor!.getEditorState().toJSON().root
- .children[0] as SerializedParagraphNode;
- expect(paragraph.children[1].type).toBe('link');
+ dispatchKeydownEventForNode(pNode, editor, 'Enter');
- const link = paragraph.children[1] as SerializedLinkNode;
- expect(link.url).toBe('https://example.com?test=true');
- const linkText = link.children[0] as SerializedTextNode;
- expect(linkText.text).toBe('https://example.com?test=true');
- });
+ expectEditorStateJSONPropToEqual(editor, '0.1.url', 'https://example.com?test=true');
+ expectEditorStateJSONPropToEqual(editor, '0.1.0.text', 'https://example.com?test=true');
});
});
\ No newline at end of file