data-structure-typed 2.2.8 → 2.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.
Files changed (137) hide show
  1. package/.github/workflows/ci.yml +9 -0
  2. package/CHANGELOG.md +1 -1
  3. package/README.md +1 -1
  4. package/README_CN.md +1 -1
  5. package/dist/cjs/index.cjs +584 -76
  6. package/dist/cjs/index.cjs.map +1 -1
  7. package/dist/cjs-legacy/index.cjs +588 -79
  8. package/dist/cjs-legacy/index.cjs.map +1 -1
  9. package/dist/esm/index.mjs +584 -76
  10. package/dist/esm/index.mjs.map +1 -1
  11. package/dist/esm-legacy/index.mjs +588 -79
  12. package/dist/esm-legacy/index.mjs.map +1 -1
  13. package/dist/types/data-structures/base/linear-base.d.ts +6 -6
  14. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +3 -4
  15. package/dist/types/data-structures/binary-tree/bst.d.ts +2 -1
  16. package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +150 -20
  17. package/dist/types/data-structures/binary-tree/tree-counter.d.ts +3 -3
  18. package/dist/types/interfaces/binary-tree.d.ts +1 -1
  19. package/dist/umd/data-structure-typed.js +588 -79
  20. package/dist/umd/data-structure-typed.js.map +1 -1
  21. package/dist/umd/data-structure-typed.min.js +3 -3
  22. package/dist/umd/data-structure-typed.min.js.map +1 -1
  23. package/package.json +4 -3
  24. package/src/data-structures/base/linear-base.ts +2 -12
  25. package/src/data-structures/binary-tree/binary-tree.ts +5 -6
  26. package/src/data-structures/binary-tree/bst.ts +79 -4
  27. package/src/data-structures/binary-tree/red-black-tree.ts +583 -73
  28. package/src/data-structures/binary-tree/tree-counter.ts +21 -9
  29. package/src/data-structures/queue/deque.ts +10 -0
  30. package/src/interfaces/binary-tree.ts +1 -1
  31. package/test/unit/data-structures/base/iterable-element-base.coverage.test.ts +106 -0
  32. package/test/unit/data-structures/base/iterable-element-base.more-branches.coverage.test.ts +61 -0
  33. package/test/unit/data-structures/base/linear-base.array.coverage.test.ts +168 -0
  34. package/test/unit/data-structures/base/linear-base.concat-else.coverage.test.ts +82 -0
  35. package/test/unit/data-structures/base/linear-base.coverage.test.ts +72 -0
  36. package/test/unit/data-structures/base/linear-base.more-branches.coverage.test.ts +417 -0
  37. package/test/unit/data-structures/binary-tree/avl-tree-counter.more-branches-3.coverage.test.ts +146 -0
  38. package/test/unit/data-structures/binary-tree/avl-tree-counter.more-branches.coverage.test.ts +93 -0
  39. package/test/unit/data-structures/binary-tree/avl-tree-multi-map.coverage.test.ts +108 -0
  40. package/test/unit/data-structures/binary-tree/avl-tree-multi-map.more-branches-2.coverage.test.ts +85 -0
  41. package/test/unit/data-structures/binary-tree/avl-tree-node.familyPosition-root-left.coverage.test.ts +17 -0
  42. package/test/unit/data-structures/binary-tree/avl-tree.more-branches-2.coverage.test.ts +99 -0
  43. package/test/unit/data-structures/binary-tree/binary-indexed-tree.more-branches.coverage.test.ts +18 -0
  44. package/test/unit/data-structures/binary-tree/binary-tree.more-branches.coverage.test.ts +56 -0
  45. package/test/unit/data-structures/binary-tree/binary-tree.remaining-branches.coverage.test.ts +229 -0
  46. package/test/unit/data-structures/binary-tree/bst.bound-by-predicate.coverage.test.ts +33 -0
  47. package/test/unit/data-structures/binary-tree/bst.coverage.test.ts +94 -0
  48. package/test/unit/data-structures/binary-tree/bst.deletebykey.coverage.test.ts +70 -0
  49. package/test/unit/data-structures/binary-tree/bst.deletewhere.coverage.test.ts +37 -0
  50. package/test/unit/data-structures/binary-tree/bst.floor-lower-predicate.coverage.test.ts +29 -0
  51. package/test/unit/data-structures/binary-tree/bst.floor-setmany.coverage.test.ts +72 -0
  52. package/test/unit/data-structures/binary-tree/bst.getnode.range-ensure.coverage.test.ts +22 -0
  53. package/test/unit/data-structures/binary-tree/bst.misc-branches.coverage.test.ts +100 -0
  54. package/test/unit/data-structures/binary-tree/bst.more-branches-2.coverage.test.ts +133 -0
  55. package/test/unit/data-structures/binary-tree/bst.more-branches-3.coverage.test.ts +45 -0
  56. package/test/unit/data-structures/binary-tree/bst.more-branches-4.coverage.test.ts +36 -0
  57. package/test/unit/data-structures/binary-tree/bst.more-branches-5.coverage.test.ts +40 -0
  58. package/test/unit/data-structures/binary-tree/bst.more.coverage.test.ts +39 -0
  59. package/test/unit/data-structures/binary-tree/bst.node-family.coverage.test.ts +29 -0
  60. package/test/unit/data-structures/binary-tree/bst.range-pruning.coverage.test.ts +43 -0
  61. package/test/unit/data-structures/binary-tree/bst.search-fastpath.coverage.test.ts +30 -0
  62. package/test/unit/data-structures/binary-tree/bst.test.ts +25 -55
  63. package/test/unit/data-structures/binary-tree/red-black-tree.boundary-corruption-repair.coverage.test.ts +66 -0
  64. package/test/unit/data-structures/binary-tree/red-black-tree.boundary-max-update.coverage.test.ts +18 -0
  65. package/test/unit/data-structures/binary-tree/red-black-tree.boundary-null.coverage.test.ts +53 -0
  66. package/test/unit/data-structures/binary-tree/red-black-tree.boundary-stale-cache.coverage.test.ts +25 -0
  67. package/test/unit/data-structures/binary-tree/red-black-tree.boundary-update.coverage.test.ts +23 -0
  68. package/test/unit/data-structures/binary-tree/red-black-tree.cache-delete.coverage.test.ts +49 -0
  69. package/test/unit/data-structures/binary-tree/red-black-tree.cache-edge.coverage.test.ts +37 -0
  70. package/test/unit/data-structures/binary-tree/red-black-tree.cache-stale-insert.coverage.test.ts +39 -0
  71. package/test/unit/data-structures/binary-tree/red-black-tree.coverage.test.ts +334 -0
  72. package/test/unit/data-structures/binary-tree/red-black-tree.delete-fixup.coverage.test.ts +68 -0
  73. package/test/unit/data-structures/binary-tree/red-black-tree.delete-successor.coverage.test.ts +75 -0
  74. package/test/unit/data-structures/binary-tree/red-black-tree.factories.coverage.test.ts +26 -0
  75. package/test/unit/data-structures/binary-tree/red-black-tree.hint-cache-compare-update.coverage.test.ts +74 -0
  76. package/test/unit/data-structures/binary-tree/red-black-tree.hint-cache-no-update.coverage.test.ts +44 -0
  77. package/test/unit/data-structures/binary-tree/red-black-tree.hint-cache-nullish.coverage.test.ts +61 -0
  78. package/test/unit/data-structures/binary-tree/red-black-tree.hint-mapmode-defined.coverage.test.ts +35 -0
  79. package/test/unit/data-structures/binary-tree/red-black-tree.hint-mapmode-undefined.coverage.test.ts +43 -0
  80. package/test/unit/data-structures/binary-tree/red-black-tree.hint-more.coverage.test.ts +99 -0
  81. package/test/unit/data-structures/binary-tree/red-black-tree.hint.coverage.test.ts +60 -0
  82. package/test/unit/data-structures/binary-tree/red-black-tree.insert-cache-nullish.coverage.test.ts +29 -0
  83. package/test/unit/data-structures/binary-tree/red-black-tree.insert-header-parent-nullish.coverage.test.ts +17 -0
  84. package/test/unit/data-structures/binary-tree/red-black-tree.internal-walk.coverage.test.ts +57 -0
  85. package/test/unit/data-structures/binary-tree/red-black-tree.minmax-cache.test.ts +65 -0
  86. package/test/unit/data-structures/binary-tree/red-black-tree.misc-inputs.coverage.test.ts +17 -0
  87. package/test/unit/data-structures/binary-tree/red-black-tree.more-branches-2.coverage.test.ts +121 -0
  88. package/test/unit/data-structures/binary-tree/red-black-tree.more-branches-3.coverage.test.ts +55 -0
  89. package/test/unit/data-structures/binary-tree/red-black-tree.more-branches-4.coverage.test.ts +44 -0
  90. package/test/unit/data-structures/binary-tree/red-black-tree.predsucc.coverage.test.ts +40 -0
  91. package/test/unit/data-structures/binary-tree/red-black-tree.remaining-branches.coverage.test.ts +123 -0
  92. package/test/unit/data-structures/binary-tree/red-black-tree.set-inputs.coverage.test.ts +64 -0
  93. package/test/unit/data-structures/binary-tree/red-black-tree.setkvnode-parent-cache.coverage.test.ts +79 -0
  94. package/test/unit/data-structures/binary-tree/red-black-tree.setkvnode-remaining.coverage.test.ts +44 -0
  95. package/test/unit/data-structures/binary-tree/red-black-tree.setkvnode-uncovered.coverage.test.ts +74 -0
  96. package/test/unit/data-structures/binary-tree/red-black-tree.update-branches.coverage.test.ts +30 -0
  97. package/test/unit/data-structures/binary-tree/segment-tree.more-branches.coverage.test.ts +31 -0
  98. package/test/unit/data-structures/binary-tree/tree-counter.coverage.test.ts +115 -0
  99. package/test/unit/data-structures/binary-tree/tree-counter.more-branches.coverage.test.ts +244 -0
  100. package/test/unit/data-structures/binary-tree/tree-counter.test.ts +4 -2
  101. package/test/unit/data-structures/binary-tree/tree-multi-map.coverage.test.ts +104 -0
  102. package/test/unit/data-structures/binary-tree/tree-multi-map.more-branches-2.coverage.test.ts +59 -0
  103. package/test/unit/data-structures/graph/abstract-graph.more-branches-2.coverage.test.ts +40 -0
  104. package/test/unit/data-structures/graph/abstract-graph.more-branches-3.coverage.test.ts +65 -0
  105. package/test/unit/data-structures/graph/abstract-graph.more-branches-4.coverage.test.ts +98 -0
  106. package/test/unit/data-structures/graph/abstract-graph.more-branches-5.coverage.test.ts +51 -0
  107. package/test/unit/data-structures/graph/abstract-graph.more-branches.coverage.test.ts +62 -0
  108. package/test/unit/data-structures/graph/directed-graph.more-branches-2.coverage.test.ts +38 -0
  109. package/test/unit/data-structures/graph/directed-graph.more-branches-3.coverage.test.ts +25 -0
  110. package/test/unit/data-structures/graph/directed-graph.more-branches.coverage.test.ts +82 -0
  111. package/test/unit/data-structures/graph/map-graph.more-branches.coverage.test.ts +22 -0
  112. package/test/unit/data-structures/graph/undirected-graph.more-branches-2.coverage.test.ts +35 -0
  113. package/test/unit/data-structures/graph/undirected-graph.more-branches.coverage.test.ts +87 -0
  114. package/test/unit/data-structures/hash/hash-map.more-branches.coverage.test.ts +64 -0
  115. package/test/unit/data-structures/hash/hash-map.toEntryFn-branch.coverage.test.ts +9 -0
  116. package/test/unit/data-structures/heap/heap.misc-branches.coverage.test.ts +110 -0
  117. package/test/unit/data-structures/heap/heap.remaining-branches.coverage.test.ts +22 -0
  118. package/test/unit/data-structures/heap/max-heap.coverage.test.ts +29 -0
  119. package/test/unit/data-structures/linked-list/doubly-linked-list.more-branches.coverage.test.ts +72 -0
  120. package/test/unit/data-structures/linked-list/linked-list.unshiftMany-else.coverage.test.ts +15 -0
  121. package/test/unit/data-structures/linked-list/singly-linked-list.coverage.test.ts +221 -0
  122. package/test/unit/data-structures/linked-list/singly-linked-list.more-branches.coverage.test.ts +86 -0
  123. package/test/unit/data-structures/linked-list/skip-linked-list.more-branches.coverage.test.ts +31 -0
  124. package/test/unit/data-structures/matrix/matrix.more-branches.coverage.test.ts +81 -0
  125. package/test/unit/data-structures/matrix/matrix.pivotElement-nullish.coverage.test.ts +28 -0
  126. package/test/unit/data-structures/priority-queue/max-priority-queue.more-branches.coverage.test.ts +10 -0
  127. package/test/unit/data-structures/priority-queue/priority-queue.coverage.test.ts +21 -0
  128. package/test/unit/data-structures/queue/deque.coverage.test.ts +173 -0
  129. package/test/unit/data-structures/queue/deque.more-branches-2.coverage.test.ts +39 -0
  130. package/test/unit/data-structures/queue/deque.more-branches-3.coverage.test.ts +9 -0
  131. package/test/unit/data-structures/queue/deque.more-branches.coverage.test.ts +95 -0
  132. package/test/unit/data-structures/queue/queue.coverage.test.ts +138 -0
  133. package/test/unit/data-structures/queue/queue.more-branches-2.coverage.test.ts +27 -0
  134. package/test/unit/data-structures/stack/stack.coverage.test.ts +112 -0
  135. package/test/unit/data-structures/tree/tree.more-branches.coverage.test.ts +9 -0
  136. package/test/unit/data-structures/trie/trie.more-branches-2.coverage.test.ts +51 -0
  137. package/test/utils/patch.ts +33 -0
@@ -0,0 +1,39 @@
1
+ import { Deque } from '../../../../src';
2
+
3
+ describe('Deque remaining branch coverage (batch 2)', () => {
4
+ it('unshiftMany covers toElementFn branch (and is executed at all)', () => {
5
+ const d = new Deque<number, { v: number }>([], {
6
+ toElementFn: (r: { v: number }) => r.v
7
+ });
8
+
9
+ expect(d.unshiftMany([{ v: 1 }, { v: 2 }])).toEqual([true, true]);
10
+ expect(d.toArray()).toEqual([2, 1]);
11
+ });
12
+
13
+ it('splice(start) uses default deleteCount = length - start', () => {
14
+ const d = new Deque<number>();
15
+ d.pushMany([1, 2, 3, 4]);
16
+
17
+ // omit deleteCount to hit the default-arg branch
18
+ const removed = d.splice(1);
19
+
20
+ expect(removed.toArray()).toEqual([2, 3, 4]);
21
+ expect(d.toArray()).toEqual([1]);
22
+ });
23
+
24
+ it('shrinkToFit covers wrap-around bucketFirst > bucketLast branch', () => {
25
+ const d = new Deque<number>();
26
+
27
+ // Force an internal wrap-around layout (reachable-only: test-side corruption).
28
+ (d as any)._length = 1;
29
+ (d as any)._bucketFirst = 2;
30
+ (d as any)._bucketLast = 1;
31
+ (d as any)._bucketCount = 4;
32
+ (d as any)._buckets = [[0], [1], [2], [3]];
33
+
34
+ expect(() => d.shrinkToFit()).not.toThrow();
35
+ expect((d as any)._bucketFirst).toBe(0);
36
+ expect((d as any)._bucketLast).toBe(3);
37
+ expect((d as any)._buckets.length).toBe(4);
38
+ });
39
+ });
@@ -0,0 +1,9 @@
1
+ import { Deque } from '../../../../src';
2
+
3
+ describe('Deque remaining branch coverage (batch 3)', () => {
4
+ it('unshiftMany covers else-branch when toElementFn is not provided', () => {
5
+ const d = new Deque<number>();
6
+ expect(d.unshiftMany([1, 2])).toEqual([true, true]);
7
+ expect(d.toArray()).toEqual([2, 1]);
8
+ });
9
+ });
@@ -0,0 +1,95 @@
1
+ import { Deque } from '../../../../src';
2
+
3
+ describe('Deque additional branch coverage', () => {
4
+ it('unshiftMany() default-arg empty iterable returns []', () => {
5
+ const d = new Deque<number>();
6
+ expect(d.unshiftMany()).toEqual([]);
7
+ });
8
+
9
+ it('splice clamps deleteCount when negative / too large (covers both clamp branches)', () => {
10
+ const d = new Deque<number>();
11
+ d.pushMany([1, 2, 3, 4]);
12
+
13
+ // deleteCount < 0 => clamp to 0
14
+ const r0 = d.splice(1, -1, 99);
15
+ expect(r0.toArray()).toEqual([]);
16
+
17
+ // deleteCount too large => clamp to length-start
18
+ const r1 = d.splice(1, 999);
19
+ expect(r1.toArray()).toEqual([99, 2, 3, 4]);
20
+ expect(d.toArray()).toEqual([1]);
21
+ });
22
+
23
+ it('shrinkToFit returns early when bucketFirst===bucketLast (covers that return branch)', () => {
24
+ const d = new Deque<number>();
25
+ d.push(1);
26
+ // Force bucketFirst===bucketLast and length>0
27
+ (d as any)._bucketFirst = 0;
28
+ (d as any)._bucketLast = 0;
29
+ d.shrinkToFit();
30
+ expect(d.length).toBe(1);
31
+ });
32
+
33
+ it('mapSame uses the thisArg===undefined branch', () => {
34
+ const d = new Deque<number>();
35
+ d.pushMany([1, 2, 3]);
36
+ const out = d.mapSame(v => v * 2);
37
+ expect(out.toArray()).toEqual([2, 4, 6]);
38
+ });
39
+
40
+ it('map() uses thisArg branch and also covers options??{} merge path', () => {
41
+ const d = new Deque<number>();
42
+ d.pushMany([1, 2]);
43
+ const ctx = { add: 10 };
44
+
45
+ const out = d.map(
46
+ function (this: any, v: number) {
47
+ return v + this.add;
48
+ },
49
+ undefined,
50
+ ctx
51
+ );
52
+
53
+ expect(out.toArray()).toEqual([11, 12]);
54
+ });
55
+
56
+ it('_setBucketSize does not reinit buckets when length>0 (covers length===0 false branch)', () => {
57
+ const d = new Deque<number>();
58
+ d.pushMany([1, 2, 3]);
59
+ const before = (d as any)._buckets;
60
+ (d as any)._setBucketSize((d as any)._bucketSize);
61
+ expect((d as any)._buckets).toBe(before);
62
+ });
63
+
64
+ it('_getIterator yields only defined values (covers v!==undefined true branch)', () => {
65
+ const d = new Deque<number>();
66
+ d.pushMany([1, 2, 3]);
67
+ // Corrupt one slot to undefined; _getIterator should skip it.
68
+ const loc = (d as any)._getBucketAndPosition(1);
69
+ (d as any)._buckets[loc.bucketIndex][loc.indexInBucket] = undefined;
70
+
71
+ const got: number[] = [];
72
+ for (const v of d) got.push(v);
73
+ expect(got).toEqual([1, 3]);
74
+ });
75
+
76
+ it('_createLike default-arg path can be called with no args', () => {
77
+ const d = new Deque<number>();
78
+ const like = (d as any)._createLike();
79
+ expect(like.length).toBe(0);
80
+ });
81
+
82
+ it('_getReverseIterator handles v===undefined by not yielding it', () => {
83
+ const d = new Deque<number>();
84
+ d.pushMany([1, 2, 3]);
85
+
86
+ // Make last element undefined
87
+ const loc = (d as any)._getBucketAndPosition(2);
88
+ (d as any)._buckets[loc.bucketIndex][loc.indexInBucket] = undefined;
89
+
90
+ const it = (d as any)._getReverseIterator();
91
+ const got: number[] = [];
92
+ for (const v of it) got.push(v);
93
+ expect(got).toEqual([2, 1]);
94
+ });
95
+ });
@@ -0,0 +1,138 @@
1
+ import { Queue } from '../../../../src';
2
+
3
+ describe('Queue coverage', () => {
4
+ it('constructor options set autoCompactRatio and push respects maxLen via shift', () => {
5
+ const q = new Queue<number>([], { maxLen: 2, autoCompactRatio: 1 });
6
+ expect(q.autoCompactRatio).toBe(1);
7
+
8
+ q.push(1);
9
+ q.push(2);
10
+ q.push(3); // maxLen overflow triggers shift()
11
+
12
+ expect([...q]).toEqual([2, 3]);
13
+ expect(q.length).toBe(2);
14
+ expect(q.first).toBe(2);
15
+ expect(q.last).toBe(3);
16
+ });
17
+
18
+ it('pushMany uses toElementFn branch', () => {
19
+ const q = new Queue<number, { v: number }>([], { toElementFn: r => r.v });
20
+ expect(q.pushMany([{ v: 1 }, { v: 2 }])).toEqual([true, true]);
21
+ expect([...q]).toEqual([1, 2]);
22
+ });
23
+
24
+ it('shift covers empty branch and compaction trigger', () => {
25
+ const q = new Queue<number>();
26
+ expect(q.shift()).toBeUndefined();
27
+
28
+ // Force compaction quickly.
29
+ q.autoCompactRatio = 0.25;
30
+ q.pushMany([1, 2, 3, 4]);
31
+
32
+ expect(q.shift()).toBe(1);
33
+ // offset=1, elements.length=4 => 0.25, not strictly greater
34
+ expect(q.offset).toBe(1);
35
+
36
+ expect(q.shift()).toBe(2);
37
+ // offset=2, elements.length=4 => 0.5 > 0.25 => compact()
38
+ expect(q.offset).toBe(0);
39
+ expect(q.elements).toEqual([3, 4]);
40
+ });
41
+
42
+ it('delete/deleteAt/addAt/setAt cover bounds and success', () => {
43
+ const q = new Queue<number>([1, 2, 3, 4]);
44
+ // consume one to introduce offset
45
+ expect(q.shift()).toBe(1);
46
+
47
+ expect(q.delete(999)).toBe(false);
48
+ expect(q.delete(3)).toBe(true);
49
+ expect([...q]).toEqual([2, 4]);
50
+
51
+ expect(q.at(-1)).toBeUndefined();
52
+ expect(q.at(999)).toBeUndefined();
53
+ expect(q.at(0)).toBe(2);
54
+
55
+ expect(q.deleteAt(-1)).toBeUndefined();
56
+ expect(q.deleteAt(999)).toBeUndefined();
57
+ expect(q.deleteAt(0)).toBe(2);
58
+ expect([...q]).toEqual([4]);
59
+
60
+ expect(q.addAt(-1, 0)).toBe(false);
61
+ expect(q.addAt(999, 0)).toBe(false);
62
+ expect(q.addAt(0, 3)).toBe(true);
63
+ expect([...q]).toEqual([3, 4]);
64
+
65
+ expect(q.setAt(-1, 0)).toBe(false);
66
+ expect(q.setAt(999, 0)).toBe(false);
67
+ expect(q.setAt(1, 40)).toBe(true);
68
+ expect([...q]).toEqual([3, 40]);
69
+ });
70
+
71
+ it('reverse/clear/compact basic behaviors', () => {
72
+ const q = new Queue<number>([1, 2, 3]);
73
+ q.shift();
74
+ expect(q.offset).toBe(1);
75
+
76
+ q.reverse();
77
+ expect(q.offset).toBe(0);
78
+ expect([...q]).toEqual([3, 2]);
79
+
80
+ q.clear();
81
+ expect(q.length).toBe(0);
82
+ expect(q.offset).toBe(0);
83
+
84
+ q.pushMany([1, 2]);
85
+ q.shift();
86
+ expect(q.compact()).toBe(true);
87
+ expect(q.offset).toBe(0);
88
+ });
89
+
90
+ it('splice triggers optional compaction and returns removed queue with copied ratio', () => {
91
+ const q = new Queue<number>([1, 2, 3, 4, 5], { autoCompactRatio: 0.2 });
92
+ q.shift();
93
+ q.shift(); // offset=2, len=5 => 0.4 > 0.2 would compact on next splice
94
+
95
+ const removed = q.splice(1, 2, 9, 8);
96
+ expect([...removed]).toEqual([4, 5]);
97
+ expect(removed.autoCompactRatio).toBe(q.autoCompactRatio);
98
+
99
+ expect([...q]).toEqual([3, 9, 8]);
100
+ expect(q.offset).toBe(0);
101
+ });
102
+
103
+ it('map/mapSame cover thisArg and default branches, and _createLike default elements branch', () => {
104
+ const q = new Queue<number>([1, 2, 3], { autoCompactRatio: 0.9 });
105
+
106
+ const mapped1 = q.map(v => v + 1);
107
+ expect([...mapped1]).toEqual([2, 3, 4]);
108
+
109
+ const ctx = { mul: 2 };
110
+ const mapped2 = q.map(function (v) {
111
+ // @ts-ignore
112
+ return v * this.mul;
113
+ }, undefined, ctx);
114
+ expect([...mapped2]).toEqual([2, 4, 6]);
115
+
116
+ const same1 = q.mapSame(v => v * 10);
117
+ expect([...same1]).toEqual([10, 20, 30]);
118
+
119
+ const same2 = q.mapSame(function (v) {
120
+ // @ts-ignore
121
+ return v + this.inc;
122
+ }, { inc: 5 });
123
+ expect([...same2]).toEqual([6, 7, 8]);
124
+
125
+ const like = (q as any)._createLike();
126
+ expect(like.length).toBe(0);
127
+ });
128
+
129
+ it('_getReverseIterator skips undefined items', () => {
130
+ const q = new Queue<number | undefined>([1, undefined, 2]);
131
+ expect([...q.toReversedArray()]).toEqual([2, undefined, 1]);
132
+
133
+ const rev: (number | undefined)[] = [];
134
+ for (const v of (q as any)._getReverseIterator()) rev.push(v);
135
+ // undefined is skipped by implementation
136
+ expect(rev).toEqual([2, 1]);
137
+ });
138
+ });
@@ -0,0 +1,27 @@
1
+ import { Queue } from '../../../../src';
2
+
3
+ describe('Queue remaining branch coverage (batch 2)', () => {
4
+ it('splice(start) hits default deleteCount=0 and can trigger auto-compaction branch', () => {
5
+ const q = new Queue<number>();
6
+ q.pushMany([1, 2, 3]);
7
+
8
+ // Prevent auto-compaction during the shifts; we want a non-zero offset.
9
+ q.autoCompactRatio = 1;
10
+
11
+ // Create offset > 0 while keeping underlying elements array non-empty.
12
+ expect(q.shift()).toBe(1);
13
+ expect(q.shift()).toBe(2);
14
+ expect(q.offset).toBe(2);
15
+
16
+ // Now ensure the condition `offset/elements.length > autoCompactRatio` is true at splice-time.
17
+ q.autoCompactRatio = 0;
18
+
19
+ // Omit deleteCount to hit the default-arg branch.
20
+ const removed = q.splice(0, undefined as any, 9);
21
+
22
+ // Should have compacted (offset reset) and inserted item.
23
+ expect(q.offset).toBe(0);
24
+ expect(q.toArray()).toEqual([9, 3]);
25
+ expect(removed.toArray()).toEqual([]);
26
+ });
27
+ });
@@ -0,0 +1,112 @@
1
+ import { Stack } from '../../../../src';
2
+
3
+ describe('Stack coverage', () => {
4
+ it('fromArray + basic ops cover isEmpty/peek/pop on empty', () => {
5
+ // constructor default params branch
6
+ const empty = new Stack<number>();
7
+ expect(empty.size).toBe(0);
8
+
9
+ const s = Stack.fromArray([1, 2, 3]);
10
+ expect([...s]).toEqual([1, 2, 3]);
11
+
12
+ expect(s.peek()).toBe(3);
13
+ expect(s.pop()).toBe(3);
14
+ expect(s.pop()).toBe(2);
15
+ expect(s.pop()).toBe(1);
16
+
17
+ expect(s.isEmpty()).toBe(true);
18
+ expect(s.peek()).toBeUndefined();
19
+ expect(s.pop()).toBeUndefined();
20
+ });
21
+
22
+ it('pushMany uses toElementFn conversion branch', () => {
23
+ const s = new Stack<number, { v: number }>([], { toElementFn: r => r.v });
24
+ const res = s.pushMany([{ v: 1 }, { v: 2 }]);
25
+ expect(res).toEqual([true, true]);
26
+ expect([...s]).toEqual([1, 2]);
27
+ });
28
+
29
+ it('delete/deleteAt cover not-found and bounds', () => {
30
+ const s = new Stack<number>([1, 2, 3, 2]);
31
+
32
+ // not found => _indexOfByEquals returns -1 => deleteAt(-1) false
33
+ expect(s.delete(999)).toBe(false);
34
+
35
+ // bounds
36
+ expect(s.deleteAt(-1)).toBe(false);
37
+ expect(s.deleteAt(999)).toBe(false);
38
+
39
+ // delete first matching occurrence (bottom-up)
40
+ expect(s.delete(2)).toBe(true);
41
+ expect([...s]).toEqual([1, 3, 2]);
42
+
43
+ // deleteAt valid
44
+ expect(s.deleteAt(1)).toBe(true);
45
+ expect([...s]).toEqual([1, 2]);
46
+ });
47
+
48
+ it('deleteWhere covers both match and no-match branches', () => {
49
+ const s = new Stack<number>([1, 2, 3]);
50
+ expect(s.deleteWhere(v => v === 2)).toBe(true);
51
+ expect([...s]).toEqual([1, 3]);
52
+
53
+ expect(s.deleteWhere(v => v === 999)).toBe(false);
54
+ expect([...s]).toEqual([1, 3]);
55
+ });
56
+
57
+ it('clear/clone/filter/mapSame/map cover instance factories and thisArg call path', () => {
58
+ const raw = [{ v: 1 }, { v: 2 }, { v: 3 }];
59
+ const s = new Stack<number, { v: number }>(raw, { toElementFn: r => r.v });
60
+
61
+ const cloned = s.clone();
62
+ expect([...cloned]).toEqual([1, 2, 3]);
63
+
64
+ const filtered = s.filter(v => v % 2 === 1);
65
+ expect([...filtered]).toEqual([1, 3]);
66
+
67
+ const mappedSame = s.mapSame(v => v * 2);
68
+ expect([...mappedSame]).toEqual([2, 4, 6]);
69
+
70
+ // mapSame with thisArg branch
71
+ const ctx2 = { mul: 3 };
72
+ const mappedSame2 = s.mapSame(function (v) {
73
+ // @ts-ignore
74
+ return v * this.mul;
75
+ }, ctx2);
76
+ expect([...mappedSame2]).toEqual([3, 6, 9]);
77
+
78
+
79
+ // map with thisArg branch
80
+ const ctx = { inc: 10 };
81
+ const mapped = s.map(function (v) {
82
+ // @ts-ignore
83
+ return v + this.inc;
84
+ }, undefined, ctx);
85
+ expect([...mapped]).toEqual([11, 12, 13]);
86
+
87
+ // map with undefined thisArg branch
88
+ const mapped2 = s.map(v => v + 1);
89
+ expect([...mapped2]).toEqual([2, 3, 4]);
90
+
91
+ // _createLike default elements branch (protected)
92
+ const like = (s as any)._createLike();
93
+ expect(like.size).toBe(0);
94
+
95
+ s.clear();
96
+ expect(s.size).toBe(0);
97
+ });
98
+
99
+ it('setEquality affects delete/search semantics', () => {
100
+ type Obj = { id: number };
101
+ const a = { id: 1 };
102
+ const b = { id: 2 };
103
+ const s = new Stack<Obj>([a, b]);
104
+
105
+ // default Object.is: new object not found
106
+ expect(s.delete({ id: 1 } as any)).toBe(false);
107
+
108
+ s.setEquality((x, y) => x.id === y.id);
109
+ expect(s.delete({ id: 1 } as any)).toBe(true);
110
+ expect([...s].map(x => x.id)).toEqual([2]);
111
+ });
112
+ });
@@ -0,0 +1,9 @@
1
+ import { TreeNode } from '../../../../src';
2
+
3
+ describe('TreeNode remaining branch coverage', () => {
4
+ it('constructor assigns children when provided (covers if(children) branch)', () => {
5
+ const child = new TreeNode('c');
6
+ const root = new TreeNode('r', undefined, [child]);
7
+ expect(root.children).toEqual([child]);
8
+ });
9
+ });
@@ -0,0 +1,51 @@
1
+ import { Trie } from '../../../../src';
2
+
3
+ describe('Trie additional branch coverage (batch 2)', () => {
4
+ it('getWords() default prefix arg and isAllWhenEmptyPrefix behavior', () => {
5
+ const t = new Trie();
6
+ t.add('a');
7
+ t.add('ab');
8
+
9
+ // prefix default arg (empty) should not collect unless isAllWhenEmptyPrefix=true
10
+ expect(t.getWords()).toEqual([]);
11
+ expect(t.getWords('', 10, true).sort()).toEqual(['a', 'ab']);
12
+ });
13
+
14
+ it('map() covers thisArg branch and non-string return TypeError branch', () => {
15
+ const t = new Trie();
16
+ t.add('a');
17
+
18
+ const ctx = { suf: 'x' };
19
+ const mapped = t.map(function (this: any, w: string) {
20
+ return w + this.suf;
21
+ }, undefined as any, ctx);
22
+ expect((mapped as any).has('ax')).toBe(true);
23
+
24
+ expect(() =>
25
+ t.map(() => 123 as any)
26
+ ).toThrow(/must return string/i);
27
+ });
28
+
29
+ it('mapSame covers both ternary arms and _spawnLike/_createLike default-arg branches', () => {
30
+ const t = new Trie();
31
+ t.add('a');
32
+
33
+ // thisArg === undefined arm
34
+ const t2 = t.mapSame(w => w + 'b');
35
+ expect(t2.has('ab')).toBe(true);
36
+
37
+ // thisArg provided arm
38
+ const ctx = { p: 'z' };
39
+ const t3 = t.mapSame(function (this: any, w: string) {
40
+ return this.p + w;
41
+ }, ctx);
42
+ expect(t3.has('za')).toBe(true);
43
+
44
+ // protected helpers default args
45
+ const like = (t as any)._createLike();
46
+ expect(like.size).toBe(0);
47
+
48
+ const spawned = (t as any)._spawnLike();
49
+ expect(spawned.size).toBe(0);
50
+ });
51
+ });
@@ -0,0 +1,33 @@
1
+ export async function withMutedConsole<T>(fn: () => T | Promise<T>): Promise<T> {
2
+ const originalLog = console.log;
3
+ const originalWarn = console.warn;
4
+ const originalError = console.error;
5
+
6
+ // Keep it minimal: silence during the callback, always restore.
7
+ console.log = (message?: any, ...optionalParams: any[]) => undefined;
8
+ console.warn = (message?: any, ...optionalParams: any[]) => undefined;
9
+ console.error = (message?: any, ...optionalParams: any[]) => undefined;
10
+
11
+ try {
12
+ return await fn();
13
+ } finally {
14
+ console.log = originalLog;
15
+ console.warn = originalWarn;
16
+ console.error = originalError;
17
+ }
18
+ }
19
+
20
+ export function withPatched<T extends object, K extends keyof T, R>(
21
+ obj: T,
22
+ key: K,
23
+ value: T[K],
24
+ fn: () => R
25
+ ): R {
26
+ const original = obj[key];
27
+ (obj as any)[key] = value;
28
+ try {
29
+ return fn();
30
+ } finally {
31
+ (obj as any)[key] = original;
32
+ }
33
+ }