From dd7fd0ebd38739156ef5866328b7eaa05c74763a Mon Sep 17 00:00:00 2001 From: awjin Date: Mon, 6 Mar 2023 00:08:45 -0800 Subject: [PATCH 1/4] After removing a ListItemNode, merge its siblings. --- .../lexical-list/src/LexicalListItemNode.ts | 13 +- .../unit/LexicalListItemNode.test.ts | 614 ++++++++++++++++++ packages/lexical-list/src/formatList.ts | 23 + 3 files changed, 649 insertions(+), 1 deletion(-) diff --git a/packages/lexical-list/src/LexicalListItemNode.ts b/packages/lexical-list/src/LexicalListItemNode.ts index e6e5968c431..42d36975dd9 100644 --- a/packages/lexical-list/src/LexicalListItemNode.ts +++ b/packages/lexical-list/src/LexicalListItemNode.ts @@ -41,8 +41,10 @@ import {$createListNode, $isListNode} from './'; import { $handleIndent, $handleOutdent, + mergeLists, updateChildrenListItemValue, } from './formatList'; +import {isNestedListNode} from './utils'; export type SerializedListItemNode = Spread< { @@ -243,10 +245,19 @@ export class ListItemNode extends ElementNode { } remove(preserveEmptyParent?: boolean): void { + const prevSibling = this.getPreviousSibling(); const nextSibling = this.getNextSibling(); super.remove(preserveEmptyParent); - if (nextSibling !== null) { + if ( + prevSibling && + nextSibling && + isNestedListNode(prevSibling) && + isNestedListNode(nextSibling) + ) { + mergeLists(prevSibling.getFirstChild(), nextSibling.getFirstChild()); + nextSibling.remove(); + } else if (nextSibling) { const parent = nextSibling.getParent(); if ($isListNode(parent)) { diff --git a/packages/lexical-list/src/__tests__/unit/LexicalListItemNode.test.ts b/packages/lexical-list/src/__tests__/unit/LexicalListItemNode.test.ts index 303b730af33..f62a58ef2ab 100644 --- a/packages/lexical-list/src/__tests__/unit/LexicalListItemNode.test.ts +++ b/packages/lexical-list/src/__tests__/unit/LexicalListItemNode.test.ts @@ -28,6 +28,10 @@ const editorConfig = Object.freeze({ }, }); +function stripLineBreaks(str: string): string { + return str.replace(/\n\s+/g, ''); +} + describe('LexicalListItemNode tests', () => { initializeUnitTest((testEnv) => { test('ListItemNode.constructor', async () => { @@ -237,6 +241,616 @@ describe('LexicalListItemNode tests', () => { }); }); + describe('ListItemNode.remove()', () => { + // - A + // - x + // - B + test('siblings are not nested', async () => { + const {editor} = testEnv; + let x; + + await editor.update(() => { + const root = $getRoot(); + const parent = new ListNode('bullet', 1); + + const A_listItem = new ListItemNode(); + A_listItem.append(new TextNode('A')); + + x = new ListItemNode(); + x.append(new TextNode('x')); + + const B_listItem = new ListItemNode(); + B_listItem.append(new TextNode('B')); + + parent.append(A_listItem, x, B_listItem); + root.append(parent); + }); + + expect(testEnv.outerHTML).toBe( + stripLineBreaks(` +
+ +
+ `), + ); + + await editor.update(() => x.remove()); + + expect(testEnv.outerHTML).toBe( + stripLineBreaks(` +
+ +
+ `), + ); + }); + + // - A + // - x + // - B + test('the previous sibling is nested', async () => { + const {editor} = testEnv; + let x; + + await editor.update(() => { + const root = $getRoot(); + const parent = new ListNode('bullet', 1); + + const A_listItem = new ListItemNode(); + const A_nestedList = new ListNode('bullet', 1); + const A_nestedListItem = new ListItemNode(); + A_listItem.append(A_nestedList); + A_nestedList.append(A_nestedListItem); + A_nestedListItem.append(new TextNode('A')); + + x = new ListItemNode(); + x.append(new TextNode('x')); + + const B_listItem = new ListItemNode(); + B_listItem.append(new TextNode('B')); + + parent.append(A_listItem, x, B_listItem); + root.append(parent); + }); + + expect(testEnv.outerHTML).toBe( + stripLineBreaks(` +
+ +
+ `), + ); + + await editor.update(() => x.remove()); + + expect(testEnv.outerHTML).toBe( + stripLineBreaks(` +
+ +
+ `), + ); + }); + + // - A + // - x + // - B + test('the next sibling is nested', async () => { + const {editor} = testEnv; + let x; + + await editor.update(() => { + const root = $getRoot(); + const parent = new ListNode('bullet', 1); + + const A_listItem = new ListItemNode(); + A_listItem.append(new TextNode('A')); + + x = new ListItemNode(); + x.append(new TextNode('x')); + + const B_listItem = new ListItemNode(); + const B_nestedList = new ListNode('bullet', 1); + const B_nestedListItem = new ListItemNode(); + B_listItem.append(B_nestedList); + B_nestedList.append(B_nestedListItem); + B_nestedListItem.append(new TextNode('B')); + + parent.append(A_listItem, x, B_listItem); + root.append(parent); + }); + + expect(testEnv.outerHTML).toBe( + stripLineBreaks(` +
+ +
+ `), + ); + + await editor.update(() => x.remove()); + + expect(testEnv.outerHTML).toBe( + stripLineBreaks(` +
+ +
+ `), + ); + }); + + // - A + // - x + // - B + test('both siblings are nested', async () => { + const {editor} = testEnv; + let x; + + await editor.update(() => { + const root = $getRoot(); + const parent = new ListNode('bullet', 1); + + const A_listItem = new ListItemNode(); + const A_nestedList = new ListNode('bullet', 1); + const A_nestedListItem = new ListItemNode(); + A_listItem.append(A_nestedList); + A_nestedList.append(A_nestedListItem); + A_nestedListItem.append(new TextNode('A')); + + x = new ListItemNode(); + x.append(new TextNode('x')); + + const B_listItem = new ListItemNode(); + const B_nestedList = new ListNode('bullet', 1); + const B_nestedListItem = new ListItemNode(); + B_listItem.append(B_nestedList); + B_nestedList.append(B_nestedListItem); + B_nestedListItem.append(new TextNode('B')); + + parent.append(A_listItem, x, B_listItem); + root.append(parent); + }); + + expect(testEnv.outerHTML).toBe( + stripLineBreaks(` +
+ +
+ `), + ); + + await editor.update(() => x.remove()); + + expect(testEnv.outerHTML).toBe( + stripLineBreaks(` +
+ +
+ `), + ); + }); + + // - A1 + // - A2 + // - x + // - B + test('the previous sibling is nested deeper than the next sibling', async () => { + const {editor} = testEnv; + let x; + + await editor.update(() => { + const root = $getRoot(); + const parent = new ListNode('bullet', 1); + + const A_listItem = new ListItemNode(); + const A_nestedList = new ListNode('bullet', 1); + const A_nestedListItem1 = new ListItemNode(); + const A_nestedListItem2 = new ListItemNode(); + const A_deeplyNestedList = new ListNode('bullet', 1); + const A_deeplyNestedListItem = new ListItemNode(); + A_listItem.append(A_nestedList); + A_nestedList.append(A_nestedListItem1); + A_nestedList.append(A_nestedListItem2); + A_nestedListItem1.append(new TextNode('A1')); + A_nestedListItem2.append(A_deeplyNestedList); + A_deeplyNestedList.append(A_deeplyNestedListItem); + A_deeplyNestedListItem.append(new TextNode('A2')); + + x = new ListItemNode(); + x.append(new TextNode('x')); + + const B_listItem = new ListItemNode(); + const B_nestedList = new ListNode('bullet', 1); + const B_nestedlistItem = new ListItemNode(); + B_listItem.append(B_nestedList); + B_nestedList.append(B_nestedlistItem); + B_nestedlistItem.append(new TextNode('B')); + + parent.append(A_listItem, x, B_listItem); + root.append(parent); + }); + + expect(testEnv.outerHTML).toBe( + stripLineBreaks(` +
+ +
+ `), + ); + + await editor.update(() => x.remove()); + + expect(testEnv.outerHTML).toBe( + stripLineBreaks(` +
+ +
+ `), + ); + }); + + // - A + // - x + // - B1 + // - B2 + test('the next sibling is nested deeper than the previous sibling', async () => { + const {editor} = testEnv; + let x; + + await editor.update(() => { + const root = $getRoot(); + const parent = new ListNode('bullet', 1); + + const A_listItem = new ListItemNode(); + const A_nestedList = new ListNode('bullet', 1); + const A_nestedListItem = new ListItemNode(); + A_listItem.append(A_nestedList); + A_nestedList.append(A_nestedListItem); + A_nestedListItem.append(new TextNode('A')); + + x = new ListItemNode(); + x.append(new TextNode('x')); + + const B_listItem = new ListItemNode(); + const B_nestedList = new ListNode('bullet', 1); + const B_nestedListItem1 = new ListItemNode(); + const B_nestedListItem2 = new ListItemNode(); + const B_deeplyNestedList = new ListNode('bullet', 1); + const B_deeplyNestedListItem = new ListItemNode(); + B_listItem.append(B_nestedList); + B_nestedList.append(B_nestedListItem1); + B_nestedList.append(B_nestedListItem2); + B_nestedListItem1.append(B_deeplyNestedList); + B_nestedListItem2.append(new TextNode('B2')); + B_deeplyNestedList.append(B_deeplyNestedListItem); + B_deeplyNestedListItem.append(new TextNode('B1')); + + parent.append(A_listItem, x, B_listItem); + root.append(parent); + }); + + expect(testEnv.outerHTML).toBe( + stripLineBreaks(` +
+ +
+ `), + ); + + await editor.update(() => x.remove()); + + expect(testEnv.outerHTML).toBe( + stripLineBreaks(` +
+ +
+ `), + ); + }); + + // - A1 + // - A2 + // - x + // - B1 + // - B2 + test('both siblings are deeply nested', async () => { + const {editor} = testEnv; + let x; + + await editor.update(() => { + const root = $getRoot(); + const parent = new ListNode('bullet', 1); + + const A_listItem = new ListItemNode(); + const A_nestedList = new ListNode('bullet', 1); + const A_nestedListItem1 = new ListItemNode(); + const A_nestedListItem2 = new ListItemNode(); + const A_deeplyNestedList = new ListNode('bullet', 1); + const A_deeplyNestedListItem = new ListItemNode(); + A_listItem.append(A_nestedList); + A_nestedList.append(A_nestedListItem1); + A_nestedList.append(A_nestedListItem2); + A_nestedListItem1.append(new TextNode('A1')); + A_nestedListItem2.append(A_deeplyNestedList); + A_deeplyNestedList.append(A_deeplyNestedListItem); + A_deeplyNestedListItem.append(new TextNode('A2')); + + x = new ListItemNode(); + x.append(new TextNode('x')); + + const B_listItem = new ListItemNode(); + const B_nestedList = new ListNode('bullet', 1); + const B_nestedListItem1 = new ListItemNode(); + const B_nestedListItem2 = new ListItemNode(); + const B_deeplyNestedList = new ListNode('bullet', 1); + const B_deeplyNestedListItem = new ListItemNode(); + B_listItem.append(B_nestedList); + B_nestedList.append(B_nestedListItem1); + B_nestedList.append(B_nestedListItem2); + B_nestedListItem1.append(B_deeplyNestedList); + B_nestedListItem2.append(new TextNode('B2')); + B_deeplyNestedList.append(B_deeplyNestedListItem); + B_deeplyNestedListItem.append(new TextNode('B1')); + + parent.append(A_listItem, x, B_listItem); + root.append(parent); + }); + + expect(testEnv.outerHTML).toBe( + stripLineBreaks(` +
+ +
+ `), + ); + + await editor.update(() => x.remove()); + + expect(testEnv.outerHTML).toBe( + stripLineBreaks(` +
+ +
+ `), + ); + }); + }); + describe('ListItemNode.insertNewAfter(): non-empty list items', () => { let listNode; let listItemNode1; diff --git a/packages/lexical-list/src/formatList.ts b/packages/lexical-list/src/formatList.ts index f206f9d9556..7b377c1bbdb 100644 --- a/packages/lexical-list/src/formatList.ts +++ b/packages/lexical-list/src/formatList.ts @@ -207,6 +207,29 @@ function createListOrMerge(node: ElementNode, listType: ListType): ListNode { } } +export function mergeLists(list1: ListNode, list2: ListNode): void { + const listItem1 = list1.getLastChild(); + const listItem2 = list2.getFirstChild(); + + if ( + listItem1 && + listItem2 && + isNestedListNode(listItem1) && + isNestedListNode(listItem2) + ) { + mergeLists(listItem1.getFirstChild(), listItem2.getFirstChild()); + listItem2.remove(); + } + + const toMerge = list2.getChildren(); + if (toMerge.length > 0) { + list1.append(...toMerge); + updateChildrenListItemValue(list1); + } + + list2.remove(); +} + export function removeList(editor: LexicalEditor): void { editor.update(() => { const selection = $getSelection(); From 26513e66e489f5577c8194b28032a0fd02a57de0 Mon Sep 17 00:00:00 2001 From: awjin Date: Mon, 6 Mar 2023 13:38:31 -0800 Subject: [PATCH 2/4] Code review: use prettier to format test strings. --- .../unit/LexicalListItemNode.test.ts | 173 ++++++++++++------ packages/lexical-list/src/__tests__/utils.ts | 30 +++ 2 files changed, 143 insertions(+), 60 deletions(-) create mode 100644 packages/lexical-list/src/__tests__/utils.ts diff --git a/packages/lexical-list/src/__tests__/unit/LexicalListItemNode.test.ts b/packages/lexical-list/src/__tests__/unit/LexicalListItemNode.test.ts index f62a58ef2ab..07e80bff7d5 100644 --- a/packages/lexical-list/src/__tests__/unit/LexicalListItemNode.test.ts +++ b/packages/lexical-list/src/__tests__/unit/LexicalListItemNode.test.ts @@ -15,6 +15,7 @@ import { ListItemNode, ListNode, } from '../..'; +import {expectHtmlToBeEqual, html} from '../utils'; const editorConfig = Object.freeze({ namespace: '', @@ -28,10 +29,6 @@ const editorConfig = Object.freeze({ }, }); -function stripLineBreaks(str: string): string { - return str.replace(/\n\s+/g, ''); -} - describe('LexicalListItemNode tests', () => { initializeUnitTest((testEnv) => { test('ListItemNode.constructor', async () => { @@ -266,9 +263,13 @@ describe('LexicalListItemNode tests', () => { root.append(parent); }); - expect(testEnv.outerHTML).toBe( - stripLineBreaks(` -
+ expectHtmlToBeEqual( + testEnv.outerHTML, + html` +
  • A @@ -281,14 +282,18 @@ describe('LexicalListItemNode tests', () => {
- `), + `, ); await editor.update(() => x.remove()); - expect(testEnv.outerHTML).toBe( - stripLineBreaks(` -
+ expectHtmlToBeEqual( + testEnv.outerHTML, + html` +
  • A @@ -298,7 +303,7 @@ describe('LexicalListItemNode tests', () => {
- `), + `, ); }); @@ -330,9 +335,13 @@ describe('LexicalListItemNode tests', () => { root.append(parent); }); - expect(testEnv.outerHTML).toBe( - stripLineBreaks(` -
+ expectHtmlToBeEqual( + testEnv.outerHTML, + html` +
    • @@ -349,14 +358,18 @@ describe('LexicalListItemNode tests', () => {
- `), + `, ); await editor.update(() => x.remove()); - expect(testEnv.outerHTML).toBe( - stripLineBreaks(` -
+ expectHtmlToBeEqual( + testEnv.outerHTML, + html` +
    • @@ -370,7 +383,7 @@ describe('LexicalListItemNode tests', () => {
- `), + `, ); }); @@ -402,9 +415,13 @@ describe('LexicalListItemNode tests', () => { root.append(parent); }); - expect(testEnv.outerHTML).toBe( - stripLineBreaks(` -
+ expectHtmlToBeEqual( + testEnv.outerHTML, + html` +
  • A @@ -421,14 +438,18 @@ describe('LexicalListItemNode tests', () => {
- `), + `, ); await editor.update(() => x.remove()); - expect(testEnv.outerHTML).toBe( - stripLineBreaks(` -
+ expectHtmlToBeEqual( + testEnv.outerHTML, + html` +
  • A @@ -442,7 +463,7 @@ describe('LexicalListItemNode tests', () => {
- `), + `, ); }); @@ -478,9 +499,13 @@ describe('LexicalListItemNode tests', () => { root.append(parent); }); - expect(testEnv.outerHTML).toBe( - stripLineBreaks(` -
+ expectHtmlToBeEqual( + testEnv.outerHTML, + html` +
    • @@ -501,14 +526,18 @@ describe('LexicalListItemNode tests', () => {
- `), + `, ); await editor.update(() => x.remove()); - expect(testEnv.outerHTML).toBe( - stripLineBreaks(` -
+ expectHtmlToBeEqual( + testEnv.outerHTML, + html` +
    • @@ -522,7 +551,7 @@ describe('LexicalListItemNode tests', () => {
- `), + `, ); }); @@ -566,9 +595,13 @@ describe('LexicalListItemNode tests', () => { root.append(parent); }); - expect(testEnv.outerHTML).toBe( - stripLineBreaks(` -
+ expectHtmlToBeEqual( + testEnv.outerHTML, + html` +
    • @@ -596,14 +629,18 @@ describe('LexicalListItemNode tests', () => {
- `), + `, ); await editor.update(() => x.remove()); - expect(testEnv.outerHTML).toBe( - stripLineBreaks(` -
+ expectHtmlToBeEqual( + testEnv.outerHTML, + html` +
    • @@ -624,7 +661,7 @@ describe('LexicalListItemNode tests', () => {
- `), + `, ); }); @@ -668,9 +705,13 @@ describe('LexicalListItemNode tests', () => { root.append(parent); }); - expect(testEnv.outerHTML).toBe( - stripLineBreaks(` -
+ expectHtmlToBeEqual( + testEnv.outerHTML, + html` +
    • @@ -698,14 +739,18 @@ describe('LexicalListItemNode tests', () => {
- `), + `, ); await editor.update(() => x.remove()); - expect(testEnv.outerHTML).toBe( - stripLineBreaks(` -
+ expectHtmlToBeEqual( + testEnv.outerHTML, + html` +
    • @@ -726,7 +771,7 @@ describe('LexicalListItemNode tests', () => {
- `), + `, ); }); @@ -778,9 +823,13 @@ describe('LexicalListItemNode tests', () => { root.append(parent); }); - expect(testEnv.outerHTML).toBe( - stripLineBreaks(` -
+ expectHtmlToBeEqual( + testEnv.outerHTML, + html` +
    • @@ -815,14 +864,18 @@ describe('LexicalListItemNode tests', () => {
- `), + `, ); await editor.update(() => x.remove()); - expect(testEnv.outerHTML).toBe( - stripLineBreaks(` -
+ expectHtmlToBeEqual( + testEnv.outerHTML, + html` +
    • @@ -846,7 +899,7 @@ describe('LexicalListItemNode tests', () => {
- `), + `, ); }); }); diff --git a/packages/lexical-list/src/__tests__/utils.ts b/packages/lexical-list/src/__tests__/utils.ts new file mode 100644 index 00000000000..b432f5c38ec --- /dev/null +++ b/packages/lexical-list/src/__tests__/utils.ts @@ -0,0 +1,30 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ +import {expect} from '@playwright/test'; +import prettier from 'prettier'; + +// This tag function is just used to trigger prettier auto-formatting. +// (https://prettier.io/blog/2020/08/24/2.1.0.html#api) +export function html(partials: TemplateStringsArray, ...params: string[]) { + let output = ''; + for (let i = 0; i < partials.length; i++) { + output += partials[i]; + if (i < partials.length - 1) { + output += params[i]; + } + } + return output; +} + +export function expectHtmlToBeEqual(expected: string, actual: string): void { + expect(prettifyHtml(expected)).toBe(prettifyHtml(actual)); +} + +function prettifyHtml(s: string) { + return prettier.format(s.replace(/\n/g, ''), {parser: 'html'}); +} From 43394cdd5d8837f2f25c6e68887e2513dc55f87b Mon Sep 17 00:00:00 2001 From: awjin Date: Mon, 6 Mar 2023 13:46:05 -0800 Subject: [PATCH 3/4] Add return types. --- packages/lexical-list/src/__tests__/utils.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/lexical-list/src/__tests__/utils.ts b/packages/lexical-list/src/__tests__/utils.ts index b432f5c38ec..bb92f7caf97 100644 --- a/packages/lexical-list/src/__tests__/utils.ts +++ b/packages/lexical-list/src/__tests__/utils.ts @@ -10,7 +10,10 @@ import prettier from 'prettier'; // This tag function is just used to trigger prettier auto-formatting. // (https://prettier.io/blog/2020/08/24/2.1.0.html#api) -export function html(partials: TemplateStringsArray, ...params: string[]) { +export function html( + partials: TemplateStringsArray, + ...params: string[] +): string { let output = ''; for (let i = 0; i < partials.length; i++) { output += partials[i]; @@ -25,6 +28,6 @@ export function expectHtmlToBeEqual(expected: string, actual: string): void { expect(prettifyHtml(expected)).toBe(prettifyHtml(actual)); } -function prettifyHtml(s: string) { +function prettifyHtml(s: string): string { return prettier.format(s.replace(/\n/g, ''), {parser: 'html'}); } From 6046140d8d43ccf979945212494796c859058502 Mon Sep 17 00:00:00 2001 From: awjin Date: Mon, 6 Mar 2023 18:18:37 -0800 Subject: [PATCH 4/4] Code review: clean up the rest of the tests. --- .../unit/LexicalListItemNode.test.ts | 364 +++++++++++++++--- 1 file changed, 320 insertions(+), 44 deletions(-) diff --git a/packages/lexical-list/src/__tests__/unit/LexicalListItemNode.test.ts b/packages/lexical-list/src/__tests__/unit/LexicalListItemNode.test.ts index 07e80bff7d5..b948d319b1f 100644 --- a/packages/lexical-list/src/__tests__/unit/LexicalListItemNode.test.ts +++ b/packages/lexical-list/src/__tests__/unit/LexicalListItemNode.test.ts @@ -51,16 +51,22 @@ describe('LexicalListItemNode tests', () => { await editor.update(() => { const listItemNode = new ListItemNode(); - expect(listItemNode.createDOM(editorConfig).outerHTML).toBe( - '
  • ', + expectHtmlToBeEqual( + listItemNode.createDOM(editorConfig).outerHTML, + html` +
  • + `, ); - expect( + expectHtmlToBeEqual( listItemNode.createDOM({ namespace: '', theme: {}, }).outerHTML, - ).toBe('
  • '); + html` +
  • + `, + ); }); }); @@ -73,8 +79,11 @@ describe('LexicalListItemNode tests', () => { const domElement = listItemNode.createDOM(editorConfig); - expect(domElement.outerHTML).toBe( - '
  • ', + expectHtmlToBeEqual( + domElement.outerHTML, + html` +
  • + `, ); const newListItemNode = new ListItemNode(); @@ -86,8 +95,11 @@ describe('LexicalListItemNode tests', () => { expect(result).toBe(false); - expect(domElement.outerHTML).toBe( - '
  • ', + expectHtmlToBeEqual( + domElement.outerHTML, + html` +
  • + `, ); }); }); @@ -102,8 +114,11 @@ describe('LexicalListItemNode tests', () => { parentListNode.append(parentlistItemNode); const domElement = parentlistItemNode.createDOM(editorConfig); - expect(domElement.outerHTML).toBe( - '
  • ', + expectHtmlToBeEqual( + domElement.outerHTML, + html` +
  • + `, ); const nestedListNode = new ListNode('bullet', 1); nestedListNode.append(new ListItemNode()); @@ -116,8 +131,13 @@ describe('LexicalListItemNode tests', () => { expect(result).toBe(false); - expect(domElement.outerHTML).toBe( - '
  • ', + expectHtmlToBeEqual( + domElement.outerHTML, + html` +
  • + `, ); }); }); @@ -148,8 +168,26 @@ describe('LexicalListItemNode tests', () => { listNode.append(listItemNode1, listItemNode2, listItemNode3); }); - expect(testEnv.outerHTML).toBe( - '
    • one
    • two
    • three
    ', + expectHtmlToBeEqual( + testEnv.outerHTML, + html` +
    +
      +
    • + one +
    • +
    • + two +
    • +
    • + three +
    • +
    +
    + `, ); }); @@ -163,8 +201,26 @@ describe('LexicalListItemNode tests', () => { listItemNode1.replace(newListItemNode); }); - expect(testEnv.outerHTML).toBe( - '
    • bar
    • two
    • three
    ', + expectHtmlToBeEqual( + testEnv.outerHTML, + html` +
    +
      +
    • + bar +
    • +
    • + two +
    • +
    • + three +
    • +
    +
    + `, ); }); @@ -175,8 +231,26 @@ describe('LexicalListItemNode tests', () => { return; }); - expect(testEnv.outerHTML).toBe( - '
    • one
    • two
    • three
    ', + expectHtmlToBeEqual( + testEnv.outerHTML, + html` +
    +
      +
    • + one +
    • +
    • + two +
    • +
    • + three +
    • +
    +
    + `, ); await editor.update(() => { @@ -184,8 +258,24 @@ describe('LexicalListItemNode tests', () => { listItemNode1.replace(paragraphNode); }); - expect(testEnv.outerHTML).toBe( - '


    • two
    • three
    ', + expectHtmlToBeEqual( + testEnv.outerHTML, + html` +
    +


    +
      +
    • + two +
    • +
    • + three +
    • +
    +
    + `, ); }); @@ -197,8 +287,24 @@ describe('LexicalListItemNode tests', () => { listItemNode3.replace(paragraphNode); }); - expect(testEnv.outerHTML).toBe( - '
    • one
    • two


    ', + expectHtmlToBeEqual( + testEnv.outerHTML, + html` +
    +
      +
    • + one +
    • +
    • + two +
    • +
    +


    +
    + `, ); }); @@ -210,8 +316,26 @@ describe('LexicalListItemNode tests', () => { listItemNode2.replace(paragraphNode); }); - expect(testEnv.outerHTML).toBe( - '
    • one


    • three
    ', + expectHtmlToBeEqual( + testEnv.outerHTML, + html` +
    +
      +
    • + one +
    • +
    +


    +
      +
    • + three +
    • +
    +
    + `, ); }); @@ -223,8 +347,20 @@ describe('LexicalListItemNode tests', () => { listItemNode3.remove(); }); - expect(testEnv.outerHTML).toBe( - '
    • one
    ', + expectHtmlToBeEqual( + testEnv.outerHTML, + html` +
    +
      +
    • + one +
    • +
    +
    + `, ); await editor.update(() => { @@ -232,8 +368,16 @@ describe('LexicalListItemNode tests', () => { listItemNode1.replace(paragraphNode); }); - expect(testEnv.outerHTML).toBe( - '


    ', + expectHtmlToBeEqual( + testEnv.outerHTML, + html` +
    +


    +
    + `, ); }); }); @@ -929,8 +1073,26 @@ describe('LexicalListItemNode tests', () => { listItemNode3.append(new TextNode('three')); }); - expect(testEnv.outerHTML).toBe( - '
    • one
    • two
    • three
    ', + expectHtmlToBeEqual( + testEnv.outerHTML, + html` +
    +
      +
    • + one +
    • +
    • + two +
    • +
    • + three +
    • +
    +
    + `, ); }); @@ -941,8 +1103,27 @@ describe('LexicalListItemNode tests', () => { listItemNode1.insertNewAfter(); }); - expect(testEnv.outerHTML).toBe( - '
    • one

    • two
    • three
    ', + expectHtmlToBeEqual( + testEnv.outerHTML, + html` +
    +
      +
    • + one +
    • +

    • +
    • + two +
    • +
    • + three +
    • +
    +
    + `, ); }); @@ -953,8 +1134,27 @@ describe('LexicalListItemNode tests', () => { listItemNode3.insertNewAfter(); }); - expect(testEnv.outerHTML).toBe( - '
    • one
    • two
    • three

    ', + expectHtmlToBeEqual( + testEnv.outerHTML, + html` +
    +
      +
    • + one +
    • +
    • + two +
    • +
    • + three +
    • +

    • +
    +
    + `, ); }); @@ -965,8 +1165,27 @@ describe('LexicalListItemNode tests', () => { listItemNode3.insertNewAfter(); }); - expect(testEnv.outerHTML).toBe( - '
    • one
    • two
    • three

    ', + expectHtmlToBeEqual( + testEnv.outerHTML, + html` +
    +
      +
    • + one +
    • +
    • + two +
    • +
    • + three +
    • +

    • +
    +
    + `, ); }); @@ -978,16 +1197,41 @@ describe('LexicalListItemNode tests', () => { listItemNode3.remove(); }); - expect(testEnv.outerHTML).toBe( - '
    • one
    ', + expectHtmlToBeEqual( + testEnv.outerHTML, + html` +
    +
      +
    • + one +
    • +
    +
    + `, ); await editor.update(() => { listItemNode1.insertNewAfter(); }); - expect(testEnv.outerHTML).toBe( - '
    • one

    ', + expectHtmlToBeEqual( + testEnv.outerHTML, + html` +
    +
      +
    • + one +
    • +

    • +
    +
    + `, ); }); }); @@ -1048,8 +1292,30 @@ describe('LexicalListItemNode tests', () => { expect(listItemNode1.getIndent()).toBe(3); }); - expect(editor.getRootElement().innerHTML).toBe( - '
          • one
    • two
    ', + expectHtmlToBeEqual( + editor.getRootElement().innerHTML, + html` +
      +
    • +
        +
      • +
          +
        • +
            +
          • + one +
          • +
          +
        • +
        +
      • +
      +
    • +
    • + two +
    • +
    + `, ); await editor.update(() => { @@ -1060,8 +1326,18 @@ describe('LexicalListItemNode tests', () => { expect(listItemNode1.getIndent()).toBe(0); }); - expect(editor.getRootElement().innerHTML).toBe( - '
    • one
    • two
    ', + expectHtmlToBeEqual( + editor.getRootElement().innerHTML, + html` +
      +
    • + one +
    • +
    • + two +
    • +
    + `, ); }); });