@cr_docs_t/dts 0.35.0 → 0.35.2

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.
Files changed (46) hide show
  1. package/dist/dts/FugueTree/FTree.d.ts +0 -1
  2. package/dist/dts/FugueTree/FTree.d.ts.map +1 -1
  3. package/dist/dts/FugueTree/FTree.js +3 -3
  4. package/dist/dts/FugueTree/FugueTree.d.ts +4 -1
  5. package/dist/dts/FugueTree/FugueTree.d.ts.map +1 -1
  6. package/dist/dts/FugueTree/FugueTree.js +9 -5
  7. package/dist/tests/unit/AST.test.d.ts +2 -0
  8. package/dist/tests/unit/AST.test.d.ts.map +1 -0
  9. package/dist/tests/unit/AST.test.js +111 -0
  10. package/dist/tests/unit/FTree.test.d.ts +2 -0
  11. package/dist/tests/unit/FTree.test.d.ts.map +1 -0
  12. package/dist/tests/unit/FTree.test.js +447 -0
  13. package/dist/tests/unit/FugueTree.test.d.ts.map +1 -0
  14. package/dist/tests/unit/FugueTree.test.js +416 -0
  15. package/dist/tests/unit/mocks/BragiAST-mocks.d.ts +2 -0
  16. package/dist/tests/unit/mocks/BragiAST-mocks.d.ts.map +1 -0
  17. package/dist/tests/unit/mocks/BragiAST-mocks.js +1 -0
  18. package/dist/tests/unit/mocks/FTree-mocks.d.ts +20 -0
  19. package/dist/tests/unit/mocks/FTree-mocks.d.ts.map +1 -0
  20. package/dist/tests/unit/mocks/FTree-mocks.js +36 -0
  21. package/dist/tests/unit/mocks/FugueTree-mocks.d.ts +24 -0
  22. package/dist/tests/unit/mocks/FugueTree-mocks.d.ts.map +1 -0
  23. package/dist/tests/unit/mocks/FugueTree-mocks.js +52 -0
  24. package/dist/tests/utils.d.ts +9 -0
  25. package/dist/tests/utils.d.ts.map +1 -0
  26. package/dist/tests/utils.js +47 -0
  27. package/dist/treesitter/index.d.ts +1 -0
  28. package/dist/treesitter/index.d.ts.map +1 -1
  29. package/dist/treesitter/index.js +1 -0
  30. package/dist/treesitter/utils.d.ts +9 -0
  31. package/dist/treesitter/utils.d.ts.map +1 -0
  32. package/dist/treesitter/utils.js +84 -0
  33. package/dist/types/Models/Schema.d.ts +1 -1
  34. package/dist/types/Models/Schema.js +1 -1
  35. package/dist/wasm/tree-sitter-latex.wasm +0 -0
  36. package/dist/wasm/web-tree-sitter.wasm +0 -0
  37. package/package.json +16 -4
  38. package/dist/tests/FugueList.test.d.ts +0 -2
  39. package/dist/tests/FugueList.test.d.ts.map +0 -1
  40. package/dist/tests/FugueList.test.js +0 -8
  41. package/dist/tests/FugueTree.test.d.ts.map +0 -1
  42. package/dist/tests/FugueTree.test.js +0 -8
  43. package/dist/tests/mocks.d.ts +0 -4
  44. package/dist/tests/mocks.d.ts.map +0 -1
  45. package/dist/tests/mocks.js +0 -4
  46. /package/dist/tests/{FugueTree.test.d.ts → unit/FugueTree.test.d.ts} +0 -0
@@ -0,0 +1,447 @@
1
+ import { describe, it, expect, beforeEach } from "@jest/globals";
2
+ import { FTree } from "../../dts/index.js";
3
+ import { ID_A0, ID_A1, ID_B0, ID_B1, ID_C0, buildHelloTree } from "./mocks/FTree-mocks.js";
4
+ // ---------------------------------------------------------------------------
5
+ // Constructor
6
+ // ---------------------------------------------------------------------------
7
+ describe("FTree constructor", () => {
8
+ it("initialises a root node that is marked deleted with a null parent", () => {
9
+ const tree = new FTree();
10
+ expect(tree.root.isDeleted).toBe(true);
11
+ expect(tree.root.parent).toBeNull();
12
+ });
13
+ it("initialises root with size 0 and empty children arrays", () => {
14
+ const tree = new FTree();
15
+ expect(tree.root.size).toBe(0);
16
+ expect(tree.root.leftChildren).toHaveLength(0);
17
+ expect(tree.root.rightChildren).toHaveLength(0);
18
+ });
19
+ it("initialises root with the sentinel id { sender: '', counter: 0 }", () => {
20
+ const tree = new FTree();
21
+ expect(tree.root.id).toEqual({ sender: "", counter: 0 });
22
+ });
23
+ it("registers the root in the node map under the empty-string sender", () => {
24
+ const tree = new FTree();
25
+ const nodes = tree.getNodes();
26
+ expect(nodes.get("")?.[0]).toBe(tree.root);
27
+ });
28
+ });
29
+ // ---------------------------------------------------------------------------
30
+ // getByID
31
+ // ---------------------------------------------------------------------------
32
+ describe("FTree.getByID", () => {
33
+ let tree;
34
+ beforeEach(() => {
35
+ tree = new FTree();
36
+ tree.addNode(ID_A0, "a", tree.root, "R");
37
+ });
38
+ it("returns the root node when looked up by its sentinel id", () => {
39
+ expect(tree.getByID({ sender: "", counter: 0 })).toBe(tree.root);
40
+ });
41
+ it("returns the correct node for a known id", () => {
42
+ const node = tree.getByID(ID_A0);
43
+ expect(node.value).toBe("a");
44
+ expect(node.id).toEqual(ID_A0);
45
+ });
46
+ it("throws for an unknown sender", () => {
47
+ expect(() => tree.getByID({ sender: "UNKNOWN", counter: 0 })).toThrow(/Unknown ID/);
48
+ });
49
+ it("throws when the counter is out of range for a known sender", () => {
50
+ expect(() => tree.getByID({ sender: "A", counter: 99 })).toThrow(/Unknown ID/);
51
+ });
52
+ });
53
+ // ---------------------------------------------------------------------------
54
+ // addNode
55
+ // ---------------------------------------------------------------------------
56
+ describe("FTree.addNode", () => {
57
+ let tree;
58
+ beforeEach(() => {
59
+ tree = new FTree();
60
+ });
61
+ it("adds the node to the tree so that it is retrievable by id", () => {
62
+ tree.addNode(ID_A0, "x", tree.root, "R");
63
+ expect(tree.getByID(ID_A0).value).toBe("x");
64
+ });
65
+ it("increments root size by 1 after a single insertion", () => {
66
+ tree.addNode(ID_A0, "a", tree.root, "R");
67
+ expect(tree.root.size).toBe(1);
68
+ });
69
+ it("increments root size cumulatively for multiple insertions", () => {
70
+ tree.addNode(ID_A0, "a", tree.root, "R");
71
+ tree.addNode(ID_A1, "b", tree.root, "R");
72
+ expect(tree.root.size).toBe(2);
73
+ });
74
+ it("places a right-side node in the parent's rightChildren array", () => {
75
+ tree.addNode(ID_A0, "r", tree.root, "R");
76
+ expect(tree.root.rightChildren).toHaveLength(1);
77
+ expect(tree.root.rightChildren[0]).toBe(tree.getByID(ID_A0));
78
+ });
79
+ it("places a left-side node in the parent's leftChildren array", () => {
80
+ tree.addNode(ID_A0, "l", tree.root, "L");
81
+ expect(tree.root.leftChildren).toHaveLength(1);
82
+ expect(tree.root.leftChildren[0]).toBe(tree.getByID(ID_A0));
83
+ });
84
+ it("sets rightOrigin to null when rightOriginID is null", () => {
85
+ tree.addNode(ID_A0, "a", tree.root, "R", null);
86
+ expect(tree.getByID(ID_A0).rightOrigin).toBeNull();
87
+ });
88
+ it("sets rightOrigin to undefined when rightOriginID argument is omitted", () => {
89
+ tree.addNode(ID_A0, "a", tree.root, "R");
90
+ expect(tree.getByID(ID_A0).rightOrigin).toBeUndefined();
91
+ });
92
+ it("resolves rightOriginID to the correct FNode pointer", () => {
93
+ tree.addNode(ID_A0, "a", tree.root, "R");
94
+ tree.addNode(ID_A1, "b", tree.root, "R", ID_A0);
95
+ const nodeA1 = tree.getByID(ID_A1);
96
+ expect(nodeA1.rightOrigin).toBe(tree.getByID(ID_A0));
97
+ });
98
+ it("throws when rightOriginID refers to a node not yet in the tree", () => {
99
+ expect(() => tree.addNode(ID_A0, "a", tree.root, "R", { sender: "GHOST", counter: 0 })).toThrow(/Unknown ID/);
100
+ });
101
+ it("accumulates nodes for the same sender under their counter index", () => {
102
+ tree.addNode(ID_A0, "a", tree.root, "R");
103
+ tree.addNode(ID_A1, "b", tree.root, "R");
104
+ expect(tree.getNodes().get("A")).toHaveLength(2);
105
+ });
106
+ it("creates a separate sender entry for each distinct sender", () => {
107
+ tree.addNode(ID_A0, "a", tree.root, "R");
108
+ tree.addNode(ID_B0, "b", tree.root, "R");
109
+ expect(tree.getNodes().has("A")).toBe(true);
110
+ expect(tree.getNodes().has("B")).toBe(true);
111
+ });
112
+ });
113
+ // ---------------------------------------------------------------------------
114
+ // Sibling ordering — right children
115
+ // ---------------------------------------------------------------------------
116
+ describe("right-children sibling ordering", () => {
117
+ let tree;
118
+ beforeEach(() => {
119
+ tree = new FTree();
120
+ });
121
+ it("nodes with no rightOrigin are ordered by ascending sender id", () => {
122
+ // Sender "B" inserts first, then "A". With null rightOrigin, lexicographic
123
+ // order governs: "A" < "B", so A should appear before B in rightChildren.
124
+ tree.addNode(ID_B0, "b", tree.root, "R", null);
125
+ tree.addNode(ID_A0, "a", tree.root, "R", null);
126
+ const right = tree.root.rightChildren;
127
+ expect(right[0]).toBe(tree.getByID(ID_A0));
128
+ expect(right[1]).toBe(tree.getByID(ID_B0));
129
+ });
130
+ it("a node with a lesser rightOrigin is placed before one with a greater rightOrigin", () => {
131
+ tree.addNode(ID_A0, "a", tree.root, "R", null);
132
+ tree.addNode(ID_A1, "b", tree.root, "R", null);
133
+ // B0 references A0 as rightOrigin (A0 < A1), so B0 should precede B1.
134
+ tree.addNode(ID_B0, "x", tree.root, "R", ID_A0);
135
+ tree.addNode(ID_B1, "y", tree.root, "R", ID_A1);
136
+ const right = tree.root.rightChildren;
137
+ expect(right.indexOf(tree.getByID(ID_B0))).toBeLessThan(right.indexOf(tree.getByID(ID_B1)));
138
+ });
139
+ });
140
+ // ---------------------------------------------------------------------------
141
+ // Sibling ordering — left children
142
+ // ---------------------------------------------------------------------------
143
+ describe("left-children sibling ordering", () => {
144
+ it("left children are sorted by ascending sender id regardless of insertion order", () => {
145
+ const tree = new FTree();
146
+ tree.addNode(ID_C0, "c", tree.root, "L");
147
+ tree.addNode(ID_A0, "a", tree.root, "L");
148
+ tree.addNode(ID_B0, "b", tree.root, "L");
149
+ const left = tree.root.leftChildren;
150
+ expect(left[0]).toBe(tree.getByID(ID_A0));
151
+ expect(left[1]).toBe(tree.getByID(ID_B0));
152
+ expect(left[2]).toBe(tree.getByID(ID_C0));
153
+ });
154
+ });
155
+ // ---------------------------------------------------------------------------
156
+ // depth
157
+ // ---------------------------------------------------------------------------
158
+ describe("FTree.depth", () => {
159
+ let tree;
160
+ beforeEach(() => {
161
+ tree = new FTree();
162
+ });
163
+ it("returns 0 for the root", () => {
164
+ expect(tree.depth(tree.root)).toBe(0);
165
+ });
166
+ it("returns 1 for a direct child of the root", () => {
167
+ tree.addNode(ID_A0, "a", tree.root, "R");
168
+ expect(tree.depth(tree.getByID(ID_A0))).toBe(1);
169
+ });
170
+ it("returns 2 for a grandchild of the root", () => {
171
+ tree.addNode(ID_A0, "a", tree.root, "R");
172
+ const parent = tree.getByID(ID_A0);
173
+ tree.addNode(ID_A1, "b", parent, "R");
174
+ expect(tree.depth(tree.getByID(ID_A1))).toBe(2);
175
+ });
176
+ });
177
+ // ---------------------------------------------------------------------------
178
+ // updateSize
179
+ // ---------------------------------------------------------------------------
180
+ describe("FTree.updateSize", () => {
181
+ it("propagates delta up through all ancestors", () => {
182
+ const tree = new FTree();
183
+ tree.addNode(ID_A0, "a", tree.root, "R");
184
+ const nodeA0 = tree.getByID(ID_A0);
185
+ tree.addNode(ID_A1, "b", nodeA0, "R");
186
+ const nodeA1 = tree.getByID(ID_A1);
187
+ tree.updateSize(nodeA1, 3);
188
+ expect(nodeA1.size).toBe(4); // 1 (from addNode) + 3
189
+ expect(nodeA0.size).toBe(5); // 2 (from addNode calls) + 3
190
+ expect(tree.root.size).toBe(5); // 2 + 3
191
+ });
192
+ it("decrements correctly when delta is negative", () => {
193
+ const tree = new FTree();
194
+ tree.addNode(ID_A0, "a", tree.root, "R");
195
+ const nodeA0 = tree.getByID(ID_A0);
196
+ tree.updateSize(nodeA0, -1);
197
+ expect(nodeA0.size).toBe(0);
198
+ expect(tree.root.size).toBe(0);
199
+ });
200
+ });
201
+ // ---------------------------------------------------------------------------
202
+ // getByIndex
203
+ // ---------------------------------------------------------------------------
204
+ describe("FTree.getByIndex", () => {
205
+ let tree;
206
+ beforeEach(() => {
207
+ tree = new FTree();
208
+ buildHelloTree(tree); // inserts "hello" under root
209
+ });
210
+ it("returns the first character at index 0", () => {
211
+ expect(tree.getByIndex(tree.root, 0).value).toBe("h");
212
+ });
213
+ it("returns the last character at index size-1", () => {
214
+ expect(tree.getByIndex(tree.root, tree.root.size - 1).value).toBe("o");
215
+ });
216
+ it("returns interior characters at their correct indices", () => {
217
+ expect(tree.getByIndex(tree.root, 1).value).toBe("e");
218
+ expect(tree.getByIndex(tree.root, 2).value).toBe("l");
219
+ });
220
+ it("throws for a negative index", () => {
221
+ expect(() => tree.getByIndex(tree.root, -1)).toThrow(/Index out of bounds/);
222
+ });
223
+ it("throws when index equals tree size", () => {
224
+ expect(() => tree.getByIndex(tree.root, tree.root.size)).toThrow(/Index out of bounds/);
225
+ });
226
+ it("skips deleted nodes when computing the index", () => {
227
+ // Mark 'e' (counter 1) as deleted and reduce sizes accordingly.
228
+ const eNode = tree.getByID({ sender: "A", counter: 1 });
229
+ eNode.isDeleted = true;
230
+ tree.updateSize(eNode, -1);
231
+ // After deletion of 'e', index 1 should now be the first 'l'.
232
+ expect(tree.getByIndex(tree.root, 1).value).toBe("l");
233
+ });
234
+ });
235
+ // ---------------------------------------------------------------------------
236
+ // getVisibleIndex
237
+ // ---------------------------------------------------------------------------
238
+ describe("FTree.getVisibleIndex", () => {
239
+ let tree;
240
+ beforeEach(() => {
241
+ tree = new FTree();
242
+ buildHelloTree(tree);
243
+ });
244
+ it("returns 0 for the first visible node", () => {
245
+ const first = tree.getByID({ sender: "A", counter: 0 });
246
+ expect(tree.getVisibleIndex(first)).toBe(0);
247
+ });
248
+ it("returns size-1 for the last visible node", () => {
249
+ const last = tree.getByID({ sender: "A", counter: 4 });
250
+ expect(tree.getVisibleIndex(last)).toBe(4);
251
+ });
252
+ it("returns the correct index for an interior node", () => {
253
+ const l1 = tree.getByID({ sender: "A", counter: 2 });
254
+ expect(tree.getVisibleIndex(l1)).toBe(2);
255
+ });
256
+ it("getByIndex and getVisibleIndex are inverses for each visible position", () => {
257
+ for (let i = 0; i < tree.root.size; i++) {
258
+ const node = tree.getByIndex(tree.root, i);
259
+ expect(tree.getVisibleIndex(node)).toBe(i);
260
+ }
261
+ });
262
+ });
263
+ // ---------------------------------------------------------------------------
264
+ // leftmostDescendant
265
+ // ---------------------------------------------------------------------------
266
+ describe("FTree.leftmostDescendant", () => {
267
+ it("returns the node itself when it has no left children", () => {
268
+ const tree = new FTree();
269
+ tree.addNode(ID_A0, "a", tree.root, "R");
270
+ const node = tree.getByID(ID_A0);
271
+ expect(tree.leftmostDescendant(node)).toBe(node);
272
+ });
273
+ it("returns the deepest left descendant when left children exist", () => {
274
+ const tree = new FTree();
275
+ tree.addNode(ID_A0, "a", tree.root, "R");
276
+ const nodeA = tree.getByID(ID_A0);
277
+ tree.addNode(ID_B0, "b", nodeA, "L");
278
+ const nodeB = tree.getByID(ID_B0);
279
+ tree.addNode(ID_C0, "c", nodeB, "L");
280
+ expect(tree.leftmostDescendant(nodeA)).toBe(tree.getByID(ID_C0));
281
+ });
282
+ });
283
+ // ---------------------------------------------------------------------------
284
+ // nextNonDescendant
285
+ // ---------------------------------------------------------------------------
286
+ describe("FTree.nextNonDescendant", () => {
287
+ it("returns null for the last node in the tree", () => {
288
+ const tree = new FTree();
289
+ tree.addNode(ID_A0, "a", tree.root, "R");
290
+ expect(tree.nextNonDescendant(tree.getByID(ID_A0))).toBeNull();
291
+ });
292
+ it("returns the next right sibling's leftmost descendant when a next sibling exists", () => {
293
+ const tree = new FTree();
294
+ tree.addNode(ID_A0, "a", tree.root, "R", null);
295
+ tree.addNode(ID_B0, "b", tree.root, "R", null);
296
+ const nodeA = tree.getByID(ID_A0);
297
+ const nodeB = tree.getByID(ID_B0);
298
+ expect(tree.nextNonDescendant(nodeA)).toBe(tree.leftmostDescendant(nodeB));
299
+ });
300
+ it("returns the parent when a left child has no further right siblings", () => {
301
+ const tree = new FTree();
302
+ tree.addNode(ID_A0, "a", tree.root, "R");
303
+ const nodeA = tree.getByID(ID_A0);
304
+ tree.addNode(ID_B0, "b", nodeA, "L");
305
+ const nodeB = tree.getByID(ID_B0);
306
+ expect(tree.nextNonDescendant(nodeB)).toBe(nodeA);
307
+ });
308
+ });
309
+ // ---------------------------------------------------------------------------
310
+ // traverse
311
+ // ---------------------------------------------------------------------------
312
+ describe("FTree.traverse", () => {
313
+ it("yields characters in document order for a linear right-child chain", () => {
314
+ const tree = new FTree();
315
+ buildHelloTree(tree);
316
+ expect([...tree.traverse(tree.root)]).toEqual(["h", "e", "l", "l", "o"]);
317
+ });
318
+ it("yields no characters for a tree containing only the root", () => {
319
+ const tree = new FTree();
320
+ expect([...tree.traverse(tree.root)]).toEqual([]);
321
+ });
322
+ it("skips deleted nodes during traversal", () => {
323
+ const tree = new FTree();
324
+ buildHelloTree(tree);
325
+ const eNode = tree.getByID({ sender: "A", counter: 1 });
326
+ eNode.isDeleted = true;
327
+ tree.updateSize(eNode, -1);
328
+ expect([...tree.traverse(tree.root)]).toEqual(["h", "l", "l", "o"]);
329
+ });
330
+ it("yields left-subtree characters before the parent and right-subtree characters after", () => {
331
+ const tree = new FTree();
332
+ tree.addNode(ID_A0, "m", tree.root, "R");
333
+ const nodeA = tree.getByID(ID_A0);
334
+ tree.addNode(ID_B0, "l", nodeA, "L");
335
+ tree.addNode(ID_C0, "r", nodeA, "R");
336
+ expect([...tree.traverse(tree.root)]).toEqual(["l", "m", "r"]);
337
+ });
338
+ it("skips subtrees whose size is 0 during traversal", () => {
339
+ const tree = new FTree();
340
+ tree.addNode(ID_A0, "a", tree.root, "R");
341
+ const nodeA = tree.getByID(ID_A0);
342
+ // Add a child whose size we artificially zero out so the traversal skips it.
343
+ tree.addNode(ID_B0, "b", nodeA, "R");
344
+ const nodeB = tree.getByID(ID_B0);
345
+ nodeB.size = 0;
346
+ nodeA.size = 1;
347
+ tree.root.size = 1;
348
+ expect([...tree.traverse(tree.root)]).toEqual(["a"]);
349
+ });
350
+ });
351
+ // ---------------------------------------------------------------------------
352
+ // save / load round-trip
353
+ // ---------------------------------------------------------------------------
354
+ describe("FTree save/load", () => {
355
+ it("round-trips an empty tree correctly", () => {
356
+ const tree = new FTree();
357
+ const data = tree.save();
358
+ const loaded = new FTree();
359
+ loaded.load(data);
360
+ expect([...loaded.traverse(loaded.root)]).toEqual([]);
361
+ expect(loaded.root.size).toBe(0);
362
+ });
363
+ it("round-trips a populated tree preserving document order", () => {
364
+ const tree = new FTree();
365
+ buildHelloTree(tree);
366
+ const data = tree.save();
367
+ const loaded = new FTree();
368
+ loaded.load(data);
369
+ expect([...loaded.traverse(loaded.root)]).toEqual(["h", "e", "l", "l", "o"]);
370
+ });
371
+ it("round-trips a tree with deleted nodes, preserving deletion state", () => {
372
+ const tree = new FTree();
373
+ buildHelloTree(tree);
374
+ const eNode = tree.getByID({ sender: "A", counter: 1 });
375
+ eNode.isDeleted = true;
376
+ tree.updateSize(eNode, -1);
377
+ const data = tree.save();
378
+ const loaded = new FTree();
379
+ loaded.load(data);
380
+ expect([...loaded.traverse(loaded.root)]).toEqual(["h", "l", "l", "o"]);
381
+ });
382
+ it("round-trips a tree that has nodes with explicit rightOrigin pointers", () => {
383
+ const tree = new FTree();
384
+ tree.addNode(ID_A0, "a", tree.root, "R", null);
385
+ tree.addNode(ID_A1, "b", tree.root, "R", null);
386
+ // Insert between A0 and A1 by referencing A1 as rightOrigin.
387
+ tree.addNode(ID_B0, "x", tree.root, "R", ID_A1);
388
+ const data = tree.save();
389
+ const loaded = new FTree();
390
+ loaded.load(data);
391
+ expect([...loaded.traverse(loaded.root)]).toEqual([...tree.traverse(tree.root)]);
392
+ });
393
+ it("preserves node sizes after a round-trip", () => {
394
+ const tree = new FTree();
395
+ buildHelloTree(tree);
396
+ const data = tree.save();
397
+ const loaded = new FTree();
398
+ loaded.load(data);
399
+ expect(loaded.root.size).toBe(5);
400
+ });
401
+ it("save produces a non-empty Uint8Array", () => {
402
+ const tree = new FTree();
403
+ buildHelloTree(tree);
404
+ const data = tree.save();
405
+ expect(data).toBeInstanceOf(Uint8Array);
406
+ expect(data.length).toBeGreaterThan(0);
407
+ });
408
+ });
409
+ // ---------------------------------------------------------------------------
410
+ // clear
411
+ // ---------------------------------------------------------------------------
412
+ describe("FTree.clear", () => {
413
+ it("resets size to 0 after clearing a populated tree", () => {
414
+ const tree = new FTree();
415
+ buildHelloTree(tree);
416
+ tree.clear();
417
+ expect(tree.root.size).toBe(0);
418
+ });
419
+ it("removes all non-root nodes from the node map", () => {
420
+ const tree = new FTree();
421
+ buildHelloTree(tree);
422
+ tree.clear();
423
+ expect(tree.getNodes().size).toBe(1); // only the "" root entry
424
+ });
425
+ it("empties root's left and right children arrays", () => {
426
+ const tree = new FTree();
427
+ tree.addNode(ID_A0, "a", tree.root, "R");
428
+ tree.addNode(ID_B0, "b", tree.root, "L");
429
+ tree.clear();
430
+ expect(tree.root.leftChildren).toHaveLength(0);
431
+ expect(tree.root.rightChildren).toHaveLength(0);
432
+ });
433
+ it("allows new nodes to be added after a clear", () => {
434
+ const tree = new FTree();
435
+ buildHelloTree(tree);
436
+ tree.clear();
437
+ tree.addNode(ID_A0, "z", tree.root, "R");
438
+ expect(tree.root.size).toBe(1);
439
+ expect([...tree.traverse(tree.root)]).toEqual(["z"]);
440
+ });
441
+ it("re-registers the root under the empty-string sender key after clearing", () => {
442
+ const tree = new FTree();
443
+ buildHelloTree(tree);
444
+ tree.clear();
445
+ expect(tree.getNodes().get("")?.[0]).toBe(tree.root);
446
+ });
447
+ });
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FugueTree.test.d.ts","sourceRoot":"","sources":["../../../src/tests/unit/FugueTree.test.ts"],"names":[],"mappings":""}