ts-data-forge 4.0.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/entry-point.mjs +2 -0
- package/dist/entry-point.mjs.map +1 -1
- package/dist/functional/index.d.mts +1 -0
- package/dist/functional/index.d.mts.map +1 -1
- package/dist/functional/index.mjs +2 -0
- package/dist/functional/index.mjs.map +1 -1
- package/dist/functional/ternary-result/impl/index.d.mts +29 -0
- package/dist/functional/ternary-result/impl/index.d.mts.map +1 -0
- package/dist/functional/ternary-result/impl/index.mjs +28 -0
- package/dist/functional/ternary-result/impl/index.mjs.map +1 -0
- package/dist/functional/ternary-result/impl/tag.d.mts +7 -0
- package/dist/functional/ternary-result/impl/tag.d.mts.map +1 -0
- package/dist/functional/ternary-result/impl/tag.mjs +9 -0
- package/dist/functional/ternary-result/impl/tag.mjs.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-err.d.mts +14 -0
- package/dist/functional/ternary-result/impl/ternary-result-err.d.mts.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-err.mjs +21 -0
- package/dist/functional/ternary-result/impl/ternary-result-err.mjs.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-expect-to-be.d.mts +18 -0
- package/dist/functional/ternary-result/impl/ternary-result-expect-to-be.d.mts.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-expect-to-be.mjs +24 -0
- package/dist/functional/ternary-result/impl/ternary-result-expect-to-be.mjs.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-flat-map.d.mts +29 -0
- package/dist/functional/ternary-result/impl/ternary-result-flat-map.d.mts.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-flat-map.mjs +41 -0
- package/dist/functional/ternary-result/impl/ternary-result-flat-map.mjs.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-fold.d.mts +27 -0
- package/dist/functional/ternary-result/impl/ternary-result-fold.d.mts.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-fold.mjs +36 -0
- package/dist/functional/ternary-result/impl/ternary-result-fold.mjs.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-from-promise.d.mts +20 -0
- package/dist/functional/ternary-result/impl/ternary-result-from-promise.d.mts.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-from-promise.mjs +24 -0
- package/dist/functional/ternary-result/impl/ternary-result-from-promise.mjs.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-from-throwable.d.mts +17 -0
- package/dist/functional/ternary-result/impl/ternary-result-from-throwable.d.mts.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-from-throwable.mjs +33 -0
- package/dist/functional/ternary-result/impl/ternary-result-from-throwable.mjs.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-is-err.d.mts +20 -0
- package/dist/functional/ternary-result/impl/ternary-result-is-err.d.mts.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-is-err.mjs +23 -0
- package/dist/functional/ternary-result/impl/ternary-result-is-err.mjs.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-is-ok.d.mts +21 -0
- package/dist/functional/ternary-result/impl/ternary-result-is-ok.d.mts.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-is-ok.mjs +24 -0
- package/dist/functional/ternary-result/impl/ternary-result-is-ok.mjs.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-is-ternary-result.d.mts +17 -0
- package/dist/functional/ternary-result/impl/ternary-result-is-ternary-result.d.mts.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-is-ternary-result.mjs +28 -0
- package/dist/functional/ternary-result/impl/ternary-result-is-ternary-result.mjs.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-is-warn.d.mts +21 -0
- package/dist/functional/ternary-result/impl/ternary-result-is-warn.d.mts.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-is-warn.mjs +24 -0
- package/dist/functional/ternary-result/impl/ternary-result-is-warn.mjs.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-map-err.d.mts +23 -0
- package/dist/functional/ternary-result/impl/ternary-result-map-err.d.mts.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-map-err.mjs +26 -0
- package/dist/functional/ternary-result/impl/ternary-result-map-err.mjs.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-map-warn.d.mts +21 -0
- package/dist/functional/ternary-result/impl/ternary-result-map-warn.d.mts.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-map-warn.mjs +29 -0
- package/dist/functional/ternary-result/impl/ternary-result-map-warn.mjs.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-map.d.mts +29 -0
- package/dist/functional/ternary-result/impl/ternary-result-map.d.mts.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-map.mjs +35 -0
- package/dist/functional/ternary-result/impl/ternary-result-map.mjs.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-ok.d.mts +16 -0
- package/dist/functional/ternary-result/impl/ternary-result-ok.d.mts.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-ok.mjs +23 -0
- package/dist/functional/ternary-result/impl/ternary-result-ok.mjs.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-or-else.d.mts +26 -0
- package/dist/functional/ternary-result/impl/ternary-result-or-else.d.mts.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-or-else.mjs +19 -0
- package/dist/functional/ternary-result/impl/ternary-result-or-else.mjs.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-to-optional.d.mts +16 -0
- package/dist/functional/ternary-result/impl/ternary-result-to-optional.d.mts.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-to-optional.mjs +25 -0
- package/dist/functional/ternary-result/impl/ternary-result-to-optional.mjs.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-err-or.d.mts +22 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-err-or.d.mts.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-err-or.mjs +17 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-err-or.mjs.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-err-throw.d.mts +18 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-err-throw.d.mts.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-err-throw.mjs +36 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-err-throw.mjs.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-err.d.mts +17 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-err.d.mts.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-err.mjs +22 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-err.mjs.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-ok-or.d.mts +22 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-ok-or.d.mts.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-ok-or.mjs +17 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-ok-or.mjs.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-ok.d.mts +17 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-ok.d.mts.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-ok.mjs +13 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-ok.mjs.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-throw.d.mts +18 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-throw.d.mts.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-throw.mjs +36 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-throw.mjs.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-warn-or.d.mts +19 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-warn-or.d.mts.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-warn-or.mjs +17 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-warn-or.mjs.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-warn-throw.d.mts +18 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-warn-throw.d.mts.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-warn-throw.mjs +32 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-warn-throw.mjs.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-warn.d.mts +17 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-warn.d.mts.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-warn.mjs +22 -0
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-warn.mjs.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-warn.d.mts +18 -0
- package/dist/functional/ternary-result/impl/ternary-result-warn.d.mts.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-warn.mjs +26 -0
- package/dist/functional/ternary-result/impl/ternary-result-warn.mjs.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-zip.d.mts +26 -0
- package/dist/functional/ternary-result/impl/ternary-result-zip.d.mts.map +1 -0
- package/dist/functional/ternary-result/impl/ternary-result-zip.mjs +48 -0
- package/dist/functional/ternary-result/impl/ternary-result-zip.mjs.map +1 -0
- package/dist/functional/ternary-result/impl/types.d.mts +25 -0
- package/dist/functional/ternary-result/impl/types.d.mts.map +1 -0
- package/dist/functional/ternary-result/impl/types.mjs +2 -0
- package/dist/functional/ternary-result/impl/types.mjs.map +1 -0
- package/dist/functional/ternary-result/impl/variant-name.d.mts +3 -0
- package/dist/functional/ternary-result/impl/variant-name.d.mts.map +1 -0
- package/dist/functional/ternary-result/impl/variant-name.mjs +16 -0
- package/dist/functional/ternary-result/impl/variant-name.mjs.map +1 -0
- package/dist/functional/ternary-result/index.d.mts +2 -0
- package/dist/functional/ternary-result/index.d.mts.map +1 -0
- package/dist/functional/ternary-result/index.mjs +3 -0
- package/dist/functional/ternary-result/index.mjs.map +1 -0
- package/dist/globals.d.mts +55 -2
- 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/index.mts +1 -0
- 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/impl/index.mts +28 -0
- package/src/functional/ternary-result/impl/tag.mts +11 -0
- package/src/functional/ternary-result/impl/ternary-result-err.mts +18 -0
- package/src/functional/ternary-result/impl/ternary-result-expect-to-be.mts +53 -0
- package/src/functional/ternary-result/impl/ternary-result-flat-map.mts +95 -0
- package/src/functional/ternary-result/impl/ternary-result-fold.mts +93 -0
- package/src/functional/ternary-result/impl/ternary-result-from-promise.mts +27 -0
- package/src/functional/ternary-result/impl/ternary-result-from-throwable.mts +31 -0
- package/src/functional/ternary-result/impl/ternary-result-is-err.mts +23 -0
- package/src/functional/ternary-result/impl/ternary-result-is-ok.mts +24 -0
- package/src/functional/ternary-result/impl/ternary-result-is-ternary-result.mts +27 -0
- package/src/functional/ternary-result/impl/ternary-result-is-warn.mts +24 -0
- package/src/functional/ternary-result/impl/ternary-result-map-err.mts +64 -0
- package/src/functional/ternary-result/impl/ternary-result-map-warn.mts +66 -0
- package/src/functional/ternary-result/impl/ternary-result-map.mts +81 -0
- package/src/functional/ternary-result/impl/ternary-result-ok.mts +20 -0
- package/src/functional/ternary-result/impl/ternary-result-or-else.mts +66 -0
- package/src/functional/ternary-result/impl/ternary-result-to-optional.mts +25 -0
- package/src/functional/ternary-result/impl/ternary-result-unwrap-err-or.mts +45 -0
- package/src/functional/ternary-result/impl/ternary-result-unwrap-err-throw.mts +40 -0
- package/src/functional/ternary-result/impl/ternary-result-unwrap-err.mts +22 -0
- package/src/functional/ternary-result/impl/ternary-result-unwrap-ok-or.mts +45 -0
- package/src/functional/ternary-result/impl/ternary-result-unwrap-ok.mts +32 -0
- package/src/functional/ternary-result/impl/ternary-result-unwrap-throw.mts +45 -0
- package/src/functional/ternary-result/impl/ternary-result-unwrap-warn-or.mts +42 -0
- package/src/functional/ternary-result/impl/ternary-result-unwrap-warn-throw.mts +38 -0
- package/src/functional/ternary-result/impl/ternary-result-unwrap-warn.mts +22 -0
- package/src/functional/ternary-result/impl/ternary-result-warn.mts +23 -0
- package/src/functional/ternary-result/impl/ternary-result-zip.mts +53 -0
- package/src/functional/ternary-result/impl/types.mts +39 -0
- package/src/functional/ternary-result/impl/variant-name.mts +17 -0
- package/src/functional/ternary-result/index.mts +1 -0
- package/src/functional/ternary-result.test.mts +214 -0
- package/src/globals.d.mts +55 -2
- 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,8 +3,8 @@ import { range } from '../../iterator/index.mjs';
|
|
|
3
3
|
import { asNonZeroUint32 } from './non-zero-uint32.mjs';
|
|
4
4
|
import { asUint32, isUint32, Uint32 } from './uint32.mjs';
|
|
5
5
|
|
|
6
|
-
describe('Uint32', () => {
|
|
7
|
-
describe(
|
|
6
|
+
describe('Uint32 test', () => {
|
|
7
|
+
describe(asUint32, () => {
|
|
8
8
|
test('accepts valid uint32 values', () => {
|
|
9
9
|
expect(() => asUint32(0)).not.toThrow();
|
|
10
10
|
expect(() => asUint32(1)).not.toThrow();
|
|
@@ -52,7 +52,7 @@ describe('Uint32', () => {
|
|
|
52
52
|
});
|
|
53
53
|
});
|
|
54
54
|
|
|
55
|
-
describe(
|
|
55
|
+
describe(isUint32, () => {
|
|
56
56
|
test('correctly identifies uint32 values', () => {
|
|
57
57
|
expect(isUint32(0)).toBe(true);
|
|
58
58
|
expect(isUint32(1)).toBe(true);
|
|
@@ -108,6 +108,7 @@ describe('Uint32', () => {
|
|
|
108
108
|
|
|
109
109
|
test('add (with clamping to uint32 range)', () => {
|
|
110
110
|
const result = Uint32.add(asUint32(4_294_967_000), asUint32(1000));
|
|
111
|
+
|
|
111
112
|
expect(result).toBe(4_294_967_295); // clamped to max
|
|
112
113
|
expect(Uint32.add(a, b)).toBe(1_500_000);
|
|
113
114
|
});
|
|
@@ -120,6 +121,7 @@ describe('Uint32', () => {
|
|
|
120
121
|
|
|
121
122
|
test('mul (with clamping to uint32 range)', () => {
|
|
122
123
|
const result = Uint32.mul(asUint32(100_000), asUint32(100_000));
|
|
124
|
+
|
|
123
125
|
expect(result).toBe(4_294_967_295); // clamped to max
|
|
124
126
|
expect(Uint32.mul(asUint32(1000), asUint32(5))).toBe(5000);
|
|
125
127
|
});
|
|
@@ -132,6 +134,7 @@ describe('Uint32', () => {
|
|
|
132
134
|
|
|
133
135
|
test('pow (with clamping to uint32 range)', () => {
|
|
134
136
|
const result = Uint32.pow(asUint32(10_000), asUint32(3));
|
|
137
|
+
|
|
135
138
|
expect(result).toBe(4_294_967_295); // clamped to max
|
|
136
139
|
expect(Uint32.pow(asUint32(2), asUint32(3))).toBe(8);
|
|
137
140
|
});
|
|
@@ -144,6 +147,7 @@ describe('Uint32', () => {
|
|
|
144
147
|
|
|
145
148
|
for (const _ of range(10)) {
|
|
146
149
|
const result = Uint32.random(min, max);
|
|
150
|
+
|
|
147
151
|
expect(result).toBeGreaterThanOrEqual(min);
|
|
148
152
|
expect(result).toBeLessThanOrEqual(max);
|
|
149
153
|
expect(Uint32.is(result)).toBe(true);
|
|
@@ -155,6 +159,7 @@ describe('Uint32', () => {
|
|
|
155
159
|
test('generates values within Uint32 range', () => {
|
|
156
160
|
for (const _ of range(10)) {
|
|
157
161
|
const result = Uint32.random(0, 30);
|
|
162
|
+
|
|
158
163
|
expect(result).toBeGreaterThanOrEqual(0);
|
|
159
164
|
expect(result).toBeLessThanOrEqual(4_294_967_295);
|
|
160
165
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { expectType } from '../../expect-type.mjs';
|
|
2
2
|
import { Int8, asInt8, isInt8 } from './int8.mjs';
|
|
3
3
|
|
|
4
|
-
describe('Int8', () => {
|
|
5
|
-
describe(
|
|
4
|
+
describe('Int8 test', () => {
|
|
5
|
+
describe(isInt8, () => {
|
|
6
6
|
test.each([
|
|
7
7
|
{ value: -128, expected: true },
|
|
8
8
|
{ value: 0, expected: true },
|
|
@@ -18,7 +18,7 @@ describe('Int8', () => {
|
|
|
18
18
|
});
|
|
19
19
|
});
|
|
20
20
|
|
|
21
|
-
describe(
|
|
21
|
+
describe(asInt8, () => {
|
|
22
22
|
test.each([
|
|
23
23
|
{ value: -128, expected: -128 },
|
|
24
24
|
{ value: 0, expected: 0 },
|
|
@@ -48,6 +48,7 @@ describe('Int8', () => {
|
|
|
48
48
|
describe('Int8.MIN_VALUE', () => {
|
|
49
49
|
test('should be -128', () => {
|
|
50
50
|
expect(Int8.MIN_VALUE).toBe(-128);
|
|
51
|
+
|
|
51
52
|
expectType<typeof Int8.MIN_VALUE, -128>('=');
|
|
52
53
|
});
|
|
53
54
|
});
|
|
@@ -55,6 +56,7 @@ describe('Int8', () => {
|
|
|
55
56
|
describe('Int8.MAX_VALUE', () => {
|
|
56
57
|
test('should be 127', () => {
|
|
57
58
|
expect(Int8.MAX_VALUE).toBe(127);
|
|
59
|
+
|
|
58
60
|
expectType<typeof Int8.MAX_VALUE, 127>('=');
|
|
59
61
|
});
|
|
60
62
|
});
|
|
@@ -96,7 +98,9 @@ describe('Int8', () => {
|
|
|
96
98
|
'Int8.abs($value) should return $expected',
|
|
97
99
|
({ expected, value }) => {
|
|
98
100
|
const result = Int8.abs(value);
|
|
101
|
+
|
|
99
102
|
expect(result).toBe(expected);
|
|
103
|
+
|
|
100
104
|
expectType<typeof result, typeof expected>('=');
|
|
101
105
|
},
|
|
102
106
|
);
|
|
@@ -172,6 +176,7 @@ describe('Int8', () => {
|
|
|
172
176
|
const min = -10;
|
|
173
177
|
const max = 10;
|
|
174
178
|
const result = Int8.random(min, max);
|
|
179
|
+
|
|
175
180
|
expect(result).toBeGreaterThanOrEqual(min);
|
|
176
181
|
expect(result).toBeLessThanOrEqual(max);
|
|
177
182
|
expect(Number.isInteger(result)).toBe(true);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { expectType } from '../../expect-type.mjs';
|
|
2
2
|
import { Uint8, asUint8, isUint8 } from './uint8.mjs';
|
|
3
3
|
|
|
4
|
-
describe('Uint8', () => {
|
|
5
|
-
describe(
|
|
4
|
+
describe('Uint8 test', () => {
|
|
5
|
+
describe(isUint8, () => {
|
|
6
6
|
test.each([
|
|
7
7
|
{ value: 0, expected: true },
|
|
8
8
|
{ value: 128, expected: true },
|
|
@@ -18,7 +18,7 @@ describe('Uint8', () => {
|
|
|
18
18
|
});
|
|
19
19
|
});
|
|
20
20
|
|
|
21
|
-
describe(
|
|
21
|
+
describe(asUint8, () => {
|
|
22
22
|
test.each([
|
|
23
23
|
{ value: 0, expected: 0 },
|
|
24
24
|
{ value: 128, expected: 128 },
|
|
@@ -48,6 +48,7 @@ describe('Uint8', () => {
|
|
|
48
48
|
describe('Uint8.MIN_VALUE', () => {
|
|
49
49
|
test('should be 0', () => {
|
|
50
50
|
expect(Uint8.MIN_VALUE).toBe(0);
|
|
51
|
+
|
|
51
52
|
expectType<typeof Uint8.MIN_VALUE, 0>('=');
|
|
52
53
|
});
|
|
53
54
|
});
|
|
@@ -55,6 +56,7 @@ describe('Uint8', () => {
|
|
|
55
56
|
describe('Uint8.MAX_VALUE', () => {
|
|
56
57
|
test('should be 255', () => {
|
|
57
58
|
expect(Uint8.MAX_VALUE).toBe(255);
|
|
59
|
+
|
|
58
60
|
expectType<typeof Uint8.MAX_VALUE, 255>('=');
|
|
59
61
|
});
|
|
60
62
|
});
|
|
@@ -156,6 +158,7 @@ describe('Uint8', () => {
|
|
|
156
158
|
const min = 10;
|
|
157
159
|
const max = 50;
|
|
158
160
|
const result = Uint8.random(min, max);
|
|
161
|
+
|
|
159
162
|
expect(result).toBeGreaterThanOrEqual(min);
|
|
160
163
|
expect(result).toBeLessThanOrEqual(max);
|
|
161
164
|
expect(Number.isInteger(result)).toBe(true);
|
package/src/number/num.test.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { expectType } from '../expect-type.mjs';
|
|
2
2
|
import { pipe } from '../functional/index.mjs';
|
|
3
|
-
import { asNonZeroFiniteNumber } from './index.mjs';
|
|
3
|
+
import { asNonZeroFiniteNumber } from './branded-types/index.mjs';
|
|
4
4
|
import { Num } from './num.mjs';
|
|
5
5
|
|
|
6
6
|
const testClamp = (
|
|
@@ -13,7 +13,7 @@ const testClamp = (
|
|
|
13
13
|
});
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
-
describe('Num', () => {
|
|
16
|
+
describe('Num test', () => {
|
|
17
17
|
describe('clamp', () => {
|
|
18
18
|
testClamp([0, 2], 2.3, 2);
|
|
19
19
|
testClamp([0, 2], -0.5, 0);
|
|
@@ -22,6 +22,7 @@ describe('Num', () => {
|
|
|
22
22
|
|
|
23
23
|
test('should support regular usage with three parameters', () => {
|
|
24
24
|
expectTypeOf(Num.clamp(15, 0, 10)).toEqualTypeOf<number>();
|
|
25
|
+
|
|
25
26
|
expect(Num.clamp(15, 0, 10)).toBe(10);
|
|
26
27
|
expect(Num.clamp(-5, 0, 10)).toBe(0);
|
|
27
28
|
expect(Num.clamp(5, 0, 10)).toBe(5);
|
|
@@ -32,12 +33,15 @@ describe('Num', () => {
|
|
|
32
33
|
const clampTo0_10 = Num.clamp(0, 10);
|
|
33
34
|
|
|
34
35
|
const result1 = pipe(15).map(clampTo0_10).value;
|
|
36
|
+
|
|
35
37
|
expect(result1).toBe(10);
|
|
36
38
|
|
|
37
39
|
const result2 = pipe(-5).map(clampTo0_10).value;
|
|
40
|
+
|
|
38
41
|
expect(result2).toBe(0);
|
|
39
42
|
|
|
40
43
|
const result3 = pipe(7.5).map(clampTo0_10).value;
|
|
44
|
+
|
|
41
45
|
expect(result3).toBe(7.5);
|
|
42
46
|
});
|
|
43
47
|
|
|
@@ -58,6 +62,7 @@ describe('Num', () => {
|
|
|
58
62
|
expect(Num.clamp(0, -10, -5)).toBe(-5);
|
|
59
63
|
|
|
60
64
|
const clampNegative = Num.clamp(-10, -5);
|
|
65
|
+
|
|
61
66
|
expect(clampNegative(-15)).toBe(-10);
|
|
62
67
|
expect(clampNegative(-7)).toBe(-7);
|
|
63
68
|
expect(clampNegative(0)).toBe(-5);
|
|
@@ -73,6 +78,7 @@ describe('Num', () => {
|
|
|
73
78
|
} else {
|
|
74
79
|
expectType<typeof x, number>('=');
|
|
75
80
|
}
|
|
81
|
+
|
|
76
82
|
expect(f(x)).toBe(true);
|
|
77
83
|
});
|
|
78
84
|
|
|
@@ -84,6 +90,7 @@ describe('Num', () => {
|
|
|
84
90
|
} else {
|
|
85
91
|
expectType<typeof x, number>('=');
|
|
86
92
|
}
|
|
93
|
+
|
|
87
94
|
expect(f(x)).toBe(false);
|
|
88
95
|
});
|
|
89
96
|
});
|
|
@@ -106,6 +113,7 @@ describe('Num', () => {
|
|
|
106
113
|
describe('isInRange', () => {
|
|
107
114
|
test('checks range (lower inclusive, upper exclusive)', () => {
|
|
108
115
|
const inRange = Num.isInRange(0, 10);
|
|
116
|
+
|
|
109
117
|
expect(inRange(5)).toBe(true);
|
|
110
118
|
expect(inRange(0)).toBe(true); // inclusive lower bound
|
|
111
119
|
expect(inRange(10)).toBe(false); // exclusive upper bound
|
|
@@ -117,6 +125,7 @@ describe('Num', () => {
|
|
|
117
125
|
describe('isInRangeInclusive', () => {
|
|
118
126
|
test('checks range (inclusive)', () => {
|
|
119
127
|
const inRange = Num.isInRangeInclusive(0, 10);
|
|
128
|
+
|
|
120
129
|
expect(inRange(5)).toBe(true);
|
|
121
130
|
expect(inRange(0)).toBe(true); // inclusive
|
|
122
131
|
expect(inRange(10)).toBe(true); // inclusive
|
|
@@ -128,6 +137,7 @@ describe('Num', () => {
|
|
|
128
137
|
describe('isUintInRange', () => {
|
|
129
138
|
test('checks uint range (lower inclusive, upper exclusive)', () => {
|
|
130
139
|
const inRange = Num.isUintInRange(0, 5);
|
|
140
|
+
|
|
131
141
|
expect(inRange(2)).toBe(true);
|
|
132
142
|
expect(inRange(0)).toBe(true); // inclusive lower bound
|
|
133
143
|
expect(inRange(5)).toBe(false); // exclusive upper bound
|
|
@@ -141,6 +151,7 @@ describe('Num', () => {
|
|
|
141
151
|
if (Num.isNonZero(x)) {
|
|
142
152
|
expectType<typeof x, NonZeroNumber>('=');
|
|
143
153
|
}
|
|
154
|
+
|
|
144
155
|
expect(Num.isNonZero(5)).toBe(true);
|
|
145
156
|
expect(Num.isNonZero(-3)).toBe(true);
|
|
146
157
|
expect(Num.isNonZero(0)).toBe(false);
|
|
@@ -203,14 +214,17 @@ describe('Num', () => {
|
|
|
203
214
|
describe('round', () => {
|
|
204
215
|
test('creates rounding function with specified precision', () => {
|
|
205
216
|
const round2 = Num.round(2);
|
|
217
|
+
|
|
206
218
|
expect(round2(3.141_59)).toBe(3.14);
|
|
207
219
|
expect(round2(2.556)).toBe(2.56);
|
|
208
220
|
|
|
209
221
|
const round1 = Num.round(1);
|
|
222
|
+
|
|
210
223
|
expect(round1(3.141_59)).toBe(3.1);
|
|
211
224
|
expect(round1(2.56)).toBe(2.6);
|
|
212
225
|
|
|
213
226
|
const round3 = Num.round(3);
|
|
227
|
+
|
|
214
228
|
expect(round3(3.1416)).toBe(3.142);
|
|
215
229
|
expect(round3(2.7182)).toBe(2.718);
|
|
216
230
|
});
|
|
@@ -30,7 +30,7 @@ describe('shallowEq', () => {
|
|
|
30
30
|
|
|
31
31
|
describe('pick', () => {
|
|
32
32
|
test('should pick specified keys', () => {
|
|
33
|
-
|
|
33
|
+
assert.deepStrictEqual(Obj.pick({ a: 1, b: 2, c: 3 }, ['a', 'b']), {
|
|
34
34
|
a: 1,
|
|
35
35
|
b: 2,
|
|
36
36
|
});
|
|
@@ -39,7 +39,8 @@ describe('pick', () => {
|
|
|
39
39
|
test('pick should support curried form', () => {
|
|
40
40
|
const pickAB = Obj.pick(['a', 'b']);
|
|
41
41
|
const result = pickAB({ a: 1, b: 2, c: 3, d: 4 });
|
|
42
|
-
|
|
42
|
+
|
|
43
|
+
assert.deepStrictEqual(result, { a: 1, b: 2 });
|
|
43
44
|
});
|
|
44
45
|
|
|
45
46
|
test('pick should work with pipe when curried', () => {
|
|
@@ -47,13 +48,15 @@ describe('pick', () => {
|
|
|
47
48
|
const user = { id: 1, name: 'Alice', email: 'alice@example.com', age: 30 };
|
|
48
49
|
|
|
49
50
|
const result = pipe(user).map(pickIdAndName).value;
|
|
50
|
-
|
|
51
|
+
|
|
52
|
+
assert.deepStrictEqual(result, { id: 1, name: 'Alice' });
|
|
51
53
|
});
|
|
52
54
|
|
|
53
55
|
test('pick should handle empty keys in curried form', () => {
|
|
54
56
|
const pickNone = Obj.pick([]);
|
|
55
57
|
const result = pickNone({ a: 1, b: 2 });
|
|
56
|
-
|
|
58
|
+
|
|
59
|
+
assert.deepStrictEqual(result, {});
|
|
57
60
|
});
|
|
58
61
|
|
|
59
62
|
test('pick should work for records that only partially contain the key in curried form', () => {
|
|
@@ -67,19 +70,24 @@ describe('pick', () => {
|
|
|
67
70
|
const result = pipe(user).map(pickVisible).value satisfies {
|
|
68
71
|
name: string;
|
|
69
72
|
};
|
|
70
|
-
|
|
73
|
+
|
|
74
|
+
assert.deepStrictEqual(result, { name: 'Alice' });
|
|
71
75
|
});
|
|
72
76
|
});
|
|
73
77
|
|
|
74
78
|
describe('omit', () => {
|
|
75
79
|
test('should omit specified keys', () => {
|
|
76
|
-
|
|
80
|
+
assert.deepStrictEqual(Obj.omit({ a: 1, b: 2, c: 3 }, ['c']), {
|
|
81
|
+
a: 1,
|
|
82
|
+
b: 2,
|
|
83
|
+
});
|
|
77
84
|
});
|
|
78
85
|
|
|
79
86
|
test('omit should support curried form', () => {
|
|
80
87
|
const omitC = Obj.omit(['c']);
|
|
81
88
|
const result = omitC({ a: 1, b: 2, c: 3, d: 4 });
|
|
82
|
-
|
|
89
|
+
|
|
90
|
+
assert.deepStrictEqual(result, { a: 1, b: 2, d: 4 });
|
|
83
91
|
});
|
|
84
92
|
|
|
85
93
|
test('omit should work with pipe when curried', () => {
|
|
@@ -92,20 +100,23 @@ describe('omit', () => {
|
|
|
92
100
|
};
|
|
93
101
|
|
|
94
102
|
const result = pipe(user).map(omitSensitive).value;
|
|
95
|
-
|
|
103
|
+
|
|
104
|
+
assert.deepStrictEqual(result, { id: 1, name: 'Alice' });
|
|
96
105
|
});
|
|
97
106
|
|
|
98
107
|
test('omit should handle empty keys in curried form', () => {
|
|
99
108
|
const omitNone = Obj.omit([]);
|
|
100
109
|
const original = { a: 1, b: 2, c: 3 };
|
|
101
110
|
const result = omitNone(original);
|
|
102
|
-
|
|
111
|
+
|
|
112
|
+
assert.deepStrictEqual(result, original);
|
|
103
113
|
});
|
|
104
114
|
|
|
105
115
|
test('should omit multiple keys in curried form', () => {
|
|
106
116
|
const omitBAndD = Obj.omit(['b', 'd']);
|
|
107
117
|
const result = omitBAndD({ a: 1, b: 2, c: 3, d: 4, e: 5 });
|
|
108
|
-
|
|
118
|
+
|
|
119
|
+
assert.deepStrictEqual(result, { a: 1, c: 3, e: 5 });
|
|
109
120
|
});
|
|
110
121
|
|
|
111
122
|
test('omit should work for records that only partially contain the key in curried form', () => {
|
|
@@ -120,7 +131,8 @@ describe('omit', () => {
|
|
|
120
131
|
id: number;
|
|
121
132
|
name: string;
|
|
122
133
|
};
|
|
123
|
-
|
|
134
|
+
|
|
135
|
+
assert.deepStrictEqual(result, { id: 1, name: 'Alice' });
|
|
124
136
|
});
|
|
125
137
|
});
|
|
126
138
|
|
|
@@ -138,7 +150,8 @@ describe('fromEntries', () => {
|
|
|
138
150
|
typeof result,
|
|
139
151
|
Readonly<{ name: 'Alice'; age: 30; active: true }>
|
|
140
152
|
>('=');
|
|
141
|
-
|
|
153
|
+
|
|
154
|
+
assert.deepStrictEqual(result, { name: 'Alice', age: 30, active: true });
|
|
142
155
|
});
|
|
143
156
|
|
|
144
157
|
test('should produce partial record when keys are unions', () => {
|
|
@@ -148,6 +161,6 @@ describe('fromEntries', () => {
|
|
|
148
161
|
Readonly<Record<'name' | 'email', string>>
|
|
149
162
|
>;
|
|
150
163
|
|
|
151
|
-
|
|
164
|
+
assert.deepStrictEqual(result, { name: 'Alice' });
|
|
152
165
|
});
|
|
153
166
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { expectType } from '../expect-type.mjs';
|
|
2
2
|
import { castDeepMutable, castMutable } from './cast-mutable.mjs';
|
|
3
3
|
|
|
4
|
-
describe(
|
|
4
|
+
describe(castMutable, () => {
|
|
5
5
|
test('should allow mutating arrays that were readonly', () => {
|
|
6
6
|
const readonlyArray: readonly number[] = [1, 2, 3];
|
|
7
7
|
const mut_array = castMutable(readonlyArray);
|
|
@@ -9,8 +9,9 @@ describe('castMutable', () => {
|
|
|
9
9
|
expectType<typeof mut_array, number[]>('=');
|
|
10
10
|
|
|
11
11
|
mut_array.push(4);
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
|
|
13
|
+
assert.deepStrictEqual(mut_array, [1, 2, 3, 4]);
|
|
14
|
+
assert.deepStrictEqual(readonlyArray, [1, 2, 3, 4]);
|
|
14
15
|
});
|
|
15
16
|
|
|
16
17
|
test('should allow mutating objects that were readonly', () => {
|
|
@@ -25,12 +26,12 @@ describe('castMutable', () => {
|
|
|
25
26
|
mut_user.age = 31;
|
|
26
27
|
mut_user.name = 'Bob';
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
assert.deepStrictEqual(mut_user, { name: 'Bob', age: 31 });
|
|
30
|
+
assert.deepStrictEqual(readonlyUser, { name: 'Bob', age: 31 });
|
|
30
31
|
});
|
|
31
32
|
});
|
|
32
33
|
|
|
33
|
-
describe(
|
|
34
|
+
describe(castDeepMutable, () => {
|
|
34
35
|
test('should enable deep mutations on nested readonly structures', () => {
|
|
35
36
|
type ReadonlyState = Readonly<{
|
|
36
37
|
user: {
|
|
@@ -66,15 +67,16 @@ describe('castDeepMutable', () => {
|
|
|
66
67
|
mut_state.user.profile.tags.push('editor');
|
|
67
68
|
mut_state.user.profile.name = 'Bob';
|
|
68
69
|
|
|
69
|
-
|
|
70
|
+
assert.deepStrictEqual(mut_state.user.profile, {
|
|
70
71
|
name: 'Bob',
|
|
71
72
|
tags: ['admin', 'owner', 'editor'],
|
|
72
73
|
});
|
|
73
|
-
|
|
74
|
+
assert.deepStrictEqual(readonlyState.user.profile.tags, [
|
|
74
75
|
'admin',
|
|
75
76
|
'owner',
|
|
76
77
|
'editor',
|
|
77
78
|
]);
|
|
79
|
+
|
|
78
80
|
expect(readonlyState.user.profile.name).toBe('Bob');
|
|
79
81
|
});
|
|
80
82
|
});
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { castDeepReadonly, castReadonly } from './cast-readonly.mjs';
|
|
2
2
|
|
|
3
|
-
describe(
|
|
3
|
+
describe(castReadonly, () => {
|
|
4
4
|
test('should cast mutable array to readonly', () => {
|
|
5
5
|
const mutableArr = [1, 2, 3];
|
|
6
6
|
const readonlyArr = castReadonly(mutableArr);
|
|
7
7
|
|
|
8
8
|
expect(readonlyArr).toBe(mutableArr); // Same reference
|
|
9
|
-
|
|
9
|
+
|
|
10
|
+
assert.deepStrictEqual(readonlyArr, [1, 2, 3]);
|
|
10
11
|
});
|
|
11
12
|
|
|
12
13
|
test('should cast mutable object to readonly', () => {
|
|
@@ -14,7 +15,8 @@ describe('castReadonly', () => {
|
|
|
14
15
|
const readonlyObj = castReadonly(mutableObj);
|
|
15
16
|
|
|
16
17
|
expect(readonlyObj).toBe(mutableObj); // Same reference
|
|
17
|
-
|
|
18
|
+
|
|
19
|
+
assert.deepStrictEqual(readonlyObj, { x: 1, y: 2 });
|
|
18
20
|
});
|
|
19
21
|
|
|
20
22
|
test('should preserve the runtime value', () => {
|
|
@@ -38,7 +40,7 @@ describe('castReadonly', () => {
|
|
|
38
40
|
});
|
|
39
41
|
});
|
|
40
42
|
|
|
41
|
-
describe(
|
|
43
|
+
describe(castDeepReadonly, () => {
|
|
42
44
|
test('should cast deeply nested structure to readonly', () => {
|
|
43
45
|
const mutableNested = {
|
|
44
46
|
a: { b: [1, 2, 3] },
|
|
@@ -47,7 +49,9 @@ describe('castDeepReadonly', () => {
|
|
|
47
49
|
const readonlyNested = castDeepReadonly(mutableNested);
|
|
48
50
|
|
|
49
51
|
expect(readonlyNested).toBe(mutableNested); // Same reference
|
|
50
|
-
|
|
52
|
+
|
|
53
|
+
assert.deepStrictEqual(readonlyNested.a.b, [1, 2, 3]);
|
|
54
|
+
|
|
51
55
|
expect(readonlyNested.c.d.e).toBe('value');
|
|
52
56
|
});
|
|
53
57
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ifThen } from './if-then.mjs';
|
|
2
2
|
|
|
3
|
-
describe(
|
|
3
|
+
describe(ifThen, () => {
|
|
4
4
|
test('should implement logical implication truth table', () => {
|
|
5
5
|
// True antecedent, true consequent -> true
|
|
6
6
|
expect(ifThen(true, true)).toBe(true);
|
|
@@ -34,6 +34,7 @@ describe('ifThen', () => {
|
|
|
34
34
|
): boolean =>
|
|
35
35
|
// If admin, then must have permission
|
|
36
36
|
ifThen(isAdmin, hasPermission);
|
|
37
|
+
|
|
37
38
|
expect(checkPermission(true, true)).toBe(true); // admin with permission
|
|
38
39
|
expect(checkPermission(true, false)).toBe(false); // admin without permission
|
|
39
40
|
expect(checkPermission(false, true)).toBe(true); // non-admin with permission
|
|
@@ -47,6 +48,7 @@ describe('ifThen', () => {
|
|
|
47
48
|
): boolean =>
|
|
48
49
|
// If premium, then all premium features must be enabled
|
|
49
50
|
ifThen(isPremium, hasAllFeatures);
|
|
51
|
+
|
|
50
52
|
expect(validateSubscription(true, true)).toBe(true); // premium with all features
|
|
51
53
|
expect(validateSubscription(true, false)).toBe(false); // premium without all features
|
|
52
54
|
expect(validateSubscription(false, true)).toBe(true); // non-premium with features
|
|
@@ -67,6 +69,7 @@ describe('ifThen', () => {
|
|
|
67
69
|
const checkExpiredLogic = (isExpired: boolean, isValid: boolean): boolean =>
|
|
68
70
|
// "If not expired then valid" is equivalent to "expired OR valid"
|
|
69
71
|
ifThen(!isExpired, isValid);
|
|
72
|
+
|
|
70
73
|
expect(checkExpiredLogic(false, true)).toBe(true); // not expired and valid
|
|
71
74
|
expect(checkExpiredLogic(false, false)).toBe(false); // not expired but invalid
|
|
72
75
|
expect(checkExpiredLogic(true, true)).toBe(true); // expired but valid (vacuous)
|
|
@@ -2,29 +2,37 @@ import { expectType } from '../expect-type.mjs';
|
|
|
2
2
|
import { pipe } from '../functional/index.mjs';
|
|
3
3
|
import { mapNullable } from './map-nullable.mjs';
|
|
4
4
|
|
|
5
|
-
describe(
|
|
5
|
+
describe(mapNullable, () => {
|
|
6
6
|
describe('regular usage', () => {
|
|
7
7
|
test('should apply function to non-null value', () => {
|
|
8
8
|
const result = mapNullable('hello', (s) => s.toUpperCase());
|
|
9
|
+
|
|
9
10
|
expect(result).toBe('HELLO');
|
|
11
|
+
|
|
10
12
|
expectType<typeof result, string | undefined>('=');
|
|
11
13
|
});
|
|
12
14
|
|
|
13
15
|
test('should apply function to non-undefined value', () => {
|
|
14
16
|
const result = mapNullable(42, (n) => n * 2);
|
|
17
|
+
|
|
15
18
|
expect(result).toBe(84);
|
|
19
|
+
|
|
16
20
|
expectType<typeof result, number | undefined>('=');
|
|
17
21
|
});
|
|
18
22
|
|
|
19
23
|
test('should return undefined for null input', () => {
|
|
20
24
|
const result = mapNullable(null, (s: string) => s.toUpperCase());
|
|
25
|
+
|
|
21
26
|
expect(result).toBeUndefined();
|
|
27
|
+
|
|
22
28
|
expectType<typeof result, string | undefined>('=');
|
|
23
29
|
});
|
|
24
30
|
|
|
25
31
|
test('should return undefined for undefined input', () => {
|
|
26
32
|
const result = mapNullable(undefined, (s: string) => s.toUpperCase());
|
|
33
|
+
|
|
27
34
|
expect(result).toBeUndefined();
|
|
35
|
+
|
|
28
36
|
expectType<typeof result, string | undefined>('=');
|
|
29
37
|
});
|
|
30
38
|
|
|
@@ -34,18 +42,21 @@ describe('mapNullable', () => {
|
|
|
34
42
|
user,
|
|
35
43
|
(u) => `${u.name} is ${u.age} years old`,
|
|
36
44
|
);
|
|
45
|
+
|
|
37
46
|
expect(result).toBe('Alice is 30 years old');
|
|
38
47
|
});
|
|
39
48
|
|
|
40
49
|
test('should work with nullable object properties', () => {
|
|
41
50
|
const user: { name?: string } = { name: 'Bob' };
|
|
42
51
|
const result = mapNullable(user.name, (name) => name.toUpperCase());
|
|
52
|
+
|
|
43
53
|
expect(result).toBe('BOB');
|
|
44
54
|
|
|
45
55
|
const userWithoutName: { name?: string } = {};
|
|
46
56
|
const resultEmpty = mapNullable(userWithoutName.name, (name) =>
|
|
47
57
|
name.toUpperCase(),
|
|
48
58
|
);
|
|
59
|
+
|
|
49
60
|
expect(resultEmpty).toBeUndefined();
|
|
50
61
|
});
|
|
51
62
|
});
|
|
@@ -55,12 +66,15 @@ describe('mapNullable', () => {
|
|
|
55
66
|
const toUpperCase = mapNullable((s: string) => s.toUpperCase());
|
|
56
67
|
|
|
57
68
|
const result1 = toUpperCase('hello');
|
|
69
|
+
|
|
58
70
|
expect(result1).toBe('HELLO');
|
|
59
71
|
|
|
60
72
|
const result2 = toUpperCase(null);
|
|
73
|
+
|
|
61
74
|
expect(result2).toBeUndefined();
|
|
62
75
|
|
|
63
76
|
const result3 = toUpperCase(undefined);
|
|
77
|
+
|
|
64
78
|
expect(result3).toBeUndefined();
|
|
65
79
|
});
|
|
66
80
|
|
|
@@ -68,12 +82,15 @@ describe('mapNullable', () => {
|
|
|
68
82
|
const double = mapNullable((n: number) => n * 2);
|
|
69
83
|
|
|
70
84
|
const result1 = double(21);
|
|
85
|
+
|
|
71
86
|
expect(result1).toBe(42);
|
|
72
87
|
|
|
73
88
|
const result2 = double(null);
|
|
89
|
+
|
|
74
90
|
expect(result2).toBeUndefined();
|
|
75
91
|
|
|
76
92
|
const result3 = double(undefined);
|
|
93
|
+
|
|
77
94
|
expect(result3).toBeUndefined();
|
|
78
95
|
});
|
|
79
96
|
|
|
@@ -84,9 +101,11 @@ describe('mapNullable', () => {
|
|
|
84
101
|
|
|
85
102
|
const user = { name: 'Charlie', age: 25 };
|
|
86
103
|
const result1 = getName(user);
|
|
104
|
+
|
|
87
105
|
expect(result1).toBe('Charlie');
|
|
88
106
|
|
|
89
107
|
const result2 = getName(null);
|
|
108
|
+
|
|
90
109
|
expect(result2).toBeUndefined();
|
|
91
110
|
});
|
|
92
111
|
|
|
@@ -141,27 +160,32 @@ describe('mapNullable', () => {
|
|
|
141
160
|
|
|
142
161
|
test('should work with zero values', () => {
|
|
143
162
|
const result = mapNullable(0, (n) => n + 1);
|
|
163
|
+
|
|
144
164
|
expect(result).toBe(1);
|
|
145
165
|
});
|
|
146
166
|
|
|
147
167
|
test('should work with empty string', () => {
|
|
148
168
|
const result = mapNullable('', (s) => s.length);
|
|
169
|
+
|
|
149
170
|
expect(result).toBe(0);
|
|
150
171
|
});
|
|
151
172
|
|
|
152
173
|
test('should work with false boolean', () => {
|
|
153
174
|
const result = mapNullable(false, (b) => !b);
|
|
175
|
+
|
|
154
176
|
expect(result).toBe(true);
|
|
155
177
|
});
|
|
156
178
|
|
|
157
179
|
test('should work with arrays', () => {
|
|
158
180
|
const result = mapNullable([1, 2, 3], (arr) => arr.length);
|
|
181
|
+
|
|
159
182
|
expect(result).toBe(3);
|
|
160
183
|
|
|
161
184
|
const nullResult = mapNullable(
|
|
162
185
|
null as number[] | null,
|
|
163
186
|
(arr) => arr.length,
|
|
164
187
|
);
|
|
188
|
+
|
|
165
189
|
expect(nullResult).toBeUndefined();
|
|
166
190
|
});
|
|
167
191
|
|
|
@@ -172,6 +196,7 @@ describe('mapNullable', () => {
|
|
|
172
196
|
};
|
|
173
197
|
|
|
174
198
|
const result = mapNullable(data, (d) => d.user.profile.name);
|
|
199
|
+
|
|
175
200
|
expect(result).toBe('Alice');
|
|
176
201
|
});
|
|
177
202
|
});
|
|
@@ -206,10 +231,12 @@ describe('mapNullable', () => {
|
|
|
206
231
|
|
|
207
232
|
const input1 = 'hello';
|
|
208
233
|
const result1 = double(getLength(toUpperCase(input1)));
|
|
234
|
+
|
|
209
235
|
expect(result1).toBe(10);
|
|
210
236
|
|
|
211
237
|
const input2: string | null = null;
|
|
212
238
|
const result2 = double(getLength(toUpperCase(input2)));
|
|
239
|
+
|
|
213
240
|
expect(result2).toBeUndefined();
|
|
214
241
|
});
|
|
215
242
|
});
|