@augment-vir/assert 31.0.0 → 31.1.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.
Files changed (63) hide show
  1. package/dist/assertions/boolean.d.ts +20 -26
  2. package/dist/assertions/boolean.js +185 -41
  3. package/dist/assertions/boundary.d.ts +40 -256
  4. package/dist/assertions/boundary.js +265 -229
  5. package/dist/assertions/enum.d.ts +12 -13
  6. package/dist/assertions/enum.js +98 -20
  7. package/dist/assertions/equality/entry-equality.d.ts +11 -15
  8. package/dist/assertions/equality/entry-equality.js +210 -43
  9. package/dist/assertions/equality/json-equality.d.ts +11 -15
  10. package/dist/assertions/equality/json-equality.js +144 -43
  11. package/dist/assertions/equality/simple-equality.d.ts +39 -46
  12. package/dist/assertions/equality/simple-equality.js +316 -61
  13. package/dist/assertions/extendable-assertions.d.ts +0 -12
  14. package/dist/assertions/extendable-assertions.js +0 -12
  15. package/dist/assertions/http.d.ts +10 -14
  16. package/dist/assertions/http.js +96 -28
  17. package/dist/assertions/instance.d.ts +10 -18
  18. package/dist/assertions/instance.js +92 -26
  19. package/dist/assertions/keys.d.ts +59 -138
  20. package/dist/assertions/keys.js +279 -162
  21. package/dist/assertions/length.d.ts +30 -212
  22. package/dist/assertions/length.js +117 -175
  23. package/dist/assertions/nullish.d.ts +8 -20
  24. package/dist/assertions/nullish.js +85 -27
  25. package/dist/assertions/numeric.d.ts +67 -81
  26. package/dist/assertions/numeric.js +564 -133
  27. package/dist/assertions/output.d.ts +2 -3
  28. package/dist/assertions/output.js +1 -7
  29. package/dist/assertions/primitive.d.ts +33 -40
  30. package/dist/assertions/primitive.js +232 -66
  31. package/dist/assertions/promise.d.ts +20 -30
  32. package/dist/assertions/promise.js +244 -53
  33. package/dist/assertions/regexp.d.ts +12 -14
  34. package/dist/assertions/regexp.js +84 -21
  35. package/dist/assertions/runtime-type.d.ts +99 -150
  36. package/dist/assertions/runtime-type.js +805 -229
  37. package/dist/assertions/throws.d.ts +24 -25
  38. package/dist/assertions/throws.js +43 -5
  39. package/dist/assertions/uuid.d.ts +11 -16
  40. package/dist/assertions/uuid.js +91 -22
  41. package/dist/assertions/values.d.ts +81 -210
  42. package/dist/assertions/values.js +627 -234
  43. package/dist/augments/guards/assert-wrap.d.ts +7 -4
  44. package/dist/augments/guards/assert-wrap.js +5 -4
  45. package/dist/augments/guards/check-wrap.d.ts +7 -5
  46. package/dist/augments/guards/check-wrap.js +5 -4
  47. package/dist/augments/guards/check.d.ts +5 -5
  48. package/dist/augments/guards/check.js +5 -4
  49. package/dist/augments/guards/wait-until.d.ts +8 -4
  50. package/dist/augments/guards/wait-until.js +7 -8
  51. package/dist/guard-types/guard-group.d.ts +5 -2
  52. package/dist/guard-types/wait-until-function.d.ts +2 -10
  53. package/dist/guard-types/wait-until-function.js +1 -9
  54. package/dist/index.d.ts +1 -0
  55. package/package.json +2 -2
  56. package/dist/guard-types/assert-wrap-function.d.ts +0 -12
  57. package/dist/guard-types/assert-wrap-function.js +0 -14
  58. package/dist/guard-types/check-function.d.ts +0 -14
  59. package/dist/guard-types/check-function.js +0 -22
  60. package/dist/guard-types/check-wrap-wrapper-function.d.ts +0 -12
  61. package/dist/guard-types/check-wrap-wrapper-function.js +0 -19
  62. package/dist/guard-types/guard-override.d.ts +0 -4
  63. package/dist/guard-types/guard-override.js +0 -10
@@ -1,88 +1,330 @@
1
1
  import { stringify } from '@augment-vir/core';
2
2
  import { AssertionError } from '../augments/assertion.error.js';
3
- import { autoGuard, autoGuardSymbol } from '../guard-types/guard-override.js';
4
- function hasValue(parent, value, failureMessage) {
3
+ import { createWaitUntil } from '../guard-types/wait-until-function.js';
4
+ function hasValue(parent, value) {
5
+ if (typeof parent === 'string') {
6
+ return typeof value === 'string' && parent.includes(value);
7
+ }
5
8
  /** Wrap this in a try/catch because `Reflect.ownKeys` can fail depending on what its input is. */
9
+ let hasValue = true;
6
10
  try {
7
- const hasValue = Reflect.ownKeys(parent)
11
+ hasValue = Reflect.ownKeys(parent)
8
12
  .map((key) => parent[key])
9
13
  .includes(value);
10
- if (!hasValue) {
11
- throw new Error('fail');
12
- }
13
- }
14
- catch {
15
- throw new AssertionError(`'${stringify(parent)}' does not have value '${stringify(value)}'.`, failureMessage);
16
- }
17
- }
18
- function lacksValue(parent, value, failureMessage) {
19
- try {
20
- hasValue(parent, value);
21
14
  }
22
15
  catch {
23
- return;
16
+ return false;
24
17
  }
25
- throw new AssertionError(`'${stringify(parent)}' has value '${stringify(value)}'.`, failureMessage);
18
+ return hasValue;
26
19
  }
27
- function hasValues(parent, values, failureMessage) {
28
- values.forEach((value) => hasValue(parent, value, failureMessage));
29
- }
30
- function lacksValues(parent, values, failureMessage) {
31
- values.forEach((value) => lacksValue(parent, value, failureMessage));
32
- }
33
- export function isIn(child, parent, failureMessage) {
20
+ export function isIn(child, parent) {
34
21
  if (typeof parent === 'string') {
35
- if (!parent.includes(child)) {
36
- throw new AssertionError(`${stringify(child)} is not in '${parent}'.`, failureMessage);
37
- }
22
+ return parent.includes(child);
38
23
  }
39
24
  else {
40
- hasValue(parent, child, failureMessage);
41
- }
42
- }
43
- function isNotIn(child, parent, failureMessage) {
44
- try {
45
- isIn(child, parent);
46
- }
47
- catch {
48
- return;
49
- }
50
- throw new AssertionError(`${stringify(child)} is not in ${stringify(parent)}.`, failureMessage);
51
- }
52
- function isEmpty(actual, failureMessage) {
53
- const input = actual;
54
- if (!input) {
55
- return;
56
- }
57
- else if (typeof input !== 'string' && typeof input !== 'object') {
58
- throw new TypeError(`Cannot check if '${stringify(input)}' is empty.`);
59
- }
60
- else if ((typeof input === 'string' && input) ||
61
- (Array.isArray(input) && input.length) ||
62
- (input instanceof Map && input.size) ||
63
- (input instanceof Set && input.size) ||
64
- (input && typeof input === 'object' && Object.keys(input).length)) {
65
- throw new AssertionError(`'${stringify(actual)}' is not empty.`, failureMessage);
25
+ return hasValue(parent, child);
66
26
  }
67
27
  }
68
- function isNotEmpty(actual, failureMessage) {
69
- try {
70
- isEmpty(actual);
71
- }
72
- catch {
73
- return;
74
- }
75
- throw new AssertionError(`'${stringify(actual)}' is empty.`, failureMessage);
76
- }
77
28
  const assertions = {
78
- hasValue,
79
- lacksValue,
80
- hasValues,
81
- lacksValues,
82
- isIn,
83
- isNotIn,
84
- isEmpty,
85
- isNotEmpty,
29
+ /**
30
+ * Asserts that an object/array parent includes a child value through reference equality.
31
+ *
32
+ * Performs no type guarding.
33
+ *
34
+ * @example
35
+ *
36
+ * ```ts
37
+ * import {assert} from '@augment-vir/assert';
38
+ *
39
+ * const child = {a: 'a'};
40
+ *
41
+ * assert.hasValue({child}, child); // passes
42
+ * assert.hasValue({child: {a: 'a'}}, child); // fails
43
+ * assert.hasValue([child], child); // passes
44
+ * ```
45
+ *
46
+ * @throws {@link AssertionError} If the assertion fails.
47
+ * @see
48
+ * - {@link assert.lacksValue} : the opposite assertion.
49
+ * - {@link assert.hasValues} : the multi-value assertion.
50
+ */
51
+ hasValue(parent, value, failureMessage) {
52
+ if (!hasValue(parent, value)) {
53
+ throw new AssertionError(`'${stringify(parent)}' does not have value '${stringify(value)}'.`, failureMessage);
54
+ }
55
+ },
56
+ /**
57
+ * Asserts that an object/array parent does _not_ include a child value through reference
58
+ * equality.
59
+ *
60
+ * Performs no type guarding.
61
+ *
62
+ * @example
63
+ *
64
+ * ```ts
65
+ * import {assert} from '@augment-vir/assert';
66
+ *
67
+ * const child = {a: 'a'};
68
+ *
69
+ * assert.lacksValue({child}, child); // fails
70
+ * assert.lacksValue({child: {a: 'a'}}, child); // passes
71
+ * assert.lacksValue([child], child); // fails
72
+ * ```
73
+ *
74
+ * @throws {@link AssertionError} If the assertion fails.
75
+ * @see
76
+ * - {@link assert.hasValue} : the opposite assertion.
77
+ * - {@link assert.lacksValues} : the multi-value assertion.
78
+ */
79
+ lacksValue(parent, value, failureMessage) {
80
+ if (hasValue(parent, value)) {
81
+ throw new AssertionError(`'${stringify(parent)}' has value '${stringify(value)}'.`, failureMessage);
82
+ }
83
+ },
84
+ /**
85
+ * Asserts that an object/array parent includes all child values through reference equality.
86
+ *
87
+ * Performs no type guarding.
88
+ *
89
+ * @example
90
+ *
91
+ * ```ts
92
+ * import {assert} from '@augment-vir/assert';
93
+ *
94
+ * const child = {a: 'a'};
95
+ * const child2 = {b: 'b'};
96
+ *
97
+ * assert.hasValues({child, child2}, [child, child2]); // passes
98
+ * assert.hasValues({child: {a: 'a'}, child2}, [child, child2]); // fails
99
+ * assert.hasValues([child], [child, child2]); // passes
100
+ * ```
101
+ *
102
+ * @throws {@link AssertionError} If the assertion fails.
103
+ * @see
104
+ * - {@link assert.lacksValues} : the opposite assertion.
105
+ * - {@link assert.hasValue} : the single-value assertion.
106
+ */
107
+ hasValues(parent, values, failureMessage) {
108
+ let missingValues = [];
109
+ if (typeof parent === 'string') {
110
+ missingValues = values.filter((value) => {
111
+ return !(typeof value === 'string' && parent.includes(value));
112
+ });
113
+ }
114
+ else {
115
+ try {
116
+ const actualValues = Reflect.ownKeys(parent).map((key) => parent[key]);
117
+ missingValues = values.filter((value) => {
118
+ return !actualValues.includes(value);
119
+ });
120
+ }
121
+ catch {
122
+ throw new AssertionError(`'${stringify(parent)}' does not have values '${stringify(values)}'.`, failureMessage);
123
+ }
124
+ }
125
+ if (missingValues.length) {
126
+ throw new AssertionError(`'${stringify(parent)}' does not have values '${stringify(missingValues)}'.`, failureMessage);
127
+ }
128
+ },
129
+ /**
130
+ * Asserts that an object/array parent includes none of the provided child values through
131
+ * reference equality.
132
+ *
133
+ * Performs no type guarding.
134
+ *
135
+ * @example
136
+ *
137
+ * ```ts
138
+ * import {assert} from '@augment-vir/assert';
139
+ *
140
+ * const child = {a: 'a'};
141
+ * const child2 = {b: 'b'};
142
+ *
143
+ * assert.lacksValues({}, [child, child2]); // passes
144
+ * assert.lacksValues({child, child2}, [child, child2]); // fails
145
+ * assert.lacksValues({child: {a: 'a'}, child2}, [child, child2]); // fails
146
+ * ```
147
+ *
148
+ * @throws {@link AssertionError} If the assertion fails.
149
+ * @see
150
+ * - {@link assert.lacksValues} : the opposite assertion.
151
+ * - {@link assert.hasValue} : the single-value assertion.
152
+ */
153
+ lacksValues(parent, values, failureMessage) {
154
+ let includedValues = [];
155
+ if (typeof parent === 'string') {
156
+ includedValues = values.filter((value) => {
157
+ return typeof value === 'string' && parent.includes(value);
158
+ });
159
+ }
160
+ else {
161
+ try {
162
+ const actualValues = Reflect.ownKeys(parent).map((key) => parent[key]);
163
+ includedValues = values.filter((value) => {
164
+ return actualValues.includes(value);
165
+ });
166
+ }
167
+ catch {
168
+ // ignore error
169
+ }
170
+ }
171
+ if (includedValues.length) {
172
+ throw new AssertionError(`'${stringify(parent)}' has values '${stringify(includedValues)}'.`, failureMessage);
173
+ }
174
+ },
175
+ /**
176
+ * Asserts that child value is contained within a parent object, array, or string through
177
+ * reference equality.
178
+ *
179
+ * Type guards the child when possible.
180
+ *
181
+ * @example
182
+ *
183
+ * ```ts
184
+ * import {assert} from '@augment-vir/assert';
185
+ *
186
+ * const child = {a: 'a'};
187
+ *
188
+ * assert.isIn(child, {child}); // passes
189
+ * assert.isIn('a', 'ab'); // passes
190
+ * assert.isIn(child, [child]); // passes
191
+ *
192
+ * assert.isIn(child, {child: {a: 'a'}}); // fails
193
+ * assert.isIn('a', 'bc'); // fails
194
+ * ```
195
+ *
196
+ * @throws {@link AssertionError} If the assertion fails.
197
+ * @see
198
+ * - {@link assert.isNotIn} : the opposite assertion.
199
+ */
200
+ isIn(child, parent, failureMessage) {
201
+ if (!isIn(child, parent)) {
202
+ throw new AssertionError(`'${stringify(child)}'\n\nis not in\n\n${stringify(parent)}.`, failureMessage);
203
+ }
204
+ },
205
+ /**
206
+ * Asserts that child value is _not_ contained within a parent object, array, or string through
207
+ * reference equality.
208
+ *
209
+ * Type guards the child when possible.
210
+ *
211
+ * @example
212
+ *
213
+ * ```ts
214
+ * import {assert} from '@augment-vir/assert';
215
+ *
216
+ * const child = {a: 'a'};
217
+ *
218
+ * assert.isNotIn(child, {child}); // fails
219
+ * assert.isNotIn('a', 'ab'); // fails
220
+ * assert.isNotIn(child, [child]); // fails
221
+ *
222
+ * assert.isNotIn(child, {child: {a: 'a'}}); // passes
223
+ * assert.isNotIn('a', 'bc'); // passes
224
+ * ```
225
+ *
226
+ * @throws {@link AssertionError} If the assertion fails.
227
+ * @see
228
+ * - {@link assert.isIn} : the opposite assertion.
229
+ */
230
+ isNotIn(child, parent, failureMessage) {
231
+ if (isIn(child, parent)) {
232
+ throw new AssertionError(`'${stringify(child)}'\n\nis in\n\n${stringify(parent)}.`, failureMessage);
233
+ }
234
+ },
235
+ /**
236
+ * Asserts that a value is empty. Supports strings, Maps, Sets, objects, and arrays.
237
+ *
238
+ * Type guards the value.
239
+ *
240
+ * @example
241
+ *
242
+ * ```ts
243
+ * import {assert} from '@augment-vir/assert';
244
+ *
245
+ * assert.isEmpty({}); // passes
246
+ * assert.isEmpty(''); // passes
247
+ * assert.isEmpty([]); // passes
248
+ *
249
+ * assert.isEmpty('a'); // fails
250
+ * assert.isEmpty({a: 'a'}); // fails
251
+ * ```
252
+ *
253
+ * @throws {@link AssertionError} If the assertion fails.
254
+ * @see
255
+ * - {@link assert.isNotEmpty} : the opposite assertion.
256
+ */
257
+ isEmpty(actual, failureMessage) {
258
+ if (typeof actual !== 'string' && typeof actual !== 'object') {
259
+ throw new AssertionError(`'${stringify(actual)}' is not empty.`, failureMessage);
260
+ }
261
+ if (typeof actual === 'string' && !actual) {
262
+ // eslint-disable-next-line sonarjs/no-gratuitous-expressions
263
+ if (!actual) {
264
+ return;
265
+ }
266
+ }
267
+ else if (Array.isArray(actual)) {
268
+ if (!actual.length) {
269
+ return;
270
+ }
271
+ }
272
+ else if (actual instanceof Map || actual instanceof Set) {
273
+ if (!actual.size) {
274
+ return;
275
+ }
276
+ }
277
+ else if (typeof actual === 'object' && !Object.keys(actual).length) {
278
+ return;
279
+ }
280
+ throw new AssertionError(`'${stringify(actual)}' is not empty.`, failureMessage);
281
+ },
282
+ /**
283
+ * Asserts that a value is _not_ empty. Supports strings, Maps, Sets, objects, and arrays.
284
+ *
285
+ * Type guards the value.
286
+ *
287
+ * @example
288
+ *
289
+ * ```ts
290
+ * import {assert} from '@augment-vir/assert';
291
+ *
292
+ * assert.isNotEmpty({}); // fails
293
+ * assert.isNotEmpty(''); // fails
294
+ * assert.isNotEmpty([]); // fails
295
+ *
296
+ * assert.isNotEmpty('a'); // passes
297
+ * assert.isNotEmpty({a: 'a'}); // passes
298
+ * ```
299
+ *
300
+ * @throws {@link AssertionError} If the assertion fails.
301
+ * @see
302
+ * - {@link assert.isEmpty} : the opposite assertion.
303
+ */
304
+ isNotEmpty(actual, failureMessage) {
305
+ if (typeof actual !== 'string' && typeof actual !== 'object') {
306
+ return;
307
+ }
308
+ if (typeof actual === 'string' && !actual) {
309
+ // eslint-disable-next-line sonarjs/no-gratuitous-expressions
310
+ if (!actual) {
311
+ throw new AssertionError(`'${stringify(actual)}' is not empty.`, failureMessage);
312
+ }
313
+ }
314
+ else if (Array.isArray(actual)) {
315
+ if (!actual.length) {
316
+ throw new AssertionError(`'${stringify(actual)}' is not empty.`, failureMessage);
317
+ }
318
+ }
319
+ else if (actual instanceof Map || actual instanceof Set) {
320
+ if (!actual.size) {
321
+ throw new AssertionError(`'${stringify(actual)}' is not empty.`, failureMessage);
322
+ }
323
+ }
324
+ else if (typeof actual === 'object' && !Object.keys(actual).length) {
325
+ throw new AssertionError(`'${stringify(actual)}' is not empty.`, failureMessage);
326
+ }
327
+ },
86
328
  };
87
329
  export const valueGuards = {
88
330
  assert: assertions,
@@ -108,7 +350,9 @@ export const valueGuards = {
108
350
  * - {@link check.lacksValue} : the opposite check.
109
351
  * - {@link check.hasValues} : the multi-value check.
110
352
  */
111
- hasValue: autoGuardSymbol,
353
+ hasValue(parent, value) {
354
+ return hasValue(parent, value);
355
+ },
112
356
  /**
113
357
  * Checks that an object/array parent does _not_ include a child value through reference
114
358
  * equality.
@@ -131,7 +375,9 @@ export const valueGuards = {
131
375
  * - {@link check.hasValue} : the opposite check.
132
376
  * - {@link check.lacksValues} : the multi-value check.
133
377
  */
134
- lacksValue: autoGuardSymbol,
378
+ lacksValue(parent, value) {
379
+ return !hasValue(parent, value);
380
+ },
135
381
  /**
136
382
  * Checks that an object/array parent includes all child values through reference equality.
137
383
  *
@@ -145,28 +391,18 @@ export const valueGuards = {
145
391
  * const child = {a: 'a'};
146
392
  * const child2 = {b: 'b'};
147
393
  *
148
- * check.hasValues({child, child2}, [
149
- * child,
150
- * child2,
151
- * ]); // returns `true`
152
- * check.hasValues({child: {a: 'a'}, child2}, [
153
- * child,
154
- * child2,
155
- * ]); // returns `false`
156
- * check.hasValues(
157
- * [child],
158
- * [
159
- * child,
160
- * child2,
161
- * ],
162
- * ); // returns `true`
394
+ * check.hasValues({child, child2}, [child, child2]); // returns `true`
395
+ * check.hasValues({child: {a: 'a'}, child2}, [child, child2]); // returns `false`
396
+ * check.hasValues([child], [child, child2]); // returns `true`
163
397
  * ```
164
398
  *
165
399
  * @see
166
400
  * - {@link check.lacksValues} : the opposite check.
167
401
  * - {@link check.hasValue} : the single-value check.
168
402
  */
169
- hasValues: autoGuardSymbol,
403
+ hasValues(parent, values) {
404
+ return values.every((value) => hasValue(parent, value));
405
+ },
170
406
  /**
171
407
  * Checks that an object/array parent includes none of the provided child values through
172
408
  * reference equality.
@@ -181,25 +417,18 @@ export const valueGuards = {
181
417
  * const child = {a: 'a'};
182
418
  * const child2 = {b: 'b'};
183
419
  *
184
- * check.lacksValues({}, [
185
- * child,
186
- * child2,
187
- * ]); // returns `true`
188
- * check.lacksValues({child, child2}, [
189
- * child,
190
- * child2,
191
- * ]); // returns `false`
192
- * check.lacksValues({child: {a: 'a'}, child2}, [
193
- * child,
194
- * child2,
195
- * ]); // returns `false`
420
+ * check.lacksValues({}, [child, child2]); // returns `true`
421
+ * check.lacksValues({child, child2}, [child, child2]); // returns `false`
422
+ * check.lacksValues({child: {a: 'a'}, child2}, [child, child2]); // returns `false`
196
423
  * ```
197
424
  *
198
425
  * @see
199
426
  * - {@link check.lacksValues} : the opposite check.
200
427
  * - {@link check.hasValue} : the single-value check.
201
428
  */
202
- lacksValues: autoGuardSymbol,
429
+ lacksValues(parent, values) {
430
+ return values.every((value) => !hasValue(parent, value));
431
+ },
203
432
  /**
204
433
  * Checks that child value is contained within a parent object, array, or string through
205
434
  * reference equality.
@@ -224,7 +453,9 @@ export const valueGuards = {
224
453
  * @see
225
454
  * - {@link check.isNotIn} : the opposite check.
226
455
  */
227
- isIn: autoGuard(),
456
+ isIn(child, parent) {
457
+ return isIn(child, parent);
458
+ },
228
459
  /**
229
460
  * Checks that child value is _not_ contained within a parent object, array, or string
230
461
  * through reference equality.
@@ -249,7 +480,9 @@ export const valueGuards = {
249
480
  * @see
250
481
  * - {@link check.isIn} : the opposite check.
251
482
  */
252
- isNotIn: autoGuard(),
483
+ isNotIn(child, parent) {
484
+ return !isIn(child, parent);
485
+ },
253
486
  /**
254
487
  * Checks that a value is empty. Supports strings, Maps, Sets, objects, and arrays.
255
488
  *
@@ -271,7 +504,26 @@ export const valueGuards = {
271
504
  * @see
272
505
  * - {@link check.isNotEmpty} : the opposite check.
273
506
  */
274
- isEmpty: autoGuard(),
507
+ isEmpty(actual) {
508
+ if (typeof actual !== 'string' && typeof actual !== 'object') {
509
+ return false;
510
+ }
511
+ if (typeof actual === 'string') {
512
+ return !actual;
513
+ }
514
+ else if (Array.isArray(actual)) {
515
+ return !actual.length;
516
+ }
517
+ else if (actual instanceof Map) {
518
+ return !actual.size;
519
+ }
520
+ else if (actual instanceof Set) {
521
+ return !actual.size;
522
+ }
523
+ else {
524
+ return !Object.keys(actual).length;
525
+ }
526
+ },
275
527
  /**
276
528
  * Checks that a value is _not_ empty. Supports strings, Maps, Sets, objects, and arrays.
277
529
  *
@@ -293,7 +545,26 @@ export const valueGuards = {
293
545
  * @see
294
546
  * - {@link check.isEmpty} : the opposite check.
295
547
  */
296
- isNotEmpty: autoGuard(),
548
+ isNotEmpty(actual) {
549
+ if (typeof actual !== 'string' && typeof actual !== 'object') {
550
+ return true;
551
+ }
552
+ if (typeof actual === 'string') {
553
+ return !!actual;
554
+ }
555
+ else if (Array.isArray(actual)) {
556
+ return !!actual.length;
557
+ }
558
+ else if (actual instanceof Map) {
559
+ return !!actual.size;
560
+ }
561
+ else if (actual instanceof Set) {
562
+ return !!actual.size;
563
+ }
564
+ else {
565
+ return !!Object.keys(actual).length;
566
+ }
567
+ },
297
568
  },
298
569
  assertWrap: {
299
570
  /**
@@ -320,7 +591,12 @@ export const valueGuards = {
320
591
  * - {@link assertWrap.lacksValue} : the opposite assertion.
321
592
  * - {@link assertWrap.hasValues} : the multi-value assertion.
322
593
  */
323
- hasValue: autoGuardSymbol,
594
+ hasValue(parent, value, failureMessage) {
595
+ if (!hasValue(parent, value)) {
596
+ throw new AssertionError(`'${stringify(parent)}' does not have value '${stringify(value)}'.`, failureMessage);
597
+ }
598
+ return parent;
599
+ },
324
600
  /**
325
601
  * Asserts that an object/array parent does _not_ include a child value through reference
326
602
  * equality. Returns the parent value if the assertion passes.
@@ -345,7 +621,12 @@ export const valueGuards = {
345
621
  * - {@link assertWrap.hasValue} : the opposite assertion.
346
622
  * - {@link assertWrap.lacksValues} : the multi-value assertion.
347
623
  */
348
- lacksValue: autoGuardSymbol,
624
+ lacksValue(parent, value, failureMessage) {
625
+ if (hasValue(parent, value)) {
626
+ throw new AssertionError(`'${stringify(parent)}' has value '${stringify(value)}'.`, failureMessage);
627
+ }
628
+ return parent;
629
+ },
349
630
  /**
350
631
  * Asserts that an object/array parent includes all child values through reference equality.
351
632
  * Returns the parent value if the assertion passes.
@@ -360,21 +641,9 @@ export const valueGuards = {
360
641
  * const child = {a: 'a'};
361
642
  * const child2 = {b: 'b'};
362
643
  *
363
- * assertWrap.hasValues({child, child2}, [
364
- * child,
365
- * child2,
366
- * ]); // returns `{child, child2}`;
367
- * assertWrap.hasValues({child: {a: 'a'}, child2}, [
368
- * child,
369
- * child2,
370
- * ]); // throws an error
371
- * assertWrap.hasValues(
372
- * [child],
373
- * [
374
- * child,
375
- * child2,
376
- * ],
377
- * ); // returns `[child]`;
644
+ * assertWrap.hasValues({child, child2}, [child, child2]); // returns `{child, child2}`;
645
+ * assertWrap.hasValues({child: {a: 'a'}, child2}, [child, child2]); // throws an error
646
+ * assertWrap.hasValues([child], [child, child2]); // returns `[child]`;
378
647
  * ```
379
648
  *
380
649
  * @returns The value if the assertion passes.
@@ -383,7 +652,29 @@ export const valueGuards = {
383
652
  * - {@link assertWrap.lacksValues} : the opposite assertion.
384
653
  * - {@link assertWrap.hasValue} : the single-value assertion.
385
654
  */
386
- hasValues: autoGuardSymbol,
655
+ hasValues(parent, values, failureMessage) {
656
+ let missingValues = [];
657
+ if (typeof parent === 'string') {
658
+ missingValues = values.filter((value) => {
659
+ return !(typeof value === 'string' && parent.includes(value));
660
+ });
661
+ }
662
+ else {
663
+ try {
664
+ const actualValues = Reflect.ownKeys(parent).map((key) => parent[key]);
665
+ missingValues = values.filter((value) => {
666
+ return !actualValues.includes(value);
667
+ });
668
+ }
669
+ catch {
670
+ throw new AssertionError(`'${stringify(parent)}' does not have values '${stringify(values)}'.`, failureMessage);
671
+ }
672
+ }
673
+ if (missingValues.length) {
674
+ throw new AssertionError(`'${stringify(parent)}' does not have values '${stringify(missingValues)}'.`, failureMessage);
675
+ }
676
+ return parent;
677
+ },
387
678
  /**
388
679
  * Asserts that an object/array parent includes none of the provided child values through
389
680
  * reference equality. Returns the parent value if the assertion passes.
@@ -398,18 +689,9 @@ export const valueGuards = {
398
689
  * const child = {a: 'a'};
399
690
  * const child2 = {b: 'b'};
400
691
  *
401
- * assertWrap.lacksValues({}, [
402
- * child,
403
- * child2,
404
- * ]); // returns `{}`;
405
- * assertWrap.lacksValues({child, child2}, [
406
- * child,
407
- * child2,
408
- * ]); // throws an error
409
- * assertWrap.lacksValues({child: {a: 'a'}, child2}, [
410
- * child,
411
- * child2,
412
- * ]); // throws an error
692
+ * assertWrap.lacksValues({}, [child, child2]); // returns `{}`;
693
+ * assertWrap.lacksValues({child, child2}, [child, child2]); // throws an error
694
+ * assertWrap.lacksValues({child: {a: 'a'}, child2}, [child, child2]); // throws an error
413
695
  * ```
414
696
  *
415
697
  * @returns The value if the assertion passes.
@@ -418,7 +700,29 @@ export const valueGuards = {
418
700
  * - {@link assertWrap.lacksValues} : the opposite assertion.
419
701
  * - {@link assertWrap.hasValue} : the single-value assertion.
420
702
  */
421
- lacksValues: autoGuardSymbol,
703
+ lacksValues(parent, values, failureMessage) {
704
+ let includedValues = [];
705
+ if (typeof parent === 'string') {
706
+ includedValues = values.filter((value) => {
707
+ return typeof value === 'string' && parent.includes(value);
708
+ });
709
+ }
710
+ else {
711
+ try {
712
+ const actualValues = Reflect.ownKeys(parent).map((key) => parent[key]);
713
+ includedValues = values.filter((value) => {
714
+ return actualValues.includes(value);
715
+ });
716
+ }
717
+ catch {
718
+ // ignore error
719
+ }
720
+ }
721
+ if (includedValues.length) {
722
+ throw new AssertionError(`'${stringify(parent)}' has values '${stringify(includedValues)}'.`, failureMessage);
723
+ }
724
+ return parent;
725
+ },
422
726
  /**
423
727
  * Asserts that child value is contained within a parent object, array, or string through
424
728
  * reference equality. Returns the child value if the assertion passes.
@@ -445,7 +749,12 @@ export const valueGuards = {
445
749
  * @see
446
750
  * - {@link assertWrap.isNotIn} : the opposite assertion.
447
751
  */
448
- isIn: autoGuard(),
752
+ isIn(child, parent, failureMessage) {
753
+ if (!isIn(child, parent)) {
754
+ throw new AssertionError(`'${stringify(child)}'\n\nis not in\n\n${stringify(parent)}.`, failureMessage);
755
+ }
756
+ return child;
757
+ },
449
758
  /**
450
759
  * Asserts that child value is _not_ contained within a parent object, array, or string
451
760
  * through reference equality. Returns the child value if the assertion passes.
@@ -472,7 +781,12 @@ export const valueGuards = {
472
781
  * @see
473
782
  * - {@link assertWrap.isIn} : the opposite assertion.
474
783
  */
475
- isNotIn: autoGuard(),
784
+ isNotIn(child, parent, failureMessage) {
785
+ if (isIn(child, parent)) {
786
+ throw new AssertionError(`'${stringify(child)}'\n\nis in\n\n${stringify(parent)}.`, failureMessage);
787
+ }
788
+ return child;
789
+ },
476
790
  /**
477
791
  * Asserts that a value is empty. Supports strings, Maps, Sets, objects, and arrays. Returns
478
792
  * the value if the assertion passes.
@@ -497,7 +811,31 @@ export const valueGuards = {
497
811
  * @see
498
812
  * - {@link assertWrap.isNotEmpty} : the opposite assertion.
499
813
  */
500
- isEmpty: autoGuard(),
814
+ isEmpty(actual, failureMessage) {
815
+ if (typeof actual !== 'string' && typeof actual !== 'object') {
816
+ throw new AssertionError(`'${stringify(actual)}' is not empty.`, failureMessage);
817
+ }
818
+ if (typeof actual === 'string' && !actual) {
819
+ // eslint-disable-next-line sonarjs/no-gratuitous-expressions
820
+ if (!actual) {
821
+ return actual;
822
+ }
823
+ }
824
+ else if (Array.isArray(actual)) {
825
+ if (!actual.length) {
826
+ return actual;
827
+ }
828
+ }
829
+ else if (actual instanceof Map || actual instanceof Set) {
830
+ if (!actual.size) {
831
+ return actual;
832
+ }
833
+ }
834
+ else if (typeof actual === 'object' && !Object.keys(actual).length) {
835
+ return actual;
836
+ }
837
+ throw new AssertionError(`'${stringify(actual)}' is not empty.`, failureMessage);
838
+ },
501
839
  /**
502
840
  * Asserts that a value is _not_ empty. Supports strings, Maps, Sets, objects, and arrays.
503
841
  * Returns the value if the assertion passes.
@@ -522,7 +860,31 @@ export const valueGuards = {
522
860
  * @see
523
861
  * - {@link assertWrap.isEmpty} : the opposite assertion.
524
862
  */
525
- isNotEmpty: autoGuard(),
863
+ isNotEmpty(actual, failureMessage) {
864
+ if (typeof actual !== 'string' && typeof actual !== 'object') {
865
+ return actual;
866
+ }
867
+ if (typeof actual === 'string' && !actual) {
868
+ // eslint-disable-next-line sonarjs/no-gratuitous-expressions
869
+ if (!actual) {
870
+ throw new AssertionError(`'${stringify(actual)}' is empty.`, failureMessage);
871
+ }
872
+ }
873
+ else if (Array.isArray(actual)) {
874
+ if (!actual.length) {
875
+ throw new AssertionError(`'${stringify(actual)}' is empty.`, failureMessage);
876
+ }
877
+ }
878
+ else if (actual instanceof Map || actual instanceof Set) {
879
+ if (!actual.size) {
880
+ throw new AssertionError(`'${stringify(actual)}' is empty.`, failureMessage);
881
+ }
882
+ }
883
+ else if (typeof actual === 'object' && !Object.keys(actual).length) {
884
+ throw new AssertionError(`'${stringify(actual)}' is empty.`, failureMessage);
885
+ }
886
+ return actual;
887
+ },
526
888
  },
527
889
  checkWrap: {
528
890
  /**
@@ -546,7 +908,14 @@ export const valueGuards = {
546
908
  * - {@link checkWrap.lacksValue} : the opposite check.
547
909
  * - {@link checkWrap.hasValues} : the multi-value check.
548
910
  */
549
- hasValue: autoGuardSymbol,
911
+ hasValue(parent, value) {
912
+ if (hasValue(parent, value)) {
913
+ return parent;
914
+ }
915
+ else {
916
+ return undefined;
917
+ }
918
+ },
550
919
  /**
551
920
  * Checks that an object/array parent does _not_ include a child value through reference
552
921
  * equality.
@@ -569,7 +938,14 @@ export const valueGuards = {
569
938
  * - {@link checkWrap.hasValue} : the opposite check.
570
939
  * - {@link checkWrap.lacksValues} : the multi-value check.
571
940
  */
572
- lacksValue: autoGuardSymbol,
941
+ lacksValue(parent, value) {
942
+ if (hasValue(parent, value)) {
943
+ return undefined;
944
+ }
945
+ else {
946
+ return parent;
947
+ }
948
+ },
573
949
  /**
574
950
  * Checks that an object/array parent includes all child values through reference equality.
575
951
  *
@@ -583,28 +959,23 @@ export const valueGuards = {
583
959
  * const child = {a: 'a'};
584
960
  * const child2 = {b: 'b'};
585
961
  *
586
- * checkWrap.hasValues({child, child2}, [
587
- * child,
588
- * child2,
589
- * ]); // returns `{child, child2}`
590
- * checkWrap.hasValues({child: {a: 'a'}, child2}, [
591
- * child,
592
- * child2,
593
- * ]); // returns `undefined`
594
- * checkWrap.hasValues(
595
- * [child],
596
- * [
597
- * child,
598
- * child2,
599
- * ],
600
- * ); // returns `[child]`
962
+ * checkWrap.hasValues({child, child2}, [child, child2]); // returns `{child, child2}`
963
+ * checkWrap.hasValues({child: {a: 'a'}, child2}, [child, child2]); // returns `undefined`
964
+ * checkWrap.hasValues([child], [child, child2]); // returns `[child]`
601
965
  * ```
602
966
  *
603
967
  * @see
604
968
  * - {@link checkWrap.lacksValues} : the opposite check.
605
969
  * - {@link checkWrap.hasValue} : the single-value check.
606
970
  */
607
- hasValues: autoGuardSymbol,
971
+ hasValues(parent, values) {
972
+ if (values.every((value) => hasValue(parent, value))) {
973
+ return parent;
974
+ }
975
+ else {
976
+ return undefined;
977
+ }
978
+ },
608
979
  /**
609
980
  * Checks that an object/array parent includes none of the provided child values through
610
981
  * reference equality.
@@ -619,25 +990,23 @@ export const valueGuards = {
619
990
  * const child = {a: 'a'};
620
991
  * const child2 = {b: 'b'};
621
992
  *
622
- * checkWrap.lacksValues({}, [
623
- * child,
624
- * child2,
625
- * ]); // returns `{}`
626
- * checkWrap.lacksValues({child, child2}, [
627
- * child,
628
- * child2,
629
- * ]); // returns `undefined`
630
- * checkWrap.lacksValues({child: {a: 'a'}, child2}, [
631
- * child,
632
- * child2,
633
- * ]); // returns `undefined`
993
+ * checkWrap.lacksValues({}, [child, child2]); // returns `{}`
994
+ * checkWrap.lacksValues({child, child2}, [child, child2]); // returns `undefined`
995
+ * checkWrap.lacksValues({child: {a: 'a'}, child2}, [child, child2]); // returns `undefined`
634
996
  * ```
635
997
  *
636
998
  * @see
637
999
  * - {@link checkWrap.lacksValues} : the opposite check.
638
1000
  * - {@link checkWrap.hasValue} : the single-value check.
639
1001
  */
640
- lacksValues: autoGuardSymbol,
1002
+ lacksValues(parent, values) {
1003
+ if (values.every((value) => hasValue(parent, value))) {
1004
+ return undefined;
1005
+ }
1006
+ else {
1007
+ return parent;
1008
+ }
1009
+ },
641
1010
  /**
642
1011
  * Checks that child value is contained within a parent object, array, or string through
643
1012
  * reference equality.
@@ -662,7 +1031,14 @@ export const valueGuards = {
662
1031
  * @see
663
1032
  * - {@link checkWrap.isNotIn} : the opposite check.
664
1033
  */
665
- isIn: autoGuard(),
1034
+ isIn(child, parent) {
1035
+ if (isIn(child, parent)) {
1036
+ return child;
1037
+ }
1038
+ else {
1039
+ return undefined;
1040
+ }
1041
+ },
666
1042
  /**
667
1043
  * Checks that child value is _not_ contained within a parent object, array, or string
668
1044
  * through reference equality.
@@ -687,7 +1063,14 @@ export const valueGuards = {
687
1063
  * @see
688
1064
  * - {@link checkWrap.isIn} : the opposite check.
689
1065
  */
690
- isNotIn: autoGuard(),
1066
+ isNotIn(child, parent) {
1067
+ if (isIn(child, parent)) {
1068
+ return undefined;
1069
+ }
1070
+ else {
1071
+ return child;
1072
+ }
1073
+ },
691
1074
  /**
692
1075
  * Checks that a value is empty. Supports strings, Maps, Sets, objects, and arrays.
693
1076
  *
@@ -709,7 +1092,30 @@ export const valueGuards = {
709
1092
  * @see
710
1093
  * - {@link checkWrap.isNotEmpty} : the opposite check.
711
1094
  */
712
- isEmpty: autoGuard(),
1095
+ isEmpty(actual) {
1096
+ if (typeof actual !== 'string' && typeof actual !== 'object') {
1097
+ return undefined;
1098
+ }
1099
+ if (typeof actual === 'string') {
1100
+ if (!actual) {
1101
+ return actual;
1102
+ }
1103
+ }
1104
+ else if (Array.isArray(actual)) {
1105
+ if (!actual.length) {
1106
+ return actual;
1107
+ }
1108
+ }
1109
+ else if (actual instanceof Map || actual instanceof Set) {
1110
+ if (!actual.size) {
1111
+ return actual;
1112
+ }
1113
+ }
1114
+ else if (typeof actual === 'object' && !Object.keys(actual).length) {
1115
+ return actual;
1116
+ }
1117
+ return undefined;
1118
+ },
713
1119
  /**
714
1120
  * Checks that a value is _not_ empty. Supports strings, Maps, Sets, objects, and arrays.
715
1121
  *
@@ -731,7 +1137,30 @@ export const valueGuards = {
731
1137
  * @see
732
1138
  * - {@link checkWrap.isEmpty} : the opposite check.
733
1139
  */
734
- isNotEmpty: autoGuard(),
1140
+ isNotEmpty(actual) {
1141
+ if (typeof actual !== 'string' && typeof actual !== 'object') {
1142
+ return actual;
1143
+ }
1144
+ if (typeof actual === 'string') {
1145
+ if (!actual) {
1146
+ return undefined;
1147
+ }
1148
+ }
1149
+ else if (Array.isArray(actual)) {
1150
+ if (!actual.length) {
1151
+ return undefined;
1152
+ }
1153
+ }
1154
+ else if (actual instanceof Map || actual instanceof Set) {
1155
+ if (!actual.size) {
1156
+ return undefined;
1157
+ }
1158
+ }
1159
+ else if (typeof actual === 'object' && !Object.keys(actual).length) {
1160
+ return undefined;
1161
+ }
1162
+ return actual;
1163
+ },
735
1164
  },
736
1165
  waitUntil: {
737
1166
  /**
@@ -763,7 +1192,7 @@ export const valueGuards = {
763
1192
  * - {@link waitUntil.lacksValue} : the opposite assertion.
764
1193
  * - {@link waitUntil.hasValues} : the multi-value assertion.
765
1194
  */
766
- hasValue: autoGuardSymbol,
1195
+ hasValue: createWaitUntil(assertions.hasValue),
767
1196
  /**
768
1197
  * Repeatedly calls a callback until its output is an object/array parent does _not_ include
769
1198
  * a child value through reference equality. Once the callback output passes, it is
@@ -793,7 +1222,7 @@ export const valueGuards = {
793
1222
  * - {@link waitUntil.hasValue} : the opposite assertion.
794
1223
  * - {@link waitUntil.lacksValues} : the multi-value assertion.
795
1224
  */
796
- lacksValue: autoGuardSymbol,
1225
+ lacksValue: createWaitUntil(assertions.lacksValue),
797
1226
  /**
798
1227
  * Repeatedly calls a callback until its output is an object/array parent includes all child
799
1228
  * values through reference equality. Once the callback output passes, it is returned. If
@@ -809,31 +1238,13 @@ export const valueGuards = {
809
1238
  * const child = {a: 'a'};
810
1239
  * const child2 = {b: 'b'};
811
1240
  *
812
- * await waitUntil.hasValues(
813
- * [
814
- * child,
815
- * child2,
816
- * ],
817
- * () => {
818
- * return {child, child2};
819
- * },
820
- * ); // returns `{child, child2}`;
821
- * await waitUntil.hasValues(
822
- * [
823
- * child,
824
- * child2,
825
- * ],
826
- * () => {
827
- * return {child: {a: 'a'}, child2};
828
- * },
829
- * ); // throws an error
830
- * await waitUntil.hasValues(
831
- * [
832
- * child,
833
- * child2,
834
- * ],
835
- * () => [child],
836
- * ); // returns `[child]`;
1241
+ * await waitUntil.hasValues([child, child2], () => {
1242
+ * return {child, child2};
1243
+ * }); // returns `{child, child2}`;
1244
+ * await waitUntil.hasValues([child, child2], () => {
1245
+ * return {child: {a: 'a'}, child2};
1246
+ * }); // throws an error
1247
+ * await waitUntil.hasValues([child, child2], () => [child]); // returns `[child]`;
837
1248
  * ```
838
1249
  *
839
1250
  * @returns The callback output once it passes.
@@ -842,7 +1253,7 @@ export const valueGuards = {
842
1253
  * - {@link waitUntil.lacksValues} : the opposite assertion.
843
1254
  * - {@link waitUntil.hasValue} : the single-value assertion.
844
1255
  */
845
- hasValues: autoGuardSymbol,
1256
+ hasValues: createWaitUntil(assertions.hasValues),
846
1257
  /**
847
1258
  * Repeatedly calls a callback until its output is an object/array parent includes none of
848
1259
  * the provided child values through reference equality. Once the callback output passes, it
@@ -858,33 +1269,15 @@ export const valueGuards = {
858
1269
  * const child = {a: 'a'};
859
1270
  * const child2 = {b: 'b'};
860
1271
  *
861
- * await waitUntil.lacksValues(
862
- * [
863
- * child,
864
- * child2,
865
- * ],
866
- * () => {
867
- * return {};
868
- * },
869
- * ); // returns `{}`;
870
- * await waitUntil.lacksValues(
871
- * [
872
- * child,
873
- * child2,
874
- * ],
875
- * () => {
876
- * return {child, child2};
877
- * },
878
- * ); // throws an error
879
- * await waitUntil.lacksValues(
880
- * [
881
- * child,
882
- * child2,
883
- * ],
884
- * () => {
885
- * return {child: {a: 'a'}, child2};
886
- * },
887
- * ); // throws an error
1272
+ * await waitUntil.lacksValues([child, child2], () => {
1273
+ * return {};
1274
+ * }); // returns `{}`;
1275
+ * await waitUntil.lacksValues([child, child2], () => {
1276
+ * return {child, child2};
1277
+ * }); // throws an error
1278
+ * await waitUntil.lacksValues([child, child2], () => {
1279
+ * return {child: {a: 'a'}, child2};
1280
+ * }); // throws an error
888
1281
  * ```
889
1282
  *
890
1283
  * @returns The callback output once it passes.
@@ -893,7 +1286,7 @@ export const valueGuards = {
893
1286
  * - {@link waitUntil.lacksValues} : the opposite assertion.
894
1287
  * - {@link waitUntil.hasValue} : the single-value assertion.
895
1288
  */
896
- lacksValues: autoGuardSymbol,
1289
+ lacksValues: createWaitUntil(assertions.lacksValues),
897
1290
  /**
898
1291
  * Repeatedly calls a callback until its output is child value is contained within a parent
899
1292
  * object, array, or string through reference equality. Once the callback output passes, it
@@ -921,7 +1314,7 @@ export const valueGuards = {
921
1314
  * @see
922
1315
  * - {@link waitUntil.isNotIn} : the opposite assertion.
923
1316
  */
924
- isIn: autoGuard(),
1317
+ isIn: createWaitUntil(assertions.isIn),
925
1318
  /**
926
1319
  * Repeatedly calls a callback until its output is child value is _not_ contained within a
927
1320
  * parent object, array, or string through reference equality. Once the callback output
@@ -949,7 +1342,7 @@ export const valueGuards = {
949
1342
  * @see
950
1343
  * - {@link waitUntil.isIn} : the opposite assertion.
951
1344
  */
952
- isNotIn: autoGuard(),
1345
+ isNotIn: createWaitUntil(assertions.isNotIn),
953
1346
  /**
954
1347
  * Repeatedly calls a callback until its output is a value is empty. Supports strings, Maps,
955
1348
  * Sets, objects, and arrays. Once the callback output passes, it is returned. If the
@@ -979,7 +1372,7 @@ export const valueGuards = {
979
1372
  * @see
980
1373
  * - {@link waitUntil.isNotEmpty} : the opposite assertion.
981
1374
  */
982
- isEmpty: autoGuard(),
1375
+ isEmpty: createWaitUntil(assertions.isEmpty),
983
1376
  /**
984
1377
  * Repeatedly calls a callback until its output is a value is _not_ empty. Supports strings,
985
1378
  * Maps, Sets, objects, and arrays. Once the callback output passes, it is returned. If the
@@ -1009,6 +1402,6 @@ export const valueGuards = {
1009
1402
  * @see
1010
1403
  * - {@link waitUntil.isEmpty} : the opposite assertion.
1011
1404
  */
1012
- isNotEmpty: autoGuard(),
1405
+ isNotEmpty: createWaitUntil(assertions.isNotEmpty),
1013
1406
  },
1014
1407
  };