vest-utils 1.5.0 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. package/README.md +7 -2
  2. package/dist/chunk-CLMFDpHK.mjs +18 -0
  3. package/dist/exports/minifyObject.cjs +114 -0
  4. package/dist/exports/minifyObject.cjs.map +1 -0
  5. package/dist/exports/minifyObject.mjs +113 -0
  6. package/dist/exports/minifyObject.mjs.map +1 -0
  7. package/dist/exports/standardSchemaSpec.cjs +0 -0
  8. package/dist/exports/standardSchemaSpec.mjs +1 -0
  9. package/dist/isEmpty-BBxAFjjm.mjs +103 -0
  10. package/dist/isEmpty-BBxAFjjm.mjs.map +1 -0
  11. package/dist/isEmpty-BuEa-96Q.cjs +235 -0
  12. package/dist/isEmpty-BuEa-96Q.cjs.map +1 -0
  13. package/dist/vest-utils.cjs +510 -0
  14. package/dist/vest-utils.cjs.map +1 -0
  15. package/dist/vest-utils.mjs +421 -0
  16. package/dist/vest-utils.mjs.map +1 -0
  17. package/minifyObject/package.json +12 -8
  18. package/package.json +43 -58
  19. package/src/Brand.ts +9 -0
  20. package/src/IO.ts +2 -0
  21. package/src/Predicates.ts +13 -0
  22. package/src/Result.ts +121 -0
  23. package/src/SimpleStateMachine.ts +157 -0
  24. package/src/StringObject.ts +6 -0
  25. package/src/__tests__/Architecture.test.ts +69 -0
  26. package/src/__tests__/Predicates.test.ts +118 -0
  27. package/src/__tests__/Result.test.ts +284 -0
  28. package/src/__tests__/SimpleStateMachine.test.ts +425 -0
  29. package/src/__tests__/StringObject.test.ts +18 -0
  30. package/src/__tests__/asArray.test.ts +14 -0
  31. package/src/__tests__/bindNot.test.ts +39 -0
  32. package/src/__tests__/bus.test.ts +135 -0
  33. package/src/__tests__/cache.test.ts +139 -0
  34. package/src/__tests__/callEach.test.ts +20 -0
  35. package/src/__tests__/defaultTo.test.ts +52 -0
  36. package/src/__tests__/deferThrow.test.ts +26 -0
  37. package/src/__tests__/either.test.ts +17 -0
  38. package/src/__tests__/freezeAssign.test.ts +24 -0
  39. package/src/__tests__/greaterThan.test.ts +68 -0
  40. package/src/__tests__/invariant.test.ts +47 -0
  41. package/src/__tests__/isArray.test.ts +16 -0
  42. package/src/__tests__/isBoolean.test.ts +16 -0
  43. package/src/__tests__/isEmpty.test.ts +55 -0
  44. package/src/__tests__/isEmptySet.test.ts +22 -0
  45. package/src/__tests__/isNull.test.ts +26 -0
  46. package/src/__tests__/isNumeric.test.ts +27 -0
  47. package/src/__tests__/isPositive.test.ts +38 -0
  48. package/src/__tests__/isPromise.test.ts +17 -0
  49. package/src/__tests__/isString.test.ts +13 -0
  50. package/src/__tests__/isUndefined.test.ts +27 -0
  51. package/src/__tests__/isUnsafeKey.test.ts +22 -0
  52. package/src/__tests__/lengthEquals.test.ts +58 -0
  53. package/src/__tests__/longerThan.test.ts +58 -0
  54. package/src/__tests__/mapFirst.test.ts +31 -0
  55. package/src/__tests__/nonnullish.test.ts +25 -0
  56. package/src/__tests__/noop.test.ts +12 -0
  57. package/src/__tests__/numberEquals.test.ts +67 -0
  58. package/src/__tests__/optionalFunctionValue.test.ts +29 -0
  59. package/src/__tests__/seq.test.ts +29 -0
  60. package/src/__tests__/text.test.ts +41 -0
  61. package/src/__tests__/tinyState.test.ts +68 -0
  62. package/src/__tests__/toNumber.test.ts +39 -0
  63. package/src/__tests__/vest-utils.test.ts +13 -0
  64. package/src/__tests__/withCatch.test.ts +17 -0
  65. package/src/__tests__/withResolvers.test.ts +45 -0
  66. package/src/asArray.ts +3 -0
  67. package/src/assign.ts +1 -0
  68. package/src/bindNot.ts +3 -0
  69. package/src/bus.ts +52 -0
  70. package/src/cache.ts +68 -0
  71. package/src/callEach.ts +5 -0
  72. package/src/defaultTo.ts +9 -0
  73. package/src/deferThrow.ts +7 -0
  74. package/src/dynamicValue.ts +9 -0
  75. package/src/either.ts +3 -0
  76. package/src/exports/__tests__/minifyObject.security.test.ts +65 -0
  77. package/src/exports/__tests__/minifyObject.test.ts +281 -0
  78. package/src/exports/minifyObject.ts +198 -0
  79. package/src/exports/standardSchemaSpec.ts +70 -0
  80. package/src/freezeAssign.ts +5 -0
  81. package/src/globals.d.ts +3 -0
  82. package/src/greaterThan.ts +8 -0
  83. package/src/hasOwnProperty.ts +9 -0
  84. package/src/invariant.ts +19 -0
  85. package/src/isArrayValue.ts +11 -0
  86. package/src/isBooleanValue.ts +3 -0
  87. package/src/isEmpty.ts +18 -0
  88. package/src/isEmptySet.ts +15 -0
  89. package/src/isFunction.ts +5 -0
  90. package/src/isNull.ts +7 -0
  91. package/src/isNullish.ts +10 -0
  92. package/src/isNumeric.ts +11 -0
  93. package/src/isPositive.ts +5 -0
  94. package/src/isPromise.ts +5 -0
  95. package/src/isStringValue.ts +3 -0
  96. package/src/isUndefined.ts +7 -0
  97. package/src/isUnsafeKey.ts +3 -0
  98. package/src/lengthEquals.ts +11 -0
  99. package/src/longerThan.ts +8 -0
  100. package/src/mapFirst.ts +25 -0
  101. package/src/nonnullish.ts +9 -0
  102. package/src/noop.ts +1 -0
  103. package/src/numberEquals.ts +11 -0
  104. package/src/seq.ts +16 -0
  105. package/src/text.ts +20 -0
  106. package/src/tinyState.ts +28 -0
  107. package/src/toNumber.ts +11 -0
  108. package/src/utilityTypes.ts +25 -0
  109. package/src/valueIsObject.ts +5 -0
  110. package/src/vest-utils.ts +73 -0
  111. package/src/withCatch.ts +11 -0
  112. package/src/withResolvers.ts +33 -0
  113. package/standardSchemaSpec/package.json +14 -0
  114. package/types/{minifyObject.d.ts → exports/minifyObject.d.cts} +4 -2
  115. package/types/exports/minifyObject.d.cts.map +1 -0
  116. package/types/exports/minifyObject.d.mts +7 -0
  117. package/types/exports/minifyObject.d.mts.map +1 -0
  118. package/types/exports/standardSchemaSpec.d.cts +59 -0
  119. package/types/exports/standardSchemaSpec.d.cts.map +1 -0
  120. package/types/exports/standardSchemaSpec.d.mts +59 -0
  121. package/types/exports/standardSchemaSpec.d.mts.map +1 -0
  122. package/types/vest-utils.d.cts +296 -0
  123. package/types/vest-utils.d.cts.map +1 -0
  124. package/types/vest-utils.d.mts +295 -0
  125. package/types/vest-utils.d.mts.map +1 -0
  126. package/types/vest-utils.d.ts +245 -143
  127. package/vitest.config.ts +9 -45
  128. package/dist/cjs/minifyObject.development.js +0 -217
  129. package/dist/cjs/minifyObject.development.js.map +0 -1
  130. package/dist/cjs/minifyObject.js +0 -6
  131. package/dist/cjs/minifyObject.production.js +0 -2
  132. package/dist/cjs/minifyObject.production.js.map +0 -1
  133. package/dist/cjs/package.json +0 -1
  134. package/dist/cjs/vest-utils.development.js +0 -378
  135. package/dist/cjs/vest-utils.development.js.map +0 -1
  136. package/dist/cjs/vest-utils.js +0 -6
  137. package/dist/cjs/vest-utils.production.js +0 -2
  138. package/dist/cjs/vest-utils.production.js.map +0 -1
  139. package/dist/es/minifyObject.development.js +0 -214
  140. package/dist/es/minifyObject.development.js.map +0 -1
  141. package/dist/es/minifyObject.production.js +0 -2
  142. package/dist/es/minifyObject.production.js.map +0 -1
  143. package/dist/es/package.json +0 -1
  144. package/dist/es/vest-utils.development.js +0 -330
  145. package/dist/es/vest-utils.development.js.map +0 -1
  146. package/dist/es/vest-utils.production.js +0 -2
  147. package/dist/es/vest-utils.production.js.map +0 -1
  148. package/dist/umd/minifyObject.development.js +0 -223
  149. package/dist/umd/minifyObject.development.js.map +0 -1
  150. package/dist/umd/minifyObject.production.js +0 -2
  151. package/dist/umd/minifyObject.production.js.map +0 -1
  152. package/dist/umd/vest-utils.development.js +0 -384
  153. package/dist/umd/vest-utils.development.js.map +0 -1
  154. package/dist/umd/vest-utils.production.js +0 -2
  155. package/dist/umd/vest-utils.production.js.map +0 -1
  156. package/types/minifyObject.d.ts.map +0 -1
  157. package/types/vest-utils.d.ts.map +0 -1
package/src/Result.ts ADDED
@@ -0,0 +1,121 @@
1
+ import { isObject } from './valueIsObject';
2
+
3
+ export type Result<T, E = unknown> = Success<T, E> | Failure<T, E>;
4
+
5
+ type Success<T, E> = {
6
+ chain<U, E2 = E>(fn: (value: T) => Result<U, E2>): Result<U, E | E2>;
7
+ map<U>(fn: (value: T) => U): Result<U, E>;
8
+ mapError<E2>(fn: (error: E) => E2): Result<T, E2>;
9
+ match<U>(handlers: { ok: (value: T) => U; err: (error: E) => U }): U;
10
+ readonly type: 'ok';
11
+ unwrap(): T;
12
+ unwrapOr(defaultValue: T): T;
13
+ readonly value: T;
14
+ };
15
+
16
+ export type Failure<T, E> = {
17
+ chain<U, E2 = E>(fn: (value: T) => Result<U, E2>): Result<U, E | E2>;
18
+ readonly error: E;
19
+ map<U>(fn: (value: T) => U): Result<U, E>;
20
+ mapError<E2>(fn: (error: E) => E2): Result<T, E2>;
21
+ match<U>(handlers: { ok: (value: T) => U; err: (error: E) => U }): U;
22
+ readonly type: 'err';
23
+ unwrap(): T;
24
+ unwrapOr(defaultValue: T): T;
25
+ };
26
+
27
+ function ok<T, E = unknown>(value: T): Success<T, E> {
28
+ return {
29
+ chain<U, E2 = E>(fn: (inner: T) => Result<U, E2>) {
30
+ return fn(value) as Result<U, E | E2>;
31
+ },
32
+ map<U>(fn: (inner: T) => U) {
33
+ return ok<U, E>(fn(value));
34
+ },
35
+ mapError<E2>(_fn: (error: E) => E2) {
36
+ return this as unknown as Success<T, E2>;
37
+ },
38
+ match<U>(handlers: { ok: (val: T) => U; err: (err: E) => U }) {
39
+ return handlers.ok(value);
40
+ },
41
+ type: 'ok',
42
+ unwrap() {
43
+ return value;
44
+ },
45
+ unwrapOr(_defaultValue: T) {
46
+ return value;
47
+ },
48
+ value,
49
+ };
50
+ }
51
+
52
+ function err<T = never, E = unknown>(error: E): Failure<T, E> {
53
+ return {
54
+ chain<U, E2 = E>(_fn: (inner: T) => Result<U, E2>) {
55
+ return this as unknown as Failure<U, E | E2>;
56
+ },
57
+ error,
58
+ map<U>(_fn: (inner: T) => U) {
59
+ return this as unknown as Failure<U, E>;
60
+ },
61
+ mapError<E2>(fn: (inner: E) => E2) {
62
+ return err<T, E2>(fn(error));
63
+ },
64
+ match<U>(handlers: { ok: (val: T) => U; err: (err: E) => U }) {
65
+ return handlers.err(error);
66
+ },
67
+ type: 'err',
68
+ unwrap() {
69
+ throw error instanceof Error ? error : new Error(String(error));
70
+ },
71
+ unwrapOr(defaultValue: T) {
72
+ return defaultValue;
73
+ },
74
+ };
75
+ }
76
+
77
+ export const makeResult = { Ok: ok, Err: err } as const;
78
+
79
+ const hasResultType = (candidate: { type?: unknown }): boolean =>
80
+ candidate.type === 'ok' || candidate.type === 'err';
81
+
82
+ const hasResultShape = (candidate: Record<string, unknown>): boolean =>
83
+ 'value' in candidate || 'error' in candidate;
84
+
85
+ export function isResult(value: unknown): value is Result<unknown, unknown> {
86
+ if (!isObject(value)) {
87
+ return false;
88
+ }
89
+
90
+ const candidate = value as { type?: unknown } & Record<string, unknown>;
91
+
92
+ if (!hasResultShape(candidate)) {
93
+ return false;
94
+ }
95
+
96
+ return hasResultType(candidate);
97
+ }
98
+
99
+ export function isSuccess<T, E>(value: Result<T, E>): value is Success<T, E> {
100
+ return value.type === 'ok';
101
+ }
102
+
103
+ export function isFailure<T, E>(value: Result<T, E>): value is Failure<T, E> {
104
+ return value.type === 'err';
105
+ }
106
+
107
+ /**
108
+ * Unwraps a Result.
109
+ * If the Result is Success, it returns the value.
110
+ * If the Result is Failure, it throws the error.
111
+ */
112
+ export function unwrap<T>(result: Result<T, any>): T {
113
+ if (isFailure(result)) {
114
+ // Ensure we always throw an Error object for better stack traces
115
+ throw result.error instanceof Error
116
+ ? result.error
117
+ : new Error(String(result.error));
118
+ }
119
+
120
+ return result.value;
121
+ }
@@ -0,0 +1,157 @@
1
+ import { isFailure, makeResult, Result } from './Result';
2
+ import { CB } from './utilityTypes';
3
+
4
+ const STATE_WILD_CARD = '*';
5
+ type TStateWildCard = typeof STATE_WILD_CARD;
6
+
7
+ type TransitionTarget<S extends string> = S | [S, CB<boolean, [payload?: any]>];
8
+ type StatesMap<S extends string = string, A extends string = string> = Record<
9
+ S | TStateWildCard,
10
+ Partial<Record<A, TransitionTarget<S>>>
11
+ >;
12
+
13
+ export type TStateMachine<
14
+ S extends string = string,
15
+ A extends string = string,
16
+ > = {
17
+ initial: S;
18
+ states: Partial<StatesMap<S, A>>;
19
+ };
20
+
21
+ export type TStateMachineApi<
22
+ S extends string = string,
23
+ A extends string = string,
24
+ > = {
25
+ getState: CB<S>;
26
+ initial: CB<S>;
27
+ staticTransition: (from: S, action: A, payload?: any) => S;
28
+ transition: (action: A, payload?: any) => Result<void, string>;
29
+ };
30
+
31
+ type TransitionValue<V> = V extends [infer T, any]
32
+ ? T extends string
33
+ ? T
34
+ : never
35
+ : V extends string
36
+ ? V
37
+ : never;
38
+
39
+ type Values<T> = T[keyof T];
40
+
41
+ type StateConfigs<M extends { states: Record<string, any> }> = Values<
42
+ M['states']
43
+ >;
44
+
45
+ type ActionFromConfig<M extends { states: Record<string, any> }> =
46
+ StateConfigs<M> extends infer SC
47
+ ? SC extends any
48
+ ? Extract<keyof SC, string>
49
+ : never
50
+ : never;
51
+
52
+ type TargetStatesFromConfig<M extends { states: Record<string, any> }> =
53
+ StateConfigs<M> extends infer SC
54
+ ? SC extends any
55
+ ? TransitionValue<Values<SC>>
56
+ : never
57
+ : never;
58
+
59
+ type StateFromConfig<
60
+ M extends { initial: string; states: Record<string, any> },
61
+ > =
62
+ | M['initial']
63
+ | Extract<keyof M['states'], string>
64
+ | TargetStatesFromConfig<M>;
65
+
66
+ export function StateMachine<
67
+ M extends { initial: string; states: Record<string, any> },
68
+ >(machine: M): TStateMachineApi<StateFromConfig<M>, ActionFromConfig<M>> {
69
+ type SMState = StateFromConfig<M>;
70
+ type SMAction = ActionFromConfig<M>;
71
+
72
+ const typedMachine = machine as TStateMachine<SMState, SMAction>;
73
+
74
+ let state = typedMachine.initial;
75
+
76
+ const api = { getState, initial, staticTransition, transition };
77
+
78
+ return api;
79
+
80
+ function getState(): SMState {
81
+ return state;
82
+ }
83
+
84
+ function initial(): SMState {
85
+ return machine.initial;
86
+ }
87
+
88
+ function transition(action: SMAction, payload?: any): Result<void, string> {
89
+ const result = calculateNextState(typedMachine, state, action, payload);
90
+
91
+ if (isFailure(result)) {
92
+ return makeResult.Err(result.error);
93
+ }
94
+
95
+ state = result.value;
96
+ return makeResult.Ok(undefined);
97
+ }
98
+
99
+ function staticTransition(
100
+ from: SMState,
101
+ action: SMAction,
102
+ payload?: any,
103
+ ): SMState {
104
+ const transitionTo = getTransitionTarget(typedMachine, from, action);
105
+ const target = Array.isArray(transitionTo)
106
+ ? evaluateConditionalTarget(transitionTo, from, payload)
107
+ : transitionTo;
108
+
109
+ return !target || target === from ? from : (target as SMState);
110
+ }
111
+ }
112
+
113
+ function getTransitionTarget<S extends string, A extends string>(
114
+ machine: TStateMachine<S, A>,
115
+ from: S,
116
+ action: A,
117
+ ): TransitionTarget<S> | undefined {
118
+ return (
119
+ machine.states[from]?.[action] ?? machine.states[STATE_WILD_CARD]?.[action]
120
+ );
121
+ }
122
+
123
+ function evaluateConditionalTarget<S extends string>(
124
+ target: [S, CB<boolean, [payload?: any]>],
125
+ from: S,
126
+ payload?: any,
127
+ ): S {
128
+ const [nextState, conditional] = target;
129
+ return conditional(payload) ? nextState : from;
130
+ }
131
+
132
+ function calculateNextState<S extends string, A extends string>(
133
+ machine: TStateMachine<S, A>,
134
+ from: S,
135
+ action: A,
136
+ payload?: any,
137
+ ): Result<S, string> {
138
+ const transitionTo = getTransitionTarget(machine, from, action);
139
+
140
+ if (!transitionTo) {
141
+ return makeResult.Err(
142
+ `Invalid transition: "${action}" from state "${from}"`,
143
+ );
144
+ }
145
+
146
+ if (Array.isArray(transitionTo)) {
147
+ const [candidateState, conditional] = transitionTo;
148
+ if (!conditional(payload)) {
149
+ return makeResult.Err(
150
+ `Invalid transition: "${action}" from state "${from}" (conditional failed)`,
151
+ );
152
+ }
153
+ return makeResult.Ok(candidateState);
154
+ }
155
+
156
+ return makeResult.Ok(transitionTo as S);
157
+ }
@@ -0,0 +1,6 @@
1
+ import dynamicValue from './dynamicValue';
2
+ import type { Stringable } from './utilityTypes';
3
+
4
+ export function StringObject(value?: Stringable): String {
5
+ return new String(dynamicValue(value));
6
+ }
@@ -0,0 +1,69 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+
3
+ import { Brand, makeBrand } from '../Brand';
4
+ import { IO } from '../IO';
5
+ import { makeResult, isResult, isSuccess, isFailure } from '../Result';
6
+
7
+ // --- CONTRACT: Branded Types ---
8
+ describe('Architecture: Branded Types', () => {
9
+ type UserId = Brand<string, 'UserId'>;
10
+ type PostId = Brand<string, 'PostId'>;
11
+
12
+ it('should not allow assignment of raw string to Branded type (Static Check)', () => {
13
+ const raw = 'user_123';
14
+ const userId = makeBrand<UserId>(raw);
15
+ // @ts-expect-error PostId is not assignable to UserId
16
+ const _postId: PostId = userId;
17
+
18
+ expect(userId).toBe(raw);
19
+ });
20
+ });
21
+
22
+ // --- CONTRACT: Result/Error Handling ---
23
+ describe('Architecture: Result Monad', () => {
24
+ it('should encapsulate errors as values', () => {
25
+ const errorResult = makeResult.Err('Something went wrong');
26
+ expect(isFailure(errorResult)).toBe(true);
27
+ expect(errorResult.error).toBe('Something went wrong');
28
+ });
29
+
30
+ it('should encapsulate success values', () => {
31
+ const successResult = makeResult.Ok(42);
32
+ expect(isSuccess(successResult)).toBe(true);
33
+ expect(successResult.value).toBe(42);
34
+ });
35
+
36
+ it('should support mapping without throwing', () => {
37
+ const val = makeResult.Ok(10);
38
+ const newResult = val.map(x => x * 2);
39
+
40
+ expect(isSuccess(newResult)).toBe(true);
41
+ // @ts-ignore
42
+ expect(newResult.value).toBe(20);
43
+ });
44
+
45
+ it('should identify generic result shapes', () => {
46
+ const okShape = makeResult.Ok('ok');
47
+ const errShape = makeResult.Err('err');
48
+ expect(isResult(okShape)).toBe(true);
49
+ expect(isResult(errShape)).toBe(true);
50
+ expect(isResult({})).toBe(false);
51
+ });
52
+ });
53
+
54
+ // --- CONTRACT: Explicit Side Effects (IO) ---
55
+ describe('Architecture: IO / Effect', () => {
56
+ it('should not execute side effect immediately', () => {
57
+ const spy = vi.fn();
58
+
59
+ const sideEffectFn = (): IO<void> => {
60
+ return () => spy();
61
+ };
62
+
63
+ const effect = sideEffectFn();
64
+ expect(spy).not.toHaveBeenCalled();
65
+
66
+ effect();
67
+ expect(spy).toHaveBeenCalled();
68
+ });
69
+ });
@@ -0,0 +1,118 @@
1
+ import { all, any } from '../Predicates';
2
+ import { describe, it, vi, expect } from 'vitest';
3
+
4
+ describe('Predicates', () => {
5
+ describe('all', () => {
6
+ it('Should return a predicate function', () => {
7
+ expect(typeof all()).toBe('function');
8
+ });
9
+
10
+ it('Should return true if all predicates return true', () => {
11
+ const predicate = all(
12
+ value => value > 0,
13
+ value => value < 10,
14
+ );
15
+
16
+ expect(predicate(5)).toBe(true);
17
+ });
18
+
19
+ it('Should return false if any predicate returns false', () => {
20
+ const predicate = all(
21
+ value => value > 0,
22
+ value => value < 10,
23
+ );
24
+
25
+ expect(predicate(15)).toBe(false);
26
+ });
27
+
28
+ it('Should return false if no predicates are passed', () => {
29
+ const predicate = all();
30
+
31
+ expect(predicate(15)).toBe(false);
32
+ });
33
+
34
+ it('Should return false if predicates are not functions', () => {
35
+ const predicate = all(
36
+ value => value > 0,
37
+ value => value < 10,
38
+ // @ts-ignore - Testing invalid input
39
+ 'not a function',
40
+ );
41
+
42
+ expect(predicate(15)).toBe(false);
43
+ });
44
+
45
+ it('Should pass each predicate the value', () => {
46
+ const spy1 = vi.fn(value => value > 0);
47
+ const spy2 = vi.fn(value => value < 10);
48
+
49
+ const predicate = all(spy1, spy2);
50
+
51
+ predicate(5);
52
+
53
+ expect(spy1).toHaveBeenCalledWith(5);
54
+ expect(spy2).toHaveBeenCalledWith(5);
55
+ });
56
+
57
+ it('When passing explicit true as a predicate, should return true', () => {
58
+ expect(all(true, true, true)(5)).toBe(true);
59
+ });
60
+
61
+ it('When passing explicit false as a predicate, should return false', () => {
62
+ expect(all(true, false, false)(5)).toBe(false);
63
+ });
64
+ });
65
+
66
+ describe('any', () => {
67
+ it('Shold return a predicate function', () => {
68
+ expect(typeof any()).toBe('function');
69
+ });
70
+
71
+ it('Should return true if any predicate returns true', () => {
72
+ expect(
73
+ any(
74
+ value => value > 0,
75
+ value => value === 10,
76
+ )(5),
77
+ ).toBe(true);
78
+ expect(
79
+ any(
80
+ value => value === 10,
81
+ value => value > 0,
82
+ )(5),
83
+ ).toBe(true);
84
+ });
85
+
86
+ it('Should return true if all predicates return true', () => {
87
+ const predicate = any(
88
+ value => value > 0,
89
+ value => value === 10,
90
+ );
91
+
92
+ expect(predicate(10)).toBe(true);
93
+ });
94
+
95
+ it('Should return false if all predicates return false', () => {
96
+ const predicate = any(
97
+ value => value > 0,
98
+ value => value === 10,
99
+ );
100
+
101
+ expect(predicate(-5)).toBe(false);
102
+ });
103
+
104
+ it('Should return false if no predicates are passed', () => {
105
+ const predicate = any();
106
+
107
+ expect(predicate(15)).toBe(false);
108
+ });
109
+
110
+ it('When passing explicit true as a predicate, should return true', () => {
111
+ expect(any(true, false, false)(5)).toBe(true);
112
+ });
113
+
114
+ it('When passing explicit false as a predicate, should return false', () => {
115
+ expect(any(false, false, false)(5)).toBe(false);
116
+ });
117
+ });
118
+ });