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
@@ -0,0 +1,18 @@
1
+ import { describe, test, expect, it } from 'vitest';
2
+
3
+ import { StringObject } from '../StringObject';
4
+
5
+ describe('StringObject', () => {
6
+ test('returns an instance of String', () => {
7
+ const str = StringObject('hello');
8
+ expect(str).toBeInstanceOf(String);
9
+ });
10
+
11
+ describe('When the passed value is a function that returns a string', () => {
12
+ it('should return a string object with the value of the function', () => {
13
+ const str = StringObject(() => 'hello');
14
+ expect(str).toBeInstanceOf(String);
15
+ expect(str.toString()).toBe('hello');
16
+ });
17
+ });
18
+ });
@@ -0,0 +1,14 @@
1
+ import asArray from '../asArray';
2
+ import { describe, it, expect } from 'vitest';
3
+
4
+ describe('asArray', () => {
5
+ it('should return an array', () => {
6
+ expect(asArray('test')).toEqual(['test']);
7
+ expect(asArray(['test'])).toEqual(['test']);
8
+ });
9
+
10
+ it('Should create a shallow copy of the array', () => {
11
+ const arr = ['test'];
12
+ expect(asArray(arr)).not.toBe(arr);
13
+ });
14
+ });
@@ -0,0 +1,39 @@
1
+ import { describe, test, expect, vi, it } from 'vitest';
2
+
3
+ import { bindNot } from '../vest-utils';
4
+
5
+ describe('bindNot', () => {
6
+ it('Should return return a function', () => {
7
+ expect(typeof bindNot(vi.fn())).toBe('function');
8
+ });
9
+
10
+ test('calling returned function runs accepted function', () => {
11
+ const fn = vi.fn();
12
+
13
+ expect(fn).not.toHaveBeenCalled();
14
+ const not = bindNot(fn);
15
+ expect(fn).not.toHaveBeenCalled();
16
+ not();
17
+ expect(fn).toHaveBeenCalledTimes(1);
18
+ });
19
+
20
+ it('Should pass arguments to accepted function', () => {
21
+ const fn = vi.fn();
22
+
23
+ const not = bindNot(fn);
24
+ not(1, 2, 3, 4);
25
+ expect(fn).toHaveBeenCalledWith(1, 2, 3, 4);
26
+ });
27
+
28
+ it('Should return the boolean negation of the original function', () => {
29
+ expect(bindNot(() => true)()).toBe(false);
30
+ expect(bindNot(() => false)()).toBe(true);
31
+ expect(bindNot(() => 'string')()).toBe(false);
32
+ expect(bindNot(() => [])()).toBe(false);
33
+ expect(bindNot(() => '')()).toBe(true);
34
+ expect(bindNot(() => 0)()).toBe(true);
35
+ expect(bindNot(() => NaN)()).toBe(true);
36
+ expect(bindNot(() => null)()).toBe(true);
37
+ expect(bindNot(() => undefined)()).toBe(true);
38
+ });
39
+ });
@@ -0,0 +1,135 @@
1
+ import { describe, it, expect, vi, test } from 'vitest';
2
+
3
+ import { createBus } from '../bus';
4
+
5
+ type TestEvents = {
6
+ test: any;
7
+ t1: void;
8
+ t2: void;
9
+ };
10
+
11
+ describe('bus', () => {
12
+ it('should be a function', () => {
13
+ expect(createBus).toBeInstanceOf(Function);
14
+ });
15
+
16
+ it('should return a bus', () => {
17
+ const bus = createBus<TestEvents>();
18
+ expect(bus).toBeInstanceOf(Object);
19
+ expect(bus.emit).toBeInstanceOf(Function);
20
+ expect(bus.on).toBeInstanceOf(Function);
21
+ });
22
+
23
+ it('should emit events', () => {
24
+ const bus = createBus<TestEvents>();
25
+ const spy = vi.fn();
26
+ bus.on('test', spy);
27
+ bus.emit('test');
28
+ expect(spy).toHaveBeenCalled();
29
+ });
30
+
31
+ it('should emit events with data', () => {
32
+ const bus = createBus<TestEvents>();
33
+ const spy = vi.fn();
34
+ bus.on('test', spy);
35
+ bus.emit('test', 'testData');
36
+ expect(spy).toHaveBeenCalledWith('testData');
37
+ });
38
+
39
+ it('should emit events with multiple listeners', () => {
40
+ const bus = createBus<TestEvents>();
41
+ const spy1 = vi.fn();
42
+ const spy2 = vi.fn();
43
+ bus.on('test', spy1);
44
+ bus.on('test', spy2);
45
+ bus.emit('test');
46
+ expect(spy1).toHaveBeenCalled();
47
+ expect(spy2).toHaveBeenCalled();
48
+ });
49
+
50
+ it('should emit events with multiple listeners and data', () => {
51
+ const bus = createBus<TestEvents>();
52
+ const spy1 = vi.fn();
53
+ const spy2 = vi.fn();
54
+ bus.on('test', spy1);
55
+ bus.on('test', spy2);
56
+ bus.emit('test', 'test1');
57
+ expect(spy1).toHaveBeenCalledWith('test1');
58
+ expect(spy2).toHaveBeenCalledWith('test1');
59
+ });
60
+
61
+ test('on returns an object with an `off` function', () => {
62
+ const bus = createBus<TestEvents>();
63
+ const spy = vi.fn();
64
+ const off = bus.on('test', spy);
65
+ expect(off).toBeInstanceOf(Object);
66
+ expect(off.off).toBeInstanceOf(Function);
67
+ });
68
+
69
+ test('off should remove a listener', () => {
70
+ const bus = createBus<TestEvents>();
71
+ const spy = vi.fn();
72
+ const off = bus.on('test', spy);
73
+ off.off();
74
+ bus.emit('test');
75
+ expect(spy).not.toHaveBeenCalled();
76
+ });
77
+
78
+ test('off should only remove specific handler', () => {
79
+ const bus = createBus<TestEvents>();
80
+ const spy1 = vi.fn();
81
+ const spy2 = vi.fn();
82
+ const off = bus.on('test', spy1);
83
+ bus.on('test', spy2);
84
+ off.off();
85
+ bus.emit('test');
86
+ expect(spy1).not.toHaveBeenCalled();
87
+ expect(spy2).toHaveBeenCalled();
88
+ });
89
+
90
+ describe('"ANY" wildcard (*)', () => {
91
+ it('Should run the wildcard handler on any event', () => {
92
+ const bus = createBus<TestEvents>();
93
+ const spy1 = vi.fn();
94
+ const spy2 = vi.fn();
95
+ const spy3 = vi.fn();
96
+ bus.on('t1', spy1);
97
+ bus.on('t2', spy2);
98
+ bus.on('*', spy3);
99
+ expect(spy1).not.toHaveBeenCalled();
100
+ expect(spy2).not.toHaveBeenCalled();
101
+ expect(spy3).not.toHaveBeenCalled();
102
+ bus.emit('t1');
103
+ expect(spy1).toHaveBeenCalledTimes(1);
104
+ expect(spy2).toHaveBeenCalledTimes(0);
105
+ expect(spy3).toHaveBeenCalledTimes(1);
106
+ bus.emit('t2');
107
+ expect(spy1).toHaveBeenCalledTimes(1);
108
+ expect(spy2).toHaveBeenCalledTimes(1);
109
+ expect(spy3).toHaveBeenCalledTimes(2);
110
+ });
111
+
112
+ it('Should call the wildcard last, regardless of when it was defined', () => {
113
+ const bus = createBus<TestEvents>();
114
+ const spy1 = vi.fn();
115
+ const spy2 = vi.fn();
116
+ const spy3 = vi.fn();
117
+ const spy4 = vi.fn();
118
+ bus.on('t1', spy1);
119
+ bus.on('*', spy4);
120
+ bus.on('t1', spy2);
121
+ bus.on('t1', spy3);
122
+ bus.emit('t1');
123
+ const invocations = [spy1, spy2, spy3, spy4]
124
+ .map(i => i.mock.invocationCallOrder[0])
125
+ .sort();
126
+
127
+ expect(invocations).toEqual([
128
+ spy1.mock.invocationCallOrder[0],
129
+ spy2.mock.invocationCallOrder[0],
130
+ spy3.mock.invocationCallOrder[0],
131
+ spy4.mock.invocationCallOrder[0],
132
+ ]);
133
+ });
134
+ });
135
+ });
@@ -0,0 +1,139 @@
1
+ import _ from 'lodash';
2
+ import { describe, it, expect, beforeEach, vi } from 'vitest';
3
+
4
+ import { cache } from '../vest-utils';
5
+
6
+ describe('lib: cache', () => {
7
+ let c: ReturnType<typeof cache>;
8
+
9
+ beforeEach(() => {
10
+ c = cache();
11
+ });
12
+ it('should return a function', () => {
13
+ expect(typeof cache()).toBe('function');
14
+ });
15
+
16
+ it('Should create a new function on each call', () => {
17
+ expect(cache()).not.toBe(cache());
18
+ });
19
+
20
+ describe('when cacheaction is a value rather than a function', () => {
21
+ it('should store the value if no hit', () => {
22
+ const res = c([1, 2, 3], 123);
23
+ expect(res).toBe(123);
24
+ });
25
+ });
26
+
27
+ describe('on cache miss', () => {
28
+ it('Should call passed cache action function and return its value', () => {
29
+ const cacheAction = vi.fn(() => ({}));
30
+ const res = c([{}], cacheAction);
31
+ expect(cacheAction).toHaveBeenCalledTimes(1);
32
+ expect(res).toBe(cacheAction.mock.results[0].value);
33
+ });
34
+ });
35
+
36
+ describe('On cache hit', () => {
37
+ it('Should return cached result', () => {
38
+ const cacheAction = vi.fn(() => {
39
+ Math.random();
40
+ });
41
+ const depsArray = [true, false, {}];
42
+ const res1 = c(depsArray, cacheAction);
43
+ expect(res1).toBe(cacheAction.mock.results[0].value);
44
+ const res2 = c(depsArray, cacheAction);
45
+ expect(res2).toBe(res1);
46
+ });
47
+
48
+ it('Should return without calling the cache action', () => {
49
+ const cacheAction = vi.fn();
50
+ const depsArray = [Math.random()];
51
+ c(depsArray, cacheAction);
52
+ expect(cacheAction).toHaveBeenCalledTimes(1);
53
+ c(depsArray, cacheAction);
54
+ expect(cacheAction).toHaveBeenCalledTimes(1);
55
+ });
56
+
57
+ it('Should limit cache results to `maxSize`', () => {
58
+ const cacheSize = _.random(5, 10);
59
+ const callCount = _.random(cacheSize, cacheSize + 10);
60
+ const diff = callCount - cacheSize;
61
+ /**
62
+ * Doing a nested check to combat the auto cleanup of the cache.
63
+ * Otherwise, each access to the cache would purge the oldest results
64
+ * and we wouldn't get an accurate read - so instantiating a new cache
65
+ * for each index is a good workaround.
66
+ */
67
+ Array.from({ length: callCount }, (_, i) => {
68
+ const c = cache(/*maxSize*/ cacheSize);
69
+ const results = Array.from({ length: callCount }, (_, j) =>
70
+ c([j], Math.random),
71
+ );
72
+
73
+ if (i < diff) {
74
+ // Here we generate a fresh `null` result
75
+ expect(c([i], () => null)).toBeNull();
76
+ } else {
77
+ // Here we retrieve an existing result
78
+ expect(c([i], () => null)).toBe(results[i]);
79
+ }
80
+ });
81
+ });
82
+ });
83
+ it('Should take into account the deps array in its entirety', () => {
84
+ const deps = Array.from({ length: 100 }, () =>
85
+ _.sample([{}, false, Math.random(), true, () => null]),
86
+ );
87
+ const c = cache();
88
+ const res = c([...deps], Math.random);
89
+ expect(c([...deps], () => undefined)).toBe(res);
90
+ const sliced = deps.slice(0, -1);
91
+ expect(c(sliced, () => null)).toBeNull();
92
+ });
93
+
94
+ describe('cache.get', () => {
95
+ describe('On cache miss', () => {
96
+ it('Should return null', () => {
97
+ expect(c.get([1, 2, 3])).toBeNull();
98
+ c([1, 2, 3], Math.random);
99
+ expect(c.get([1, 2, '3'])).toBeNull();
100
+ });
101
+ });
102
+
103
+ describe('On cache hit', () => {
104
+ it('Should return cached key and item from cache storage', () => {
105
+ const res = c([1, 2, 3], Math.random);
106
+ expect(c.get([1, 2, 3])?.[0]).toEqual([1, 2, 3]);
107
+ expect(c.get([1, 2, 3])?.[1]).toEqual(res);
108
+ });
109
+ });
110
+ });
111
+
112
+ describe('cache.set', () => {
113
+ it('Should set a value to the cache storage by its dependencies', () => {
114
+ const deps = [1, 2, 3];
115
+ const res = Math.random();
116
+ c.set(deps, res);
117
+ expect(c.get(deps)?.[1]).toBe(res);
118
+ });
119
+
120
+ it('Should update an existing value in the cache storage by its dependencies', () => {
121
+ const deps = [1, 2, 3];
122
+ const res = Math.random();
123
+ c.set(deps, res);
124
+ const updatedRes = Math.random();
125
+ c.set(deps, updatedRes);
126
+ expect(c.get(deps)?.[1]).toBe(updatedRes);
127
+ });
128
+ });
129
+
130
+ describe('cache.invalidate', () => {
131
+ it('Should remove cached item from cache storage by its dependencies', () => {
132
+ const deps = [1, 2, 3];
133
+ c(deps, Math.random);
134
+ expect(c.get(deps)).not.toBeNull();
135
+ c.invalidate(deps);
136
+ expect(c.get(deps)).toBeNull();
137
+ });
138
+ });
139
+ });
@@ -0,0 +1,20 @@
1
+ import callEach from '../callEach';
2
+ import { describe, it, expect, vi } from 'vitest';
3
+
4
+ describe('callEach', () => {
5
+ it('should call all functions in the array', () => {
6
+ const mockFn1 = vi.fn();
7
+ const mockFn2 = vi.fn();
8
+ const mockFn3 = vi.fn();
9
+
10
+ callEach([mockFn1, mockFn2, mockFn3]);
11
+
12
+ expect(mockFn1).toHaveBeenCalled();
13
+ expect(mockFn2).toHaveBeenCalled();
14
+ expect(mockFn3).toHaveBeenCalled();
15
+ });
16
+
17
+ it('should not throw an error if the array is empty', () => {
18
+ expect(() => callEach([])).not.toThrow();
19
+ });
20
+ });
@@ -0,0 +1,52 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+
3
+ import { defaultTo } from '../vest-utils';
4
+
5
+ describe('defaultTo', () => {
6
+ describe('When value is a function', () => {
7
+ it('Should call the function', () => {
8
+ const value = vi.fn(() => 'return value');
9
+
10
+ expect(defaultTo(value, 'fallback value')).toBe('return value');
11
+ expect(value).toHaveBeenCalled();
12
+ });
13
+ describe('When value is nullish', () => {
14
+ it('Should return fallback value', () => {
15
+ expect(defaultTo(null, 'fallback value')).toBe('fallback value');
16
+ expect(defaultTo(undefined, 'fallback value')).toBe('fallback value');
17
+ });
18
+ });
19
+
20
+ describe('When value is not nullish', () => {
21
+ it('Should use value', () => {
22
+ expect(defaultTo('value', 'fallback value')).toBe('value');
23
+ });
24
+ });
25
+ });
26
+
27
+ describe('When value is not a function', () => {
28
+ describe('When the value is nullish', () => {
29
+ it('Should return fallback value', () => {
30
+ expect(defaultTo(null, 'fallback value')).toBe('fallback value');
31
+ expect(defaultTo(undefined, 'fallback value')).toBe('fallback value');
32
+ });
33
+ });
34
+ describe('When the value is not nullish', () => {
35
+ it.each([0, false, true, 1, [], {}, NaN])(
36
+ 'Should return the same value',
37
+ value => {
38
+ expect(defaultTo(value, 'fallback value')).toBe(value);
39
+ },
40
+ );
41
+ });
42
+ });
43
+
44
+ describe('When the fallback value is a function', () => {
45
+ it('Should call the function and return its return value', () => {
46
+ const fallbackValue = vi.fn(() => 'fallback value');
47
+
48
+ expect(defaultTo(null, fallbackValue)).toBe('fallback value');
49
+ expect(fallbackValue).toHaveBeenCalled();
50
+ });
51
+ });
52
+ });
@@ -0,0 +1,26 @@
1
+ import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest';
2
+
3
+ import { deferThrow } from '../vest-utils';
4
+ // @ts-ignore
5
+ const _to = global.setTimeout;
6
+ describe('deferThrow', () => {
7
+ beforeEach(() => {
8
+ // @ts-ignore
9
+ global.setTimeout = vi.fn();
10
+ });
11
+
12
+ afterEach(() => {
13
+ global.setTimeout = _to;
14
+ });
15
+ it('Should start a timer', () => {
16
+ deferThrow();
17
+ expect(global.setTimeout).toHaveBeenCalled();
18
+ });
19
+
20
+ it('Should throw a timed out error with the provided message', () => {
21
+ deferThrow('message');
22
+ // @ts-ignore
23
+ const timeoutCB = global.setTimeout.mock.calls[0][0];
24
+ expect(() => timeoutCB()).toThrow('message');
25
+ });
26
+ });
@@ -0,0 +1,17 @@
1
+ import either from '../either';
2
+ import { describe, it, expect } from 'vitest';
3
+
4
+ describe('either', () => {
5
+ it('returns true if one argument is truthy and the other is falsy', () => {
6
+ expect(either(true, false)).toBe(true);
7
+ expect(either(1, 0)).toBe(true);
8
+ expect(either('hello', '')).toBe(true);
9
+ });
10
+
11
+ it('returns false if both arguments are truthy or falsy', () => {
12
+ expect(either(true, true)).toBe(false);
13
+ expect(either(false, false)).toBe(false);
14
+ expect(either(1, 2)).toBe(false);
15
+ expect(either('', null)).toBe(false);
16
+ });
17
+ });
@@ -0,0 +1,24 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { freezeAssign } from '../freezeAssign';
3
+
4
+ describe('freezeAssign', () => {
5
+ it('Should assign properties and freeze the object', () => {
6
+ const target = {};
7
+ const source = { a: 1 };
8
+ const result = freezeAssign(target, source);
9
+
10
+ expect(result).toEqual({ a: 1 });
11
+ expect(Object.isFrozen(result)).toBe(true);
12
+ expect(result).toBe(target); // assign modifies and returns target
13
+ });
14
+
15
+ it('Should handle multiple sources', () => {
16
+ const result = freezeAssign<{ a: number; b: number }>(
17
+ {},
18
+ { a: 1 },
19
+ { b: 2 },
20
+ );
21
+ expect(result).toEqual({ a: 1, b: 2 });
22
+ expect(Object.isFrozen(result)).toBe(true);
23
+ });
24
+ });
@@ -0,0 +1,68 @@
1
+ import { faker } from '@faker-js/faker';
2
+ import { greaterThan } from '../greaterThan';
3
+ import { describe, it, expect, beforeEach } from 'vitest';
4
+
5
+ describe('Tests greaterThan rule', () => {
6
+ describe('Arguments are numbers', () => {
7
+ let arg0: number;
8
+
9
+ beforeEach(() => {
10
+ arg0 = faker.number.int();
11
+ });
12
+
13
+ describe('When first argument is larger', () => {
14
+ it('Should return true', () => {
15
+ expect(greaterThan(arg0, arg0 - 1)).toBe(true);
16
+ });
17
+ });
18
+
19
+ describe('When first argument is smaller', () => {
20
+ it('Should return true', () => {
21
+ expect(greaterThan(arg0, arg0 + 1)).toBe(false);
22
+ });
23
+ });
24
+
25
+ describe('When values are equal', () => {
26
+ it('Should return false', () => {
27
+ expect(greaterThan(arg0, arg0)).toBe(false);
28
+ });
29
+ });
30
+ });
31
+
32
+ describe('Arguments are numeric strings', () => {
33
+ let arg0: string;
34
+
35
+ beforeEach(() => {
36
+ arg0 = faker.number.int().toString();
37
+ });
38
+
39
+ describe('When first argument is larger', () => {
40
+ it('Should return true', () => {
41
+ expect(greaterThan('100', '99')).toBe(true);
42
+ });
43
+ });
44
+
45
+ describe('When first argument is smaller', () => {
46
+ it('Should return true', () => {
47
+ expect(greaterThan(`${arg0}`, `${arg0 + 1}`)).toBe(false);
48
+ });
49
+ });
50
+
51
+ describe('When values are equal', () => {
52
+ it('Should return false', () => {
53
+ expect(greaterThan(arg0, arg0)).toBe(false);
54
+ });
55
+ });
56
+ });
57
+
58
+ describe('Arguments are non numeric', () => {
59
+ [faker.lorem.word(), `${faker.number.int()}`.split(''), {}].forEach(
60
+ element => {
61
+ it('Should return false', () => {
62
+ // @ts-expect-error - testing invalid input
63
+ expect(greaterThan(element, 0)).toBe(false);
64
+ });
65
+ },
66
+ );
67
+ });
68
+ });
@@ -0,0 +1,47 @@
1
+ import { describe, it, expect } from 'vitest';
2
+
3
+ import { invariant } from '../vest-utils';
4
+
5
+ describe('invariant', () => {
6
+ it('should throw an error when condition is false', () => {
7
+ expect(() => {
8
+ invariant(false, 'message');
9
+ }).toThrow(Error);
10
+ });
11
+
12
+ it("Should throw an error with the message if it's a string", () => {
13
+ expect(() => {
14
+ invariant(false, 'message');
15
+ }).toThrow('message');
16
+ });
17
+
18
+ it('should contintue when condition is true', () => {
19
+ expect(() => {
20
+ invariant(true, 'message');
21
+ }).not.toThrow();
22
+ });
23
+
24
+ describe('When passed message is a string object', () => {
25
+ it('should throw the value of the string object', () => {
26
+ expect(() => {
27
+ invariant(false, new String('message'));
28
+ }).toThrow('message');
29
+ });
30
+ });
31
+
32
+ describe('Shen passed message is a function', () => {
33
+ it('should throw the value of the function', () => {
34
+ expect(() => {
35
+ invariant(false, () => 'message');
36
+ }).toThrow('message');
37
+ });
38
+ });
39
+
40
+ describe('When message is falsy', () => {
41
+ it('should throw an error with the message', () => {
42
+ expect(() => {
43
+ invariant(false, '');
44
+ }).toThrow('');
45
+ });
46
+ });
47
+ });
@@ -0,0 +1,16 @@
1
+ import { isArray } from '../isArrayValue';
2
+ import { describe, it, expect } from 'vitest';
3
+
4
+ describe('Tests isArray rule', () => {
5
+ it('Should return true for an empty array', () => {
6
+ expect(isArray([])).toBe(true);
7
+ });
8
+
9
+ it('Should return true for an array with elements', () => {
10
+ expect(isArray([1, 2, 3])).toBe(true);
11
+ });
12
+
13
+ it('Should return false a string', () => {
14
+ expect(isArray('1')).toBe(false);
15
+ });
16
+ });
@@ -0,0 +1,16 @@
1
+ import isBoolean from '../isBooleanValue';
2
+ import { describe, it, expect } from 'vitest';
3
+
4
+ describe('isBoolean', () => {
5
+ it('Should pass for a boolean value', () => {
6
+ expect(isBoolean(true)).toBe(true);
7
+ expect(isBoolean(false)).toBe(true);
8
+ expect(isBoolean(Boolean(1))).toBe(true);
9
+ });
10
+
11
+ it('Should fail for a non boolean value', () => {
12
+ expect(isBoolean('true')).toBe(false);
13
+ expect(isBoolean([false])).toBe(false);
14
+ expect(isBoolean(null)).toBe(false);
15
+ });
16
+ });