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
|
@@ -3,20 +3,24 @@ import { Optional } from './optional/index.mjs';
|
|
|
3
3
|
import { pipe } from './pipe.mjs';
|
|
4
4
|
import { Result } from './result/index.mjs';
|
|
5
5
|
|
|
6
|
-
describe('Result', () => {
|
|
6
|
+
describe('Result test', () => {
|
|
7
7
|
describe('ok', () => {
|
|
8
8
|
test('creates Ok result', () => {
|
|
9
9
|
const result = Result.ok(42);
|
|
10
|
+
|
|
10
11
|
expect(Result.isOk(result)).toBe(true);
|
|
11
12
|
expect(Result.isErr(result)).toBe(false);
|
|
12
13
|
expect(result.value).toBe(42);
|
|
14
|
+
|
|
13
15
|
expectType<typeof result, Result<number, never>>('<=');
|
|
14
16
|
});
|
|
15
17
|
|
|
16
18
|
test('creates Ok result with string', () => {
|
|
17
19
|
const result = Result.ok('success');
|
|
20
|
+
|
|
18
21
|
expect(Result.isOk(result)).toBe(true);
|
|
19
22
|
expect(result.value).toBe('success');
|
|
23
|
+
|
|
20
24
|
expectType<typeof result, Result<string, never>>('<=');
|
|
21
25
|
});
|
|
22
26
|
});
|
|
@@ -24,16 +28,20 @@ describe('Result', () => {
|
|
|
24
28
|
describe('err', () => {
|
|
25
29
|
test('creates Err result', () => {
|
|
26
30
|
const result = Result.err('error message');
|
|
31
|
+
|
|
27
32
|
expect(Result.isErr(result)).toBe(true);
|
|
28
33
|
expect(Result.isOk(result)).toBe(false);
|
|
29
34
|
expect(result.value).toBe('error message');
|
|
35
|
+
|
|
30
36
|
expectType<typeof result, Result<never, string>>('<=');
|
|
31
37
|
});
|
|
32
38
|
|
|
33
39
|
test('creates Err result with number', () => {
|
|
34
40
|
const result = Result.err(404);
|
|
41
|
+
|
|
35
42
|
expect(Result.isErr(result)).toBe(true);
|
|
36
43
|
expect(result.value).toBe(404);
|
|
44
|
+
|
|
37
45
|
expectType<typeof result, Result<never, number>>('<=');
|
|
38
46
|
});
|
|
39
47
|
});
|
|
@@ -43,12 +51,14 @@ describe('Result', () => {
|
|
|
43
51
|
const result: Result<number, string> = Result.ok(42);
|
|
44
52
|
if (Result.isOk(result)) {
|
|
45
53
|
expectType<typeof result, Ok<number>>('<=');
|
|
54
|
+
|
|
46
55
|
expect(result.value).toBe(42);
|
|
47
56
|
}
|
|
48
57
|
});
|
|
49
58
|
|
|
50
59
|
test('returns false for Err results', () => {
|
|
51
60
|
const result: Result<number, string> = Result.err('error');
|
|
61
|
+
|
|
52
62
|
expect(Result.isOk(result)).toBe(false);
|
|
53
63
|
});
|
|
54
64
|
});
|
|
@@ -58,12 +68,14 @@ describe('Result', () => {
|
|
|
58
68
|
const result: Result<number, string> = Result.err('error');
|
|
59
69
|
if (Result.isErr(result)) {
|
|
60
70
|
expectType<typeof result, Err<string>>('<=');
|
|
71
|
+
|
|
61
72
|
expect(result.value).toBe('error');
|
|
62
73
|
}
|
|
63
74
|
});
|
|
64
75
|
|
|
65
76
|
test('returns false for Ok results', () => {
|
|
66
77
|
const result: Result<number, string> = Result.ok(42);
|
|
78
|
+
|
|
67
79
|
expect(Result.isErr(result)).toBe(false);
|
|
68
80
|
});
|
|
69
81
|
});
|
|
@@ -71,11 +83,13 @@ describe('Result', () => {
|
|
|
71
83
|
describe('isResult', () => {
|
|
72
84
|
test('recognizes Ok results', () => {
|
|
73
85
|
const result = Result.ok(42);
|
|
86
|
+
|
|
74
87
|
expect(Result.isResult(result)).toBe(true);
|
|
75
88
|
});
|
|
76
89
|
|
|
77
90
|
test('recognizes Err results', () => {
|
|
78
91
|
const result = Result.err('error');
|
|
92
|
+
|
|
79
93
|
expect(Result.isResult(result)).toBe(true);
|
|
80
94
|
});
|
|
81
95
|
|
|
@@ -93,7 +107,9 @@ describe('Result', () => {
|
|
|
93
107
|
test('maps Ok result', () => {
|
|
94
108
|
const result = Result.ok(5);
|
|
95
109
|
const mapped = Result.map(result, (x) => x * 2);
|
|
110
|
+
|
|
96
111
|
expect(Result.isOk(mapped)).toBe(true);
|
|
112
|
+
|
|
97
113
|
if (Result.isOk(mapped)) {
|
|
98
114
|
expect(mapped.value).toBe(10);
|
|
99
115
|
}
|
|
@@ -103,7 +119,9 @@ describe('Result', () => {
|
|
|
103
119
|
test('preserves Err result', () => {
|
|
104
120
|
const result: Result<number, string> = Result.err('error');
|
|
105
121
|
const mapped = Result.map(result, (x) => x * 2);
|
|
122
|
+
|
|
106
123
|
expect(Result.isErr(mapped)).toBe(true);
|
|
124
|
+
|
|
107
125
|
if (Result.isErr(mapped)) {
|
|
108
126
|
expect(mapped.value).toBe('error');
|
|
109
127
|
}
|
|
@@ -117,13 +135,16 @@ describe('Result', () => {
|
|
|
117
135
|
const mapped = doubler(okResult);
|
|
118
136
|
|
|
119
137
|
expect(Result.isOk(mapped)).toBe(true);
|
|
138
|
+
|
|
120
139
|
if (Result.isOk(mapped)) {
|
|
121
140
|
expect(mapped.value).toBe(10);
|
|
122
141
|
}
|
|
123
142
|
|
|
124
143
|
const errResult: Result<number, string> = Result.err('error');
|
|
125
144
|
const mappedErr = doubler(errResult);
|
|
145
|
+
|
|
126
146
|
expect(Result.isErr(mappedErr)).toBe(true);
|
|
147
|
+
|
|
127
148
|
if (Result.isErr(mappedErr)) {
|
|
128
149
|
expect(mappedErr.value).toBe('error');
|
|
129
150
|
}
|
|
@@ -136,6 +157,7 @@ describe('Result', () => {
|
|
|
136
157
|
const result = pipe(Result.ok(5)).map(doubler).map(toStringFn).value;
|
|
137
158
|
|
|
138
159
|
expect(Result.isOk(result)).toBe(true);
|
|
160
|
+
|
|
139
161
|
if (Result.isOk(result)) {
|
|
140
162
|
expect(result.value).toBe('10');
|
|
141
163
|
}
|
|
@@ -146,7 +168,9 @@ describe('Result', () => {
|
|
|
146
168
|
test('maps Err result', () => {
|
|
147
169
|
const result: Result<number, string> = Result.err('error');
|
|
148
170
|
const mapped = Result.mapErr(result, (e) => e.toUpperCase());
|
|
171
|
+
|
|
149
172
|
expect(Result.isErr(mapped)).toBe(true);
|
|
173
|
+
|
|
150
174
|
if (Result.isErr(mapped)) {
|
|
151
175
|
expect(mapped.value).toBe('ERROR');
|
|
152
176
|
}
|
|
@@ -156,7 +180,9 @@ describe('Result', () => {
|
|
|
156
180
|
test('preserves Ok result', () => {
|
|
157
181
|
const result: Result<number, string> = Result.ok(42);
|
|
158
182
|
const mapped = Result.mapErr(result, (e: string) => e.toUpperCase());
|
|
183
|
+
|
|
159
184
|
expect(Result.isOk(mapped)).toBe(true);
|
|
185
|
+
|
|
160
186
|
if (Result.isOk(mapped)) {
|
|
161
187
|
expect(mapped.value).toBe(42);
|
|
162
188
|
}
|
|
@@ -168,14 +194,18 @@ describe('Result', () => {
|
|
|
168
194
|
|
|
169
195
|
const errResult: Result<number, string> = Result.err('error');
|
|
170
196
|
const mapped = errorUppercase(errResult);
|
|
197
|
+
|
|
171
198
|
expect(Result.isErr(mapped)).toBe(true);
|
|
199
|
+
|
|
172
200
|
if (Result.isErr(mapped)) {
|
|
173
201
|
expect(mapped.value).toBe('ERROR');
|
|
174
202
|
}
|
|
175
203
|
|
|
176
204
|
const okResult: Result<number, string> = Result.ok(42);
|
|
177
205
|
const mappedOk = errorUppercase(okResult);
|
|
206
|
+
|
|
178
207
|
expect(Result.isOk(mappedOk)).toBe(true);
|
|
208
|
+
|
|
179
209
|
if (Result.isOk(mappedOk)) {
|
|
180
210
|
expect(mappedOk.value).toBe(42);
|
|
181
211
|
}
|
|
@@ -190,6 +220,7 @@ describe('Result', () => {
|
|
|
190
220
|
.map(errorPrefix).value;
|
|
191
221
|
|
|
192
222
|
expect(Result.isErr(result)).toBe(true);
|
|
223
|
+
|
|
193
224
|
if (Result.isErr(result)) {
|
|
194
225
|
expect(result.value).toBe('ERROR: FAILED');
|
|
195
226
|
}
|
|
@@ -200,12 +231,15 @@ describe('Result', () => {
|
|
|
200
231
|
test('unwraps Ok result', () => {
|
|
201
232
|
const result = Result.ok(42);
|
|
202
233
|
const value = Result.unwrapThrow(result);
|
|
234
|
+
|
|
203
235
|
expect(value).toBe(42);
|
|
236
|
+
|
|
204
237
|
expectType<typeof value, number>('<=');
|
|
205
238
|
});
|
|
206
239
|
|
|
207
240
|
test('throws on Err result', () => {
|
|
208
241
|
const result = Result.err('error message');
|
|
242
|
+
|
|
209
243
|
expect(() => Result.unwrapThrow(result)).toThrow('error message');
|
|
210
244
|
});
|
|
211
245
|
});
|
|
@@ -214,14 +248,18 @@ describe('Result', () => {
|
|
|
214
248
|
test('unwraps Ok result', () => {
|
|
215
249
|
const result = Result.ok(42);
|
|
216
250
|
const value = Result.unwrapOkOr(result, 0);
|
|
251
|
+
|
|
217
252
|
expect(value).toBe(42);
|
|
253
|
+
|
|
218
254
|
expectType<typeof value, number>('<=');
|
|
219
255
|
});
|
|
220
256
|
|
|
221
257
|
test('returns default for Err result', () => {
|
|
222
258
|
const result: Result<number, string> = Result.err('error');
|
|
223
259
|
const value = Result.unwrapOkOr(result, 0);
|
|
260
|
+
|
|
224
261
|
expect(value).toBe(0);
|
|
262
|
+
|
|
225
263
|
expectType<typeof value, number>('<=');
|
|
226
264
|
});
|
|
227
265
|
|
|
@@ -230,10 +268,12 @@ describe('Result', () => {
|
|
|
230
268
|
|
|
231
269
|
const okResult = Result.ok(100);
|
|
232
270
|
const successValue = unwrapWithDefault(okResult);
|
|
271
|
+
|
|
233
272
|
expect(successValue).toBe(100);
|
|
234
273
|
|
|
235
274
|
const errResult: Result<number, string> = Result.err('failed');
|
|
236
275
|
const defaultValue = unwrapWithDefault(errResult);
|
|
276
|
+
|
|
237
277
|
expect(defaultValue).toBe(42);
|
|
238
278
|
});
|
|
239
279
|
|
|
@@ -241,11 +281,13 @@ describe('Result', () => {
|
|
|
241
281
|
const unwrapWithDefault = Result.unwrapOkOr(0);
|
|
242
282
|
|
|
243
283
|
const successResult = pipe(Result.ok(200)).map(unwrapWithDefault).value;
|
|
284
|
+
|
|
244
285
|
expect(successResult).toBe(200);
|
|
245
286
|
|
|
246
287
|
const errorResult = pipe(Result.err('computation failed')).map(
|
|
247
288
|
unwrapWithDefault,
|
|
248
289
|
).value;
|
|
290
|
+
|
|
249
291
|
expect(errorResult).toBe(0);
|
|
250
292
|
});
|
|
251
293
|
});
|
|
@@ -254,7 +296,9 @@ describe('Result', () => {
|
|
|
254
296
|
test('unwraps Err result', () => {
|
|
255
297
|
const result: Result<number, string> = Result.err('error');
|
|
256
298
|
const value = Result.unwrapErr(result);
|
|
299
|
+
|
|
257
300
|
expect(value).toBe('error');
|
|
301
|
+
|
|
258
302
|
expectType<typeof value, string | undefined>('<=');
|
|
259
303
|
});
|
|
260
304
|
|
|
@@ -263,7 +307,9 @@ describe('Result', () => {
|
|
|
263
307
|
|
|
264
308
|
// eslint-disable-next-line @typescript-eslint/no-confusing-void-expression
|
|
265
309
|
const value = Result.unwrapErr(result);
|
|
310
|
+
|
|
266
311
|
expect(value).toBeUndefined();
|
|
312
|
+
|
|
267
313
|
expectType<typeof value, string | undefined>('<=');
|
|
268
314
|
});
|
|
269
315
|
});
|
|
@@ -276,7 +322,9 @@ describe('Result', () => {
|
|
|
276
322
|
(x) => x * 2,
|
|
277
323
|
() => 0,
|
|
278
324
|
);
|
|
325
|
+
|
|
279
326
|
expect(Result.isOk(folded)).toBe(true);
|
|
327
|
+
|
|
280
328
|
if (Result.isOk(folded)) {
|
|
281
329
|
expect(folded.value).toBe(84);
|
|
282
330
|
}
|
|
@@ -290,7 +338,9 @@ describe('Result', () => {
|
|
|
290
338
|
(x) => x * 2,
|
|
291
339
|
(e) => e.length,
|
|
292
340
|
);
|
|
341
|
+
|
|
293
342
|
expect(Result.isErr(folded)).toBe(true);
|
|
343
|
+
|
|
294
344
|
if (Result.isErr(folded)) {
|
|
295
345
|
expect(folded.value).toBe(5); // length of 'error'
|
|
296
346
|
}
|
|
@@ -305,14 +355,18 @@ describe('Result', () => {
|
|
|
305
355
|
|
|
306
356
|
const okResult = Result.ok(42);
|
|
307
357
|
const foldedOk = folder(okResult);
|
|
358
|
+
|
|
308
359
|
expect(Result.isOk(foldedOk)).toBe(true);
|
|
360
|
+
|
|
309
361
|
if (Result.isOk(foldedOk)) {
|
|
310
362
|
expect(foldedOk.value).toBe(84);
|
|
311
363
|
}
|
|
312
364
|
|
|
313
365
|
const errResult: Result<number, string> = Result.err('error');
|
|
314
366
|
const foldedErr = folder(errResult);
|
|
367
|
+
|
|
315
368
|
expect(Result.isErr(foldedErr)).toBe(true);
|
|
369
|
+
|
|
316
370
|
if (Result.isErr(foldedErr)) {
|
|
317
371
|
expect(foldedErr.value).toBe(5);
|
|
318
372
|
}
|
|
@@ -327,6 +381,7 @@ describe('Result', () => {
|
|
|
327
381
|
const result = pipe(Result.ok(21)).map(folder).value;
|
|
328
382
|
|
|
329
383
|
expect(Result.isOk(result)).toBe(true);
|
|
384
|
+
|
|
330
385
|
if (Result.isOk(result)) {
|
|
331
386
|
expect(result.value).toBe(42);
|
|
332
387
|
}
|
|
@@ -334,6 +389,7 @@ describe('Result', () => {
|
|
|
334
389
|
const errorResult = pipe(Result.err('error')).map(folder).value;
|
|
335
390
|
|
|
336
391
|
expect(Result.isErr(errorResult)).toBe(true);
|
|
392
|
+
|
|
337
393
|
if (Result.isErr(errorResult)) {
|
|
338
394
|
expect(errorResult.value).toBe(0);
|
|
339
395
|
}
|
|
@@ -346,6 +402,7 @@ describe('Result', () => {
|
|
|
346
402
|
Promise.resolve().then(() => 42);
|
|
347
403
|
|
|
348
404
|
const result = await Result.fromPromise(asyncFn());
|
|
405
|
+
|
|
349
406
|
expect(Result.isOk(result)).toBe(true);
|
|
350
407
|
expect(Result.unwrapOk(result)).toBe(42);
|
|
351
408
|
});
|
|
@@ -356,6 +413,7 @@ describe('Result', () => {
|
|
|
356
413
|
Promise.reject(error).then(() => 42);
|
|
357
414
|
|
|
358
415
|
const result = await Result.fromPromise(asyncFn());
|
|
416
|
+
|
|
359
417
|
expect(Result.isErr(result)).toBe(true);
|
|
360
418
|
expect(Result.unwrapErr(result)).toBe(error);
|
|
361
419
|
});
|
|
@@ -365,6 +423,7 @@ describe('Result', () => {
|
|
|
365
423
|
const result = await Result.fromPromise(stringPromise);
|
|
366
424
|
|
|
367
425
|
expect(Result.unwrapOk(result)).toBe('hello');
|
|
426
|
+
|
|
368
427
|
expectType<typeof result, Result<string, unknown>>('=');
|
|
369
428
|
});
|
|
370
429
|
});
|
|
@@ -378,9 +437,11 @@ describe('Result', () => {
|
|
|
378
437
|
Result.ok(a / b);
|
|
379
438
|
|
|
380
439
|
const result = Result.flatMap(Result.ok(10), (x) => divide(x, 2));
|
|
440
|
+
|
|
381
441
|
expect(Result.unwrapOk(result)).toBe(5);
|
|
382
442
|
|
|
383
443
|
const error = Result.flatMap(Result.ok(10), (x) => divide(x, 0));
|
|
444
|
+
|
|
384
445
|
expect(Result.unwrapErr(error)).toBe('Division by zero');
|
|
385
446
|
});
|
|
386
447
|
|
|
@@ -388,6 +449,7 @@ describe('Result', () => {
|
|
|
388
449
|
const result = Result.flatMap(Result.err('initial error'), (_: never) =>
|
|
389
450
|
Result.ok(42),
|
|
390
451
|
);
|
|
452
|
+
|
|
391
453
|
expect(Result.unwrapErr(result)).toBe('initial error');
|
|
392
454
|
});
|
|
393
455
|
|
|
@@ -405,6 +467,7 @@ describe('Result', () => {
|
|
|
405
467
|
Result.flatMap(parseNumber('100'), (x) => divide(x, 2)),
|
|
406
468
|
(x) => Result.ok(x + 10),
|
|
407
469
|
);
|
|
470
|
+
|
|
408
471
|
expect(Result.unwrapOk(result)).toBe(60);
|
|
409
472
|
});
|
|
410
473
|
|
|
@@ -419,20 +482,26 @@ describe('Result', () => {
|
|
|
419
482
|
|
|
420
483
|
const okResult = Result.ok(10);
|
|
421
484
|
const result = divideBy2(okResult);
|
|
485
|
+
|
|
422
486
|
expect(Result.isOk(result)).toBe(true);
|
|
487
|
+
|
|
423
488
|
if (Result.isOk(result)) {
|
|
424
489
|
expect(result.value).toBe(5);
|
|
425
490
|
}
|
|
426
491
|
|
|
427
492
|
const divideByZero = Result.flatMap((x: number) => divide(x, 0));
|
|
428
493
|
const errorResult = divideByZero(Result.ok(10));
|
|
494
|
+
|
|
429
495
|
expect(Result.isErr(errorResult)).toBe(true);
|
|
496
|
+
|
|
430
497
|
if (Result.isErr(errorResult)) {
|
|
431
498
|
expect(errorResult.value).toBe('Division by zero');
|
|
432
499
|
}
|
|
433
500
|
|
|
434
501
|
const initialError = divideBy2(Result.err('initial error'));
|
|
502
|
+
|
|
435
503
|
expect(Result.isErr(initialError)).toBe(true);
|
|
504
|
+
|
|
436
505
|
if (Result.isErr(initialError)) {
|
|
437
506
|
expect(initialError.value).toBe('initial error');
|
|
438
507
|
}
|
|
@@ -453,6 +522,7 @@ describe('Result', () => {
|
|
|
453
522
|
const result = pipe(Result.ok('42')).map(parser).map(doubler).value;
|
|
454
523
|
|
|
455
524
|
expect(Result.isOk(result)).toBe(true);
|
|
525
|
+
|
|
456
526
|
if (Result.isOk(result)) {
|
|
457
527
|
expect(result.value).toBe(84);
|
|
458
528
|
}
|
|
@@ -463,6 +533,7 @@ describe('Result', () => {
|
|
|
463
533
|
test('should swap Ok to Err', () => {
|
|
464
534
|
const okResult = Result.ok(42);
|
|
465
535
|
const swapped = Result.swap(okResult);
|
|
536
|
+
|
|
466
537
|
expect(Result.isErr(swapped)).toBe(true);
|
|
467
538
|
expect(Result.unwrapErr(swapped)).toBe(42);
|
|
468
539
|
});
|
|
@@ -470,6 +541,7 @@ describe('Result', () => {
|
|
|
470
541
|
test('should swap Err to Ok', () => {
|
|
471
542
|
const errResult = Result.err('error');
|
|
472
543
|
const swapped = Result.swap(errResult);
|
|
544
|
+
|
|
473
545
|
expect(Result.isOk(swapped)).toBe(true);
|
|
474
546
|
expect(Result.unwrapOk(swapped)).toBe('error');
|
|
475
547
|
});
|
|
@@ -479,6 +551,7 @@ describe('Result', () => {
|
|
|
479
551
|
test('should convert Ok to Some-like', () => {
|
|
480
552
|
const okResult = Result.ok(42);
|
|
481
553
|
const optional = Result.toOptional(okResult);
|
|
554
|
+
|
|
482
555
|
expect(Optional.isSome(optional)).toBe(true);
|
|
483
556
|
expect(Optional.unwrapThrow(optional)).toBe(42);
|
|
484
557
|
});
|
|
@@ -486,6 +559,7 @@ describe('Result', () => {
|
|
|
486
559
|
test('should convert Err to None-like', () => {
|
|
487
560
|
const errResult = Result.err('error');
|
|
488
561
|
const optional = Result.toOptional(errResult);
|
|
562
|
+
|
|
489
563
|
expect(Optional.isNone(optional)).toBe(true);
|
|
490
564
|
});
|
|
491
565
|
});
|
|
@@ -493,11 +567,13 @@ describe('Result', () => {
|
|
|
493
567
|
describe('unwrapErrThrow', () => {
|
|
494
568
|
test('should return error value for Err', () => {
|
|
495
569
|
const result = Result.err('error message');
|
|
570
|
+
|
|
496
571
|
expect(Result.unwrapErrThrow(result)).toBe('error message');
|
|
497
572
|
});
|
|
498
573
|
|
|
499
574
|
test('should throw for Ok', () => {
|
|
500
575
|
const result = Result.ok(42);
|
|
576
|
+
|
|
501
577
|
expect(() => Result.unwrapErrThrow(result)).toThrow(
|
|
502
578
|
'Expected Err but got Ok: 42',
|
|
503
579
|
);
|
|
@@ -505,6 +581,7 @@ describe('Result', () => {
|
|
|
505
581
|
|
|
506
582
|
test('should use custom toString function', () => {
|
|
507
583
|
const result = Result.ok({ id: 1, name: 'test' });
|
|
584
|
+
|
|
508
585
|
expect(() =>
|
|
509
586
|
Result.unwrapErrThrow(result, (obj) => `Object(id=${obj.id})`),
|
|
510
587
|
).toThrow('Expected Err but got Ok: Object(id=1)');
|
|
@@ -515,12 +592,14 @@ describe('Result', () => {
|
|
|
515
592
|
test('should return error value for Err result', () => {
|
|
516
593
|
const result = Result.err('error message');
|
|
517
594
|
const value = Result.unwrapErrOr(result, 'default');
|
|
595
|
+
|
|
518
596
|
expect(value).toBe('error message');
|
|
519
597
|
});
|
|
520
598
|
|
|
521
599
|
test('should return default value for Ok result', () => {
|
|
522
600
|
const result = Result.ok(42);
|
|
523
601
|
const value = Result.unwrapErrOr(result, 'default');
|
|
602
|
+
|
|
524
603
|
expect(value).toBe('default');
|
|
525
604
|
});
|
|
526
605
|
|
|
@@ -529,10 +608,12 @@ describe('Result', () => {
|
|
|
529
608
|
|
|
530
609
|
const errResult: Result<number, string> = Result.err('failed');
|
|
531
610
|
const errorValue = unwrapErrorWithDefault(errResult);
|
|
611
|
+
|
|
532
612
|
expect(errorValue).toBe('failed');
|
|
533
613
|
|
|
534
614
|
const okResult: Result<number, string> = Result.ok(42);
|
|
535
615
|
const defaultValue = unwrapErrorWithDefault(okResult);
|
|
616
|
+
|
|
536
617
|
expect(defaultValue).toBe('unknown error');
|
|
537
618
|
});
|
|
538
619
|
|
|
@@ -542,11 +623,13 @@ describe('Result', () => {
|
|
|
542
623
|
const errorResult = pipe(Result.err('network failure')).map(
|
|
543
624
|
unwrapErrorWithDefault,
|
|
544
625
|
).value;
|
|
626
|
+
|
|
545
627
|
expect(errorResult).toBe('network failure');
|
|
546
628
|
|
|
547
629
|
const okResult = pipe(Result.ok('success')).map(
|
|
548
630
|
unwrapErrorWithDefault,
|
|
549
631
|
).value;
|
|
632
|
+
|
|
550
633
|
expect(okResult).toBe('unknown error');
|
|
551
634
|
});
|
|
552
635
|
});
|
|
@@ -555,11 +638,13 @@ describe('Result', () => {
|
|
|
555
638
|
test('should return value for Ok result', () => {
|
|
556
639
|
const result = Result.ok(42);
|
|
557
640
|
const value = Result.expectToBe(result, 'Expected valid number');
|
|
641
|
+
|
|
558
642
|
expect(value).toBe(42);
|
|
559
643
|
});
|
|
560
644
|
|
|
561
645
|
test('should throw custom error for Err result', () => {
|
|
562
646
|
const result = Result.err('failed');
|
|
647
|
+
|
|
563
648
|
expect(() => Result.expectToBe(result, 'Operation must succeed')).toThrow(
|
|
564
649
|
'Operation must succeed',
|
|
565
650
|
);
|
|
@@ -570,9 +655,11 @@ describe('Result', () => {
|
|
|
570
655
|
|
|
571
656
|
const okResult = Result.ok('success');
|
|
572
657
|
const value = mustBeOk(okResult);
|
|
658
|
+
|
|
573
659
|
expect(value).toBe('success');
|
|
574
660
|
|
|
575
661
|
const errResult: Result<string, string> = Result.err('failed');
|
|
662
|
+
|
|
576
663
|
expect(() => mustBeOk(errResult)).toThrow('Expected successful result');
|
|
577
664
|
});
|
|
578
665
|
|
|
@@ -580,6 +667,7 @@ describe('Result', () => {
|
|
|
580
667
|
const mustBeOk = Result.expectToBe('Validation failed');
|
|
581
668
|
|
|
582
669
|
const successResult = pipe(Result.ok(100)).map(mustBeOk).value;
|
|
670
|
+
|
|
583
671
|
expect(successResult).toBe(100);
|
|
584
672
|
|
|
585
673
|
expect(
|
|
@@ -593,6 +681,7 @@ describe('Result', () => {
|
|
|
593
681
|
const primary = Result.ok(42);
|
|
594
682
|
const fallback = Result.ok(100);
|
|
595
683
|
const result = Result.orElse(primary, fallback);
|
|
684
|
+
|
|
596
685
|
expect(Result.unwrapOk(result)).toBe(42);
|
|
597
686
|
});
|
|
598
687
|
|
|
@@ -600,6 +689,7 @@ describe('Result', () => {
|
|
|
600
689
|
const primary = Result.err('error');
|
|
601
690
|
const fallback = Result.ok('default');
|
|
602
691
|
const result = Result.orElse(primary, fallback);
|
|
692
|
+
|
|
603
693
|
expect(Result.unwrapOk(result)).toBe('default');
|
|
604
694
|
});
|
|
605
695
|
|
|
@@ -607,6 +697,7 @@ describe('Result', () => {
|
|
|
607
697
|
const primary = Result.err('error1');
|
|
608
698
|
const fallback = Result.err('error2');
|
|
609
699
|
const result = Result.orElse(primary, fallback);
|
|
700
|
+
|
|
610
701
|
expect(Result.unwrapErr(result)).toBe('error2');
|
|
611
702
|
});
|
|
612
703
|
|
|
@@ -615,14 +706,18 @@ describe('Result', () => {
|
|
|
615
706
|
|
|
616
707
|
const okResult = Result.ok('primary');
|
|
617
708
|
const result = fallbackTo(okResult);
|
|
709
|
+
|
|
618
710
|
expect(Result.isOk(result)).toBe(true);
|
|
711
|
+
|
|
619
712
|
if (Result.isOk(result)) {
|
|
620
713
|
expect(result.value).toBe('primary');
|
|
621
714
|
}
|
|
622
715
|
|
|
623
716
|
const errResult: Result<string, string> = Result.err('failed');
|
|
624
717
|
const fallbackResult = fallbackTo(errResult);
|
|
718
|
+
|
|
625
719
|
expect(Result.isOk(fallbackResult)).toBe(true);
|
|
720
|
+
|
|
626
721
|
if (Result.isOk(fallbackResult)) {
|
|
627
722
|
expect(fallbackResult.value).toBe('fallback');
|
|
628
723
|
}
|
|
@@ -632,13 +727,17 @@ describe('Result', () => {
|
|
|
632
727
|
const fallbackTo = Result.orElse(Result.ok('backup'));
|
|
633
728
|
|
|
634
729
|
const okResult = pipe(Result.ok('original')).map(fallbackTo).value;
|
|
730
|
+
|
|
635
731
|
expect(Result.isOk(okResult)).toBe(true);
|
|
732
|
+
|
|
636
733
|
if (Result.isOk(okResult)) {
|
|
637
734
|
expect(okResult.value).toBe('original');
|
|
638
735
|
}
|
|
639
736
|
|
|
640
737
|
const errResult = pipe(Result.err('network error')).map(fallbackTo).value;
|
|
738
|
+
|
|
641
739
|
expect(Result.isOk(errResult)).toBe(true);
|
|
740
|
+
|
|
642
741
|
if (Result.isOk(errResult)) {
|
|
643
742
|
expect(errResult.value).toBe('backup');
|
|
644
743
|
}
|
|
@@ -650,13 +749,15 @@ describe('Result', () => {
|
|
|
650
749
|
const a = Result.ok(1);
|
|
651
750
|
const b = Result.ok('hello');
|
|
652
751
|
const zipped = Result.zip(a, b);
|
|
653
|
-
|
|
752
|
+
|
|
753
|
+
assert.deepStrictEqual(Result.unwrapOk(zipped), [1, 'hello']);
|
|
654
754
|
});
|
|
655
755
|
|
|
656
756
|
test('should return first Err if first is Err', () => {
|
|
657
757
|
const a = Result.err('error1');
|
|
658
758
|
const b = Result.ok('hello');
|
|
659
759
|
const zipped = Result.zip(a, b);
|
|
760
|
+
|
|
660
761
|
expect(Result.unwrapErr(zipped)).toBe('error1');
|
|
661
762
|
});
|
|
662
763
|
|
|
@@ -664,6 +765,7 @@ describe('Result', () => {
|
|
|
664
765
|
const a = Result.ok(1);
|
|
665
766
|
const b = Result.err('error2');
|
|
666
767
|
const zipped = Result.zip(a, b);
|
|
768
|
+
|
|
667
769
|
expect(Result.unwrapErr(zipped)).toBe('error2');
|
|
668
770
|
});
|
|
669
771
|
|
|
@@ -671,6 +773,7 @@ describe('Result', () => {
|
|
|
671
773
|
const a = Result.err('error1');
|
|
672
774
|
const b = Result.err('error2');
|
|
673
775
|
const zipped = Result.zip(a, b);
|
|
776
|
+
|
|
674
777
|
expect(Result.unwrapErr(zipped)).toBe('error1');
|
|
675
778
|
});
|
|
676
779
|
});
|
|
@@ -678,16 +781,20 @@ describe('Result', () => {
|
|
|
678
781
|
describe('fromThrowable', () => {
|
|
679
782
|
test('should return Ok when function succeeds', () => {
|
|
680
783
|
const result = Result.fromThrowable(() => 42);
|
|
784
|
+
|
|
681
785
|
expect(Result.isOk(result)).toBe(true);
|
|
682
786
|
expect(Result.unwrapOk(result)).toBe(42);
|
|
787
|
+
|
|
683
788
|
expectType<typeof result, Result<number, Error>>('<=');
|
|
684
789
|
});
|
|
685
790
|
|
|
686
791
|
test('should return Ok with object when function succeeds', () => {
|
|
687
792
|
const obj = { name: 'test', value: 123 };
|
|
688
793
|
const result = Result.fromThrowable(() => obj);
|
|
794
|
+
|
|
689
795
|
expect(Result.isOk(result)).toBe(true);
|
|
690
|
-
|
|
796
|
+
|
|
797
|
+
assert.deepStrictEqual(Result.unwrapOk(result), obj);
|
|
691
798
|
});
|
|
692
799
|
|
|
693
800
|
test('should return Err when function throws Error', () => {
|
|
@@ -695,9 +802,12 @@ describe('Result', () => {
|
|
|
695
802
|
const result = Result.fromThrowable(() => {
|
|
696
803
|
throw new Error(errorMessage);
|
|
697
804
|
});
|
|
805
|
+
|
|
698
806
|
expect(Result.isErr(result)).toBe(true);
|
|
807
|
+
|
|
699
808
|
if (Result.isErr(result)) {
|
|
700
809
|
const error = result.value;
|
|
810
|
+
|
|
701
811
|
expect(error).toBeInstanceOf(Error);
|
|
702
812
|
expect(error.message).toBe(errorMessage);
|
|
703
813
|
}
|
|
@@ -709,9 +819,12 @@ describe('Result', () => {
|
|
|
709
819
|
// eslint-disable-next-line @typescript-eslint/only-throw-error
|
|
710
820
|
throw errorMessage;
|
|
711
821
|
});
|
|
822
|
+
|
|
712
823
|
expect(Result.isErr(result)).toBe(true);
|
|
824
|
+
|
|
713
825
|
if (Result.isErr(result)) {
|
|
714
826
|
const error = result.value;
|
|
827
|
+
|
|
715
828
|
expect(error).toBeInstanceOf(Error);
|
|
716
829
|
expect(error.message).toBe(errorMessage);
|
|
717
830
|
}
|
|
@@ -722,9 +835,12 @@ describe('Result', () => {
|
|
|
722
835
|
// eslint-disable-next-line @typescript-eslint/only-throw-error
|
|
723
836
|
throw 404;
|
|
724
837
|
});
|
|
838
|
+
|
|
725
839
|
expect(Result.isErr(result)).toBe(true);
|
|
840
|
+
|
|
726
841
|
if (Result.isErr(result)) {
|
|
727
842
|
const error = result.value;
|
|
843
|
+
|
|
728
844
|
expect(error).toBeInstanceOf(Error);
|
|
729
845
|
expect(error.message).toBe('404');
|
|
730
846
|
}
|
|
@@ -736,14 +852,19 @@ describe('Result', () => {
|
|
|
736
852
|
|
|
737
853
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
738
854
|
const validResult = Result.fromThrowable(() => JSON.parse(validJson));
|
|
855
|
+
|
|
739
856
|
expect(Result.isOk(validResult)).toBe(true);
|
|
740
|
-
|
|
857
|
+
|
|
858
|
+
assert.deepStrictEqual(Result.unwrapOk(validResult), { key: 'value' });
|
|
741
859
|
|
|
742
860
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
743
861
|
const invalidResult = Result.fromThrowable(() => JSON.parse(invalidJson));
|
|
862
|
+
|
|
744
863
|
expect(Result.isErr(invalidResult)).toBe(true);
|
|
864
|
+
|
|
745
865
|
if (Result.isErr(invalidResult)) {
|
|
746
866
|
const error = invalidResult.value;
|
|
867
|
+
|
|
747
868
|
expect(error).toBeInstanceOf(Error);
|
|
748
869
|
}
|
|
749
870
|
});
|
|
@@ -762,8 +883,10 @@ describe('Result', () => {
|
|
|
762
883
|
});
|
|
763
884
|
|
|
764
885
|
expect(Result.isErr(result)).toBe(true);
|
|
886
|
+
|
|
765
887
|
if (Result.isErr(result)) {
|
|
766
888
|
const error = result.value;
|
|
889
|
+
|
|
767
890
|
expect(error.message).toBe('Index out of bounds');
|
|
768
891
|
}
|
|
769
892
|
});
|