ts-data-forge 1.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/LICENSE +201 -0
- package/README.md +534 -0
- package/package.json +101 -0
- package/src/array/array-utils-creation.test.mts +443 -0
- package/src/array/array-utils-modification.test.mts +197 -0
- package/src/array/array-utils-overload-type-error.test.mts +149 -0
- package/src/array/array-utils-reducing-value.test.mts +425 -0
- package/src/array/array-utils-search.test.mts +169 -0
- package/src/array/array-utils-set-op.test.mts +335 -0
- package/src/array/array-utils-slice-clamped.test.mts +113 -0
- package/src/array/array-utils-slicing.test.mts +316 -0
- package/src/array/array-utils-transformation.test.mts +790 -0
- package/src/array/array-utils-validation.test.mts +492 -0
- package/src/array/array-utils.mts +4000 -0
- package/src/array/array.test.mts +146 -0
- package/src/array/index.mts +2 -0
- package/src/array/tuple-utils.mts +519 -0
- package/src/array/tuple-utils.test.mts +518 -0
- package/src/collections/imap-mapped.mts +801 -0
- package/src/collections/imap-mapped.test.mts +860 -0
- package/src/collections/imap.mts +651 -0
- package/src/collections/imap.test.mts +932 -0
- package/src/collections/index.mts +6 -0
- package/src/collections/iset-mapped.mts +889 -0
- package/src/collections/iset-mapped.test.mts +1187 -0
- package/src/collections/iset.mts +682 -0
- package/src/collections/iset.test.mts +1084 -0
- package/src/collections/queue.mts +390 -0
- package/src/collections/queue.test.mts +282 -0
- package/src/collections/stack.mts +423 -0
- package/src/collections/stack.test.mts +225 -0
- package/src/expect-type.mts +206 -0
- package/src/functional/index.mts +4 -0
- package/src/functional/match.mts +300 -0
- package/src/functional/match.test.mts +177 -0
- package/src/functional/optional.mts +733 -0
- package/src/functional/optional.test.mts +619 -0
- package/src/functional/pipe.mts +212 -0
- package/src/functional/pipe.test.mts +85 -0
- package/src/functional/result.mts +1134 -0
- package/src/functional/result.test.mts +777 -0
- package/src/globals.d.mts +38 -0
- package/src/guard/has-key.mts +119 -0
- package/src/guard/has-key.test.mts +219 -0
- package/src/guard/index.mts +7 -0
- package/src/guard/is-non-empty-string.mts +108 -0
- package/src/guard/is-non-empty-string.test.mts +91 -0
- package/src/guard/is-non-null-object.mts +106 -0
- package/src/guard/is-non-null-object.test.mts +90 -0
- package/src/guard/is-primitive.mts +165 -0
- package/src/guard/is-primitive.test.mts +102 -0
- package/src/guard/is-record.mts +153 -0
- package/src/guard/is-record.test.mts +112 -0
- package/src/guard/is-type.mts +450 -0
- package/src/guard/is-type.test.mts +496 -0
- package/src/guard/key-is-in.mts +163 -0
- package/src/guard/key-is-in.test.mts +19 -0
- package/src/index.mts +10 -0
- package/src/iterator/index.mts +1 -0
- package/src/iterator/range.mts +120 -0
- package/src/iterator/range.test.mts +33 -0
- package/src/json/index.mts +1 -0
- package/src/json/json.mts +711 -0
- package/src/json/json.test.mts +628 -0
- package/src/number/branded-types/finite-number.mts +354 -0
- package/src/number/branded-types/finite-number.test.mts +135 -0
- package/src/number/branded-types/index.mts +26 -0
- package/src/number/branded-types/int.mts +278 -0
- package/src/number/branded-types/int.test.mts +140 -0
- package/src/number/branded-types/int16.mts +192 -0
- package/src/number/branded-types/int16.test.mts +170 -0
- package/src/number/branded-types/int32.mts +193 -0
- package/src/number/branded-types/int32.test.mts +170 -0
- package/src/number/branded-types/non-negative-finite-number.mts +223 -0
- package/src/number/branded-types/non-negative-finite-number.test.mts +188 -0
- package/src/number/branded-types/non-negative-int16.mts +187 -0
- package/src/number/branded-types/non-negative-int16.test.mts +201 -0
- package/src/number/branded-types/non-negative-int32.mts +187 -0
- package/src/number/branded-types/non-negative-int32.test.mts +204 -0
- package/src/number/branded-types/non-zero-finite-number.mts +229 -0
- package/src/number/branded-types/non-zero-finite-number.test.mts +198 -0
- package/src/number/branded-types/non-zero-int.mts +167 -0
- package/src/number/branded-types/non-zero-int.test.mts +177 -0
- package/src/number/branded-types/non-zero-int16.mts +196 -0
- package/src/number/branded-types/non-zero-int16.test.mts +195 -0
- package/src/number/branded-types/non-zero-int32.mts +196 -0
- package/src/number/branded-types/non-zero-int32.test.mts +197 -0
- package/src/number/branded-types/non-zero-safe-int.mts +196 -0
- package/src/number/branded-types/non-zero-safe-int.test.mts +232 -0
- package/src/number/branded-types/non-zero-uint16.mts +189 -0
- package/src/number/branded-types/non-zero-uint16.test.mts +199 -0
- package/src/number/branded-types/non-zero-uint32.mts +189 -0
- package/src/number/branded-types/non-zero-uint32.test.mts +199 -0
- package/src/number/branded-types/positive-finite-number.mts +241 -0
- package/src/number/branded-types/positive-finite-number.test.mts +204 -0
- package/src/number/branded-types/positive-int.mts +304 -0
- package/src/number/branded-types/positive-int.test.mts +176 -0
- package/src/number/branded-types/positive-int16.mts +188 -0
- package/src/number/branded-types/positive-int16.test.mts +197 -0
- package/src/number/branded-types/positive-int32.mts +188 -0
- package/src/number/branded-types/positive-int32.test.mts +197 -0
- package/src/number/branded-types/positive-safe-int.mts +187 -0
- package/src/number/branded-types/positive-safe-int.test.mts +210 -0
- package/src/number/branded-types/positive-uint16.mts +188 -0
- package/src/number/branded-types/positive-uint16.test.mts +203 -0
- package/src/number/branded-types/positive-uint32.mts +188 -0
- package/src/number/branded-types/positive-uint32.test.mts +203 -0
- package/src/number/branded-types/safe-int.mts +291 -0
- package/src/number/branded-types/safe-int.test.mts +170 -0
- package/src/number/branded-types/safe-uint.mts +187 -0
- package/src/number/branded-types/safe-uint.test.mts +176 -0
- package/src/number/branded-types/uint.mts +179 -0
- package/src/number/branded-types/uint.test.mts +158 -0
- package/src/number/branded-types/uint16.mts +186 -0
- package/src/number/branded-types/uint16.test.mts +170 -0
- package/src/number/branded-types/uint32.mts +218 -0
- package/src/number/branded-types/uint32.test.mts +170 -0
- package/src/number/enum/index.mts +2 -0
- package/src/number/enum/int8.mts +344 -0
- package/src/number/enum/int8.test.mts +180 -0
- package/src/number/enum/uint8.mts +293 -0
- package/src/number/enum/uint8.test.mts +164 -0
- package/src/number/index.mts +4 -0
- package/src/number/num.mts +604 -0
- package/src/number/num.test.mts +242 -0
- package/src/number/refined-number-utils.mts +566 -0
- package/src/object/index.mts +1 -0
- package/src/object/object.mts +447 -0
- package/src/object/object.test.mts +124 -0
- package/src/others/cast-mutable.mts +113 -0
- package/src/others/cast-readonly.mts +192 -0
- package/src/others/cast-readonly.test.mts +89 -0
- package/src/others/if-then.mts +98 -0
- package/src/others/if-then.test.mts +75 -0
- package/src/others/index.mts +7 -0
- package/src/others/map-nullable.mts +172 -0
- package/src/others/map-nullable.test.mts +297 -0
- package/src/others/memoize-function.mts +196 -0
- package/src/others/memoize-function.test.mts +168 -0
- package/src/others/tuple.mts +160 -0
- package/src/others/tuple.test.mts +11 -0
- package/src/others/unknown-to-string.mts +215 -0
- package/src/others/unknown-to-string.test.mts +114 -0
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import { expectType } from '../expect-type.mjs';
|
|
2
|
+
import { pipe } from '../functional/index.mjs';
|
|
3
|
+
import { Num } from './num.mjs';
|
|
4
|
+
|
|
5
|
+
const testClamp = (
|
|
6
|
+
[a, b]: readonly [number, number],
|
|
7
|
+
target: number,
|
|
8
|
+
expected: number,
|
|
9
|
+
): void => {
|
|
10
|
+
test(`clamp ${target} to [${a}, ${b}]`, () => {
|
|
11
|
+
expect(Num.clamp(a, b)(target)).toBe(expected);
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
describe('Num', () => {
|
|
16
|
+
describe('clamp', () => {
|
|
17
|
+
testClamp([0, 2], 2.3, 2);
|
|
18
|
+
testClamp([0, 2], -0.5, 0);
|
|
19
|
+
testClamp([0, 2], 1.5, 1.5);
|
|
20
|
+
testClamp([0, 2], Number.NaN, 0);
|
|
21
|
+
|
|
22
|
+
test('should support regular usage with three parameters', () => {
|
|
23
|
+
expectTypeOf(Num.clamp(15, 0, 10)).toEqualTypeOf<number>();
|
|
24
|
+
expect(Num.clamp(15, 0, 10)).toBe(10);
|
|
25
|
+
expect(Num.clamp(-5, 0, 10)).toBe(0);
|
|
26
|
+
expect(Num.clamp(5, 0, 10)).toBe(5);
|
|
27
|
+
expect(Num.clamp(Number.NaN, 0, 10)).toBe(0);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test('should work with pipe when curried', () => {
|
|
31
|
+
const clampTo0_10 = Num.clamp(0, 10);
|
|
32
|
+
|
|
33
|
+
const result1 = pipe(15).map(clampTo0_10).value;
|
|
34
|
+
expect(result1).toBe(10);
|
|
35
|
+
|
|
36
|
+
const result2 = pipe(-5).map(clampTo0_10).value;
|
|
37
|
+
expect(result2).toBe(0);
|
|
38
|
+
|
|
39
|
+
const result3 = pipe(7.5).map(clampTo0_10).value;
|
|
40
|
+
expect(result3).toBe(7.5);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test('should handle edge cases in curried form', () => {
|
|
44
|
+
const clampTo5_15 = Num.clamp(5, 15);
|
|
45
|
+
|
|
46
|
+
expectType<typeof clampTo5_15, (target: number) => number>('=');
|
|
47
|
+
|
|
48
|
+
// Invalid (non-finite) values return the lower bound
|
|
49
|
+
expect(clampTo5_15(Number.POSITIVE_INFINITY)).toBe(5);
|
|
50
|
+
expect(clampTo5_15(Number.NEGATIVE_INFINITY)).toBe(5);
|
|
51
|
+
expect(clampTo5_15(Number.NaN)).toBe(5);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test('should work with negative ranges', () => {
|
|
55
|
+
expect(Num.clamp(-15, -10, -5)).toBe(-10);
|
|
56
|
+
expect(Num.clamp(-7, -10, -5)).toBe(-7);
|
|
57
|
+
expect(Num.clamp(0, -10, -5)).toBe(-5);
|
|
58
|
+
|
|
59
|
+
const clampNegative = Num.clamp(-10, -5);
|
|
60
|
+
expect(clampNegative(-15)).toBe(-10);
|
|
61
|
+
expect(clampNegative(-7)).toBe(-7);
|
|
62
|
+
expect(clampNegative(0)).toBe(-5);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
describe('isUintInRangeInclusive', () => {
|
|
67
|
+
test('truthy case', () => {
|
|
68
|
+
const f = Num.isUintInRangeInclusive(0, 4);
|
|
69
|
+
const x: number = 2;
|
|
70
|
+
if (f(x)) {
|
|
71
|
+
expectType<typeof x, 0 | 1 | 2 | 3 | 4>('=');
|
|
72
|
+
} else {
|
|
73
|
+
expectType<typeof x, number>('=');
|
|
74
|
+
}
|
|
75
|
+
expect(f(x)).toBe(true);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test('falsy case', () => {
|
|
79
|
+
const f = Num.isUintInRangeInclusive(0, 4);
|
|
80
|
+
const x: number = 100;
|
|
81
|
+
if (f(x)) {
|
|
82
|
+
expectType<typeof x, 0 | 1 | 2 | 3 | 4>('=');
|
|
83
|
+
} else {
|
|
84
|
+
expectType<typeof x, number>('=');
|
|
85
|
+
}
|
|
86
|
+
expect(f(x)).toBe(false);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
describe('from', () => {
|
|
91
|
+
test('converts string to number', () => {
|
|
92
|
+
expect(Num.from('123')).toBe(123);
|
|
93
|
+
expect(Num.from('123.45')).toBe(123.45);
|
|
94
|
+
expect(Num.from('-42')).toBe(-42);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
test('handles edge cases', () => {
|
|
98
|
+
expect(Num.from('')).toBe(0);
|
|
99
|
+
expect(Num.from('abc')).toBeNaN();
|
|
100
|
+
expect(Num.from(true)).toBe(1);
|
|
101
|
+
expect(Num.from(false)).toBe(0);
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
describe('isInRange', () => {
|
|
106
|
+
test('checks range (lower inclusive, upper exclusive)', () => {
|
|
107
|
+
const inRange = Num.isInRange(0, 10);
|
|
108
|
+
expect(inRange(5)).toBe(true);
|
|
109
|
+
expect(inRange(0)).toBe(true); // inclusive lower bound
|
|
110
|
+
expect(inRange(10)).toBe(false); // exclusive upper bound
|
|
111
|
+
expect(inRange(-1)).toBe(false);
|
|
112
|
+
expect(inRange(15)).toBe(false);
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
describe('isInRangeInclusive', () => {
|
|
117
|
+
test('checks range (inclusive)', () => {
|
|
118
|
+
const inRange = Num.isInRangeInclusive(0, 10);
|
|
119
|
+
expect(inRange(5)).toBe(true);
|
|
120
|
+
expect(inRange(0)).toBe(true); // inclusive
|
|
121
|
+
expect(inRange(10)).toBe(true); // inclusive
|
|
122
|
+
expect(inRange(-1)).toBe(false);
|
|
123
|
+
expect(inRange(15)).toBe(false);
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
describe('isUintInRange', () => {
|
|
128
|
+
test('checks uint range (lower inclusive, upper exclusive)', () => {
|
|
129
|
+
const inRange = Num.isUintInRange(0, 5);
|
|
130
|
+
expect(inRange(2)).toBe(true);
|
|
131
|
+
expect(inRange(0)).toBe(true); // inclusive lower bound
|
|
132
|
+
expect(inRange(5)).toBe(false); // exclusive upper bound
|
|
133
|
+
expect(inRange(-1)).toBe(false);
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
describe('isNonZero', () => {
|
|
138
|
+
test('type guard for non-zero numbers', () => {
|
|
139
|
+
const x: number = 5;
|
|
140
|
+
if (Num.isNonZero(x)) {
|
|
141
|
+
expectType<typeof x, NonZeroNumber>('=');
|
|
142
|
+
}
|
|
143
|
+
expect(Num.isNonZero(5)).toBe(true);
|
|
144
|
+
expect(Num.isNonZero(-3)).toBe(true);
|
|
145
|
+
expect(Num.isNonZero(0)).toBe(false);
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
describe('isNonNegative', () => {
|
|
150
|
+
test('type guard for non-negative numbers', () => {
|
|
151
|
+
expect(Num.isNonNegative(5)).toBe(true);
|
|
152
|
+
expect(Num.isNonNegative(0)).toBe(true);
|
|
153
|
+
expect(Num.isNonNegative(-1)).toBe(false);
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
describe('isPositive', () => {
|
|
158
|
+
test('type guard for positive numbers', () => {
|
|
159
|
+
expect(Num.isPositive(5)).toBe(true);
|
|
160
|
+
expect(Num.isPositive(0.1)).toBe(true);
|
|
161
|
+
expect(Num.isPositive(0)).toBe(false);
|
|
162
|
+
expect(Num.isPositive(-1)).toBe(false);
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
describe('div', () => {
|
|
167
|
+
test('basic division', () => {
|
|
168
|
+
expect(Num.div(10, 2)).toBe(5);
|
|
169
|
+
expect(Num.div(7, 3)).toBe(7 / 3);
|
|
170
|
+
expect(Num.div(-10, 2)).toBe(-5);
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
describe('divInt', () => {
|
|
175
|
+
test('integer division (floor)', () => {
|
|
176
|
+
expect(Num.divInt(10, 3)).toBe(3);
|
|
177
|
+
expect(Num.divInt(7, 2)).toBe(3);
|
|
178
|
+
expect(Num.divInt(-7, 2)).toBe(-4); // floor division
|
|
179
|
+
expect(Num.divInt(10.7, 3.2)).toBe(3); // floors both operands
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
describe('roundAt', () => {
|
|
184
|
+
test('rounds to specified decimal places', () => {
|
|
185
|
+
expect(Num.roundAt(3.14159, 2)).toBe(3.14);
|
|
186
|
+
expect(Num.roundAt(3.14159, 3)).toBe(3.142);
|
|
187
|
+
expect(Num.roundAt(2.555, 2)).toBe(2.56);
|
|
188
|
+
expect(Num.roundAt(123.456, 1)).toBe(123.5);
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
describe('roundToInt', () => {
|
|
193
|
+
test('rounds to nearest integer', () => {
|
|
194
|
+
expect(Num.roundToInt(3.4)).toBe(3);
|
|
195
|
+
expect(Num.roundToInt(3.6)).toBe(4);
|
|
196
|
+
expect(Num.roundToInt(2.5)).toBe(3);
|
|
197
|
+
expect(Num.roundToInt(-2.3)).toBe(-1); // bitwise behavior: -2.3 + 0.5 = -1.8, then floor with bitwise OR
|
|
198
|
+
expect(Num.roundToInt(-2.7)).toBe(-2); // bitwise behavior: -2.7 + 0.5 = -2.2, then floor with bitwise OR
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
describe('round', () => {
|
|
203
|
+
test('creates rounding function with specified precision', () => {
|
|
204
|
+
const round2 = Num.round(2);
|
|
205
|
+
expect(round2(3.14159)).toBe(3.14);
|
|
206
|
+
expect(round2(2.556)).toBe(2.56);
|
|
207
|
+
|
|
208
|
+
const round1 = Num.round(1);
|
|
209
|
+
expect(round1(3.14159)).toBe(3.1);
|
|
210
|
+
expect(round1(2.56)).toBe(2.6);
|
|
211
|
+
|
|
212
|
+
const round3 = Num.round(3);
|
|
213
|
+
expect(round3(3.1416)).toBe(3.142);
|
|
214
|
+
expect(round3(2.7182)).toBe(2.718);
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
describe('mapNaN2Undefined', () => {
|
|
219
|
+
test('maps NaN to undefined', () => {
|
|
220
|
+
expect(Num.mapNaN2Undefined(5)).toBe(5);
|
|
221
|
+
expect(Num.mapNaN2Undefined(0)).toBe(0);
|
|
222
|
+
expect(Num.mapNaN2Undefined(-3.14)).toBe(-3.14);
|
|
223
|
+
expect(Num.mapNaN2Undefined(Number.NaN)).toBeUndefined();
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
describe('increment', () => {
|
|
228
|
+
test('increments SmallUint values', () => {
|
|
229
|
+
expect(Num.increment(0)).toBe(1);
|
|
230
|
+
expect(Num.increment(5)).toBe(6);
|
|
231
|
+
expect(Num.increment(38)).toBe(39);
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
describe('decrement', () => {
|
|
236
|
+
test('decrements PositiveSmallInt values', () => {
|
|
237
|
+
expect(Num.decrement(1)).toBe(0);
|
|
238
|
+
expect(Num.decrement(5)).toBe(4);
|
|
239
|
+
expect(Num.decrement(39)).toBe(38);
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
});
|