ts-data-forge 4.1.0 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/json/json.d.mts +9 -3
- package/dist/json/json.d.mts.map +1 -1
- package/dist/json/json.mjs +6 -0
- package/dist/json/json.mjs.map +1 -1
- package/package.json +13 -13
- package/src/array/impl/array-utils-creation.test.mts +187 -74
- package/src/array/impl/array-utils-element-access.test.mts +19 -3
- package/src/array/impl/array-utils-iterators.test.mts +44 -24
- package/src/array/impl/array-utils-modification.test.mts +36 -33
- package/src/array/impl/array-utils-reducing-value.test.mts +47 -16
- package/src/array/impl/array-utils-search.test.mts +42 -9
- package/src/array/impl/array-utils-set-op.test.mts +54 -26
- package/src/array/impl/array-utils-size.test.mts +1 -0
- package/src/array/impl/array-utils-slice-clamped.test.mts +20 -11
- package/src/array/impl/array-utils-slicing.test.mts +27 -21
- package/src/array/impl/array-utils-transformation.test.mts +140 -92
- package/src/array/impl/array-utils-validation.test.mts +58 -10
- package/src/array/impl/array.test.mts +5 -5
- package/src/collections/imap-mapped.test.mts +63 -18
- package/src/collections/imap.test.mts +74 -26
- package/src/collections/iset-mapped.test.mts +81 -30
- package/src/collections/iset.test.mts +168 -68
- package/src/collections/queue.test.mts +32 -1
- package/src/collections/stack.test.mts +22 -8
- package/src/functional/match.test.mts +1 -1
- package/src/functional/optional.test.mts +61 -4
- package/src/functional/pipe.test.mts +10 -1
- package/src/functional/result.test.mts +127 -4
- package/src/functional/ternary-result.test.mts +34 -18
- package/src/guard/is-non-empty-string.test.mts +5 -2
- package/src/guard/is-non-null-object.test.mts +3 -5
- package/src/guard/is-primitive.test.mts +5 -3
- package/src/guard/is-record.test.mts +1 -1
- package/src/guard/is-type.test.mts +35 -20
- package/src/guard/key-is-in.test.mts +1 -1
- package/src/iterator/range.test.mts +22 -16
- package/src/json/json.mts +9 -3
- package/src/json/json.test.mts +140 -64
- package/src/number/branded-types/finite-number.test.mts +3 -2
- package/src/number/branded-types/int.test.mts +4 -3
- package/src/number/branded-types/int16.test.mts +9 -3
- package/src/number/branded-types/int32.test.mts +9 -3
- package/src/number/branded-types/non-negative-finite-number.test.mts +6 -4
- package/src/number/branded-types/non-negative-int16.test.mts +8 -3
- package/src/number/branded-types/non-negative-int32.test.mts +8 -3
- package/src/number/branded-types/non-zero-finite-number.test.mts +6 -3
- package/src/number/branded-types/non-zero-int.test.mts +6 -3
- package/src/number/branded-types/non-zero-int16.test.mts +9 -3
- package/src/number/branded-types/non-zero-int32.test.mts +9 -3
- package/src/number/branded-types/non-zero-safe-int.test.mts +10 -3
- package/src/number/branded-types/non-zero-uint16.test.mts +8 -3
- package/src/number/branded-types/non-zero-uint32.test.mts +8 -3
- package/src/number/branded-types/positive-finite-number.test.mts +7 -3
- package/src/number/branded-types/positive-int.test.mts +5 -3
- package/src/number/branded-types/positive-int16.test.mts +8 -3
- package/src/number/branded-types/positive-int32.test.mts +8 -3
- package/src/number/branded-types/positive-safe-int.test.mts +8 -3
- package/src/number/branded-types/positive-uint16.test.mts +8 -3
- package/src/number/branded-types/positive-uint32.test.mts +8 -3
- package/src/number/branded-types/safe-int.test.mts +8 -2
- package/src/number/branded-types/safe-uint.test.mts +8 -3
- package/src/number/branded-types/uint.test.mts +5 -3
- package/src/number/branded-types/uint16.test.mts +8 -3
- package/src/number/branded-types/uint32.test.mts +8 -3
- package/src/number/enum/int8.test.mts +8 -3
- package/src/number/enum/uint8.test.mts +6 -3
- package/src/number/num.test.mts +16 -2
- package/src/object/object.test.mts +26 -13
- package/src/others/cast-mutable.test.mts +10 -8
- package/src/others/cast-readonly.test.mts +9 -5
- package/src/others/if-then.test.mts +4 -1
- package/src/others/map-nullable.test.mts +28 -1
- package/src/others/memoize-function.test.mts +20 -17
- package/src/others/tuple.test.mts +3 -2
- package/src/others/unknown-to-string.test.mts +15 -2
- package/src/promise/promise.test.mts +6 -1
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { memoizeFunction } from './memoize-function.mjs';
|
|
2
2
|
|
|
3
|
-
describe(
|
|
3
|
+
describe(memoizeFunction, () => {
|
|
4
4
|
test('should cache results for the same arguments', () => {
|
|
5
5
|
const mockFn = vi.fn((x: number) => x * 2);
|
|
6
6
|
const memoized = memoizeFunction(mockFn, (x) => x);
|
|
7
7
|
|
|
8
8
|
// First call
|
|
9
9
|
expect(memoized(5)).toBe(10);
|
|
10
|
-
expect(mockFn).
|
|
10
|
+
expect(mockFn).toHaveBeenCalledOnce();
|
|
11
11
|
|
|
12
12
|
// Second call with same argument - should use cache
|
|
13
13
|
expect(memoized(5)).toBe(10);
|
|
14
|
-
expect(mockFn).
|
|
14
|
+
expect(mockFn).toHaveBeenCalledOnce();
|
|
15
15
|
|
|
16
16
|
// Call with different argument
|
|
17
17
|
expect(memoized(3)).toBe(6);
|
|
@@ -23,10 +23,10 @@ describe('memoizeFunction', () => {
|
|
|
23
23
|
const memoized = memoizeFunction(mockFn, (a, b) => `${a},${b}`);
|
|
24
24
|
|
|
25
25
|
expect(memoized(2, 3)).toBe(5);
|
|
26
|
-
expect(mockFn).
|
|
26
|
+
expect(mockFn).toHaveBeenCalledOnce();
|
|
27
27
|
|
|
28
28
|
expect(memoized(2, 3)).toBe(5);
|
|
29
|
-
expect(mockFn).
|
|
29
|
+
expect(mockFn).toHaveBeenCalledOnce();
|
|
30
30
|
|
|
31
31
|
expect(memoized(3, 2)).toBe(5);
|
|
32
32
|
expect(mockFn).toHaveBeenCalledTimes(2);
|
|
@@ -38,12 +38,12 @@ describe('memoizeFunction', () => {
|
|
|
38
38
|
|
|
39
39
|
// eslint-disable-next-line @typescript-eslint/no-confusing-void-expression
|
|
40
40
|
expect(memoized(5)).toBeUndefined();
|
|
41
|
-
expect(mockFn).
|
|
41
|
+
expect(mockFn).toHaveBeenCalledOnce();
|
|
42
42
|
|
|
43
43
|
// Should use cache even for undefined
|
|
44
44
|
// eslint-disable-next-line @typescript-eslint/no-confusing-void-expression
|
|
45
45
|
expect(memoized(5)).toBeUndefined();
|
|
46
|
-
expect(mockFn).
|
|
46
|
+
expect(mockFn).toHaveBeenCalledOnce();
|
|
47
47
|
});
|
|
48
48
|
|
|
49
49
|
test('should work with object arguments using primitive cache keys', () => {
|
|
@@ -56,11 +56,11 @@ describe('memoizeFunction', () => {
|
|
|
56
56
|
const user3 = { id: 2, name: 'Charlie' };
|
|
57
57
|
|
|
58
58
|
expect(memoized(user1)).toBe('Hello Alice');
|
|
59
|
-
expect(mockFn).
|
|
59
|
+
expect(mockFn).toHaveBeenCalledOnce();
|
|
60
60
|
|
|
61
61
|
// Same id, should use cache (even though name is different)
|
|
62
62
|
expect(memoized(user2)).toBe('Hello Alice');
|
|
63
|
-
expect(mockFn).
|
|
63
|
+
expect(mockFn).toHaveBeenCalledOnce();
|
|
64
64
|
|
|
65
65
|
// Different id, should call function
|
|
66
66
|
expect(memoized(user3)).toBe('Hello Charlie');
|
|
@@ -73,6 +73,7 @@ describe('memoizeFunction', () => {
|
|
|
73
73
|
(x: string) => x.length,
|
|
74
74
|
(x) => x.length,
|
|
75
75
|
);
|
|
76
|
+
|
|
76
77
|
expect(withNumber('hello')).toBe(5);
|
|
77
78
|
expect(withNumber('world')).toBe(5); // Same length, uses cache
|
|
78
79
|
|
|
@@ -81,6 +82,7 @@ describe('memoizeFunction', () => {
|
|
|
81
82
|
(x: number) => x * 2,
|
|
82
83
|
(x) => x > 0,
|
|
83
84
|
);
|
|
85
|
+
|
|
84
86
|
expect(withBoolean(5)).toBe(10);
|
|
85
87
|
expect(withBoolean(3)).toBe(10); // Both positive, uses cache
|
|
86
88
|
expect(withBoolean(-2)).toBe(-4); // Negative, new cache entry
|
|
@@ -93,6 +95,7 @@ describe('memoizeFunction', () => {
|
|
|
93
95
|
(s) => s,
|
|
94
96
|
);
|
|
95
97
|
const result1 = withSymbol(sym1);
|
|
98
|
+
|
|
96
99
|
expect(withSymbol(sym1)).toBe(result1); // Same symbol, uses cache
|
|
97
100
|
expect(withSymbol(sym2)).not.toBe(result1); // Different symbol
|
|
98
101
|
});
|
|
@@ -102,10 +105,10 @@ describe('memoizeFunction', () => {
|
|
|
102
105
|
const memoized = memoizeFunction(mockFn, (x) => x);
|
|
103
106
|
|
|
104
107
|
expect(memoized(null)).toBe('default');
|
|
105
|
-
expect(mockFn).
|
|
108
|
+
expect(mockFn).toHaveBeenCalledOnce();
|
|
106
109
|
|
|
107
110
|
expect(memoized(null)).toBe('default');
|
|
108
|
-
expect(mockFn).
|
|
111
|
+
expect(mockFn).toHaveBeenCalledOnce();
|
|
109
112
|
|
|
110
113
|
expect(memoized(undefined)).toBe('default');
|
|
111
114
|
expect(mockFn).toHaveBeenCalledTimes(2);
|
|
@@ -124,15 +127,15 @@ describe('memoizeFunction', () => {
|
|
|
124
127
|
expect(memoized1(5)).toBe(10);
|
|
125
128
|
expect(memoized2(5)).toBe(15);
|
|
126
129
|
|
|
127
|
-
expect(fn1).
|
|
128
|
-
expect(fn2).
|
|
130
|
+
expect(fn1).toHaveBeenCalledOnce();
|
|
131
|
+
expect(fn2).toHaveBeenCalledOnce();
|
|
129
132
|
|
|
130
133
|
// Each has its own cache
|
|
131
134
|
expect(memoized1(5)).toBe(10);
|
|
132
135
|
expect(memoized2(5)).toBe(15);
|
|
133
136
|
|
|
134
|
-
expect(fn1).
|
|
135
|
-
expect(fn2).
|
|
137
|
+
expect(fn1).toHaveBeenCalledOnce();
|
|
138
|
+
expect(fn2).toHaveBeenCalledOnce();
|
|
136
139
|
});
|
|
137
140
|
|
|
138
141
|
test('should work with complex cache key generation', () => {
|
|
@@ -156,11 +159,11 @@ describe('memoizeFunction', () => {
|
|
|
156
159
|
const args3 = { category: 'books', subcategory: 'fiction', id: 124 };
|
|
157
160
|
|
|
158
161
|
expect(memoized(args1)).toBe('books/fiction/123');
|
|
159
|
-
expect(mockFn).
|
|
162
|
+
expect(mockFn).toHaveBeenCalledOnce();
|
|
160
163
|
|
|
161
164
|
// Same cache key, should use cache
|
|
162
165
|
expect(memoized(args2)).toBe('books/fiction/123');
|
|
163
|
-
expect(mockFn).
|
|
166
|
+
expect(mockFn).toHaveBeenCalledOnce();
|
|
164
167
|
|
|
165
168
|
// Different id, different cache key
|
|
166
169
|
expect(memoized(args3)).toBe('books/fiction/124');
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { expectType } from '../expect-type.mjs';
|
|
2
2
|
import { tp } from './tuple.mjs';
|
|
3
3
|
|
|
4
|
-
describe(
|
|
4
|
+
describe(tp, () => {
|
|
5
5
|
test('test type', () => {
|
|
6
6
|
const tuple = tp(1, 2, 3);
|
|
7
|
-
|
|
7
|
+
|
|
8
|
+
assert.deepStrictEqual(tuple, [1, 2, 3]);
|
|
8
9
|
|
|
9
10
|
expectType<typeof tuple, readonly [1, 2, 3]>('=');
|
|
10
11
|
});
|
|
@@ -1,50 +1,58 @@
|
|
|
1
1
|
import { unknownToString } from './unknown-to-string.mjs';
|
|
2
2
|
|
|
3
|
-
describe(
|
|
3
|
+
describe(unknownToString, () => {
|
|
4
4
|
test('string', () => {
|
|
5
5
|
const result = unknownToString('aaaaa');
|
|
6
|
+
|
|
6
7
|
expect(result).toBe('aaaaa');
|
|
7
8
|
expect(JSON.stringify('aaaaa')).toBe('"aaaaa"');
|
|
8
9
|
});
|
|
9
10
|
|
|
10
11
|
test('number', () => {
|
|
11
12
|
const result = unknownToString(1);
|
|
13
|
+
|
|
12
14
|
expect(result).toBe('1');
|
|
13
15
|
expect(JSON.stringify(1)).toBe('1');
|
|
14
16
|
});
|
|
15
17
|
|
|
16
18
|
test('boolean', () => {
|
|
17
19
|
const result = unknownToString(true);
|
|
20
|
+
|
|
18
21
|
expect(result).toBe('true');
|
|
19
22
|
expect(JSON.stringify(true)).toBe('true');
|
|
20
23
|
});
|
|
21
24
|
|
|
22
25
|
test('symbol', () => {
|
|
23
26
|
const result = unknownToString(Symbol('sym'));
|
|
27
|
+
|
|
24
28
|
expect(result).toBe('Symbol(sym)');
|
|
25
29
|
expect(JSON.stringify(Symbol('sym'))).toBeUndefined();
|
|
26
30
|
});
|
|
27
31
|
|
|
28
32
|
test('function', () => {
|
|
29
33
|
const result = unknownToString(() => 0);
|
|
34
|
+
|
|
30
35
|
expect(result).toBe('() => 0');
|
|
31
36
|
expect(JSON.stringify(() => 0)).toBeUndefined();
|
|
32
37
|
});
|
|
33
38
|
|
|
34
39
|
test('undefined', () => {
|
|
35
40
|
const result = unknownToString(undefined);
|
|
41
|
+
|
|
36
42
|
expect(result).toBe('undefined');
|
|
37
43
|
expect(JSON.stringify(undefined)).toBeUndefined();
|
|
38
44
|
});
|
|
39
45
|
|
|
40
46
|
test('null', () => {
|
|
41
47
|
const result = unknownToString(null);
|
|
48
|
+
|
|
42
49
|
expect(result).toBe('null');
|
|
43
50
|
expect(JSON.stringify(null)).toBe('null');
|
|
44
51
|
});
|
|
45
52
|
|
|
46
53
|
test('object', () => {
|
|
47
54
|
const result = unknownToString({ a: { b: 1 } });
|
|
55
|
+
|
|
48
56
|
expect(result).toBe('{"a":{"b":1}}');
|
|
49
57
|
expect(JSON.stringify({ a: { b: 1 } })).toBe('{"a":{"b":1}}');
|
|
50
58
|
});
|
|
@@ -54,6 +62,7 @@ describe('unknownToString', () => {
|
|
|
54
62
|
{ a: { b: 1 } },
|
|
55
63
|
{ prettyPrintObject: true },
|
|
56
64
|
);
|
|
65
|
+
|
|
57
66
|
expect(result).toBe(
|
|
58
67
|
[
|
|
59
68
|
//
|
|
@@ -70,13 +79,16 @@ describe('unknownToString', () => {
|
|
|
70
79
|
const mut_circular: { a: number; self?: unknown } = { a: 1 };
|
|
71
80
|
mut_circular.self = mut_circular;
|
|
72
81
|
const result = unknownToString(mut_circular);
|
|
82
|
+
|
|
73
83
|
// Should return an error message string instead of throwing
|
|
74
|
-
|
|
84
|
+
expectTypeOf(result).toBeString();
|
|
85
|
+
|
|
75
86
|
expect(result).toMatch(/circular|serialize/iu);
|
|
76
87
|
});
|
|
77
88
|
|
|
78
89
|
test('BigInt value', () => {
|
|
79
90
|
const result = unknownToString(123n);
|
|
91
|
+
|
|
80
92
|
expect(result).toBe('123n');
|
|
81
93
|
});
|
|
82
94
|
|
|
@@ -89,6 +101,7 @@ describe('unknownToString', () => {
|
|
|
89
101
|
};
|
|
90
102
|
|
|
91
103
|
const result = unknownToString(value);
|
|
104
|
+
|
|
92
105
|
expect(result).toBe('[Circular or Non-serializable]');
|
|
93
106
|
});
|
|
94
107
|
});
|
|
@@ -2,7 +2,7 @@ import { expectType } from '../expect-type.mjs';
|
|
|
2
2
|
import { Result } from '../functional/index.mjs';
|
|
3
3
|
import { createPromise } from './promise.mjs';
|
|
4
4
|
|
|
5
|
-
describe(
|
|
5
|
+
describe(createPromise, () => {
|
|
6
6
|
test('resolves to Result.ok when executor resolves', async () => {
|
|
7
7
|
const resultPromise = createPromise<number, Error>((resolve) => {
|
|
8
8
|
resolve(42);
|
|
@@ -11,7 +11,9 @@ describe('createPromise', () => {
|
|
|
11
11
|
expectType<typeof resultPromise, Promise<Result<number, Error>>>('=');
|
|
12
12
|
|
|
13
13
|
const result = await resultPromise;
|
|
14
|
+
|
|
14
15
|
expect(Result.isOk(result)).toBe(true);
|
|
16
|
+
|
|
15
17
|
if (Result.isOk(result)) {
|
|
16
18
|
expect(result.value).toBe(42);
|
|
17
19
|
}
|
|
@@ -24,6 +26,7 @@ describe('createPromise', () => {
|
|
|
24
26
|
});
|
|
25
27
|
|
|
26
28
|
expect(Result.isErr(result)).toBe(true);
|
|
29
|
+
|
|
27
30
|
if (Result.isErr(result)) {
|
|
28
31
|
expect(result.value).toBe(rejection);
|
|
29
32
|
}
|
|
@@ -35,8 +38,10 @@ describe('createPromise', () => {
|
|
|
35
38
|
});
|
|
36
39
|
|
|
37
40
|
expect(Result.isErr(result)).toBe(true);
|
|
41
|
+
|
|
38
42
|
if (Result.isErr(result)) {
|
|
39
43
|
expectType<typeof result.value, string>('=');
|
|
44
|
+
|
|
40
45
|
expect(result.value).toBe('failure');
|
|
41
46
|
}
|
|
42
47
|
});
|