data-structure-typed 1.52.3 → 1.52.5
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.
- package/CHANGELOG.md +2 -1
- package/README.md +13 -13
- package/README_zh-CN.md +216 -26
- package/benchmark/report.html +13 -13
- package/benchmark/report.json +158 -158
- package/dist/cjs/data-structures/base/iterable-element-base.d.ts +1 -37
- package/dist/cjs/data-structures/base/iterable-element-base.js +1 -37
- package/dist/cjs/data-structures/base/iterable-element-base.js.map +1 -1
- package/dist/cjs/data-structures/base/iterable-entry-base.d.ts +2 -54
- package/dist/cjs/data-structures/base/iterable-entry-base.js +1 -49
- package/dist/cjs/data-structures/base/iterable-entry-base.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.d.ts +0 -32
- package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.js +9 -41
- package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/avl-tree.d.ts +0 -46
- package/dist/cjs/data-structures/binary-tree/avl-tree.js +0 -46
- package/dist/cjs/data-structures/binary-tree/avl-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/binary-tree.d.ts +82 -147
- package/dist/cjs/data-structures/binary-tree/binary-tree.js +299 -331
- package/dist/cjs/data-structures/binary-tree/binary-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/bst.d.ts +1 -40
- package/dist/cjs/data-structures/binary-tree/bst.js +12 -44
- package/dist/cjs/data-structures/binary-tree/bst.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/rb-tree.d.ts +0 -48
- package/dist/cjs/data-structures/binary-tree/rb-tree.js +2 -50
- package/dist/cjs/data-structures/binary-tree/rb-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/tree-multi-map.d.ts +0 -32
- package/dist/cjs/data-structures/binary-tree/tree-multi-map.js +9 -41
- package/dist/cjs/data-structures/binary-tree/tree-multi-map.js.map +1 -1
- package/dist/cjs/data-structures/graph/abstract-graph.d.ts +0 -75
- package/dist/cjs/data-structures/graph/abstract-graph.js +0 -75
- package/dist/cjs/data-structures/graph/abstract-graph.js.map +1 -1
- package/dist/cjs/data-structures/graph/directed-graph.d.ts +0 -98
- package/dist/cjs/data-structures/graph/directed-graph.js +0 -98
- package/dist/cjs/data-structures/graph/directed-graph.js.map +1 -1
- package/dist/cjs/data-structures/graph/undirected-graph.d.ts +0 -50
- package/dist/cjs/data-structures/graph/undirected-graph.js +0 -50
- package/dist/cjs/data-structures/graph/undirected-graph.js.map +1 -1
- package/dist/cjs/data-structures/hash/hash-map.d.ts +5 -92
- package/dist/cjs/data-structures/hash/hash-map.js +29 -115
- package/dist/cjs/data-structures/hash/hash-map.js.map +1 -1
- package/dist/cjs/data-structures/heap/heap.d.ts +0 -32
- package/dist/cjs/data-structures/heap/heap.js +0 -32
- package/dist/cjs/data-structures/heap/heap.js.map +1 -1
- package/dist/cjs/data-structures/linked-list/doubly-linked-list.d.ts +5 -88
- package/dist/cjs/data-structures/linked-list/doubly-linked-list.js +5 -88
- package/dist/cjs/data-structures/linked-list/doubly-linked-list.js.map +1 -1
- package/dist/cjs/data-structures/linked-list/singly-linked-list.d.ts +1 -83
- package/dist/cjs/data-structures/linked-list/singly-linked-list.js +2 -84
- package/dist/cjs/data-structures/linked-list/singly-linked-list.js.map +1 -1
- package/dist/cjs/data-structures/linked-list/skip-linked-list.d.ts +1 -35
- package/dist/cjs/data-structures/linked-list/skip-linked-list.js +1 -35
- package/dist/cjs/data-structures/linked-list/skip-linked-list.js.map +1 -1
- package/dist/cjs/data-structures/queue/deque.d.ts +1 -98
- package/dist/cjs/data-structures/queue/deque.js +3 -99
- package/dist/cjs/data-structures/queue/deque.js.map +1 -1
- package/dist/cjs/data-structures/queue/queue.d.ts +5 -58
- package/dist/cjs/data-structures/queue/queue.js +4 -57
- package/dist/cjs/data-structures/queue/queue.js.map +1 -1
- package/dist/cjs/data-structures/stack/stack.d.ts +1 -34
- package/dist/cjs/data-structures/stack/stack.js +1 -34
- package/dist/cjs/data-structures/stack/stack.js.map +1 -1
- package/dist/cjs/data-structures/tree/tree.js +0 -1
- package/dist/cjs/data-structures/tree/tree.js.map +1 -1
- package/dist/cjs/data-structures/trie/trie.d.ts +0 -64
- package/dist/cjs/data-structures/trie/trie.js +0 -64
- package/dist/cjs/data-structures/trie/trie.js.map +1 -1
- package/dist/cjs/types/data-structures/binary-tree/binary-tree.d.ts +8 -0
- package/dist/cjs/types/data-structures/binary-tree/binary-tree.js +6 -0
- package/dist/cjs/types/data-structures/binary-tree/binary-tree.js.map +1 -1
- package/dist/cjs/types/utils/utils.d.ts +13 -12
- package/dist/cjs/utils/number.d.ts +13 -0
- package/dist/cjs/utils/number.js +13 -0
- package/dist/cjs/utils/number.js.map +1 -1
- package/dist/cjs/utils/utils.d.ts +125 -3
- package/dist/cjs/utils/utils.js +177 -21
- package/dist/cjs/utils/utils.js.map +1 -1
- package/dist/mjs/data-structures/base/iterable-element-base.d.ts +1 -37
- package/dist/mjs/data-structures/base/iterable-element-base.js +1 -37
- package/dist/mjs/data-structures/base/iterable-entry-base.d.ts +2 -54
- package/dist/mjs/data-structures/base/iterable-entry-base.js +1 -49
- package/dist/mjs/data-structures/binary-tree/avl-tree-multi-map.d.ts +0 -32
- package/dist/mjs/data-structures/binary-tree/avl-tree-multi-map.js +9 -41
- package/dist/mjs/data-structures/binary-tree/avl-tree.d.ts +0 -46
- package/dist/mjs/data-structures/binary-tree/avl-tree.js +0 -46
- package/dist/mjs/data-structures/binary-tree/binary-tree.d.ts +82 -147
- package/dist/mjs/data-structures/binary-tree/binary-tree.js +298 -332
- package/dist/mjs/data-structures/binary-tree/bst.d.ts +1 -40
- package/dist/mjs/data-structures/binary-tree/bst.js +12 -44
- package/dist/mjs/data-structures/binary-tree/rb-tree.d.ts +0 -48
- package/dist/mjs/data-structures/binary-tree/rb-tree.js +2 -50
- package/dist/mjs/data-structures/binary-tree/tree-multi-map.d.ts +0 -32
- package/dist/mjs/data-structures/binary-tree/tree-multi-map.js +9 -41
- package/dist/mjs/data-structures/graph/abstract-graph.d.ts +0 -75
- package/dist/mjs/data-structures/graph/abstract-graph.js +0 -75
- package/dist/mjs/data-structures/graph/directed-graph.d.ts +0 -98
- package/dist/mjs/data-structures/graph/directed-graph.js +0 -98
- package/dist/mjs/data-structures/graph/undirected-graph.d.ts +0 -50
- package/dist/mjs/data-structures/graph/undirected-graph.js +0 -50
- package/dist/mjs/data-structures/hash/hash-map.d.ts +5 -92
- package/dist/mjs/data-structures/hash/hash-map.js +29 -115
- package/dist/mjs/data-structures/heap/heap.d.ts +0 -32
- package/dist/mjs/data-structures/heap/heap.js +0 -32
- package/dist/mjs/data-structures/linked-list/doubly-linked-list.d.ts +5 -88
- package/dist/mjs/data-structures/linked-list/doubly-linked-list.js +5 -88
- package/dist/mjs/data-structures/linked-list/singly-linked-list.d.ts +1 -83
- package/dist/mjs/data-structures/linked-list/singly-linked-list.js +2 -84
- package/dist/mjs/data-structures/linked-list/skip-linked-list.d.ts +1 -35
- package/dist/mjs/data-structures/linked-list/skip-linked-list.js +1 -35
- package/dist/mjs/data-structures/queue/deque.d.ts +1 -98
- package/dist/mjs/data-structures/queue/deque.js +3 -99
- package/dist/mjs/data-structures/queue/queue.d.ts +5 -58
- package/dist/mjs/data-structures/queue/queue.js +4 -57
- package/dist/mjs/data-structures/stack/stack.d.ts +1 -34
- package/dist/mjs/data-structures/stack/stack.js +1 -34
- package/dist/mjs/data-structures/tree/tree.js +0 -1
- package/dist/mjs/data-structures/trie/trie.d.ts +0 -64
- package/dist/mjs/data-structures/trie/trie.js +0 -64
- package/dist/mjs/types/data-structures/binary-tree/binary-tree.d.ts +8 -0
- package/dist/mjs/types/data-structures/binary-tree/binary-tree.js +5 -1
- package/dist/mjs/types/utils/utils.d.ts +13 -12
- package/dist/mjs/utils/number.d.ts +13 -0
- package/dist/mjs/utils/number.js +13 -0
- package/dist/mjs/utils/utils.d.ts +125 -3
- package/dist/mjs/utils/utils.js +177 -21
- package/dist/umd/data-structure-typed.js +414 -1482
- package/dist/umd/data-structure-typed.min.js +5 -4
- package/dist/umd/data-structure-typed.min.js.map +1 -1
- package/package.json +6 -6
- package/src/data-structures/base/iterable-element-base.ts +2 -42
- package/src/data-structures/base/iterable-entry-base.ts +3 -62
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +8 -48
- package/src/data-structures/binary-tree/avl-tree.ts +0 -57
- package/src/data-structures/binary-tree/binary-tree.ts +329 -358
- package/src/data-structures/binary-tree/bst.ts +11 -54
- package/src/data-structures/binary-tree/rb-tree.ts +2 -62
- package/src/data-structures/binary-tree/tree-multi-map.ts +8 -48
- package/src/data-structures/graph/abstract-graph.ts +0 -92
- package/src/data-structures/graph/directed-graph.ts +0 -122
- package/src/data-structures/graph/undirected-graph.ts +0 -62
- package/src/data-structures/hash/hash-map.ts +31 -139
- package/src/data-structures/heap/heap.ts +0 -40
- package/src/data-structures/linked-list/doubly-linked-list.ts +5 -112
- package/src/data-structures/linked-list/singly-linked-list.ts +2 -104
- package/src/data-structures/linked-list/skip-linked-list.ts +1 -44
- package/src/data-structures/queue/deque.ts +2 -125
- package/src/data-structures/queue/queue.ts +5 -72
- package/src/data-structures/stack/stack.ts +1 -43
- package/src/data-structures/tree/tree.ts +1 -1
- package/src/data-structures/trie/trie.ts +0 -80
- package/src/types/data-structures/binary-tree/binary-tree.ts +8 -1
- package/src/types/utils/utils.ts +17 -15
- package/src/utils/number.ts +13 -0
- package/src/utils/utils.ts +174 -18
- package/test/config.ts +8 -0
- package/test/integration/all-in-one.test.ts +1 -1
- package/test/unit/data-structures/binary-tree/avl-tree-multi-map.test.ts +13 -13
- package/test/unit/data-structures/binary-tree/avl-tree.test.ts +18 -13
- package/test/unit/data-structures/binary-tree/binary-tree.test.ts +471 -64
- package/test/unit/data-structures/binary-tree/bst.test.ts +167 -23
- package/test/unit/data-structures/binary-tree/overall.test.ts +1 -1
- package/test/unit/data-structures/binary-tree/rb-tree.test.ts +136 -13
- package/test/unit/data-structures/binary-tree/tree-multi-map.test.ts +18 -13
- package/test/unit/data-structures/graph/directed-graph.test.ts +46 -32
- package/test/unit/data-structures/graph/map-graph.test.ts +24 -2
- package/test/unit/data-structures/graph/undirected-graph.test.ts +24 -24
- package/test/unit/data-structures/hash/hash-map.test.ts +225 -35
- package/test/unit/data-structures/heap/heap.test.ts +47 -39
- package/test/unit/data-structures/heap/min-heap.test.ts +5 -5
- package/test/unit/data-structures/linked-list/doubly-linked-list.test.ts +34 -4
- package/test/unit/data-structures/linked-list/singly-linked-list.test.ts +32 -0
- package/test/unit/data-structures/matrix/matrix.test.ts +35 -5
- package/test/unit/data-structures/priority-queue/max-priority-queue.test.ts +31 -0
- package/test/unit/data-structures/priority-queue/min-priority-queue.test.ts +18 -0
- package/test/unit/data-structures/priority-queue/priority-queue.test.ts +17 -0
- package/test/unit/data-structures/queue/deque.test.ts +288 -47
- package/test/unit/data-structures/queue/queue.test.ts +62 -37
- package/test/unit/data-structures/stack/stack.test.ts +30 -5
- package/test/unit/data-structures/tree/tree.test.ts +58 -0
- package/test/unit/data-structures/trie/trie.test.ts +46 -5
- package/test/unit/utils/utils.test.ts +169 -0
|
@@ -10,68 +10,68 @@ describe('Queue', () => {
|
|
|
10
10
|
queue = new Queue<number>();
|
|
11
11
|
});
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
it('new Queue() should create an empty queue', () => {
|
|
14
14
|
expect(queue.size).toBe(0);
|
|
15
15
|
expect(queue.isEmpty()).toBeTruthy();
|
|
16
16
|
});
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
it('push should add elements to the queue', () => {
|
|
19
19
|
queue.push(1);
|
|
20
20
|
queue.push(2);
|
|
21
21
|
expect(queue.size).toBe(2);
|
|
22
22
|
});
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
it('shift should remove the first element', () => {
|
|
25
25
|
queue.push(1);
|
|
26
26
|
queue.push(2);
|
|
27
27
|
expect(queue.shift()).toBe(1);
|
|
28
28
|
expect(queue.size).toBe(1);
|
|
29
29
|
});
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
it('shift should return undefined if queue is empty', () => {
|
|
32
32
|
expect(queue.shift()).toBeUndefined();
|
|
33
33
|
});
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
it('first should return the first element without removing it', () => {
|
|
36
36
|
queue.push(1);
|
|
37
37
|
queue.push(2);
|
|
38
38
|
expect(queue.first).toBe(1);
|
|
39
39
|
expect(queue.size).toBe(2);
|
|
40
40
|
});
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
it('first should return undefined if queue is empty', () => {
|
|
43
43
|
expect(queue.first).toBeUndefined();
|
|
44
44
|
});
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
it('size should return the number of elements', () => {
|
|
47
47
|
queue.push(1);
|
|
48
48
|
queue.push(2);
|
|
49
49
|
expect(queue.size).toBe(2);
|
|
50
50
|
});
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
it('isEmpty should return true if the queue is empty', () => {
|
|
53
53
|
expect(queue.isEmpty()).toBeTruthy();
|
|
54
54
|
});
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
it('isEmpty should return false if the queue is not empty', () => {
|
|
57
57
|
queue.push(1);
|
|
58
58
|
expect(queue.isEmpty()).toBeFalsy();
|
|
59
59
|
});
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
it('toArray should return an array of queue elements', () => {
|
|
62
62
|
queue.push(1);
|
|
63
63
|
queue.push(2);
|
|
64
64
|
expect(queue.toArray()).toEqual([1, 2]);
|
|
65
65
|
});
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
it('clear should remove all elements from the queue', () => {
|
|
68
68
|
queue.push(1);
|
|
69
69
|
queue.push(2);
|
|
70
70
|
queue.clear();
|
|
71
71
|
expect(queue.size).toBe(0);
|
|
72
72
|
});
|
|
73
73
|
|
|
74
|
-
|
|
74
|
+
it('forEach should iterate over all elements', () => {
|
|
75
75
|
const arr: number[] = [];
|
|
76
76
|
queue.push(1);
|
|
77
77
|
queue.push(2);
|
|
@@ -80,7 +80,7 @@ describe('Queue', () => {
|
|
|
80
80
|
});
|
|
81
81
|
|
|
82
82
|
// Boundary value testing
|
|
83
|
-
|
|
83
|
+
it('push and shift with many elements', () => {
|
|
84
84
|
for (let i = 0; i < 1000; i++) {
|
|
85
85
|
queue.push(i);
|
|
86
86
|
}
|
|
@@ -90,7 +90,7 @@ describe('Queue', () => {
|
|
|
90
90
|
expect(queue.isEmpty()).toBeTruthy();
|
|
91
91
|
});
|
|
92
92
|
|
|
93
|
-
|
|
93
|
+
it('compact method should work well', () => {
|
|
94
94
|
for (let i = 0; i < 1000; i++) queue.push(i);
|
|
95
95
|
|
|
96
96
|
for (let i = 0; i < 499; i++) queue.shift();
|
|
@@ -100,7 +100,7 @@ describe('Queue', () => {
|
|
|
100
100
|
expect(queue.elements.length).toBe(501);
|
|
101
101
|
});
|
|
102
102
|
|
|
103
|
-
|
|
103
|
+
it('should at after shifting', () => {
|
|
104
104
|
for (let i = 0; i < 100; i++) {
|
|
105
105
|
queue.push(i);
|
|
106
106
|
}
|
|
@@ -114,7 +114,7 @@ describe('Queue', () => {
|
|
|
114
114
|
}
|
|
115
115
|
});
|
|
116
116
|
|
|
117
|
-
|
|
117
|
+
it('should toElementFn', () => {
|
|
118
118
|
const queue = new Queue<string, { id: string }>([{ id: '1' }, { id: '5' }, { id: '3' }, { id: '4' }, { id: '2' }], {
|
|
119
119
|
toElementFn: rawElement => rawElement.id
|
|
120
120
|
});
|
|
@@ -177,6 +177,29 @@ describe('Queue', () => {
|
|
|
177
177
|
expect([...queue]).toEqual(['1', '6', '9']);
|
|
178
178
|
expect([...cloned]).toEqual(['1', '6', '0', '5', '9']);
|
|
179
179
|
});
|
|
180
|
+
|
|
181
|
+
it('should set autoCompactRatio', function () {
|
|
182
|
+
const queue = new Queue<number>();
|
|
183
|
+
|
|
184
|
+
queue.autoCompactRatio = 0.3;
|
|
185
|
+
queue.push(1);
|
|
186
|
+
queue.push(2);
|
|
187
|
+
queue.push(3);
|
|
188
|
+
queue.push(4);
|
|
189
|
+
queue.push(5);
|
|
190
|
+
queue.push(6);
|
|
191
|
+
queue.push(7);
|
|
192
|
+
queue.push(8);
|
|
193
|
+
queue.push(9);
|
|
194
|
+
queue.push(10);
|
|
195
|
+
expect(queue.elements.length).toBe(10);
|
|
196
|
+
while (queue.size > 7) queue.shift();
|
|
197
|
+
expect(queue.size).toBe(7);
|
|
198
|
+
expect(queue.elements.length).toBe(10);
|
|
199
|
+
queue.shift();
|
|
200
|
+
expect(queue.size).toBe(6);
|
|
201
|
+
expect(queue.elements.length).toBe(6);
|
|
202
|
+
});
|
|
180
203
|
});
|
|
181
204
|
|
|
182
205
|
describe('Queue - Advanced Methods', () => {
|
|
@@ -186,7 +209,7 @@ describe('Queue - Advanced Methods', () => {
|
|
|
186
209
|
queue = new Queue<number>();
|
|
187
210
|
});
|
|
188
211
|
|
|
189
|
-
|
|
212
|
+
it('reduce should apply a function against an accumulator and each element', () => {
|
|
190
213
|
queue.push(1);
|
|
191
214
|
queue.push(2);
|
|
192
215
|
queue.push(3);
|
|
@@ -194,13 +217,13 @@ describe('Queue - Advanced Methods', () => {
|
|
|
194
217
|
expect(sum).toBe(6);
|
|
195
218
|
});
|
|
196
219
|
|
|
197
|
-
|
|
220
|
+
it('reduce should return initial value for empty queue', () => {
|
|
198
221
|
const initialValue = 0;
|
|
199
222
|
const sum = queue.reduce((acc, val) => acc + val, initialValue);
|
|
200
223
|
expect(sum).toBe(initialValue);
|
|
201
224
|
});
|
|
202
225
|
|
|
203
|
-
|
|
226
|
+
it('filter should return a new queue with all elements that pass the test implemented by provided function', () => {
|
|
204
227
|
queue.push(1);
|
|
205
228
|
queue.push(2);
|
|
206
229
|
queue.push(3);
|
|
@@ -208,12 +231,12 @@ describe('Queue - Advanced Methods', () => {
|
|
|
208
231
|
expect(filteredQueue.toArray()).toEqual([2, 3]);
|
|
209
232
|
});
|
|
210
233
|
|
|
211
|
-
|
|
234
|
+
it('filter should return an empty queue for empty queue', () => {
|
|
212
235
|
const filteredQueue = queue.filter(val => val > 1);
|
|
213
236
|
expect(filteredQueue.isEmpty()).toBeTruthy();
|
|
214
237
|
});
|
|
215
238
|
|
|
216
|
-
|
|
239
|
+
it('map should create a new queue with the results of calling a provided function on every element', () => {
|
|
217
240
|
queue.push(1);
|
|
218
241
|
queue.push(2);
|
|
219
242
|
queue.push(3);
|
|
@@ -221,7 +244,7 @@ describe('Queue - Advanced Methods', () => {
|
|
|
221
244
|
expect(mappedQueue.toArray()).toEqual([2, 4, 6]);
|
|
222
245
|
});
|
|
223
246
|
|
|
224
|
-
|
|
247
|
+
it('map should return an empty queue for empty queue', () => {
|
|
225
248
|
const mappedQueue = queue.map(val => val * 2);
|
|
226
249
|
expect(mappedQueue.isEmpty()).toBeTruthy();
|
|
227
250
|
});
|
|
@@ -233,31 +256,31 @@ describe('Queue - Additional Methods', () => {
|
|
|
233
256
|
queue = new Queue<number>();
|
|
234
257
|
});
|
|
235
258
|
|
|
236
|
-
|
|
259
|
+
it('peekLast should return the last element without removing it', () => {
|
|
237
260
|
queue.push(1);
|
|
238
261
|
queue.push(2);
|
|
239
262
|
expect(queue.last).toBe(2);
|
|
240
263
|
expect(queue.size).toBe(2);
|
|
241
264
|
});
|
|
242
265
|
|
|
243
|
-
|
|
266
|
+
it('peekLast should return undefined if queue is empty', () => {
|
|
244
267
|
expect(queue.last).toBeUndefined();
|
|
245
268
|
});
|
|
246
269
|
|
|
247
|
-
|
|
270
|
+
it('at should return the element at the specified index', () => {
|
|
248
271
|
queue.push(1);
|
|
249
272
|
queue.push(2);
|
|
250
273
|
queue.push(3);
|
|
251
274
|
expect(queue.at(1)).toBe(2);
|
|
252
275
|
});
|
|
253
276
|
|
|
254
|
-
|
|
277
|
+
it('at should return undefined for an invalid index', () => {
|
|
255
278
|
queue.push(1);
|
|
256
279
|
expect(queue.at(3)).toBeUndefined();
|
|
257
280
|
expect(queue.at(-1)).toBeUndefined();
|
|
258
281
|
});
|
|
259
282
|
|
|
260
|
-
|
|
283
|
+
it('print should not throw any errors', () => {
|
|
261
284
|
expect(() => {
|
|
262
285
|
queue.push(1);
|
|
263
286
|
// queue.print();
|
|
@@ -266,19 +289,19 @@ describe('Queue - Additional Methods', () => {
|
|
|
266
289
|
});
|
|
267
290
|
|
|
268
291
|
describe('Queue - Static and Clone Methods', () => {
|
|
269
|
-
|
|
292
|
+
it('fromArray should create a new queue from an array', () => {
|
|
270
293
|
const array = [1, 2, 3];
|
|
271
294
|
const queue = Queue.fromArray(array);
|
|
272
295
|
expect(queue.toArray()).toEqual(array);
|
|
273
296
|
expect(queue.size).toBe(array.length);
|
|
274
297
|
});
|
|
275
298
|
|
|
276
|
-
|
|
299
|
+
it('fromArray should create an empty queue from an empty array', () => {
|
|
277
300
|
const queue = Queue.fromArray([]);
|
|
278
301
|
expect(queue.isEmpty()).toBeTruthy();
|
|
279
302
|
});
|
|
280
303
|
|
|
281
|
-
|
|
304
|
+
it('clone should create a new queue with the same elements', () => {
|
|
282
305
|
const originalQueue = new Queue<number>();
|
|
283
306
|
originalQueue.push(1);
|
|
284
307
|
originalQueue.push(2);
|
|
@@ -288,7 +311,7 @@ describe('Queue - Static and Clone Methods', () => {
|
|
|
288
311
|
expect(clonedQueue.size).toBe(originalQueue.size);
|
|
289
312
|
});
|
|
290
313
|
|
|
291
|
-
|
|
314
|
+
it('clone should not affect the original queue when mutated', () => {
|
|
292
315
|
const originalQueue = new Queue<number>();
|
|
293
316
|
originalQueue.push(1);
|
|
294
317
|
originalQueue.push(2);
|
|
@@ -306,18 +329,16 @@ describe('LinkedListQueue', () => {
|
|
|
306
329
|
|
|
307
330
|
beforeEach(() => {
|
|
308
331
|
queue = new LinkedListQueue<string>();
|
|
332
|
+
queue.push('A');
|
|
333
|
+
queue.push('B');
|
|
309
334
|
});
|
|
310
335
|
|
|
311
336
|
it('should push elements to the end of the queue', () => {
|
|
312
|
-
queue.push('A');
|
|
313
|
-
queue.push('B');
|
|
314
337
|
expect(queue.first).toBe('A');
|
|
315
338
|
expect(queue.size).toBe(2);
|
|
316
339
|
});
|
|
317
340
|
|
|
318
341
|
it('should shift elements from the front of the queue', () => {
|
|
319
|
-
queue.push('A');
|
|
320
|
-
queue.push('B');
|
|
321
342
|
const dequeued = queue.shift();
|
|
322
343
|
expect(dequeued).toBe('A');
|
|
323
344
|
expect(queue.first).toBe('B');
|
|
@@ -325,8 +346,12 @@ describe('LinkedListQueue', () => {
|
|
|
325
346
|
});
|
|
326
347
|
|
|
327
348
|
it('should peek at the front of the queue', () => {
|
|
328
|
-
queue.push('A');
|
|
329
|
-
queue.push('B');
|
|
330
349
|
expect(queue.first).toBe('A');
|
|
331
350
|
});
|
|
351
|
+
|
|
352
|
+
it('should clone method work correctly', () => {
|
|
353
|
+
const cloned = queue.clone();
|
|
354
|
+
expect(cloned instanceof LinkedListQueue).toBe(true);
|
|
355
|
+
expect(cloned.size).toBe(2);
|
|
356
|
+
});
|
|
332
357
|
});
|
|
@@ -19,6 +19,7 @@ describe('Stack', () => {
|
|
|
19
19
|
});
|
|
20
20
|
|
|
21
21
|
it('should peek at the top element without removing it', () => {
|
|
22
|
+
expect(stack.peek()).toBe(undefined);
|
|
22
23
|
stack.push(1);
|
|
23
24
|
stack.push(2);
|
|
24
25
|
stack.push(3);
|
|
@@ -93,7 +94,7 @@ describe('Stack iterative methods', () => {
|
|
|
93
94
|
stack.push(3);
|
|
94
95
|
});
|
|
95
96
|
|
|
96
|
-
|
|
97
|
+
it('should iterate through the stack', () => {
|
|
97
98
|
const result: number[] = [];
|
|
98
99
|
for (const element of stack) {
|
|
99
100
|
result.push(element);
|
|
@@ -102,7 +103,7 @@ describe('Stack iterative methods', () => {
|
|
|
102
103
|
expect(result).toEqual([1, 2, 3]); // iteration should start from the top of the stack
|
|
103
104
|
});
|
|
104
105
|
|
|
105
|
-
|
|
106
|
+
it('should apply forEach to the stack', () => {
|
|
106
107
|
const result: number[] = [];
|
|
107
108
|
stack.forEach(element => {
|
|
108
109
|
result.push(element);
|
|
@@ -111,23 +112,47 @@ describe('Stack iterative methods', () => {
|
|
|
111
112
|
expect(result).toEqual([1, 2, 3]);
|
|
112
113
|
});
|
|
113
114
|
|
|
114
|
-
|
|
115
|
+
it('should filter elements in the stack', () => {
|
|
115
116
|
const filteredStack = stack.filter(element => element > 1);
|
|
116
117
|
|
|
117
118
|
expect(filteredStack.size).toBe(2);
|
|
118
119
|
expect([...filteredStack]).toEqual([2, 3]);
|
|
119
120
|
});
|
|
120
121
|
|
|
121
|
-
|
|
122
|
+
it('should map elements in the stack', () => {
|
|
122
123
|
const mappedStack = stack.map(element => element * 2);
|
|
123
124
|
|
|
124
125
|
expect(mappedStack.size).toBe(3);
|
|
125
126
|
expect([...mappedStack]).toEqual([2, 4, 6]);
|
|
126
127
|
});
|
|
127
128
|
|
|
128
|
-
|
|
129
|
+
it('should reduce elements in the stack', () => {
|
|
129
130
|
const sum = stack.reduce((accumulator, element) => accumulator + element, 0);
|
|
130
131
|
|
|
131
132
|
expect(sum).toBe(6);
|
|
132
133
|
});
|
|
134
|
+
|
|
135
|
+
it('should toElementFn', () => {
|
|
136
|
+
const stack = new Stack([{ key: 1 }, { key: 2 }, { key: 5 }, { key: 3 }], { toElementFn: item => item.key });
|
|
137
|
+
expect(stack.size).toBe(4);
|
|
138
|
+
expect([...stack]).toEqual([1, 2, 5, 3]);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it('should fromArray', () => {
|
|
142
|
+
const stack = Stack.fromArray([1, 2, 5, 3]);
|
|
143
|
+
expect(stack instanceof Stack).toBe(true);
|
|
144
|
+
expect(stack.size).toBe(4);
|
|
145
|
+
expect([...stack]).toEqual([1, 2, 5, 3]);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it('should iterable-element-base toElementFn', () => {
|
|
149
|
+
const stack = new Stack<{ key: number }>([1, 2, 5, 3], { toElementFn: key => ({ key }) });
|
|
150
|
+
expect([...stack]).toEqual([{ key: 1 }, { key: 2 }, { key: 5 }, { key: 3 }]);
|
|
151
|
+
expect(() => {
|
|
152
|
+
new Stack<{ key: number }>([1, 2, 5, 3], {
|
|
153
|
+
// @ts-ignore
|
|
154
|
+
toElementFn: {}
|
|
155
|
+
});
|
|
156
|
+
}).toThrow('toElementFn must be a function type');
|
|
157
|
+
});
|
|
133
158
|
});
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { TreeNode } from '../../../../src';
|
|
2
|
+
|
|
3
|
+
describe('TreeNode', () => {
|
|
4
|
+
it('should create a tree node with key and value', () => {
|
|
5
|
+
const node = new TreeNode<string>('root', 'RootValue');
|
|
6
|
+
expect(node.key).toBe('root');
|
|
7
|
+
expect(node.value).toBe('RootValue');
|
|
8
|
+
expect(node.children).toEqual(undefined);
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it('should allow setting and getting key and value', () => {
|
|
12
|
+
const node = new TreeNode<string>('node1', 'Value1');
|
|
13
|
+
node.key = 'newKey';
|
|
14
|
+
node.value = 'newValue';
|
|
15
|
+
expect(node.key).toBe('newKey');
|
|
16
|
+
expect(node.value).toBe('newValue');
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('should add a single child node', () => {
|
|
20
|
+
const parent = new TreeNode<string>('parent');
|
|
21
|
+
const child = new TreeNode<string>('child', 'ChildValue');
|
|
22
|
+
|
|
23
|
+
parent.addChildren(child);
|
|
24
|
+
|
|
25
|
+
expect(parent.children).toHaveLength(1);
|
|
26
|
+
expect(parent.children?.[0].key).toBe('child');
|
|
27
|
+
expect(parent.children?.[0].value).toBe('ChildValue');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('should add multiple children nodes', () => {
|
|
31
|
+
const parent = new TreeNode<string>('parent');
|
|
32
|
+
const child1 = new TreeNode<string>('child1');
|
|
33
|
+
const child2 = new TreeNode<string>('child2');
|
|
34
|
+
|
|
35
|
+
parent.addChildren([child1, child2]);
|
|
36
|
+
|
|
37
|
+
expect(parent.children).toHaveLength(2);
|
|
38
|
+
expect(parent.children?.[0].key).toBe('child1');
|
|
39
|
+
expect(parent.children?.[1].key).toBe('child2');
|
|
40
|
+
parent.children = [];
|
|
41
|
+
|
|
42
|
+
expect(parent.children[0]).toBe(undefined);
|
|
43
|
+
expect(parent.children[1]).toBe(undefined);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('should calculate the correct height of the tree', () => {
|
|
47
|
+
const root = new TreeNode<string>('root');
|
|
48
|
+
const child1 = new TreeNode<string>('child1');
|
|
49
|
+
const child2 = new TreeNode<string>('child2');
|
|
50
|
+
const grandChild = new TreeNode<string>('grandChild');
|
|
51
|
+
|
|
52
|
+
root.addChildren(child1);
|
|
53
|
+
root.addChildren(child2);
|
|
54
|
+
child1.addChildren(grandChild);
|
|
55
|
+
|
|
56
|
+
expect(root.getHeight()).toBe(2); // root -> child1 -> grandChild (height = 2)
|
|
57
|
+
});
|
|
58
|
+
});
|
|
@@ -22,6 +22,31 @@ describe('TrieNode', () => {
|
|
|
22
22
|
node.isEnd = true;
|
|
23
23
|
expect(node.isEnd).toBe(true);
|
|
24
24
|
});
|
|
25
|
+
|
|
26
|
+
it('should set key property correctly', () => {
|
|
27
|
+
const node = new TrieNode('a');
|
|
28
|
+
node.isEnd = false;
|
|
29
|
+
expect(node).toEqual({
|
|
30
|
+
_children: new Map(),
|
|
31
|
+
_isEnd: false,
|
|
32
|
+
_key: 'a'
|
|
33
|
+
});
|
|
34
|
+
node.key = 'b';
|
|
35
|
+
expect(node.key).toBe('b');
|
|
36
|
+
expect(node).toEqual({
|
|
37
|
+
_children: new Map(),
|
|
38
|
+
_isEnd: false,
|
|
39
|
+
_key: 'b'
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('should set children property correctly', () => {
|
|
44
|
+
const node = new TrieNode('a');
|
|
45
|
+
node.isEnd = false;
|
|
46
|
+
const children = new Map<string, TrieNode>([['p', new TrieNode('p')]]);
|
|
47
|
+
node.children = children;
|
|
48
|
+
expect(node.children).toEqual(children);
|
|
49
|
+
});
|
|
25
50
|
});
|
|
26
51
|
|
|
27
52
|
describe('Trie', () => {
|
|
@@ -865,29 +890,45 @@ describe('Trie class', () => {
|
|
|
865
890
|
trie = new Trie(['apple', 'app', 'banana', 'band', 'bandana']);
|
|
866
891
|
});
|
|
867
892
|
|
|
868
|
-
|
|
893
|
+
it('[Symbol.iterator] should iterate over all words', () => {
|
|
869
894
|
const words = [...trie];
|
|
870
895
|
expect(words).toEqual(['app', 'apple', 'banana', 'band', 'bandana']);
|
|
871
896
|
});
|
|
872
897
|
|
|
873
|
-
|
|
898
|
+
it('forEach should execute a callback for each word', () => {
|
|
874
899
|
const mockCallback = jest.fn();
|
|
875
900
|
trie.forEach(mockCallback);
|
|
876
901
|
expect(mockCallback).toHaveBeenCalledTimes(5);
|
|
877
902
|
});
|
|
878
903
|
|
|
879
|
-
|
|
904
|
+
it('filter should return words that satisfy the predicate', () => {
|
|
880
905
|
const filteredWords = trie.filter(word => word.startsWith('ba'));
|
|
881
906
|
expect([...filteredWords]).toEqual(['banana', 'band', 'bandana']);
|
|
882
907
|
});
|
|
883
908
|
|
|
884
|
-
|
|
909
|
+
it('map should apply a function to each word', () => {
|
|
885
910
|
const mappedWords = trie.map(word => word.length.toString());
|
|
886
911
|
expect([...mappedWords]).toEqual(['3', '5', '6', '4', '7']);
|
|
887
912
|
});
|
|
888
913
|
|
|
889
|
-
|
|
914
|
+
it('reduce should reduce the words to a single value', () => {
|
|
890
915
|
const concatenatedWords = trie.reduce((acc, word) => acc + word, '');
|
|
891
916
|
expect(concatenatedWords).toEqual('appapplebananabandbandana');
|
|
892
917
|
});
|
|
918
|
+
|
|
919
|
+
it('reduce should new Trie with toElementFn be correct', () => {
|
|
920
|
+
const trieB = new Trie([{ name: 'apple' }, { name: 'app' }, { name: 'arm' }], { toElementFn: item => item.name });
|
|
921
|
+
expect(trieB.isEmpty()).toBe(false);
|
|
922
|
+
expect(trieB.size).toBe(3);
|
|
923
|
+
expect(trieB.has('apple')).toBe(true);
|
|
924
|
+
expect(trieB.has('app')).toBe(true);
|
|
925
|
+
expect(trieB.has('arm')).toBe(true);
|
|
926
|
+
expect(trieB.hasPrefix('ap')).toBe(true);
|
|
927
|
+
trieB.clear();
|
|
928
|
+
expect(trieB.size).toBe(0);
|
|
929
|
+
expect(trieB.has('apple')).toBe(false);
|
|
930
|
+
expect(trieB.has('app')).toBe(false);
|
|
931
|
+
expect(trieB.has('arm')).toBe(false);
|
|
932
|
+
expect(trieB.hasPrefix('ap')).toBe(false);
|
|
933
|
+
});
|
|
893
934
|
});
|
|
@@ -3,3 +3,172 @@ describe('isNaN', () => {
|
|
|
3
3
|
expect(isNaN('string' as unknown as number)).toBe(true);
|
|
4
4
|
});
|
|
5
5
|
});
|
|
6
|
+
|
|
7
|
+
import { isComparable } from '../../../src';
|
|
8
|
+
|
|
9
|
+
describe('isComparable', () => {
|
|
10
|
+
describe('primitive types', () => {
|
|
11
|
+
it('numbers should be comparable', () => {
|
|
12
|
+
expect(isComparable(42)).toBe(true);
|
|
13
|
+
expect(isComparable(0)).toBe(true);
|
|
14
|
+
expect(isComparable(-1)).toBe(true);
|
|
15
|
+
expect(isComparable(Infinity)).toBe(true);
|
|
16
|
+
expect(isComparable(-Infinity)).toBe(true);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('NaN should not be comparable', () => {
|
|
20
|
+
expect(isComparable(NaN)).toBe(false);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('strings should be comparable', () => {
|
|
24
|
+
expect(isComparable('hello')).toBe(true);
|
|
25
|
+
expect(isComparable('')).toBe(true);
|
|
26
|
+
expect(isComparable('123')).toBe(true);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('BigInt should be comparable', () => {
|
|
30
|
+
expect(isComparable(BigInt(42))).toBe(true);
|
|
31
|
+
expect(isComparable(BigInt(0))).toBe(true);
|
|
32
|
+
expect(isComparable(BigInt(-1))).toBe(true);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('boolean should not be comparable', () => {
|
|
36
|
+
expect(isComparable(true)).toBe(true);
|
|
37
|
+
expect(isComparable(false)).toBe(true);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('null and undefined should not be comparable', () => {
|
|
41
|
+
expect(isComparable(null)).toBe(false);
|
|
42
|
+
expect(isComparable(undefined)).toBe(false);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('symbols should not be comparable', () => {
|
|
46
|
+
expect(isComparable(Symbol('test'))).toBe(false);
|
|
47
|
+
expect(isComparable(Symbol.for('test'))).toBe(false);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
describe('Date objects', () => {
|
|
52
|
+
it('valid Date objects should be comparable', () => {
|
|
53
|
+
expect(isComparable(new Date())).toBe(true);
|
|
54
|
+
expect(isComparable(new Date('2024-01-01'))).toBe(true);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('invalid Date objects should not be comparable', () => {
|
|
58
|
+
expect(isComparable(new Date('invalid'))).toBe(false);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
describe('arrays', () => {
|
|
63
|
+
it('arrays should be comparable as they convert to string', () => {
|
|
64
|
+
expect(isComparable([])).toBe(true);
|
|
65
|
+
expect(isComparable([1, 2, 3])).toBe(true);
|
|
66
|
+
expect(isComparable(['a', 'b', 'c'])).toBe(true);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
describe('plain objects', () => {
|
|
71
|
+
it('plain objects should not be comparable', () => {
|
|
72
|
+
expect(isComparable({})).toBe(false);
|
|
73
|
+
expect(isComparable({ a: 1 })).toBe(false);
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
describe('custom objects', () => {
|
|
78
|
+
it('objects with numeric valueOf should be comparable', () => {
|
|
79
|
+
expect(isComparable({ valueOf: () => 42 })).toBe(true);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('objects with string valueOf should be comparable', () => {
|
|
83
|
+
expect(isComparable({ valueOf: () => 'test' })).toBe(true);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('objects with boolean valueOf should not be comparable', () => {
|
|
87
|
+
expect(isComparable({ valueOf: () => true })).toBe(true);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('objects with nested valueOf/toString should be comparable', () => {
|
|
91
|
+
expect(
|
|
92
|
+
isComparable({
|
|
93
|
+
valueOf: () => ({ toString: () => '42' })
|
|
94
|
+
})
|
|
95
|
+
).toBe(true);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
describe('deeply nested objects', () => {
|
|
100
|
+
it('objects with deeply nested valueOf should be comparable', () => {
|
|
101
|
+
const deeplyNested = {
|
|
102
|
+
valueOf: () => ({
|
|
103
|
+
valueOf: () => 42
|
|
104
|
+
})
|
|
105
|
+
};
|
|
106
|
+
expect(isComparable(deeplyNested)).toBe(true);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('objects with very deeply nested conversion should be comparable', () => {
|
|
110
|
+
const veryDeeplyNested = {
|
|
111
|
+
valueOf: () => ({
|
|
112
|
+
valueOf: () => ({
|
|
113
|
+
toString: () => '42'
|
|
114
|
+
})
|
|
115
|
+
})
|
|
116
|
+
};
|
|
117
|
+
expect(isComparable(veryDeeplyNested)).toBe(true);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('objects with circular references should not be comparable', () => {
|
|
121
|
+
const circular: any = {
|
|
122
|
+
valueOf: () => circular
|
|
123
|
+
};
|
|
124
|
+
expect(isComparable(circular)).toBe(false);
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
describe('edge cases', () => {
|
|
129
|
+
it('objects returning non-primitive values should be handled correctly', () => {
|
|
130
|
+
const complexObject = {
|
|
131
|
+
valueOf: () => ({
|
|
132
|
+
toString: () => ({
|
|
133
|
+
valueOf: () => 'valid'
|
|
134
|
+
})
|
|
135
|
+
})
|
|
136
|
+
};
|
|
137
|
+
expect(isComparable(complexObject)).toBe(false);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it('objects returning primitive values should be handled correctly', () => {
|
|
141
|
+
const complexObject = {
|
|
142
|
+
valueOf: () => ({
|
|
143
|
+
valueOf: () => ({
|
|
144
|
+
valueOf: () => ({
|
|
145
|
+
valueOf: () => ({
|
|
146
|
+
toString: () => `{
|
|
147
|
+
valueOf: () => 'valid'
|
|
148
|
+
}`
|
|
149
|
+
})
|
|
150
|
+
})
|
|
151
|
+
})
|
|
152
|
+
})
|
|
153
|
+
};
|
|
154
|
+
expect(isComparable(complexObject)).toBe(true);
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
describe('type checking', () => {
|
|
159
|
+
// it('should narrow types correctly', () => {
|
|
160
|
+
// const value: unknown = 42;
|
|
161
|
+
// if (isComparable(value)) {
|
|
162
|
+
// // Type narrowing here should succeed
|
|
163
|
+
// const result = value > 0;
|
|
164
|
+
// expect(result).toBe(true);
|
|
165
|
+
// }
|
|
166
|
+
// });
|
|
167
|
+
|
|
168
|
+
it('should work with type guard in array methods', () => {
|
|
169
|
+
const values: unknown[] = [42, 'test', true, null, undefined, new Date()];
|
|
170
|
+
const comparableValues = values.filter(item => isComparable(item));
|
|
171
|
+
expect(comparableValues.length).toBe(4);
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
});
|