@btc-vision/transaction 1.7.6 → 1.7.7
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/browser/index.js +1 -1
- package/browser/src/_version.d.ts +1 -1
- package/browser/src/deterministic/DeterministicMap.d.ts +3 -3
- package/browser/src/deterministic/FastMap.d.ts +24 -0
- package/browser/src/opnet.d.ts +1 -1
- package/browser/test/fastmap-setall.test.d.ts +1 -0
- package/browser/test/fastmap.test.d.ts +1 -0
- package/browser/test/old/FastBigIntMap.d.ts +18 -0
- package/browser/test/oldfastmap.test.d.ts +1 -0
- package/build/_version.d.ts +1 -1
- package/build/_version.js +1 -1
- package/build/deterministic/AddressMap.js +2 -2
- package/build/deterministic/DeterministicMap.d.ts +3 -3
- package/build/deterministic/DeterministicMap.js +2 -2
- package/build/deterministic/FastMap.d.ts +24 -0
- package/build/deterministic/{Map.js → FastMap.js} +22 -28
- package/build/opnet.d.ts +1 -1
- package/build/opnet.js +1 -1
- package/package.json +1 -1
- package/src/_version.ts +1 -1
- package/src/deterministic/AddressMap.ts +3 -3
- package/src/deterministic/DeterministicMap.ts +9 -6
- package/src/deterministic/{Map.ts → FastMap.ts} +46 -33
- package/src/opnet.ts +1 -1
- package/test/fastmap-setall.test.ts +143 -0
- package/test/fastmap.test.ts +917 -0
- package/test/old/FastBigIntMap.ts +132 -0
- package/test/oldfastmap.test.ts +917 -0
- package/browser/src/deterministic/Map.d.ts +0 -19
- package/build/deterministic/Map.d.ts +0 -19
|
@@ -0,0 +1,917 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { FastBigIntMap } from './old/FastBigIntMap';
|
|
3
|
+
|
|
4
|
+
describe('FastBigIntMap - Comprehensive Tests', () => {
|
|
5
|
+
describe('Constructor', () => {
|
|
6
|
+
it('should create an empty map with no parameters', () => {
|
|
7
|
+
const map = new FastBigIntMap();
|
|
8
|
+
expect(map.size).toBe(0);
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it('should create an empty map with null parameter', () => {
|
|
12
|
+
const map = new FastBigIntMap(null);
|
|
13
|
+
expect(map.size).toBe(0);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('should create an empty map with undefined parameter', () => {
|
|
17
|
+
const map = new FastBigIntMap(undefined);
|
|
18
|
+
expect(map.size).toBe(0);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('should create a map from an array of tuples', () => {
|
|
22
|
+
const entries: ReadonlyArray<readonly [bigint, bigint]> = [
|
|
23
|
+
[1n, 100n],
|
|
24
|
+
[2n, 200n],
|
|
25
|
+
[3n, 300n],
|
|
26
|
+
];
|
|
27
|
+
const map = new FastBigIntMap(entries);
|
|
28
|
+
|
|
29
|
+
expect(map.size).toBe(3);
|
|
30
|
+
expect(map.get(1n)).toBe(100n);
|
|
31
|
+
expect(map.get(2n)).toBe(200n);
|
|
32
|
+
expect(map.get(3n)).toBe(300n);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('should create a map from an empty array', () => {
|
|
36
|
+
const map = new FastBigIntMap([]);
|
|
37
|
+
expect(map.size).toBe(0);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('should create a map from another FastBigIntMap instance', () => {
|
|
41
|
+
const original = new FastBigIntMap([
|
|
42
|
+
[10n, 1000n],
|
|
43
|
+
[20n, 2000n],
|
|
44
|
+
]);
|
|
45
|
+
const copy = new FastBigIntMap(original);
|
|
46
|
+
|
|
47
|
+
expect(copy.size).toBe(2);
|
|
48
|
+
expect(copy.get(10n)).toBe(1000n);
|
|
49
|
+
expect(copy.get(20n)).toBe(2000n);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('should create an independent copy when constructed from another FastBigIntMap', () => {
|
|
53
|
+
const original = new FastBigIntMap([[1n, 100n]]);
|
|
54
|
+
const copy = new FastBigIntMap(original);
|
|
55
|
+
|
|
56
|
+
// Modify original
|
|
57
|
+
original.set(1n, 999n);
|
|
58
|
+
original.set(2n, 200n);
|
|
59
|
+
|
|
60
|
+
// Copy should remain unchanged
|
|
61
|
+
expect(copy.get(1n)).toBe(100n);
|
|
62
|
+
expect(copy.has(2n)).toBe(false);
|
|
63
|
+
expect(copy.size).toBe(1);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('should handle duplicate keys in initial array (last value wins)', () => {
|
|
67
|
+
const entries: ReadonlyArray<readonly [bigint, bigint]> = [
|
|
68
|
+
[1n, 100n],
|
|
69
|
+
[1n, 200n],
|
|
70
|
+
[1n, 300n],
|
|
71
|
+
];
|
|
72
|
+
const map = new FastBigIntMap(entries);
|
|
73
|
+
|
|
74
|
+
expect(map.size).toBe(1);
|
|
75
|
+
expect(map.get(1n)).toBe(300n);
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
describe('size property', () => {
|
|
80
|
+
it('should return 0 for empty map', () => {
|
|
81
|
+
const map = new FastBigIntMap();
|
|
82
|
+
expect(map.size).toBe(0);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('should return correct size after adding elements', () => {
|
|
86
|
+
const map = new FastBigIntMap();
|
|
87
|
+
map.set(1n, 100n);
|
|
88
|
+
expect(map.size).toBe(1);
|
|
89
|
+
|
|
90
|
+
map.set(2n, 200n);
|
|
91
|
+
expect(map.size).toBe(2);
|
|
92
|
+
|
|
93
|
+
map.set(3n, 300n);
|
|
94
|
+
expect(map.size).toBe(3);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('should not increase size when updating existing key', () => {
|
|
98
|
+
const map = new FastBigIntMap();
|
|
99
|
+
map.set(1n, 100n);
|
|
100
|
+
expect(map.size).toBe(1);
|
|
101
|
+
|
|
102
|
+
map.set(1n, 200n);
|
|
103
|
+
expect(map.size).toBe(1);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it('should decrease size after deletion', () => {
|
|
107
|
+
const map = new FastBigIntMap([
|
|
108
|
+
[1n, 100n],
|
|
109
|
+
[2n, 200n],
|
|
110
|
+
]);
|
|
111
|
+
expect(map.size).toBe(2);
|
|
112
|
+
|
|
113
|
+
map.delete(1n);
|
|
114
|
+
expect(map.size).toBe(1);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('should be 0 after clear', () => {
|
|
118
|
+
const map = new FastBigIntMap([
|
|
119
|
+
[1n, 100n],
|
|
120
|
+
[2n, 200n],
|
|
121
|
+
]);
|
|
122
|
+
map.clear();
|
|
123
|
+
expect(map.size).toBe(0);
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
describe('set method', () => {
|
|
128
|
+
it('should add a new key-value pair', () => {
|
|
129
|
+
const map = new FastBigIntMap();
|
|
130
|
+
map.set(1n, 100n);
|
|
131
|
+
|
|
132
|
+
expect(map.has(1n)).toBe(true);
|
|
133
|
+
expect(map.get(1n)).toBe(100n);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it('should update an existing key', () => {
|
|
137
|
+
const map = new FastBigIntMap();
|
|
138
|
+
map.set(1n, 100n);
|
|
139
|
+
map.set(1n, 200n);
|
|
140
|
+
|
|
141
|
+
expect(map.size).toBe(1);
|
|
142
|
+
expect(map.get(1n)).toBe(200n);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it('should return this for chaining', () => {
|
|
146
|
+
const map = new FastBigIntMap();
|
|
147
|
+
const result = map.set(1n, 100n);
|
|
148
|
+
|
|
149
|
+
expect(result).toBe(map);
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
it('should allow method chaining', () => {
|
|
153
|
+
const map = new FastBigIntMap();
|
|
154
|
+
map.set(1n, 100n).set(2n, 200n).set(3n, 300n);
|
|
155
|
+
|
|
156
|
+
expect(map.size).toBe(3);
|
|
157
|
+
expect(map.get(1n)).toBe(100n);
|
|
158
|
+
expect(map.get(2n)).toBe(200n);
|
|
159
|
+
expect(map.get(3n)).toBe(300n);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it('should handle negative bigint keys', () => {
|
|
163
|
+
const map = new FastBigIntMap();
|
|
164
|
+
map.set(-1n, 100n);
|
|
165
|
+
map.set(-999999999999999999n, 200n);
|
|
166
|
+
|
|
167
|
+
expect(map.get(-1n)).toBe(100n);
|
|
168
|
+
expect(map.get(-999999999999999999n)).toBe(200n);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it('should handle very large bigint keys', () => {
|
|
172
|
+
const map = new FastBigIntMap();
|
|
173
|
+
const largeKey = 12345678901234567890123456789012345678901234567890n;
|
|
174
|
+
map.set(largeKey, 100n);
|
|
175
|
+
|
|
176
|
+
expect(map.has(largeKey)).toBe(true);
|
|
177
|
+
expect(map.get(largeKey)).toBe(100n);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it('should handle zero as key', () => {
|
|
181
|
+
const map = new FastBigIntMap();
|
|
182
|
+
map.set(0n, 100n);
|
|
183
|
+
|
|
184
|
+
expect(map.has(0n)).toBe(true);
|
|
185
|
+
expect(map.get(0n)).toBe(100n);
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
it('should handle negative values', () => {
|
|
189
|
+
const map = new FastBigIntMap();
|
|
190
|
+
map.set(1n, -100n);
|
|
191
|
+
|
|
192
|
+
expect(map.get(1n)).toBe(-100n);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it('should handle zero as value', () => {
|
|
196
|
+
const map = new FastBigIntMap();
|
|
197
|
+
map.set(1n, 0n);
|
|
198
|
+
|
|
199
|
+
expect(map.get(1n)).toBe(0n);
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
describe('get method', () => {
|
|
204
|
+
it('should return the value for an existing key', () => {
|
|
205
|
+
const map = new FastBigIntMap([[1n, 100n]]);
|
|
206
|
+
expect(map.get(1n)).toBe(100n);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
it('should return undefined for a non-existing key', () => {
|
|
210
|
+
const map = new FastBigIntMap();
|
|
211
|
+
expect(map.get(1n)).toBeUndefined();
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
it('should return undefined for key in empty map', () => {
|
|
215
|
+
const map = new FastBigIntMap();
|
|
216
|
+
expect(map.get(999n)).toBeUndefined();
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
it('should return correct value after update', () => {
|
|
220
|
+
const map = new FastBigIntMap();
|
|
221
|
+
map.set(1n, 100n);
|
|
222
|
+
map.set(1n, 200n);
|
|
223
|
+
|
|
224
|
+
expect(map.get(1n)).toBe(200n);
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
it('should return undefined for deleted key', () => {
|
|
228
|
+
const map = new FastBigIntMap([[1n, 100n]]);
|
|
229
|
+
map.delete(1n);
|
|
230
|
+
|
|
231
|
+
expect(map.get(1n)).toBeUndefined();
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
describe('has method', () => {
|
|
236
|
+
it('should return true for existing key', () => {
|
|
237
|
+
const map = new FastBigIntMap([[1n, 100n]]);
|
|
238
|
+
expect(map.has(1n)).toBe(true);
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
it('should return false for non-existing key', () => {
|
|
242
|
+
const map = new FastBigIntMap();
|
|
243
|
+
expect(map.has(1n)).toBe(false);
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
it('should return false after key is deleted', () => {
|
|
247
|
+
const map = new FastBigIntMap([[1n, 100n]]);
|
|
248
|
+
map.delete(1n);
|
|
249
|
+
|
|
250
|
+
expect(map.has(1n)).toBe(false);
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
it('should return false after clear', () => {
|
|
254
|
+
const map = new FastBigIntMap([[1n, 100n]]);
|
|
255
|
+
map.clear();
|
|
256
|
+
|
|
257
|
+
expect(map.has(1n)).toBe(false);
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
it('should distinguish between different keys', () => {
|
|
261
|
+
const map = new FastBigIntMap([[1n, 100n]]);
|
|
262
|
+
|
|
263
|
+
expect(map.has(1n)).toBe(true);
|
|
264
|
+
expect(map.has(2n)).toBe(false);
|
|
265
|
+
expect(map.has(-1n)).toBe(false);
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
describe('delete method', () => {
|
|
270
|
+
it('should delete an existing key and return true', () => {
|
|
271
|
+
const map = new FastBigIntMap([[1n, 100n]]);
|
|
272
|
+
const result = map.delete(1n);
|
|
273
|
+
|
|
274
|
+
expect(result).toBe(true);
|
|
275
|
+
expect(map.has(1n)).toBe(false);
|
|
276
|
+
expect(map.size).toBe(0);
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
it('should return false for non-existing key', () => {
|
|
280
|
+
const map = new FastBigIntMap();
|
|
281
|
+
const result = map.delete(1n);
|
|
282
|
+
|
|
283
|
+
expect(result).toBe(false);
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
it('should return false when deleting from empty map', () => {
|
|
287
|
+
const map = new FastBigIntMap();
|
|
288
|
+
expect(map.delete(999n)).toBe(false);
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
it('should only delete the specified key', () => {
|
|
292
|
+
const map = new FastBigIntMap([
|
|
293
|
+
[1n, 100n],
|
|
294
|
+
[2n, 200n],
|
|
295
|
+
[3n, 300n],
|
|
296
|
+
]);
|
|
297
|
+
map.delete(2n);
|
|
298
|
+
|
|
299
|
+
expect(map.has(1n)).toBe(true);
|
|
300
|
+
expect(map.has(2n)).toBe(false);
|
|
301
|
+
expect(map.has(3n)).toBe(true);
|
|
302
|
+
expect(map.size).toBe(2);
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
it('should maintain insertion order after deletion', () => {
|
|
306
|
+
const map = new FastBigIntMap([
|
|
307
|
+
[1n, 100n],
|
|
308
|
+
[2n, 200n],
|
|
309
|
+
[3n, 300n],
|
|
310
|
+
]);
|
|
311
|
+
map.delete(2n);
|
|
312
|
+
|
|
313
|
+
const keys = [...map.keys()];
|
|
314
|
+
expect(keys).toEqual([1n, 3n]);
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
it('should return false when deleting already deleted key', () => {
|
|
318
|
+
const map = new FastBigIntMap([[1n, 100n]]);
|
|
319
|
+
map.delete(1n);
|
|
320
|
+
|
|
321
|
+
expect(map.delete(1n)).toBe(false);
|
|
322
|
+
});
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
describe('clear method', () => {
|
|
326
|
+
it('should remove all entries', () => {
|
|
327
|
+
const map = new FastBigIntMap([
|
|
328
|
+
[1n, 100n],
|
|
329
|
+
[2n, 200n],
|
|
330
|
+
[3n, 300n],
|
|
331
|
+
]);
|
|
332
|
+
map.clear();
|
|
333
|
+
|
|
334
|
+
expect(map.size).toBe(0);
|
|
335
|
+
expect(map.has(1n)).toBe(false);
|
|
336
|
+
expect(map.has(2n)).toBe(false);
|
|
337
|
+
expect(map.has(3n)).toBe(false);
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
it('should work on empty map', () => {
|
|
341
|
+
const map = new FastBigIntMap();
|
|
342
|
+
map.clear();
|
|
343
|
+
|
|
344
|
+
expect(map.size).toBe(0);
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
it('should allow adding entries after clear', () => {
|
|
348
|
+
const map = new FastBigIntMap([[1n, 100n]]);
|
|
349
|
+
map.clear();
|
|
350
|
+
map.set(2n, 200n);
|
|
351
|
+
|
|
352
|
+
expect(map.size).toBe(1);
|
|
353
|
+
expect(map.get(2n)).toBe(200n);
|
|
354
|
+
});
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
describe('setAll method', () => {
|
|
358
|
+
it('should copy all entries from another map', () => {
|
|
359
|
+
const source = new FastBigIntMap([
|
|
360
|
+
[1n, 100n],
|
|
361
|
+
[2n, 200n],
|
|
362
|
+
]);
|
|
363
|
+
const target = new FastBigIntMap();
|
|
364
|
+
target.setAll(source);
|
|
365
|
+
|
|
366
|
+
expect(target.size).toBe(2);
|
|
367
|
+
expect(target.get(1n)).toBe(100n);
|
|
368
|
+
expect(target.get(2n)).toBe(200n);
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
it('should replace all existing entries', () => {
|
|
372
|
+
const source = new FastBigIntMap([[1n, 100n]]);
|
|
373
|
+
const target = new FastBigIntMap([
|
|
374
|
+
[2n, 200n],
|
|
375
|
+
[3n, 300n],
|
|
376
|
+
]);
|
|
377
|
+
target.setAll(source);
|
|
378
|
+
|
|
379
|
+
expect(target.size).toBe(1);
|
|
380
|
+
expect(target.get(1n)).toBe(100n);
|
|
381
|
+
expect(target.has(2n)).toBe(false);
|
|
382
|
+
expect(target.has(3n)).toBe(false);
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
it('should create independent copy (modifications to source do not affect target)', () => {
|
|
386
|
+
const source = new FastBigIntMap([[1n, 100n]]);
|
|
387
|
+
const target = new FastBigIntMap();
|
|
388
|
+
target.setAll(source);
|
|
389
|
+
|
|
390
|
+
source.set(1n, 999n);
|
|
391
|
+
source.set(2n, 200n);
|
|
392
|
+
|
|
393
|
+
expect(target.get(1n)).toBe(100n);
|
|
394
|
+
expect(target.has(2n)).toBe(false);
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
it('should handle empty source map', () => {
|
|
398
|
+
const source = new FastBigIntMap();
|
|
399
|
+
const target = new FastBigIntMap([[1n, 100n]]);
|
|
400
|
+
target.setAll(source);
|
|
401
|
+
|
|
402
|
+
expect(target.size).toBe(0);
|
|
403
|
+
});
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
describe('addAll method', () => {
|
|
407
|
+
it('should add all entries from another map', () => {
|
|
408
|
+
const source = new FastBigIntMap([
|
|
409
|
+
[1n, 100n],
|
|
410
|
+
[2n, 200n],
|
|
411
|
+
]);
|
|
412
|
+
const target = new FastBigIntMap();
|
|
413
|
+
target.addAll(source);
|
|
414
|
+
|
|
415
|
+
expect(target.size).toBe(2);
|
|
416
|
+
expect(target.get(1n)).toBe(100n);
|
|
417
|
+
expect(target.get(2n)).toBe(200n);
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
it('should merge with existing entries', () => {
|
|
421
|
+
const source = new FastBigIntMap([
|
|
422
|
+
[2n, 200n],
|
|
423
|
+
[3n, 300n],
|
|
424
|
+
]);
|
|
425
|
+
const target = new FastBigIntMap([[1n, 100n]]);
|
|
426
|
+
target.addAll(source);
|
|
427
|
+
|
|
428
|
+
expect(target.size).toBe(3);
|
|
429
|
+
expect(target.get(1n)).toBe(100n);
|
|
430
|
+
expect(target.get(2n)).toBe(200n);
|
|
431
|
+
expect(target.get(3n)).toBe(300n);
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
it('should overwrite existing keys with values from source', () => {
|
|
435
|
+
const source = new FastBigIntMap([[1n, 999n]]);
|
|
436
|
+
const target = new FastBigIntMap([[1n, 100n]]);
|
|
437
|
+
target.addAll(source);
|
|
438
|
+
|
|
439
|
+
expect(target.size).toBe(1);
|
|
440
|
+
expect(target.get(1n)).toBe(999n);
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
it('should handle empty source map', () => {
|
|
444
|
+
const source = new FastBigIntMap();
|
|
445
|
+
const target = new FastBigIntMap([[1n, 100n]]);
|
|
446
|
+
target.addAll(source);
|
|
447
|
+
|
|
448
|
+
expect(target.size).toBe(1);
|
|
449
|
+
expect(target.get(1n)).toBe(100n);
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
it('should preserve insertion order (existing keys first, then new keys)', () => {
|
|
453
|
+
const source = new FastBigIntMap([
|
|
454
|
+
[2n, 200n],
|
|
455
|
+
[3n, 300n],
|
|
456
|
+
]);
|
|
457
|
+
const target = new FastBigIntMap([[1n, 100n]]);
|
|
458
|
+
target.addAll(source);
|
|
459
|
+
|
|
460
|
+
const keys = [...target.keys()];
|
|
461
|
+
expect(keys).toEqual([1n, 2n, 3n]);
|
|
462
|
+
});
|
|
463
|
+
});
|
|
464
|
+
|
|
465
|
+
describe('entries method', () => {
|
|
466
|
+
it('should return an iterator of [key, value] pairs', () => {
|
|
467
|
+
const map = new FastBigIntMap([
|
|
468
|
+
[1n, 100n],
|
|
469
|
+
[2n, 200n],
|
|
470
|
+
]);
|
|
471
|
+
const entries = [...map.entries()];
|
|
472
|
+
|
|
473
|
+
expect(entries).toEqual([
|
|
474
|
+
[1n, 100n],
|
|
475
|
+
[2n, 200n],
|
|
476
|
+
]);
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
it('should return empty iterator for empty map', () => {
|
|
480
|
+
const map = new FastBigIntMap();
|
|
481
|
+
const entries = [...map.entries()];
|
|
482
|
+
|
|
483
|
+
expect(entries).toEqual([]);
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
it('should iterate in insertion order', () => {
|
|
487
|
+
const map = new FastBigIntMap();
|
|
488
|
+
map.set(3n, 300n);
|
|
489
|
+
map.set(1n, 100n);
|
|
490
|
+
map.set(2n, 200n);
|
|
491
|
+
|
|
492
|
+
const entries = [...map.entries()];
|
|
493
|
+
expect(entries).toEqual([
|
|
494
|
+
[3n, 300n],
|
|
495
|
+
[1n, 100n],
|
|
496
|
+
[2n, 200n],
|
|
497
|
+
]);
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
it('should be usable with for...of loop', () => {
|
|
501
|
+
const map = new FastBigIntMap([
|
|
502
|
+
[1n, 100n],
|
|
503
|
+
[2n, 200n],
|
|
504
|
+
]);
|
|
505
|
+
const collected: [bigint, bigint][] = [];
|
|
506
|
+
|
|
507
|
+
for (const entry of map.entries()) {
|
|
508
|
+
collected.push(entry);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
expect(collected).toEqual([
|
|
512
|
+
[1n, 100n],
|
|
513
|
+
[2n, 200n],
|
|
514
|
+
]);
|
|
515
|
+
});
|
|
516
|
+
});
|
|
517
|
+
|
|
518
|
+
describe('keys method', () => {
|
|
519
|
+
it('should return an iterator of keys', () => {
|
|
520
|
+
const map = new FastBigIntMap([
|
|
521
|
+
[1n, 100n],
|
|
522
|
+
[2n, 200n],
|
|
523
|
+
[3n, 300n],
|
|
524
|
+
]);
|
|
525
|
+
const keys = [...map.keys()];
|
|
526
|
+
|
|
527
|
+
expect(keys).toEqual([1n, 2n, 3n]);
|
|
528
|
+
});
|
|
529
|
+
|
|
530
|
+
it('should return empty iterator for empty map', () => {
|
|
531
|
+
const map = new FastBigIntMap();
|
|
532
|
+
const keys = [...map.keys()];
|
|
533
|
+
|
|
534
|
+
expect(keys).toEqual([]);
|
|
535
|
+
});
|
|
536
|
+
|
|
537
|
+
it('should iterate in insertion order', () => {
|
|
538
|
+
const map = new FastBigIntMap();
|
|
539
|
+
map.set(5n, 500n);
|
|
540
|
+
map.set(1n, 100n);
|
|
541
|
+
map.set(3n, 300n);
|
|
542
|
+
|
|
543
|
+
const keys = [...map.keys()];
|
|
544
|
+
expect(keys).toEqual([5n, 1n, 3n]);
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
it('should be usable with for...of loop', () => {
|
|
548
|
+
const map = new FastBigIntMap([
|
|
549
|
+
[1n, 100n],
|
|
550
|
+
[2n, 200n],
|
|
551
|
+
]);
|
|
552
|
+
const collected: bigint[] = [];
|
|
553
|
+
|
|
554
|
+
for (const key of map.keys()) {
|
|
555
|
+
collected.push(key);
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
expect(collected).toEqual([1n, 2n]);
|
|
559
|
+
});
|
|
560
|
+
});
|
|
561
|
+
|
|
562
|
+
describe('values method', () => {
|
|
563
|
+
it('should return an iterator of values', () => {
|
|
564
|
+
const map = new FastBigIntMap([
|
|
565
|
+
[1n, 100n],
|
|
566
|
+
[2n, 200n],
|
|
567
|
+
[3n, 300n],
|
|
568
|
+
]);
|
|
569
|
+
const values = [...map.values()];
|
|
570
|
+
|
|
571
|
+
expect(values).toEqual([100n, 200n, 300n]);
|
|
572
|
+
});
|
|
573
|
+
|
|
574
|
+
it('should return empty iterator for empty map', () => {
|
|
575
|
+
const map = new FastBigIntMap();
|
|
576
|
+
const values = [...map.values()];
|
|
577
|
+
|
|
578
|
+
expect(values).toEqual([]);
|
|
579
|
+
});
|
|
580
|
+
|
|
581
|
+
it('should iterate in insertion order', () => {
|
|
582
|
+
const map = new FastBigIntMap();
|
|
583
|
+
map.set(3n, 300n);
|
|
584
|
+
map.set(1n, 100n);
|
|
585
|
+
map.set(2n, 200n);
|
|
586
|
+
|
|
587
|
+
const values = [...map.values()];
|
|
588
|
+
expect(values).toEqual([300n, 100n, 200n]);
|
|
589
|
+
});
|
|
590
|
+
|
|
591
|
+
it('should be usable with for...of loop', () => {
|
|
592
|
+
const map = new FastBigIntMap([
|
|
593
|
+
[1n, 100n],
|
|
594
|
+
[2n, 200n],
|
|
595
|
+
]);
|
|
596
|
+
const collected: bigint[] = [];
|
|
597
|
+
|
|
598
|
+
for (const value of map.values()) {
|
|
599
|
+
collected.push(value);
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
expect(collected).toEqual([100n, 200n]);
|
|
603
|
+
});
|
|
604
|
+
});
|
|
605
|
+
|
|
606
|
+
describe('forEach method', () => {
|
|
607
|
+
it('should call callback for each entry', () => {
|
|
608
|
+
const map = new FastBigIntMap([
|
|
609
|
+
[1n, 100n],
|
|
610
|
+
[2n, 200n],
|
|
611
|
+
]);
|
|
612
|
+
const callback = vi.fn();
|
|
613
|
+
|
|
614
|
+
map.forEach(callback);
|
|
615
|
+
|
|
616
|
+
expect(callback).toHaveBeenCalledTimes(2);
|
|
617
|
+
expect(callback).toHaveBeenNthCalledWith(1, 100n, 1n, map);
|
|
618
|
+
expect(callback).toHaveBeenNthCalledWith(2, 200n, 2n, map);
|
|
619
|
+
});
|
|
620
|
+
|
|
621
|
+
it('should not call callback for empty map', () => {
|
|
622
|
+
const map = new FastBigIntMap();
|
|
623
|
+
const callback = vi.fn();
|
|
624
|
+
|
|
625
|
+
map.forEach(callback);
|
|
626
|
+
|
|
627
|
+
expect(callback).not.toHaveBeenCalled();
|
|
628
|
+
});
|
|
629
|
+
|
|
630
|
+
it('should iterate in insertion order', () => {
|
|
631
|
+
const map = new FastBigIntMap();
|
|
632
|
+
map.set(3n, 300n);
|
|
633
|
+
map.set(1n, 100n);
|
|
634
|
+
map.set(2n, 200n);
|
|
635
|
+
|
|
636
|
+
const order: bigint[] = [];
|
|
637
|
+
map.forEach((value, key) => {
|
|
638
|
+
order.push(key);
|
|
639
|
+
});
|
|
640
|
+
|
|
641
|
+
expect(order).toEqual([3n, 1n, 2n]);
|
|
642
|
+
});
|
|
643
|
+
|
|
644
|
+
it('should use thisArg when provided', () => {
|
|
645
|
+
const map = new FastBigIntMap([[1n, 100n]]);
|
|
646
|
+
const context = { multiplier: 2n };
|
|
647
|
+
|
|
648
|
+
let result: bigint = 0n;
|
|
649
|
+
map.forEach(function (this: { multiplier: bigint }, value) {
|
|
650
|
+
result = value * this.multiplier;
|
|
651
|
+
}, context);
|
|
652
|
+
|
|
653
|
+
expect(result).toBe(200n);
|
|
654
|
+
});
|
|
655
|
+
|
|
656
|
+
it('should work without thisArg', () => {
|
|
657
|
+
const map = new FastBigIntMap([[1n, 100n]]);
|
|
658
|
+
let sum = 0n;
|
|
659
|
+
|
|
660
|
+
map.forEach((value) => {
|
|
661
|
+
sum += value;
|
|
662
|
+
});
|
|
663
|
+
|
|
664
|
+
expect(sum).toBe(100n);
|
|
665
|
+
});
|
|
666
|
+
|
|
667
|
+
it('should pass map as third argument', () => {
|
|
668
|
+
const map = new FastBigIntMap([[1n, 100n]]);
|
|
669
|
+
let receivedMap: FastBigIntMap | null = null;
|
|
670
|
+
|
|
671
|
+
map.forEach((value, key, m) => {
|
|
672
|
+
receivedMap = m;
|
|
673
|
+
});
|
|
674
|
+
|
|
675
|
+
expect(receivedMap).toBe(map);
|
|
676
|
+
});
|
|
677
|
+
});
|
|
678
|
+
|
|
679
|
+
describe('Symbol.iterator', () => {
|
|
680
|
+
it('should make map iterable with for...of', () => {
|
|
681
|
+
const map = new FastBigIntMap([
|
|
682
|
+
[1n, 100n],
|
|
683
|
+
[2n, 200n],
|
|
684
|
+
]);
|
|
685
|
+
const collected: [bigint, bigint][] = [];
|
|
686
|
+
|
|
687
|
+
for (const entry of map) {
|
|
688
|
+
collected.push(entry);
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
expect(collected).toEqual([
|
|
692
|
+
[1n, 100n],
|
|
693
|
+
[2n, 200n],
|
|
694
|
+
]);
|
|
695
|
+
});
|
|
696
|
+
|
|
697
|
+
it('should return same iterator as entries()', () => {
|
|
698
|
+
const map = new FastBigIntMap([
|
|
699
|
+
[1n, 100n],
|
|
700
|
+
[2n, 200n],
|
|
701
|
+
]);
|
|
702
|
+
|
|
703
|
+
const fromIterator = [...map];
|
|
704
|
+
const fromEntries = [...map.entries()];
|
|
705
|
+
|
|
706
|
+
expect(fromIterator).toEqual(fromEntries);
|
|
707
|
+
});
|
|
708
|
+
|
|
709
|
+
it('should work with spread operator', () => {
|
|
710
|
+
const map = new FastBigIntMap([
|
|
711
|
+
[1n, 100n],
|
|
712
|
+
[2n, 200n],
|
|
713
|
+
]);
|
|
714
|
+
const entries = [...map];
|
|
715
|
+
|
|
716
|
+
expect(entries).toEqual([
|
|
717
|
+
[1n, 100n],
|
|
718
|
+
[2n, 200n],
|
|
719
|
+
]);
|
|
720
|
+
});
|
|
721
|
+
|
|
722
|
+
it('should work with Array.from', () => {
|
|
723
|
+
const map = new FastBigIntMap([
|
|
724
|
+
[1n, 100n],
|
|
725
|
+
[2n, 200n],
|
|
726
|
+
]);
|
|
727
|
+
const entries = Array.from(map);
|
|
728
|
+
|
|
729
|
+
expect(entries).toEqual([
|
|
730
|
+
[1n, 100n],
|
|
731
|
+
[2n, 200n],
|
|
732
|
+
]);
|
|
733
|
+
});
|
|
734
|
+
|
|
735
|
+
it('should work with destructuring', () => {
|
|
736
|
+
const map = new FastBigIntMap([
|
|
737
|
+
[1n, 100n],
|
|
738
|
+
[2n, 200n],
|
|
739
|
+
]);
|
|
740
|
+
const [first, second] = map;
|
|
741
|
+
|
|
742
|
+
expect(first).toEqual([1n, 100n]);
|
|
743
|
+
expect(second).toEqual([2n, 200n]);
|
|
744
|
+
});
|
|
745
|
+
|
|
746
|
+
it('should return empty iterator for empty map', () => {
|
|
747
|
+
const map = new FastBigIntMap();
|
|
748
|
+
const entries = [...map];
|
|
749
|
+
|
|
750
|
+
expect(entries).toEqual([]);
|
|
751
|
+
});
|
|
752
|
+
});
|
|
753
|
+
|
|
754
|
+
describe('Insertion order preservation', () => {
|
|
755
|
+
it('should maintain insertion order across all iteration methods', () => {
|
|
756
|
+
const map = new FastBigIntMap();
|
|
757
|
+
map.set(5n, 500n);
|
|
758
|
+
map.set(1n, 100n);
|
|
759
|
+
map.set(3n, 300n);
|
|
760
|
+
map.set(2n, 200n);
|
|
761
|
+
map.set(4n, 400n);
|
|
762
|
+
|
|
763
|
+
const keysFromKeys = [...map.keys()];
|
|
764
|
+
const keysFromEntries = [...map.entries()].map(([k]) => k);
|
|
765
|
+
const keysFromForEach: bigint[] = [];
|
|
766
|
+
map.forEach((_, key) => keysFromForEach.push(key));
|
|
767
|
+
const keysFromIterator = [...map].map(([k]) => k);
|
|
768
|
+
|
|
769
|
+
const expectedOrder = [5n, 1n, 3n, 2n, 4n];
|
|
770
|
+
|
|
771
|
+
expect(keysFromKeys).toEqual(expectedOrder);
|
|
772
|
+
expect(keysFromEntries).toEqual(expectedOrder);
|
|
773
|
+
expect(keysFromForEach).toEqual(expectedOrder);
|
|
774
|
+
expect(keysFromIterator).toEqual(expectedOrder);
|
|
775
|
+
});
|
|
776
|
+
|
|
777
|
+
it('should not change order when updating existing key', () => {
|
|
778
|
+
const map = new FastBigIntMap();
|
|
779
|
+
map.set(1n, 100n);
|
|
780
|
+
map.set(2n, 200n);
|
|
781
|
+
map.set(3n, 300n);
|
|
782
|
+
|
|
783
|
+
// Update middle key
|
|
784
|
+
map.set(2n, 999n);
|
|
785
|
+
|
|
786
|
+
const keys = [...map.keys()];
|
|
787
|
+
expect(keys).toEqual([1n, 2n, 3n]);
|
|
788
|
+
expect(map.get(2n)).toBe(999n);
|
|
789
|
+
});
|
|
790
|
+
});
|
|
791
|
+
|
|
792
|
+
describe('Edge cases', () => {
|
|
793
|
+
it('should handle maximum safe bigint values', () => {
|
|
794
|
+
const map = new FastBigIntMap();
|
|
795
|
+
const maxSafe = BigInt(Number.MAX_SAFE_INTEGER);
|
|
796
|
+
const minSafe = BigInt(Number.MIN_SAFE_INTEGER);
|
|
797
|
+
|
|
798
|
+
map.set(maxSafe, 1n);
|
|
799
|
+
map.set(minSafe, 2n);
|
|
800
|
+
|
|
801
|
+
expect(map.get(maxSafe)).toBe(1n);
|
|
802
|
+
expect(map.get(minSafe)).toBe(2n);
|
|
803
|
+
});
|
|
804
|
+
|
|
805
|
+
it('should handle extremely large bigints', () => {
|
|
806
|
+
const map = new FastBigIntMap();
|
|
807
|
+
const hugeKey = 10n ** 100n;
|
|
808
|
+
const hugeValue = 10n ** 200n;
|
|
809
|
+
|
|
810
|
+
map.set(hugeKey, hugeValue);
|
|
811
|
+
|
|
812
|
+
expect(map.get(hugeKey)).toBe(hugeValue);
|
|
813
|
+
});
|
|
814
|
+
|
|
815
|
+
it('should handle many entries', () => {
|
|
816
|
+
const map = new FastBigIntMap();
|
|
817
|
+
const count = 10000;
|
|
818
|
+
|
|
819
|
+
for (let i = 0; i < count; i++) {
|
|
820
|
+
map.set(BigInt(i), BigInt(i * 10));
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
expect(map.size).toBe(count);
|
|
824
|
+
expect(map.get(0n)).toBe(0n);
|
|
825
|
+
expect(map.get(5000n)).toBe(50000n);
|
|
826
|
+
expect(map.get(9999n)).toBe(99990n);
|
|
827
|
+
});
|
|
828
|
+
|
|
829
|
+
it('should correctly handle 0n as both key and value', () => {
|
|
830
|
+
const map = new FastBigIntMap();
|
|
831
|
+
map.set(0n, 0n);
|
|
832
|
+
|
|
833
|
+
expect(map.has(0n)).toBe(true);
|
|
834
|
+
expect(map.get(0n)).toBe(0n);
|
|
835
|
+
expect(map.size).toBe(1);
|
|
836
|
+
});
|
|
837
|
+
|
|
838
|
+
it('should handle negative zero (-0n is same as 0n in bigint)', () => {
|
|
839
|
+
const map = new FastBigIntMap();
|
|
840
|
+
map.set(-0n, 100n);
|
|
841
|
+
|
|
842
|
+
expect(map.get(0n)).toBe(100n);
|
|
843
|
+
expect(map.has(-0n)).toBe(true);
|
|
844
|
+
});
|
|
845
|
+
|
|
846
|
+
it('should handle operations in sequence', () => {
|
|
847
|
+
const map = new FastBigIntMap();
|
|
848
|
+
|
|
849
|
+
// Add
|
|
850
|
+
map.set(1n, 100n);
|
|
851
|
+
map.set(2n, 200n);
|
|
852
|
+
expect(map.size).toBe(2);
|
|
853
|
+
|
|
854
|
+
// Update
|
|
855
|
+
map.set(1n, 150n);
|
|
856
|
+
expect(map.get(1n)).toBe(150n);
|
|
857
|
+
expect(map.size).toBe(2);
|
|
858
|
+
|
|
859
|
+
// Delete
|
|
860
|
+
map.delete(1n);
|
|
861
|
+
expect(map.size).toBe(1);
|
|
862
|
+
expect(map.has(1n)).toBe(false);
|
|
863
|
+
|
|
864
|
+
// Add back
|
|
865
|
+
map.set(1n, 100n);
|
|
866
|
+
expect(map.size).toBe(2);
|
|
867
|
+
|
|
868
|
+
// Clear
|
|
869
|
+
map.clear();
|
|
870
|
+
expect(map.size).toBe(0);
|
|
871
|
+
|
|
872
|
+
// Add after clear
|
|
873
|
+
map.set(3n, 300n);
|
|
874
|
+
expect(map.size).toBe(1);
|
|
875
|
+
expect(map.get(3n)).toBe(300n);
|
|
876
|
+
});
|
|
877
|
+
});
|
|
878
|
+
|
|
879
|
+
describe('Type safety and method signatures', () => {
|
|
880
|
+
it('set should accept bigint key and bigint value', () => {
|
|
881
|
+
const map = new FastBigIntMap();
|
|
882
|
+
const result = map.set(1n, 100n);
|
|
883
|
+
|
|
884
|
+
expect(result).toBeInstanceOf(FastBigIntMap);
|
|
885
|
+
});
|
|
886
|
+
|
|
887
|
+
it('get should return bigint or undefined', () => {
|
|
888
|
+
const map = new FastBigIntMap([[1n, 100n]]);
|
|
889
|
+
|
|
890
|
+
const existing: bigint | undefined = map.get(1n);
|
|
891
|
+
const nonExisting: bigint | undefined = map.get(999n);
|
|
892
|
+
|
|
893
|
+
expect(typeof existing).toBe('bigint');
|
|
894
|
+
expect(nonExisting).toBeUndefined();
|
|
895
|
+
});
|
|
896
|
+
|
|
897
|
+
it('has should return boolean', () => {
|
|
898
|
+
const map = new FastBigIntMap([[1n, 100n]]);
|
|
899
|
+
|
|
900
|
+
expect(typeof map.has(1n)).toBe('boolean');
|
|
901
|
+
expect(typeof map.has(999n)).toBe('boolean');
|
|
902
|
+
});
|
|
903
|
+
|
|
904
|
+
it('delete should return boolean', () => {
|
|
905
|
+
const map = new FastBigIntMap([[1n, 100n]]);
|
|
906
|
+
|
|
907
|
+
expect(typeof map.delete(1n)).toBe('boolean');
|
|
908
|
+
expect(typeof map.delete(999n)).toBe('boolean');
|
|
909
|
+
});
|
|
910
|
+
|
|
911
|
+
it('size should return number', () => {
|
|
912
|
+
const map = new FastBigIntMap([[1n, 100n]]);
|
|
913
|
+
|
|
914
|
+
expect(typeof map.size).toBe('number');
|
|
915
|
+
});
|
|
916
|
+
});
|
|
917
|
+
});
|