2 * Copyright (c) Meta Platforms, Inc. and affiliates.
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
8 import {$createParagraphNode, $getRoot} from 'lexical';
9 import {initializeUnitTest} from 'lexical/src/__tests__/utils';
11 import {$createListItemNode, $createListNode} from '../..';
12 import {$getListDepth, $getTopListNode, $isLastItemInList} from '../../utils';
14 describe('Lexical List Utils tests', () => {
15 initializeUnitTest((testEnv) => {
16 test('getListDepth should return the 1-based depth of a list with one levels', async () => {
17 const editor = testEnv.editor;
22 const root = $getRoot();
24 const topListNode = $createListNode('bullet');
26 root.append(topListNode);
28 const result = $getListDepth(topListNode);
30 expect(result).toEqual(1);
34 test('getListDepth should return the 1-based depth of a list with two levels', async () => {
35 const editor = testEnv.editor;
37 await editor.update(() => {
44 const root = $getRoot();
46 const topListNode = $createListNode('bullet');
47 const secondLevelListNode = $createListNode('bullet');
49 const listItem1 = $createListItemNode();
50 const listItem2 = $createListItemNode();
51 const listItem3 = $createListItemNode();
53 root.append(topListNode);
55 topListNode.append(listItem1);
56 topListNode.append(listItem2);
57 topListNode.append(secondLevelListNode);
59 secondLevelListNode.append(listItem3);
61 const result = $getListDepth(secondLevelListNode);
63 expect(result).toEqual(2);
67 test('getListDepth should return the 1-based depth of a list with five levels', async () => {
68 const editor = testEnv.editor;
70 await editor.update(() => {
81 const root = $getRoot();
83 const topListNode = $createListNode('bullet');
84 const listNode2 = $createListNode('bullet');
85 const listNode3 = $createListNode('bullet');
86 const listNode4 = $createListNode('bullet');
87 const listNode5 = $createListNode('bullet');
89 const listItem1 = $createListItemNode();
90 const listItem2 = $createListItemNode();
91 const listItem3 = $createListItemNode();
92 const listItem4 = $createListItemNode();
94 root.append(topListNode);
96 topListNode.append(listItem1);
98 listItem1.append(listNode2);
99 listNode2.append(listItem2);
100 listItem2.append(listNode3);
101 listNode3.append(listItem3);
102 listItem3.append(listNode4);
103 listNode4.append(listItem4);
104 listItem4.append(listNode5);
106 const result = $getListDepth(listNode5);
108 expect(result).toEqual(5);
112 test('getTopListNode should return the top list node when the list is a direct child of the RootNode', async () => {
113 const editor = testEnv.editor;
115 await editor.update(() => {
122 const root = $getRoot();
124 const topListNode = $createListNode('bullet');
125 const secondLevelListNode = $createListNode('bullet');
127 const listItem1 = $createListItemNode();
128 const listItem2 = $createListItemNode();
129 const listItem3 = $createListItemNode();
131 root.append(topListNode);
133 topListNode.append(listItem1);
134 topListNode.append(listItem2);
135 topListNode.append(secondLevelListNode);
136 secondLevelListNode.append(listItem3);
138 const result = $getTopListNode(listItem3);
139 expect(result.getKey()).toEqual(topListNode.getKey());
143 test('getTopListNode should return the top list node when the list is not a direct child of the RootNode', async () => {
144 const editor = testEnv.editor;
146 await editor.update(() => {
154 const root = $getRoot();
156 const paragraphNode = $createParagraphNode();
157 const topListNode = $createListNode('bullet');
158 const secondLevelListNode = $createListNode('bullet');
160 const listItem1 = $createListItemNode();
161 const listItem2 = $createListItemNode();
162 const listItem3 = $createListItemNode();
163 root.append(paragraphNode);
164 paragraphNode.append(topListNode);
165 topListNode.append(listItem1);
166 topListNode.append(listItem2);
167 topListNode.append(secondLevelListNode);
168 secondLevelListNode.append(listItem3);
170 const result = $getTopListNode(listItem3);
171 expect(result.getKey()).toEqual(topListNode.getKey());
175 test('getTopListNode should return the top list node when the list item is deeply nested.', async () => {
176 const editor = testEnv.editor;
178 await editor.update(() => {
188 const root = $getRoot();
190 const paragraphNode = $createParagraphNode();
191 const topListNode = $createListNode('bullet');
192 const secondLevelListNode = $createListNode('bullet');
193 const thirdLevelListNode = $createListNode('bullet');
195 const listItem1 = $createListItemNode();
196 const listItem2 = $createListItemNode();
197 const listItem3 = $createListItemNode();
198 const listItem4 = $createListItemNode();
199 root.append(paragraphNode);
200 paragraphNode.append(topListNode);
201 topListNode.append(listItem1);
202 listItem1.append(secondLevelListNode);
203 secondLevelListNode.append(listItem2);
204 listItem2.append(thirdLevelListNode);
205 thirdLevelListNode.append(listItem3);
206 topListNode.append(listItem4);
208 const result = $getTopListNode(listItem4);
209 expect(result.getKey()).toEqual(topListNode.getKey());
213 test('isLastItemInList should return true if the listItem is the last in a nested list.', async () => {
214 const editor = testEnv.editor;
216 await editor.update(() => {
224 const root = $getRoot();
226 const topListNode = $createListNode('bullet');
227 const secondLevelListNode = $createListNode('bullet');
228 const thirdLevelListNode = $createListNode('bullet');
230 const listItem1 = $createListItemNode();
231 const listItem2 = $createListItemNode();
232 const listItem3 = $createListItemNode();
234 root.append(topListNode);
236 topListNode.append(listItem1);
237 listItem1.append(secondLevelListNode);
238 secondLevelListNode.append(listItem2);
239 listItem2.append(thirdLevelListNode);
240 thirdLevelListNode.append(listItem3);
242 const result = $isLastItemInList(listItem3);
244 expect(result).toEqual(true);
248 test('isLastItemInList should return true if the listItem is the last in a non-nested list.', async () => {
249 const editor = testEnv.editor;
251 await editor.update(() => {
256 const root = $getRoot();
258 const topListNode = $createListNode('bullet');
260 const listItem1 = $createListItemNode();
261 const listItem2 = $createListItemNode();
263 root.append(topListNode);
265 topListNode.append(listItem1);
266 topListNode.append(listItem2);
268 const result = $isLastItemInList(listItem2);
270 expect(result).toEqual(true);
274 test('isLastItemInList should return false if the listItem is not the last in a nested list.', async () => {
275 const editor = testEnv.editor;
277 await editor.update(() => {
285 const root = $getRoot();
287 const topListNode = $createListNode('bullet');
288 const secondLevelListNode = $createListNode('bullet');
289 const thirdLevelListNode = $createListNode('bullet');
291 const listItem1 = $createListItemNode();
292 const listItem2 = $createListItemNode();
293 const listItem3 = $createListItemNode();
295 root.append(topListNode);
297 topListNode.append(listItem1);
298 listItem1.append(secondLevelListNode);
299 secondLevelListNode.append(listItem2);
300 listItem2.append(thirdLevelListNode);
301 thirdLevelListNode.append(listItem3);
303 const result = $isLastItemInList(listItem2);
305 expect(result).toEqual(false);
309 test('isLastItemInList should return true if the listItem is not the last in a non-nested list.', async () => {
310 const editor = testEnv.editor;
312 await editor.update(() => {
317 const root = $getRoot();
319 const topListNode = $createListNode('bullet');
321 const listItem1 = $createListItemNode();
322 const listItem2 = $createListItemNode();
324 root.append(topListNode);
326 topListNode.append(listItem1);
327 topListNode.append(listItem2);
329 const result = $isLastItemInList(listItem1);
331 expect(result).toEqual(false);