ts-data-forge 2.1.0 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -15
- package/dist/array/array-utils.mjs +8 -8
- package/dist/array/array-utils.mjs.map +1 -1
- package/dist/collections/imap.d.mts +1 -1
- package/dist/collections/imap.d.mts.map +1 -1
- package/dist/collections/imap.mjs +1 -1
- package/dist/collections/imap.mjs.map +1 -1
- package/dist/collections/iset-mapped.d.mts +1 -1
- package/dist/collections/iset-mapped.mjs +1 -1
- package/dist/collections/iset.d.mts +2 -2
- package/dist/collections/iset.mjs +2 -2
- package/dist/collections/queue.d.mts +1 -1
- package/dist/collections/queue.d.mts.map +1 -1
- package/dist/collections/queue.mjs +7 -8
- package/dist/collections/queue.mjs.map +1 -1
- package/dist/collections/stack.d.mts +1 -1
- package/dist/collections/stack.d.mts.map +1 -1
- package/dist/collections/stack.mjs +6 -7
- package/dist/collections/stack.mjs.map +1 -1
- package/dist/entry-point.d.mts.map +1 -1
- package/dist/functional/match.d.mts.map +1 -1
- package/dist/functional/match.mjs +1 -6
- package/dist/functional/match.mjs.map +1 -1
- package/dist/functional/result.d.mts.map +1 -1
- package/dist/functional/result.mjs +3 -6
- package/dist/functional/result.mjs.map +1 -1
- package/dist/json/json.d.mts.map +1 -1
- package/dist/json/json.mjs.map +1 -1
- package/dist/others/memoize-function.d.mts +1 -1
- package/dist/others/memoize-function.mjs +1 -1
- package/package.json +12 -3
- package/src/array/array-utils-creation.test.mts +9 -8
- package/src/array/array-utils-overload-type-error.test.mts +6 -2
- package/src/array/array-utils-search.test.mts +1 -1
- package/src/array/array-utils-slicing.test.mts +0 -42
- package/src/array/array-utils-transformation.test.mts +11 -186
- package/src/array/array-utils-validation.test.mts +27 -27
- package/src/array/array-utils.mts +7 -7
- package/src/collections/imap-mapped.test.mts +15 -11
- package/src/collections/imap.mts +2 -3
- package/src/collections/imap.test.mts +20 -19
- package/src/collections/iset-mapped.mts +1 -1
- package/src/collections/iset-mapped.test.mts +14 -104
- package/src/collections/iset.mts +3 -3
- package/src/collections/iset.test.mts +43 -34
- package/src/collections/queue.mts +12 -10
- package/src/collections/queue.test.mts +46 -44
- package/src/collections/stack.mts +10 -9
- package/src/collections/stack.test.mts +12 -10
- package/src/entry-point.mts +1 -0
- package/src/functional/match.mts +1 -5
- package/src/functional/optional.test.mts +7 -7
- package/src/functional/result.mts +3 -5
- package/src/guard/is-non-empty-string.test.mts +1 -1
- package/src/guard/is-non-null-object.test.mts +3 -3
- package/src/guard/is-primitive.test.mts +6 -6
- package/src/guard/is-type.test.mts +8 -12
- package/src/iterator/range.test.mts +1 -1
- package/src/json/json.mts +1 -2
- package/src/json/json.test.mts +25 -28
- package/src/number/branded-types/finite-number.test.mts +2 -1
- package/src/number/branded-types/int.test.mts +2 -1
- package/src/number/branded-types/int16.test.mts +3 -2
- package/src/number/branded-types/int32.test.mts +3 -2
- package/src/number/branded-types/non-negative-finite-number.test.mts +3 -2
- package/src/number/branded-types/non-negative-int16.test.mts +3 -2
- package/src/number/branded-types/non-negative-int32.test.mts +3 -2
- package/src/number/branded-types/non-zero-finite-number.test.mts +4 -3
- package/src/number/branded-types/non-zero-int.test.mts +4 -3
- package/src/number/branded-types/non-zero-int16.test.mts +3 -2
- package/src/number/branded-types/non-zero-int32.test.mts +3 -2
- package/src/number/branded-types/non-zero-safe-int.test.mts +4 -3
- package/src/number/branded-types/non-zero-uint16.test.mts +3 -2
- package/src/number/branded-types/non-zero-uint32.test.mts +3 -2
- package/src/number/branded-types/positive-finite-number.test.mts +3 -2
- package/src/number/branded-types/positive-int.test.mts +3 -2
- package/src/number/branded-types/positive-int16.test.mts +3 -2
- package/src/number/branded-types/positive-int32.test.mts +3 -2
- package/src/number/branded-types/positive-safe-int.test.mts +3 -2
- package/src/number/branded-types/positive-uint16.test.mts +3 -2
- package/src/number/branded-types/positive-uint32.test.mts +3 -2
- package/src/number/branded-types/safe-int.test.mts +3 -2
- package/src/number/branded-types/safe-uint.test.mts +3 -2
- package/src/number/branded-types/uint.test.mts +3 -2
- package/src/number/branded-types/uint16.test.mts +3 -2
- package/src/number/branded-types/uint32.test.mts +3 -2
- package/src/object/object.test.mts +10 -10
- package/src/others/cast-readonly.test.mts +8 -8
- package/src/others/memoize-function.mts +1 -1
- package/src/others/memoize-function.test.mts +2 -2
- package/src/others/unknown-to-string.test.mts +3 -3
|
@@ -19,14 +19,16 @@ describe('Arr validations', () => {
|
|
|
19
19
|
});
|
|
20
20
|
|
|
21
21
|
test('should refine union types correctly', () => {
|
|
22
|
-
|
|
22
|
+
const processValue = (
|
|
23
|
+
value: string | readonly number[] | null,
|
|
24
|
+
): number => {
|
|
23
25
|
if (Arr.isArray(value)) {
|
|
24
26
|
// value should be typed as number[]
|
|
25
27
|
expectType<typeof value, readonly number[]>('=');
|
|
26
28
|
return value.length;
|
|
27
29
|
}
|
|
28
30
|
return 0;
|
|
29
|
-
}
|
|
31
|
+
};
|
|
30
32
|
|
|
31
33
|
expect(processValue([1, 2, 3])).toBe(3);
|
|
32
34
|
expect(processValue('hello')).toBe(0);
|
|
@@ -37,7 +39,7 @@ describe('Arr validations', () => {
|
|
|
37
39
|
const readonlyArray: readonly number[] = [1, 2, 3];
|
|
38
40
|
if (Arr.isArray(readonlyArray)) {
|
|
39
41
|
expectType<typeof readonlyArray, readonly number[]>('=');
|
|
40
|
-
expect(readonlyArray
|
|
42
|
+
expect(readonlyArray).toHaveLength(3);
|
|
41
43
|
}
|
|
42
44
|
});
|
|
43
45
|
|
|
@@ -45,25 +47,25 @@ describe('Arr validations', () => {
|
|
|
45
47
|
const mutableArray: number[] = [1, 2, 3];
|
|
46
48
|
if (Arr.isArray(mutableArray)) {
|
|
47
49
|
expectType<typeof mutableArray, number[]>('=');
|
|
48
|
-
expect(mutableArray
|
|
50
|
+
expect(mutableArray).toHaveLength(3);
|
|
49
51
|
}
|
|
50
52
|
});
|
|
51
53
|
|
|
52
54
|
test('should exclude impossible array types from unions', () => {
|
|
53
|
-
|
|
54
|
-
value: string | boolean | readonly number[] | {
|
|
55
|
-
): number {
|
|
55
|
+
const checkUnion = (
|
|
56
|
+
value: string | boolean | readonly number[] | Readonly<{ a: number }>,
|
|
57
|
+
): number => {
|
|
56
58
|
if (Arr.isArray(value)) {
|
|
57
59
|
// Only number[] should remain
|
|
58
60
|
expectType<typeof value, readonly number[]>('=');
|
|
59
61
|
return value.length;
|
|
60
62
|
}
|
|
61
63
|
// Non-array types
|
|
62
|
-
expectType<typeof value, string | boolean | {
|
|
64
|
+
expectType<typeof value, string | boolean | Readonly<{ a: number }>>(
|
|
63
65
|
'=',
|
|
64
66
|
);
|
|
65
67
|
return -1;
|
|
66
|
-
}
|
|
68
|
+
};
|
|
67
69
|
|
|
68
70
|
expect(checkUnion([1, 2])).toBe(2);
|
|
69
71
|
expect(checkUnion('test')).toBe(-1);
|
|
@@ -72,17 +74,17 @@ describe('Arr validations', () => {
|
|
|
72
74
|
});
|
|
73
75
|
|
|
74
76
|
test('should exclude impossible array types from unions (including unknown)', () => {
|
|
75
|
-
|
|
77
|
+
const checkUnion = (
|
|
76
78
|
value:
|
|
77
79
|
| string
|
|
78
80
|
| boolean
|
|
79
81
|
| readonly number[]
|
|
80
|
-
| {
|
|
82
|
+
| Readonly<{ a: number }>
|
|
81
83
|
// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
|
|
82
84
|
| unknown
|
|
83
85
|
// eslint-disable-next-line @typescript-eslint/no-restricted-types
|
|
84
86
|
| object,
|
|
85
|
-
): number {
|
|
87
|
+
): number => {
|
|
86
88
|
if (Arr.isArray(value)) {
|
|
87
89
|
// Only number[] should remain
|
|
88
90
|
expectType<typeof value, readonly unknown[]>('=');
|
|
@@ -93,14 +95,14 @@ describe('Arr validations', () => {
|
|
|
93
95
|
typeof value,
|
|
94
96
|
| string
|
|
95
97
|
| boolean
|
|
96
|
-
| {
|
|
98
|
+
| Readonly<{ a: number }>
|
|
97
99
|
// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
|
|
98
100
|
| unknown
|
|
99
101
|
// eslint-disable-next-line @typescript-eslint/no-restricted-types
|
|
100
102
|
| object
|
|
101
103
|
>('=');
|
|
102
104
|
return -1;
|
|
103
|
-
}
|
|
105
|
+
};
|
|
104
106
|
|
|
105
107
|
expect(checkUnion([1, 2])).toBe(2);
|
|
106
108
|
expect(checkUnion('test')).toBe(-1);
|
|
@@ -126,7 +128,7 @@ describe('Arr validations', () => {
|
|
|
126
128
|
const value: unknown = [1, 2, 3];
|
|
127
129
|
if (Arr.isArray(value)) {
|
|
128
130
|
expectType<typeof value, readonly unknown[]>('=');
|
|
129
|
-
expect(value
|
|
131
|
+
expect(value).toHaveLength(3);
|
|
130
132
|
}
|
|
131
133
|
});
|
|
132
134
|
|
|
@@ -186,13 +188,13 @@ describe('Arr validations', () => {
|
|
|
186
188
|
});
|
|
187
189
|
|
|
188
190
|
test('should work with generic function', () => {
|
|
189
|
-
|
|
191
|
+
const processGeneric = <T,>(value: T | readonly number[]): number => {
|
|
190
192
|
if (Arr.isArray(value)) {
|
|
191
193
|
// Type is narrowed to array type within this block
|
|
192
194
|
return value.length;
|
|
193
195
|
}
|
|
194
196
|
return 0;
|
|
195
|
-
}
|
|
197
|
+
};
|
|
196
198
|
expect(processGeneric([1, 2, 3])).toBe(3);
|
|
197
199
|
expect(processGeneric('hello')).toBe(0);
|
|
198
200
|
});
|
|
@@ -207,14 +209,14 @@ describe('Arr validations', () => {
|
|
|
207
209
|
|
|
208
210
|
test('should work with conditional types', () => {
|
|
209
211
|
type ArrayOrValue<T> = T extends readonly unknown[] ? T : readonly T[];
|
|
210
|
-
|
|
212
|
+
const makeArray = <T,>(value: T): ArrayOrValue<T> => {
|
|
211
213
|
if (Arr.isArray(value)) {
|
|
212
214
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
213
215
|
return value as ArrayOrValue<T>;
|
|
214
216
|
}
|
|
215
217
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
216
218
|
return [value] as ArrayOrValue<T>;
|
|
217
|
-
}
|
|
219
|
+
};
|
|
218
220
|
expect(makeArray([1, 2, 3])).toStrictEqual([1, 2, 3]);
|
|
219
221
|
expect(makeArray(5)).toStrictEqual([5]);
|
|
220
222
|
});
|
|
@@ -229,9 +231,7 @@ describe('Arr validations', () => {
|
|
|
229
231
|
});
|
|
230
232
|
|
|
231
233
|
test('should work with branded types', () => {
|
|
232
|
-
type BrandedArray = readonly number[] & {
|
|
233
|
-
readonly __brand: unique symbol;
|
|
234
|
-
};
|
|
234
|
+
type BrandedArray = readonly number[] & Readonly<{ __brand: unknown }>;
|
|
235
235
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
236
236
|
const branded = [1, 2, 3] as unknown as BrandedArray;
|
|
237
237
|
if (Arr.isArray(branded)) {
|
|
@@ -248,7 +248,7 @@ describe('Arr validations', () => {
|
|
|
248
248
|
| null;
|
|
249
249
|
|
|
250
250
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
251
|
-
|
|
251
|
+
const processComplex = (value: ComplexUnion): number => {
|
|
252
252
|
if (Arr.isArray(value)) {
|
|
253
253
|
expectType<typeof value, readonly number[]>('=');
|
|
254
254
|
return value.length;
|
|
@@ -267,7 +267,7 @@ describe('Arr validations', () => {
|
|
|
267
267
|
| { type: 'object'; data: Record<string, unknown> }
|
|
268
268
|
>('=');
|
|
269
269
|
return -1;
|
|
270
|
-
}
|
|
270
|
+
};
|
|
271
271
|
|
|
272
272
|
expect(processComplex([1, 2, 3])).toBe(3);
|
|
273
273
|
expect(processComplex('test')).toBe(4);
|
|
@@ -293,7 +293,7 @@ describe('Arr validations', () => {
|
|
|
293
293
|
const sym = Symbol('test');
|
|
294
294
|
const arrWithSymbol = Object.assign([1, 2, 3], { [sym]: 'value' });
|
|
295
295
|
if (Arr.isArray(arrWithSymbol)) {
|
|
296
|
-
expect(arrWithSymbol
|
|
296
|
+
expect(arrWithSymbol).toHaveLength(3);
|
|
297
297
|
}
|
|
298
298
|
});
|
|
299
299
|
});
|
|
@@ -390,7 +390,7 @@ describe('Arr validations', () => {
|
|
|
390
390
|
const array: readonly number[] = [1, 2, 3];
|
|
391
391
|
if (Arr.isArrayOfLength(array, 3)) {
|
|
392
392
|
expectType<typeof array, ArrayOfLength<3, number>>('=');
|
|
393
|
-
expect(array
|
|
393
|
+
expect(array).toHaveLength(3);
|
|
394
394
|
}
|
|
395
395
|
});
|
|
396
396
|
});
|
|
@@ -455,7 +455,7 @@ describe('Arr validations', () => {
|
|
|
455
455
|
const array: readonly number[] = [1, 2, 3];
|
|
456
456
|
if (Arr.isArrayAtLeastLength(array, 2)) {
|
|
457
457
|
expectType<typeof array, ArrayAtLeastLen<2, number>>('=');
|
|
458
|
-
expect(array.length
|
|
458
|
+
expect(array.length).toBeGreaterThanOrEqual(2);
|
|
459
459
|
}
|
|
460
460
|
});
|
|
461
461
|
});
|
|
@@ -2133,9 +2133,9 @@ export namespace Arr {
|
|
|
2133
2133
|
switch (args.length) {
|
|
2134
2134
|
case 3: {
|
|
2135
2135
|
const [array, value, [start, end]] = args;
|
|
2136
|
-
const
|
|
2137
|
-
|
|
2138
|
-
return
|
|
2136
|
+
const mut_cp: (E | V)[] = castMutable(copy(array));
|
|
2137
|
+
mut_cp.fill(value, start, end);
|
|
2138
|
+
return mut_cp;
|
|
2139
2139
|
}
|
|
2140
2140
|
case 2: {
|
|
2141
2141
|
const [value, fillRange] = args;
|
|
@@ -2669,7 +2669,7 @@ export namespace Arr {
|
|
|
2669
2669
|
const [array, searchElement] = args;
|
|
2670
2670
|
|
|
2671
2671
|
const index = array.indexOf(searchElement);
|
|
2672
|
-
return index
|
|
2672
|
+
return index !== -1 ? asUint32(index) : -1;
|
|
2673
2673
|
}
|
|
2674
2674
|
case 1: {
|
|
2675
2675
|
const [searchElement] = args;
|
|
@@ -2702,7 +2702,7 @@ export namespace Arr {
|
|
|
2702
2702
|
case 3: {
|
|
2703
2703
|
const [array, searchElement, fromIndex] = args;
|
|
2704
2704
|
const index = array.indexOf(searchElement, fromIndex);
|
|
2705
|
-
return index
|
|
2705
|
+
return index !== -1 ? asUint32(index) : -1;
|
|
2706
2706
|
}
|
|
2707
2707
|
case 2: {
|
|
2708
2708
|
const [searchElement, fromIndex] = args;
|
|
@@ -2750,7 +2750,7 @@ export namespace Arr {
|
|
|
2750
2750
|
case 2: {
|
|
2751
2751
|
const [array, searchElement] = args;
|
|
2752
2752
|
const index = array.lastIndexOf(searchElement);
|
|
2753
|
-
return index
|
|
2753
|
+
return index !== -1 ? asUint32(index) : -1;
|
|
2754
2754
|
}
|
|
2755
2755
|
case 1: {
|
|
2756
2756
|
const [searchElement] = args;
|
|
@@ -2785,7 +2785,7 @@ export namespace Arr {
|
|
|
2785
2785
|
|
|
2786
2786
|
const index = array.lastIndexOf(searchElement, fromIndex);
|
|
2787
2787
|
|
|
2788
|
-
return index
|
|
2788
|
+
return index !== -1 ? asUint32(index) : -1;
|
|
2789
2789
|
}
|
|
2790
2790
|
case 2: {
|
|
2791
2791
|
const [searchElement, fromIndex] = args;
|
|
@@ -83,10 +83,12 @@ describe('IMapMapped.create', () => {
|
|
|
83
83
|
|
|
84
84
|
test('should handle complex key transformations', () => {
|
|
85
85
|
type ComplexKey = { nested: { id: number }; arr: number[] };
|
|
86
|
-
const complexKeyToString = (
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
86
|
+
const complexKeyToString = (
|
|
87
|
+
key: DeepReadonly<{
|
|
88
|
+
nested: { id: number };
|
|
89
|
+
arr: number[];
|
|
90
|
+
}>,
|
|
91
|
+
): string => `${key.nested.id}_${key.arr.join(',')}`;
|
|
90
92
|
const stringToComplexKey = (str: string): ComplexKey => {
|
|
91
93
|
const [idStr, arrStr] = str.split('_');
|
|
92
94
|
return {
|
|
@@ -527,6 +529,7 @@ describe('IMapMapped.some', () => {
|
|
|
527
529
|
testKeyToString,
|
|
528
530
|
stringToTestKey,
|
|
529
531
|
);
|
|
532
|
+
// eslint-disable-next-line unicorn/prefer-includes
|
|
530
533
|
expect(map.some((value) => value === 'Alice')).toBe(true);
|
|
531
534
|
});
|
|
532
535
|
|
|
@@ -539,6 +542,7 @@ describe('IMapMapped.some', () => {
|
|
|
539
542
|
testKeyToString,
|
|
540
543
|
stringToTestKey,
|
|
541
544
|
);
|
|
545
|
+
// eslint-disable-next-line unicorn/prefer-includes
|
|
542
546
|
expect(map.some((value) => value === 'Charlie')).toBe(false);
|
|
543
547
|
});
|
|
544
548
|
|
|
@@ -704,15 +708,15 @@ describe('IMapMapped.forEach', () => {
|
|
|
704
708
|
testKeyToString,
|
|
705
709
|
stringToTestKey,
|
|
706
710
|
);
|
|
707
|
-
const
|
|
711
|
+
const mut_collected: [TestKey, string][] = [];
|
|
708
712
|
|
|
709
|
-
map.
|
|
710
|
-
|
|
711
|
-
}
|
|
713
|
+
for (const [key, value] of map.entries()) {
|
|
714
|
+
mut_collected.push([key, value]);
|
|
715
|
+
}
|
|
712
716
|
|
|
713
|
-
expect(
|
|
714
|
-
expect(
|
|
715
|
-
expect(
|
|
717
|
+
expect(mut_collected).toHaveLength(2);
|
|
718
|
+
expect(mut_collected).toContainEqual([{ id: 1, type: 'user' }, 'Alice']);
|
|
719
|
+
expect(mut_collected).toContainEqual([{ id: 2, type: 'admin' }, 'Bob']);
|
|
716
720
|
});
|
|
717
721
|
});
|
|
718
722
|
|
package/src/collections/imap.mts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Optional, Result } from '../functional/index.mjs';
|
|
2
2
|
import { asUint32 } from '../number/index.mjs';
|
|
3
|
-
import { tp } from '../others/index.mjs';
|
|
4
|
-
import { unknownToString } from '../others/unknown-to-string.mjs';
|
|
3
|
+
import { tp, unknownToString } from '../others/index.mjs';
|
|
5
4
|
|
|
6
5
|
/**
|
|
7
6
|
* Interface for an immutable map with O(1) lookup performance and functional programming patterns.
|
|
@@ -323,7 +322,7 @@ export namespace IMap {
|
|
|
323
322
|
*
|
|
324
323
|
* // From custom iterable
|
|
325
324
|
* function* generateEntries(): Generator<[string, number]> {
|
|
326
|
-
* for (
|
|
325
|
+
* for (const i of range(3)) {
|
|
327
326
|
* yield [`item${i}`, i * 10];
|
|
328
327
|
* }
|
|
329
328
|
* }
|
|
@@ -25,15 +25,15 @@ describe('IMap[Symbol.iterator]', () => {
|
|
|
25
25
|
['a', 1],
|
|
26
26
|
['b', 2],
|
|
27
27
|
]);
|
|
28
|
-
const
|
|
28
|
+
const mut_collected: (readonly [string, number])[] = [];
|
|
29
29
|
|
|
30
30
|
for (const entry of map) {
|
|
31
|
-
|
|
31
|
+
mut_collected.push(entry);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
expect(
|
|
35
|
-
expect(
|
|
36
|
-
expect(
|
|
34
|
+
expect(mut_collected).toHaveLength(2);
|
|
35
|
+
expect(mut_collected).toContainEqual(['a', 1]);
|
|
36
|
+
expect(mut_collected).toContainEqual(['b', 2]);
|
|
37
37
|
});
|
|
38
38
|
|
|
39
39
|
test('should work with spread operator', () => {
|
|
@@ -41,7 +41,7 @@ describe('IMap[Symbol.iterator]', () => {
|
|
|
41
41
|
['a', 1],
|
|
42
42
|
['b', 2],
|
|
43
43
|
]);
|
|
44
|
-
const entries =
|
|
44
|
+
const entries = Array.from(map);
|
|
45
45
|
|
|
46
46
|
expect(entries).toHaveLength(2);
|
|
47
47
|
expect(entries).toContainEqual(['a', 1]);
|
|
@@ -282,8 +282,8 @@ describe('IMap.get', () => {
|
|
|
282
282
|
['undef', undefined],
|
|
283
283
|
['null', null],
|
|
284
284
|
]);
|
|
285
|
-
expect(Optional.unwrap(map.get('undef'))).
|
|
286
|
-
expect(Optional.unwrap(map.get('null'))).
|
|
285
|
+
expect(Optional.unwrap(map.get('undef'))).toBeUndefined();
|
|
286
|
+
expect(Optional.unwrap(map.get('null'))).toBeNull();
|
|
287
287
|
});
|
|
288
288
|
});
|
|
289
289
|
|
|
@@ -781,27 +781,28 @@ describe('IMap.forEach', () => {
|
|
|
781
781
|
['b', 2],
|
|
782
782
|
['c', 3],
|
|
783
783
|
]);
|
|
784
|
-
const
|
|
784
|
+
const mut_collected: [string, number][] = [];
|
|
785
785
|
|
|
786
|
-
map.
|
|
787
|
-
|
|
788
|
-
}
|
|
786
|
+
for (const [key, value] of map.entries()) {
|
|
787
|
+
mut_collected.push([key, value]);
|
|
788
|
+
}
|
|
789
789
|
|
|
790
|
-
expect(
|
|
791
|
-
expect(
|
|
792
|
-
expect(
|
|
793
|
-
expect(
|
|
790
|
+
expect(mut_collected).toHaveLength(3);
|
|
791
|
+
expect(mut_collected).toContainEqual(['a', 1]);
|
|
792
|
+
expect(mut_collected).toContainEqual(['b', 2]);
|
|
793
|
+
expect(mut_collected).toContainEqual(['c', 3]);
|
|
794
794
|
});
|
|
795
795
|
|
|
796
796
|
test('should work with empty map', () => {
|
|
797
797
|
const map = IMap.create<string, number>([]);
|
|
798
|
-
let
|
|
798
|
+
let mut_called = false;
|
|
799
799
|
|
|
800
|
+
// eslint-disable-next-line unicorn/no-array-for-each
|
|
800
801
|
map.forEach(() => {
|
|
801
|
-
|
|
802
|
+
mut_called = true;
|
|
802
803
|
});
|
|
803
804
|
|
|
804
|
-
expect(
|
|
805
|
+
expect(mut_called).toBe(false);
|
|
805
806
|
});
|
|
806
807
|
});
|
|
807
808
|
|
|
@@ -611,7 +611,7 @@ export namespace ISetMapped {
|
|
|
611
611
|
*
|
|
612
612
|
* const combinedFlags = ISetMapped.union(setA, setB);
|
|
613
613
|
* // The order might vary as sets are unordered internally.
|
|
614
|
-
* console.log(combinedFlags.toArray().map(f => f.flagName).
|
|
614
|
+
* console.log(combinedFlags.toArray().map(f => f.flagName).toSorted());
|
|
615
615
|
* // Output: ["betaFeature", "darkMode", "newUI"]
|
|
616
616
|
* ```
|
|
617
617
|
*/
|
|
@@ -212,96 +212,6 @@ describe('ISetMapped.entries', () => {
|
|
|
212
212
|
});
|
|
213
213
|
});
|
|
214
214
|
|
|
215
|
-
describe('ISetMapped.union', () => {
|
|
216
|
-
test('case 1', () => {
|
|
217
|
-
const s0 = ISetMapped.create(
|
|
218
|
-
[{ v: 1 }, { v: 2 }, { v: 3 }],
|
|
219
|
-
toKey,
|
|
220
|
-
fromKey,
|
|
221
|
-
);
|
|
222
|
-
const s1 = ISetMapped.create(
|
|
223
|
-
[{ v: 3 }, { v: 4 }, { v: 5 }],
|
|
224
|
-
toKey,
|
|
225
|
-
fromKey,
|
|
226
|
-
);
|
|
227
|
-
|
|
228
|
-
expect(s0.union(s1)).toStrictEqual(
|
|
229
|
-
ISetMapped.create(
|
|
230
|
-
[{ v: 1 }, { v: 2 }, { v: 3 }, { v: 4 }, { v: 5 }],
|
|
231
|
-
toKey,
|
|
232
|
-
fromKey,
|
|
233
|
-
),
|
|
234
|
-
);
|
|
235
|
-
});
|
|
236
|
-
test('case 2', () => {
|
|
237
|
-
const s0 = ISetMapped.create(
|
|
238
|
-
[{ v: 1 }, { v: 2 }, { v: 3 }],
|
|
239
|
-
toKey,
|
|
240
|
-
fromKey,
|
|
241
|
-
);
|
|
242
|
-
const s1 = ISetMapped.create([], toKey, fromKey);
|
|
243
|
-
|
|
244
|
-
expect(s0.union(s1)).toStrictEqual(
|
|
245
|
-
ISetMapped.create([{ v: 1 }, { v: 2 }, { v: 3 }], toKey, fromKey),
|
|
246
|
-
);
|
|
247
|
-
});
|
|
248
|
-
test('case 3', () => {
|
|
249
|
-
const s0 = ISetMapped.create([], toKey, fromKey);
|
|
250
|
-
const s1 = ISetMapped.create(
|
|
251
|
-
[{ v: 1 }, { v: 2 }, { v: 3 }],
|
|
252
|
-
toKey,
|
|
253
|
-
fromKey,
|
|
254
|
-
);
|
|
255
|
-
|
|
256
|
-
expect(s0.union(s1)).toStrictEqual(
|
|
257
|
-
ISetMapped.create([{ v: 1 }, { v: 2 }, { v: 3 }], toKey, fromKey),
|
|
258
|
-
);
|
|
259
|
-
});
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
describe('ISetMapped.intersect', () => {
|
|
263
|
-
test('case 1', () => {
|
|
264
|
-
const s0 = ISetMapped.create(
|
|
265
|
-
[{ v: 1 }, { v: 2 }, { v: 3 }],
|
|
266
|
-
toKey,
|
|
267
|
-
fromKey,
|
|
268
|
-
);
|
|
269
|
-
const s1 = ISetMapped.create(
|
|
270
|
-
[{ v: 2 }, { v: 3 }, { v: 4 }],
|
|
271
|
-
toKey,
|
|
272
|
-
fromKey,
|
|
273
|
-
);
|
|
274
|
-
|
|
275
|
-
expect(s0.intersect(s1)).toStrictEqual(
|
|
276
|
-
ISetMapped.create([{ v: 2 }, { v: 3 }], toKey, fromKey),
|
|
277
|
-
);
|
|
278
|
-
});
|
|
279
|
-
test('case 2', () => {
|
|
280
|
-
const s0 = ISetMapped.create(
|
|
281
|
-
[{ v: 1 }, { v: 2 }, { v: 3 }],
|
|
282
|
-
toKey,
|
|
283
|
-
fromKey,
|
|
284
|
-
);
|
|
285
|
-
const s1 = ISetMapped.create([], toKey, fromKey);
|
|
286
|
-
|
|
287
|
-
expect(s0.intersect(s1)).toStrictEqual(
|
|
288
|
-
ISetMapped.create([], toKey, fromKey),
|
|
289
|
-
);
|
|
290
|
-
});
|
|
291
|
-
test('case 3', () => {
|
|
292
|
-
const s0 = ISetMapped.create([], toKey, fromKey);
|
|
293
|
-
const s1 = ISetMapped.create(
|
|
294
|
-
[{ v: 1 }, { v: 2 }, { v: 3 }],
|
|
295
|
-
toKey,
|
|
296
|
-
fromKey,
|
|
297
|
-
);
|
|
298
|
-
|
|
299
|
-
expect(s0.intersect(s1)).toStrictEqual(
|
|
300
|
-
ISetMapped.create([], toKey, fromKey),
|
|
301
|
-
);
|
|
302
|
-
});
|
|
303
|
-
});
|
|
304
|
-
|
|
305
215
|
describe('ISetMapped.subtract', () => {
|
|
306
216
|
test('case 1', () => {
|
|
307
217
|
const s0 = ISetMapped.create(
|
|
@@ -901,15 +811,15 @@ describe('ISetMapped additional functionality with complex types', () => {
|
|
|
901
811
|
testElementToString,
|
|
902
812
|
stringToTestElement,
|
|
903
813
|
);
|
|
904
|
-
const
|
|
814
|
+
const mut_collected: TestElement[] = [];
|
|
905
815
|
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
}
|
|
816
|
+
for (const el of set) {
|
|
817
|
+
mut_collected.push(el);
|
|
818
|
+
}
|
|
909
819
|
|
|
910
|
-
expect(
|
|
911
|
-
expect(
|
|
912
|
-
expect(
|
|
820
|
+
expect(mut_collected).toHaveLength(2);
|
|
821
|
+
expect(mut_collected).toContainEqual({ id: 1, type: 'user' });
|
|
822
|
+
expect(mut_collected).toContainEqual({ id: 2, type: 'admin' });
|
|
913
823
|
});
|
|
914
824
|
});
|
|
915
825
|
|
|
@@ -1125,9 +1035,9 @@ describe('ISetMapped additional functionality with complex types', () => {
|
|
|
1125
1035
|
const entries = Array.from(set.entries());
|
|
1126
1036
|
|
|
1127
1037
|
expect(entries).toHaveLength(2);
|
|
1128
|
-
|
|
1038
|
+
for (const [key, value] of entries) {
|
|
1129
1039
|
expect(key).toStrictEqual(value);
|
|
1130
|
-
}
|
|
1040
|
+
}
|
|
1131
1041
|
});
|
|
1132
1042
|
|
|
1133
1043
|
test('should work with for-of loop', () => {
|
|
@@ -1139,15 +1049,15 @@ describe('ISetMapped additional functionality with complex types', () => {
|
|
|
1139
1049
|
testElementToString,
|
|
1140
1050
|
stringToTestElement,
|
|
1141
1051
|
);
|
|
1142
|
-
const
|
|
1052
|
+
const mut_collected: TestElement[] = [];
|
|
1143
1053
|
|
|
1144
1054
|
for (const element of set) {
|
|
1145
|
-
|
|
1055
|
+
mut_collected.push(element);
|
|
1146
1056
|
}
|
|
1147
1057
|
|
|
1148
|
-
expect(
|
|
1149
|
-
expect(
|
|
1150
|
-
expect(
|
|
1058
|
+
expect(mut_collected).toHaveLength(2);
|
|
1059
|
+
expect(mut_collected).toContainEqual({ id: 1, type: 'user' });
|
|
1060
|
+
expect(mut_collected).toContainEqual({ id: 2, type: 'admin' });
|
|
1151
1061
|
});
|
|
1152
1062
|
});
|
|
1153
1063
|
|
package/src/collections/iset.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Result } from '../functional/index.mjs';
|
|
2
2
|
import { asUint32 } from '../number/index.mjs';
|
|
3
|
-
import { unknownToString } from '../others/
|
|
3
|
+
import { unknownToString } from '../others/index.mjs';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Interface for an immutable set with O(1) lookup performance and set operation support.
|
|
@@ -258,7 +258,7 @@ export namespace ISet {
|
|
|
258
258
|
* .filter(x => x % 2 === 0) // Keep even numbers: 2, 4
|
|
259
259
|
* .add(6) // Add 6: 2, 4, 6
|
|
260
260
|
* .delete(2); // Remove 2: 4, 6
|
|
261
|
-
* console.log(processedNumbers.toArray().
|
|
261
|
+
* console.log(processedNumbers.toArray().toSorted()); // Output: [4, 6]
|
|
262
262
|
*
|
|
263
263
|
* // From generator function
|
|
264
264
|
* function* generatePrimes(): Generator<number> {
|
|
@@ -445,7 +445,7 @@ export namespace ISet {
|
|
|
445
445
|
* const rolePermissions = ISet.create(["write", "execute", "admin"]);
|
|
446
446
|
*
|
|
447
447
|
* const allPermissions = ISet.union(userPermissions, rolePermissions);
|
|
448
|
-
* console.log(allPermissions.toArray().
|
|
448
|
+
* console.log(allPermissions.toArray().toSorted());
|
|
449
449
|
* // Output: ["admin", "execute", "read", "write"]
|
|
450
450
|
*
|
|
451
451
|
* // Union with different types (type widening)
|