@augment-vir/assert 31.71.4 → 31.72.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.
|
@@ -1,12 +1,38 @@
|
|
|
1
|
-
import { type MaybePromise, type NarrowToExpected, type RequiredKeysOf } from '@augment-vir/core';
|
|
1
|
+
import { type AnyObject, type MaybePromise, type NarrowToExpected, type RequiredKeysOf, type SetRequiredAndNotNull } from '@augment-vir/core';
|
|
2
2
|
import { type SetRequired } from 'type-fest';
|
|
3
3
|
import { type WaitUntilOptions } from '../guard-types/wait-until-function.js';
|
|
4
|
-
/**
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Helper type for `hasKey`.
|
|
6
|
+
*
|
|
7
|
+
* @category Assert : Util
|
|
8
|
+
* @category Package : @augment-vir/assert
|
|
9
|
+
* @package [`@augment-vir/assert`](https://www.npmjs.com/package/@augment-vir/assert)
|
|
10
|
+
*/
|
|
11
|
+
export type ExtractValue<Key extends PropertyKey, Parent> = Key extends keyof Parent ? Key extends keyof SetRequired<Parent, Key> ? SetRequired<Parent, Key>[Key] : never : Key extends keyof Extract<Parent, Record<Key, any>> ? Key extends keyof SetRequired<Extract<Parent, Record<Key, any>>, Key> ? SetRequired<Extract<Parent, Record<Key, any>>, Key>[Key] : never : never;
|
|
12
|
+
/**
|
|
13
|
+
* Helper type for `hasKey`.
|
|
14
|
+
*
|
|
15
|
+
* @category Assert : Util
|
|
16
|
+
* @category Package : @augment-vir/assert
|
|
17
|
+
* @package [`@augment-vir/assert`](https://www.npmjs.com/package/@augment-vir/assert)
|
|
18
|
+
*/
|
|
19
|
+
export type CombinedParentValue<Key extends PropertyKey, Parent> = ExtractValue<Key, Parent> extends never ? unknown : ExtractValue<Key, Parent>;
|
|
20
|
+
/**
|
|
21
|
+
* Helper type for `hasKey`.
|
|
22
|
+
*
|
|
23
|
+
* @category Assert : Util
|
|
24
|
+
* @category Package : @augment-vir/assert
|
|
25
|
+
* @package [`@augment-vir/assert`](https://www.npmjs.com/package/@augment-vir/assert)
|
|
26
|
+
*/
|
|
27
|
+
export type CombineTypeWithKey<Key extends PropertyKey, Parent> = Parent & Record<Key, CombinedParentValue<Key, Parent>>;
|
|
28
|
+
/**
|
|
29
|
+
* Helper type for `hasDefinedProperty` and `hasDefinedProperties`.
|
|
30
|
+
*
|
|
31
|
+
* @category Assert : Util
|
|
32
|
+
* @category Package : @augment-vir/assert
|
|
33
|
+
* @package [`@augment-vir/assert`](https://www.npmjs.com/package/@augment-vir/assert)
|
|
34
|
+
*/
|
|
35
|
+
export type WithDefinedProperties<Parent extends AnyObject, Keys extends keyof Parent> = Parent & SetRequiredAndNotNull<Parent, Keys>;
|
|
10
36
|
declare function hasKey<const Key extends PropertyKey, const Parent>(this: void, parent: Parent, key: Key): parent is CombineTypeWithKey<Key, Parent>;
|
|
11
37
|
export declare const keyGuards: {
|
|
12
38
|
assert: {
|
|
@@ -140,6 +166,53 @@ export declare const keyGuards: {
|
|
|
140
166
|
* - {@link assert.lacksKey} : the single-key assertion.
|
|
141
167
|
*/
|
|
142
168
|
lacksKeys<const Parent, const Key extends PropertyKey>(this: void, parent: Parent, keys: ReadonlyArray<Key>, failureMessage?: string | undefined): asserts parent is Exclude<Parent, Partial<Record<Key, any>>>;
|
|
169
|
+
/**
|
|
170
|
+
* Asserts that a parent object has the given property and that its value is defined (not `null`
|
|
171
|
+
* and not `undefined`).
|
|
172
|
+
*
|
|
173
|
+
* Type guards the parent value.
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
*
|
|
177
|
+
* ```ts
|
|
178
|
+
* import {assert} from '@augment-vir/assert';
|
|
179
|
+
*
|
|
180
|
+
* assert.hasDefinedProperty({a: 0, b: 1}, 'a'); // passes
|
|
181
|
+
* assert.hasDefinedProperty({a: undefined, b: 1}, 'a'); // fails
|
|
182
|
+
* assert.hasDefinedProperty({a: 0, b: 1}, 'c'); // fails
|
|
183
|
+
* ```
|
|
184
|
+
*
|
|
185
|
+
* @throws {@link AssertionError} If the property is missing or not defined.
|
|
186
|
+
* @see
|
|
187
|
+
* - {@link assert.hasDefinedProperties} : the multi-property assertion.
|
|
188
|
+
*/
|
|
189
|
+
hasDefinedProperty<const Parent extends AnyObject, const Key extends keyof Parent>(this: void, parent: Parent, key: Key, failureMessage?: string | undefined): asserts parent is WithDefinedProperties<Parent, Key>;
|
|
190
|
+
/**
|
|
191
|
+
* Asserts that a parent object has all the given properties and that each of their values is
|
|
192
|
+
* defined (not `null` and not `undefined`).
|
|
193
|
+
*
|
|
194
|
+
* Type guards the parent value.
|
|
195
|
+
*
|
|
196
|
+
* @example
|
|
197
|
+
*
|
|
198
|
+
* ```ts
|
|
199
|
+
* import {assert} from '@augment-vir/assert';
|
|
200
|
+
*
|
|
201
|
+
* assert.hasDefinedProperties({a: 0, b: 1}, [
|
|
202
|
+
* 'a',
|
|
203
|
+
* 'b',
|
|
204
|
+
* ]); // passes
|
|
205
|
+
* assert.hasDefinedProperties({a: 0, b: undefined}, [
|
|
206
|
+
* 'a',
|
|
207
|
+
* 'b',
|
|
208
|
+
* ]); // fails
|
|
209
|
+
* ```
|
|
210
|
+
*
|
|
211
|
+
* @throws {@link AssertionError} If any of the properties are missing or not defined.
|
|
212
|
+
* @see
|
|
213
|
+
* - {@link assert.hasDefinedProperty} : the single-property assertion.
|
|
214
|
+
*/
|
|
215
|
+
hasDefinedProperties<const Parent extends AnyObject, const Keys extends keyof Parent>(this: void, parent: Parent, keys: ReadonlyArray<Keys>, failureMessage?: string | undefined): asserts parent is WithDefinedProperties<Parent, Keys>;
|
|
143
216
|
};
|
|
144
217
|
check: {
|
|
145
218
|
/**
|
|
@@ -266,6 +339,51 @@ export declare const keyGuards: {
|
|
|
266
339
|
* - {@link check.lacksKey} : the single-key check.
|
|
267
340
|
*/
|
|
268
341
|
lacksKeys<const Parent, const Key extends PropertyKey>(this: void, parent: Parent, keys: ReadonlyArray<Key>): parent is Exclude<Parent, Partial<Record<Key, any>>>;
|
|
342
|
+
/**
|
|
343
|
+
* Checks that a parent object has the given property and that its value is defined (not
|
|
344
|
+
* `null` and not `undefined`).
|
|
345
|
+
*
|
|
346
|
+
* Type guards the parent value.
|
|
347
|
+
*
|
|
348
|
+
* @example
|
|
349
|
+
*
|
|
350
|
+
* ```ts
|
|
351
|
+
* import {check} from '@augment-vir/assert';
|
|
352
|
+
*
|
|
353
|
+
* check.hasDefinedProperty({a: 0, b: 1}, 'a'); // returns `true`
|
|
354
|
+
* check.hasDefinedProperty({a: undefined, b: 1}, 'a'); // returns `false`
|
|
355
|
+
* check.hasDefinedProperty({a: 0, b: 1}, 'c'); // returns `false`
|
|
356
|
+
* ```
|
|
357
|
+
*
|
|
358
|
+
* @see
|
|
359
|
+
* - {@link check.hasDefinedProperties} : the multi-property check.
|
|
360
|
+
*/
|
|
361
|
+
hasDefinedProperty<const Parent extends AnyObject, const Key extends keyof Parent>(this: void, parent: Parent, key: Key): parent is WithDefinedProperties<Parent, Key>;
|
|
362
|
+
/**
|
|
363
|
+
* Checks that a parent object has all the given properties and that each of their values is
|
|
364
|
+
* defined (not `null` and not `undefined`).
|
|
365
|
+
*
|
|
366
|
+
* Type guards the parent value.
|
|
367
|
+
*
|
|
368
|
+
* @example
|
|
369
|
+
*
|
|
370
|
+
* ```ts
|
|
371
|
+
* import {check} from '@augment-vir/assert';
|
|
372
|
+
*
|
|
373
|
+
* check.hasDefinedProperties({a: 0, b: 1}, [
|
|
374
|
+
* 'a',
|
|
375
|
+
* 'b',
|
|
376
|
+
* ]); // returns `true`
|
|
377
|
+
* check.hasDefinedProperties({a: 0, b: undefined}, [
|
|
378
|
+
* 'a',
|
|
379
|
+
* 'b',
|
|
380
|
+
* ]); // returns `false`
|
|
381
|
+
* ```
|
|
382
|
+
*
|
|
383
|
+
* @see
|
|
384
|
+
* - {@link check.hasDefinedProperty} : the single-property check.
|
|
385
|
+
*/
|
|
386
|
+
hasDefinedProperties<const Parent extends AnyObject, const Keys extends keyof Parent>(this: void, parent: Parent, keys: ReadonlyArray<Keys>): parent is WithDefinedProperties<Parent, Keys>;
|
|
269
387
|
};
|
|
270
388
|
assertWrap: {
|
|
271
389
|
/**
|
|
@@ -407,6 +525,54 @@ export declare const keyGuards: {
|
|
|
407
525
|
* - {@link assertWrap.lacksKey} : the single-key assertion.
|
|
408
526
|
*/
|
|
409
527
|
lacksKeys<const Parent, const Key extends PropertyKey>(this: void, parent: Parent, keys: ReadonlyArray<Key>, failureMessage?: string | undefined): Exclude<Parent, Partial<Record<Key, any>>>;
|
|
528
|
+
/**
|
|
529
|
+
* Asserts that a parent object has the given property and that its value is defined (not
|
|
530
|
+
* `null` and not `undefined`). Returns the parent if the assertion passes.
|
|
531
|
+
*
|
|
532
|
+
* Type guards the parent value.
|
|
533
|
+
*
|
|
534
|
+
* @example
|
|
535
|
+
*
|
|
536
|
+
* ```ts
|
|
537
|
+
* import {assertWrap} from '@augment-vir/assert';
|
|
538
|
+
*
|
|
539
|
+
* assertWrap.hasDefinedProperty({a: 0, b: 1}, 'a'); // returns `{a: 0, b: 1}`
|
|
540
|
+
* assertWrap.hasDefinedProperty({a: undefined, b: 1}, 'a'); // throws an error
|
|
541
|
+
* ```
|
|
542
|
+
*
|
|
543
|
+
* @returns The parent if the assertion passes.
|
|
544
|
+
* @throws {@link AssertionError} If the property is missing or not defined.
|
|
545
|
+
* @see
|
|
546
|
+
* - {@link assertWrap.hasDefinedProperties} : the multi-property assertion.
|
|
547
|
+
*/
|
|
548
|
+
hasDefinedProperty<const Parent extends AnyObject, const Key extends keyof Parent>(this: void, parent: Parent, key: Key, failureMessage?: string | undefined): WithDefinedProperties<Parent, Key>;
|
|
549
|
+
/**
|
|
550
|
+
* Asserts that a parent object has all the given properties and that each of their values
|
|
551
|
+
* is defined (not `null` and not `undefined`). Returns the parent if the assertion passes.
|
|
552
|
+
*
|
|
553
|
+
* Type guards the parent value.
|
|
554
|
+
*
|
|
555
|
+
* @example
|
|
556
|
+
*
|
|
557
|
+
* ```ts
|
|
558
|
+
* import {assertWrap} from '@augment-vir/assert';
|
|
559
|
+
*
|
|
560
|
+
* assertWrap.hasDefinedProperties({a: 0, b: 1}, [
|
|
561
|
+
* 'a',
|
|
562
|
+
* 'b',
|
|
563
|
+
* ]); // returns `{a: 0, b: 1}`
|
|
564
|
+
* assertWrap.hasDefinedProperties({a: 0, b: undefined}, [
|
|
565
|
+
* 'a',
|
|
566
|
+
* 'b',
|
|
567
|
+
* ]); // throws an error
|
|
568
|
+
* ```
|
|
569
|
+
*
|
|
570
|
+
* @returns The parent if the assertion passes.
|
|
571
|
+
* @throws {@link AssertionError} If any of the properties are missing or not defined.
|
|
572
|
+
* @see
|
|
573
|
+
* - {@link assertWrap.hasDefinedProperty} : the single-property assertion.
|
|
574
|
+
*/
|
|
575
|
+
hasDefinedProperties<const Parent extends AnyObject, const Keys extends keyof Parent>(this: void, parent: Parent, keys: ReadonlyArray<Keys>, failureMessage?: string | undefined): WithDefinedProperties<Parent, Keys>;
|
|
410
576
|
};
|
|
411
577
|
checkWrap: {
|
|
412
578
|
/**
|
|
@@ -545,6 +711,54 @@ export declare const keyGuards: {
|
|
|
545
711
|
* - {@link checkWrap.lacksKey} : the single-key check.
|
|
546
712
|
*/
|
|
547
713
|
lacksKeys<const Parent, const Key extends PropertyKey>(this: void, parent: Parent, keys: ReadonlyArray<Key>): Exclude<Parent, Partial<Record<Key, any>>> | undefined;
|
|
714
|
+
/**
|
|
715
|
+
* Checks that a parent object has the given property and that its value is defined (not
|
|
716
|
+
* `null` and not `undefined`). Returns the parent value if the check passes, otherwise
|
|
717
|
+
* `undefined`.
|
|
718
|
+
*
|
|
719
|
+
* Type guards the parent value.
|
|
720
|
+
*
|
|
721
|
+
* @example
|
|
722
|
+
*
|
|
723
|
+
* ```ts
|
|
724
|
+
* import {checkWrap} from '@augment-vir/assert';
|
|
725
|
+
*
|
|
726
|
+
* checkWrap.hasDefinedProperty({a: 0, b: 1}, 'a'); // returns `{a: 0, b: 1}`
|
|
727
|
+
* checkWrap.hasDefinedProperty({a: undefined, b: 1}, 'a'); // returns `undefined`
|
|
728
|
+
* ```
|
|
729
|
+
*
|
|
730
|
+
* @returns The parent value if the check passes, otherwise `undefined`.
|
|
731
|
+
* @see
|
|
732
|
+
* - {@link checkWrap.hasDefinedProperties} : the multi-property check.
|
|
733
|
+
*/
|
|
734
|
+
hasDefinedProperty<const Parent extends AnyObject, const Key extends keyof Parent>(this: void, parent: Parent, key: Key): WithDefinedProperties<Parent, Key> | undefined;
|
|
735
|
+
/**
|
|
736
|
+
* Checks that a parent object has all the given properties and that each of their values is
|
|
737
|
+
* defined (not `null` and not `undefined`). Returns the parent value if the check passes,
|
|
738
|
+
* otherwise `undefined`.
|
|
739
|
+
*
|
|
740
|
+
* Type guards the parent value.
|
|
741
|
+
*
|
|
742
|
+
* @example
|
|
743
|
+
*
|
|
744
|
+
* ```ts
|
|
745
|
+
* import {checkWrap} from '@augment-vir/assert';
|
|
746
|
+
*
|
|
747
|
+
* checkWrap.hasDefinedProperties({a: 0, b: 1}, [
|
|
748
|
+
* 'a',
|
|
749
|
+
* 'b',
|
|
750
|
+
* ]); // returns `{a: 0, b: 1}`
|
|
751
|
+
* checkWrap.hasDefinedProperties({a: 0, b: undefined}, [
|
|
752
|
+
* 'a',
|
|
753
|
+
* 'b',
|
|
754
|
+
* ]); // returns `undefined`
|
|
755
|
+
* ```
|
|
756
|
+
*
|
|
757
|
+
* @returns The parent value if the check passes, otherwise `undefined`.
|
|
758
|
+
* @see
|
|
759
|
+
* - {@link checkWrap.hasDefinedProperty} : the single-property check.
|
|
760
|
+
*/
|
|
761
|
+
hasDefinedProperties<const Parent extends AnyObject, const Keys extends keyof Parent>(this: void, parent: Parent, keys: ReadonlyArray<Keys>): WithDefinedProperties<Parent, Keys> | undefined;
|
|
548
762
|
};
|
|
549
763
|
waitUntil: {
|
|
550
764
|
/**
|
|
@@ -723,6 +937,70 @@ export declare const keyGuards: {
|
|
|
723
937
|
* - {@link waitUntil.lacksKey} : the single-key assertion.
|
|
724
938
|
*/
|
|
725
939
|
lacksKeys: <const Parent, const Keys extends PropertyKey>(this: void, keys: ReadonlyArray<Keys>, callback: () => MaybePromise<Parent>, options?: WaitUntilOptions | undefined, failureMessage?: string | undefined) => Promise<Exclude<Parent, Partial<Record<Keys, any>>>>;
|
|
940
|
+
/**
|
|
941
|
+
* Repeatedly calls a callback until its output is a parent object that has the first, key
|
|
942
|
+
* input defined (not `null` and not `undefined`). Once the callback output passes, it is
|
|
943
|
+
* returned. If the attempts time out, an error is thrown.
|
|
944
|
+
*
|
|
945
|
+
* Type guards the parent value.
|
|
946
|
+
*
|
|
947
|
+
* @example
|
|
948
|
+
*
|
|
949
|
+
* ```ts
|
|
950
|
+
* import {waitUntil} from '@augment-vir/assert';
|
|
951
|
+
*
|
|
952
|
+
* await waitUntil.hasDefinedProperty('a', () => {
|
|
953
|
+
* return {a: 0, b: 1};
|
|
954
|
+
* }); // returns `{a: 0, b: 1}`
|
|
955
|
+
* await waitUntil.hasDefinedProperty('a', () => {
|
|
956
|
+
* return {a: undefined, b: 1};
|
|
957
|
+
* }); // throws an error
|
|
958
|
+
* ```
|
|
959
|
+
*
|
|
960
|
+
* @returns The callback output once it passes.
|
|
961
|
+
* @throws {@link AssertionError} On timeout.
|
|
962
|
+
* @see
|
|
963
|
+
* - {@link waitUntil.hasDefinedProperties} : the multi-property assertion.
|
|
964
|
+
*/
|
|
965
|
+
hasDefinedProperty: <const Parent extends AnyObject, const Key extends keyof Parent>(this: void, key: Key, callback: () => MaybePromise<Parent>, options?: WaitUntilOptions | undefined, failureMessage?: string | undefined) => Promise<WithDefinedProperties<Parent, Key>>;
|
|
966
|
+
/**
|
|
967
|
+
* Repeatedly calls a callback until its output is a parent object that has all of the
|
|
968
|
+
* first, keys input defined (not `null` and not `undefined`). Once the callback output
|
|
969
|
+
* passes, it is returned. If the attempts time out, an error is thrown.
|
|
970
|
+
*
|
|
971
|
+
* Type guards the parent value.
|
|
972
|
+
*
|
|
973
|
+
* @example
|
|
974
|
+
*
|
|
975
|
+
* ```ts
|
|
976
|
+
* import {waitUntil} from '@augment-vir/assert';
|
|
977
|
+
*
|
|
978
|
+
* await waitUntil.hasDefinedProperties(
|
|
979
|
+
* [
|
|
980
|
+
* 'a',
|
|
981
|
+
* 'b',
|
|
982
|
+
* ],
|
|
983
|
+
* () => {
|
|
984
|
+
* return {a: 0, b: 1};
|
|
985
|
+
* },
|
|
986
|
+
* ); // returns `{a: 0, b: 1}`
|
|
987
|
+
* await waitUntil.hasDefinedProperties(
|
|
988
|
+
* [
|
|
989
|
+
* 'a',
|
|
990
|
+
* 'b',
|
|
991
|
+
* ],
|
|
992
|
+
* () => {
|
|
993
|
+
* return {a: 0, b: undefined};
|
|
994
|
+
* },
|
|
995
|
+
* ); // throws an error
|
|
996
|
+
* ```
|
|
997
|
+
*
|
|
998
|
+
* @returns The callback output once it passes.
|
|
999
|
+
* @throws {@link AssertionError} On timeout.
|
|
1000
|
+
* @see
|
|
1001
|
+
* - {@link waitUntil.hasDefinedProperty} : the single-property assertion.
|
|
1002
|
+
*/
|
|
1003
|
+
hasDefinedProperties: <const Parent extends AnyObject, const Keys extends keyof Parent>(this: void, keys: ReadonlyArray<Keys>, callback: () => MaybePromise<Parent>, options?: WaitUntilOptions | undefined, failureMessage?: string | undefined) => Promise<WithDefinedProperties<Parent, Keys>>;
|
|
726
1004
|
};
|
|
727
1005
|
};
|
|
728
1006
|
export {};
|
package/dist/assertions/keys.js
CHANGED
|
@@ -177,6 +177,62 @@ const assertions = {
|
|
|
177
177
|
throw new AssertionError(`'${stringify(parent)}' does not lack keys '${existingKeys.join(',')}'.`, failureMessage);
|
|
178
178
|
}
|
|
179
179
|
},
|
|
180
|
+
/**
|
|
181
|
+
* Asserts that a parent object has the given property and that its value is defined (not `null`
|
|
182
|
+
* and not `undefined`).
|
|
183
|
+
*
|
|
184
|
+
* Type guards the parent value.
|
|
185
|
+
*
|
|
186
|
+
* @example
|
|
187
|
+
*
|
|
188
|
+
* ```ts
|
|
189
|
+
* import {assert} from '@augment-vir/assert';
|
|
190
|
+
*
|
|
191
|
+
* assert.hasDefinedProperty({a: 0, b: 1}, 'a'); // passes
|
|
192
|
+
* assert.hasDefinedProperty({a: undefined, b: 1}, 'a'); // fails
|
|
193
|
+
* assert.hasDefinedProperty({a: 0, b: 1}, 'c'); // fails
|
|
194
|
+
* ```
|
|
195
|
+
*
|
|
196
|
+
* @throws {@link AssertionError} If the property is missing or not defined.
|
|
197
|
+
* @see
|
|
198
|
+
* - {@link assert.hasDefinedProperties} : the multi-property assertion.
|
|
199
|
+
*/
|
|
200
|
+
hasDefinedProperty(parent, key, failureMessage) {
|
|
201
|
+
if (parent[key] == undefined) {
|
|
202
|
+
throw new AssertionError(`'${stringify(parent)}' does not have a defined property '${String(key)}'.`, failureMessage);
|
|
203
|
+
}
|
|
204
|
+
},
|
|
205
|
+
/**
|
|
206
|
+
* Asserts that a parent object has all the given properties and that each of their values is
|
|
207
|
+
* defined (not `null` and not `undefined`).
|
|
208
|
+
*
|
|
209
|
+
* Type guards the parent value.
|
|
210
|
+
*
|
|
211
|
+
* @example
|
|
212
|
+
*
|
|
213
|
+
* ```ts
|
|
214
|
+
* import {assert} from '@augment-vir/assert';
|
|
215
|
+
*
|
|
216
|
+
* assert.hasDefinedProperties({a: 0, b: 1}, [
|
|
217
|
+
* 'a',
|
|
218
|
+
* 'b',
|
|
219
|
+
* ]); // passes
|
|
220
|
+
* assert.hasDefinedProperties({a: 0, b: undefined}, [
|
|
221
|
+
* 'a',
|
|
222
|
+
* 'b',
|
|
223
|
+
* ]); // fails
|
|
224
|
+
* ```
|
|
225
|
+
*
|
|
226
|
+
* @throws {@link AssertionError} If any of the properties are missing or not defined.
|
|
227
|
+
* @see
|
|
228
|
+
* - {@link assert.hasDefinedProperty} : the single-property assertion.
|
|
229
|
+
*/
|
|
230
|
+
hasDefinedProperties(parent, keys, failureMessage) {
|
|
231
|
+
const undefinedKeys = keys.filter((key) => parent[key] == undefined);
|
|
232
|
+
if (undefinedKeys.length) {
|
|
233
|
+
throw new AssertionError(`'${stringify(parent)}' does not have defined properties '${undefinedKeys.join(',')}'.`, failureMessage);
|
|
234
|
+
}
|
|
235
|
+
},
|
|
180
236
|
};
|
|
181
237
|
export const keyGuards = {
|
|
182
238
|
assert: assertions,
|
|
@@ -315,6 +371,55 @@ export const keyGuards = {
|
|
|
315
371
|
lacksKeys(parent, keys) {
|
|
316
372
|
return keys.every((key) => !hasKey(parent, key));
|
|
317
373
|
},
|
|
374
|
+
/**
|
|
375
|
+
* Checks that a parent object has the given property and that its value is defined (not
|
|
376
|
+
* `null` and not `undefined`).
|
|
377
|
+
*
|
|
378
|
+
* Type guards the parent value.
|
|
379
|
+
*
|
|
380
|
+
* @example
|
|
381
|
+
*
|
|
382
|
+
* ```ts
|
|
383
|
+
* import {check} from '@augment-vir/assert';
|
|
384
|
+
*
|
|
385
|
+
* check.hasDefinedProperty({a: 0, b: 1}, 'a'); // returns `true`
|
|
386
|
+
* check.hasDefinedProperty({a: undefined, b: 1}, 'a'); // returns `false`
|
|
387
|
+
* check.hasDefinedProperty({a: 0, b: 1}, 'c'); // returns `false`
|
|
388
|
+
* ```
|
|
389
|
+
*
|
|
390
|
+
* @see
|
|
391
|
+
* - {@link check.hasDefinedProperties} : the multi-property check.
|
|
392
|
+
*/
|
|
393
|
+
hasDefinedProperty(parent, key) {
|
|
394
|
+
return parent[key] != undefined;
|
|
395
|
+
},
|
|
396
|
+
/**
|
|
397
|
+
* Checks that a parent object has all the given properties and that each of their values is
|
|
398
|
+
* defined (not `null` and not `undefined`).
|
|
399
|
+
*
|
|
400
|
+
* Type guards the parent value.
|
|
401
|
+
*
|
|
402
|
+
* @example
|
|
403
|
+
*
|
|
404
|
+
* ```ts
|
|
405
|
+
* import {check} from '@augment-vir/assert';
|
|
406
|
+
*
|
|
407
|
+
* check.hasDefinedProperties({a: 0, b: 1}, [
|
|
408
|
+
* 'a',
|
|
409
|
+
* 'b',
|
|
410
|
+
* ]); // returns `true`
|
|
411
|
+
* check.hasDefinedProperties({a: 0, b: undefined}, [
|
|
412
|
+
* 'a',
|
|
413
|
+
* 'b',
|
|
414
|
+
* ]); // returns `false`
|
|
415
|
+
* ```
|
|
416
|
+
*
|
|
417
|
+
* @see
|
|
418
|
+
* - {@link check.hasDefinedProperty} : the single-property check.
|
|
419
|
+
*/
|
|
420
|
+
hasDefinedProperties(parent, keys) {
|
|
421
|
+
return keys.every((key) => parent[key] != undefined);
|
|
422
|
+
},
|
|
318
423
|
},
|
|
319
424
|
assertWrap: {
|
|
320
425
|
/**
|
|
@@ -488,6 +593,65 @@ export const keyGuards = {
|
|
|
488
593
|
}
|
|
489
594
|
return parent;
|
|
490
595
|
},
|
|
596
|
+
/**
|
|
597
|
+
* Asserts that a parent object has the given property and that its value is defined (not
|
|
598
|
+
* `null` and not `undefined`). Returns the parent if the assertion passes.
|
|
599
|
+
*
|
|
600
|
+
* Type guards the parent value.
|
|
601
|
+
*
|
|
602
|
+
* @example
|
|
603
|
+
*
|
|
604
|
+
* ```ts
|
|
605
|
+
* import {assertWrap} from '@augment-vir/assert';
|
|
606
|
+
*
|
|
607
|
+
* assertWrap.hasDefinedProperty({a: 0, b: 1}, 'a'); // returns `{a: 0, b: 1}`
|
|
608
|
+
* assertWrap.hasDefinedProperty({a: undefined, b: 1}, 'a'); // throws an error
|
|
609
|
+
* ```
|
|
610
|
+
*
|
|
611
|
+
* @returns The parent if the assertion passes.
|
|
612
|
+
* @throws {@link AssertionError} If the property is missing or not defined.
|
|
613
|
+
* @see
|
|
614
|
+
* - {@link assertWrap.hasDefinedProperties} : the multi-property assertion.
|
|
615
|
+
*/
|
|
616
|
+
hasDefinedProperty(parent, key, failureMessage) {
|
|
617
|
+
if (parent[key] == undefined) {
|
|
618
|
+
throw new AssertionError(`'${stringify(parent)}' does not have a defined property '${String(key)}'.`, failureMessage);
|
|
619
|
+
}
|
|
620
|
+
return parent;
|
|
621
|
+
},
|
|
622
|
+
/**
|
|
623
|
+
* Asserts that a parent object has all the given properties and that each of their values
|
|
624
|
+
* is defined (not `null` and not `undefined`). Returns the parent if the assertion passes.
|
|
625
|
+
*
|
|
626
|
+
* Type guards the parent value.
|
|
627
|
+
*
|
|
628
|
+
* @example
|
|
629
|
+
*
|
|
630
|
+
* ```ts
|
|
631
|
+
* import {assertWrap} from '@augment-vir/assert';
|
|
632
|
+
*
|
|
633
|
+
* assertWrap.hasDefinedProperties({a: 0, b: 1}, [
|
|
634
|
+
* 'a',
|
|
635
|
+
* 'b',
|
|
636
|
+
* ]); // returns `{a: 0, b: 1}`
|
|
637
|
+
* assertWrap.hasDefinedProperties({a: 0, b: undefined}, [
|
|
638
|
+
* 'a',
|
|
639
|
+
* 'b',
|
|
640
|
+
* ]); // throws an error
|
|
641
|
+
* ```
|
|
642
|
+
*
|
|
643
|
+
* @returns The parent if the assertion passes.
|
|
644
|
+
* @throws {@link AssertionError} If any of the properties are missing or not defined.
|
|
645
|
+
* @see
|
|
646
|
+
* - {@link assertWrap.hasDefinedProperty} : the single-property assertion.
|
|
647
|
+
*/
|
|
648
|
+
hasDefinedProperties(parent, keys, failureMessage) {
|
|
649
|
+
const undefinedKeys = keys.filter((key) => parent[key] == undefined);
|
|
650
|
+
if (undefinedKeys.length) {
|
|
651
|
+
throw new AssertionError(`'${stringify(parent)}' does not have defined properties '${undefinedKeys.join(',')}'.`, failureMessage);
|
|
652
|
+
}
|
|
653
|
+
return parent;
|
|
654
|
+
},
|
|
491
655
|
},
|
|
492
656
|
checkWrap: {
|
|
493
657
|
/**
|
|
@@ -668,6 +832,68 @@ export const keyGuards = {
|
|
|
668
832
|
return undefined;
|
|
669
833
|
}
|
|
670
834
|
},
|
|
835
|
+
/**
|
|
836
|
+
* Checks that a parent object has the given property and that its value is defined (not
|
|
837
|
+
* `null` and not `undefined`). Returns the parent value if the check passes, otherwise
|
|
838
|
+
* `undefined`.
|
|
839
|
+
*
|
|
840
|
+
* Type guards the parent value.
|
|
841
|
+
*
|
|
842
|
+
* @example
|
|
843
|
+
*
|
|
844
|
+
* ```ts
|
|
845
|
+
* import {checkWrap} from '@augment-vir/assert';
|
|
846
|
+
*
|
|
847
|
+
* checkWrap.hasDefinedProperty({a: 0, b: 1}, 'a'); // returns `{a: 0, b: 1}`
|
|
848
|
+
* checkWrap.hasDefinedProperty({a: undefined, b: 1}, 'a'); // returns `undefined`
|
|
849
|
+
* ```
|
|
850
|
+
*
|
|
851
|
+
* @returns The parent value if the check passes, otherwise `undefined`.
|
|
852
|
+
* @see
|
|
853
|
+
* - {@link checkWrap.hasDefinedProperties} : the multi-property check.
|
|
854
|
+
*/
|
|
855
|
+
hasDefinedProperty(parent, key) {
|
|
856
|
+
if (parent[key] == undefined) {
|
|
857
|
+
return undefined;
|
|
858
|
+
}
|
|
859
|
+
else {
|
|
860
|
+
return parent;
|
|
861
|
+
}
|
|
862
|
+
},
|
|
863
|
+
/**
|
|
864
|
+
* Checks that a parent object has all the given properties and that each of their values is
|
|
865
|
+
* defined (not `null` and not `undefined`). Returns the parent value if the check passes,
|
|
866
|
+
* otherwise `undefined`.
|
|
867
|
+
*
|
|
868
|
+
* Type guards the parent value.
|
|
869
|
+
*
|
|
870
|
+
* @example
|
|
871
|
+
*
|
|
872
|
+
* ```ts
|
|
873
|
+
* import {checkWrap} from '@augment-vir/assert';
|
|
874
|
+
*
|
|
875
|
+
* checkWrap.hasDefinedProperties({a: 0, b: 1}, [
|
|
876
|
+
* 'a',
|
|
877
|
+
* 'b',
|
|
878
|
+
* ]); // returns `{a: 0, b: 1}`
|
|
879
|
+
* checkWrap.hasDefinedProperties({a: 0, b: undefined}, [
|
|
880
|
+
* 'a',
|
|
881
|
+
* 'b',
|
|
882
|
+
* ]); // returns `undefined`
|
|
883
|
+
* ```
|
|
884
|
+
*
|
|
885
|
+
* @returns The parent value if the check passes, otherwise `undefined`.
|
|
886
|
+
* @see
|
|
887
|
+
* - {@link checkWrap.hasDefinedProperty} : the single-property check.
|
|
888
|
+
*/
|
|
889
|
+
hasDefinedProperties(parent, keys) {
|
|
890
|
+
if (keys.every((key) => parent[key] != undefined)) {
|
|
891
|
+
return parent;
|
|
892
|
+
}
|
|
893
|
+
else {
|
|
894
|
+
return undefined;
|
|
895
|
+
}
|
|
896
|
+
},
|
|
671
897
|
},
|
|
672
898
|
waitUntil: {
|
|
673
899
|
/**
|
|
@@ -846,5 +1072,69 @@ export const keyGuards = {
|
|
|
846
1072
|
* - {@link waitUntil.lacksKey} : the single-key assertion.
|
|
847
1073
|
*/
|
|
848
1074
|
lacksKeys: createWaitUntil(assertions.lacksKeys),
|
|
1075
|
+
/**
|
|
1076
|
+
* Repeatedly calls a callback until its output is a parent object that has the first, key
|
|
1077
|
+
* input defined (not `null` and not `undefined`). Once the callback output passes, it is
|
|
1078
|
+
* returned. If the attempts time out, an error is thrown.
|
|
1079
|
+
*
|
|
1080
|
+
* Type guards the parent value.
|
|
1081
|
+
*
|
|
1082
|
+
* @example
|
|
1083
|
+
*
|
|
1084
|
+
* ```ts
|
|
1085
|
+
* import {waitUntil} from '@augment-vir/assert';
|
|
1086
|
+
*
|
|
1087
|
+
* await waitUntil.hasDefinedProperty('a', () => {
|
|
1088
|
+
* return {a: 0, b: 1};
|
|
1089
|
+
* }); // returns `{a: 0, b: 1}`
|
|
1090
|
+
* await waitUntil.hasDefinedProperty('a', () => {
|
|
1091
|
+
* return {a: undefined, b: 1};
|
|
1092
|
+
* }); // throws an error
|
|
1093
|
+
* ```
|
|
1094
|
+
*
|
|
1095
|
+
* @returns The callback output once it passes.
|
|
1096
|
+
* @throws {@link AssertionError} On timeout.
|
|
1097
|
+
* @see
|
|
1098
|
+
* - {@link waitUntil.hasDefinedProperties} : the multi-property assertion.
|
|
1099
|
+
*/
|
|
1100
|
+
hasDefinedProperty: createWaitUntil(assertions.hasDefinedProperty),
|
|
1101
|
+
/**
|
|
1102
|
+
* Repeatedly calls a callback until its output is a parent object that has all of the
|
|
1103
|
+
* first, keys input defined (not `null` and not `undefined`). Once the callback output
|
|
1104
|
+
* passes, it is returned. If the attempts time out, an error is thrown.
|
|
1105
|
+
*
|
|
1106
|
+
* Type guards the parent value.
|
|
1107
|
+
*
|
|
1108
|
+
* @example
|
|
1109
|
+
*
|
|
1110
|
+
* ```ts
|
|
1111
|
+
* import {waitUntil} from '@augment-vir/assert';
|
|
1112
|
+
*
|
|
1113
|
+
* await waitUntil.hasDefinedProperties(
|
|
1114
|
+
* [
|
|
1115
|
+
* 'a',
|
|
1116
|
+
* 'b',
|
|
1117
|
+
* ],
|
|
1118
|
+
* () => {
|
|
1119
|
+
* return {a: 0, b: 1};
|
|
1120
|
+
* },
|
|
1121
|
+
* ); // returns `{a: 0, b: 1}`
|
|
1122
|
+
* await waitUntil.hasDefinedProperties(
|
|
1123
|
+
* [
|
|
1124
|
+
* 'a',
|
|
1125
|
+
* 'b',
|
|
1126
|
+
* ],
|
|
1127
|
+
* () => {
|
|
1128
|
+
* return {a: 0, b: undefined};
|
|
1129
|
+
* },
|
|
1130
|
+
* ); // throws an error
|
|
1131
|
+
* ```
|
|
1132
|
+
*
|
|
1133
|
+
* @returns The callback output once it passes.
|
|
1134
|
+
* @throws {@link AssertionError} On timeout.
|
|
1135
|
+
* @see
|
|
1136
|
+
* - {@link waitUntil.hasDefinedProperty} : the single-property assertion.
|
|
1137
|
+
*/
|
|
1138
|
+
hasDefinedProperties: createWaitUntil(assertions.hasDefinedProperties),
|
|
849
1139
|
},
|
|
850
1140
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { stringify } from '@augment-vir/core';
|
|
1
|
+
import { isPrimitive, stringify } from '@augment-vir/core';
|
|
2
2
|
import { AssertionError } from '../augments/assertion.error.js';
|
|
3
3
|
import { createWaitUntil } from '../guard-types/wait-until-function.js';
|
|
4
4
|
const assertions = {
|
|
@@ -77,11 +77,7 @@ const assertions = {
|
|
|
77
77
|
* - {@link assert.isNotPrimitive} : the opposite assertion.
|
|
78
78
|
*/
|
|
79
79
|
isPrimitive(actual, failureMessage) {
|
|
80
|
-
|
|
81
|
-
* `null` is a primitive but `typeof null` gives `'object'` so we have to special case
|
|
82
|
-
* `null` here.
|
|
83
|
-
*/
|
|
84
|
-
if (actual !== null && (typeof actual === 'object' || typeof actual === 'function')) {
|
|
80
|
+
if (!isPrimitive(actual)) {
|
|
85
81
|
throw new AssertionError(`'${stringify(actual)}' is not a Primitive.`, failureMessage);
|
|
86
82
|
}
|
|
87
83
|
},
|
|
@@ -106,11 +102,7 @@ const assertions = {
|
|
|
106
102
|
* - {@link assert.isPrimitive} : the opposite assertion.
|
|
107
103
|
*/
|
|
108
104
|
isNotPrimitive(actual, failureMessage) {
|
|
109
|
-
|
|
110
|
-
* `null` is a primitive but `typeof null` gives `'object'` so we have to special case
|
|
111
|
-
* `null` here.
|
|
112
|
-
*/
|
|
113
|
-
if (actual === null || (typeof actual !== 'object' && typeof actual !== 'function')) {
|
|
105
|
+
if (isPrimitive(actual)) {
|
|
114
106
|
throw new AssertionError(`'${stringify(actual)}' is not a Primitive.`, failureMessage);
|
|
115
107
|
}
|
|
116
108
|
},
|
|
@@ -138,11 +130,7 @@ export const primitiveGuards = {
|
|
|
138
130
|
* - {@link check.isPrimitive} : the opposite check.
|
|
139
131
|
*/
|
|
140
132
|
isNotPrimitive(actual) {
|
|
141
|
-
|
|
142
|
-
* `null` is a primitive but `typeof null` gives `'object'` so we have to special case
|
|
143
|
-
* `null` here.
|
|
144
|
-
*/
|
|
145
|
-
return actual !== null && (typeof actual === 'object' || typeof actual === 'function');
|
|
133
|
+
return !isPrimitive(actual);
|
|
146
134
|
},
|
|
147
135
|
/**
|
|
148
136
|
* Checks that a value is _not_ a valid `PropertyKey`. `PropertyKey` is a built-in
|
|
@@ -188,11 +176,7 @@ export const primitiveGuards = {
|
|
|
188
176
|
* - {@link check.isNotPrimitive} : the opposite check.
|
|
189
177
|
*/
|
|
190
178
|
isPrimitive(actual) {
|
|
191
|
-
|
|
192
|
-
* `null` is a primitive but `typeof null` gives `'object'` so we have to special case
|
|
193
|
-
* `null` here.
|
|
194
|
-
*/
|
|
195
|
-
return actual === null || (typeof actual !== 'object' && typeof actual !== 'function');
|
|
179
|
+
return isPrimitive(actual);
|
|
196
180
|
},
|
|
197
181
|
/**
|
|
198
182
|
* Checks that a value is _not_ a JavaScript
|
|
@@ -243,11 +227,7 @@ export const primitiveGuards = {
|
|
|
243
227
|
* - {@link assertWrap.isNotPropertyKey} : the opposite assertion.
|
|
244
228
|
*/
|
|
245
229
|
isNotPrimitive(actual, failureMessage) {
|
|
246
|
-
|
|
247
|
-
* `null` is a primitive but `typeof null` gives `'object'` so we have to special case
|
|
248
|
-
* `null` here.
|
|
249
|
-
*/
|
|
250
|
-
if (actual === null || (typeof actual !== 'object' && typeof actual !== 'function')) {
|
|
230
|
+
if (isPrimitive(actual)) {
|
|
251
231
|
throw new AssertionError(`'${stringify(actual)}' is not a Primitive.`, failureMessage);
|
|
252
232
|
}
|
|
253
233
|
return actual;
|
|
@@ -305,11 +285,7 @@ export const primitiveGuards = {
|
|
|
305
285
|
* - {@link assertWrap.isNotPrimitive} : the opposite assertion.
|
|
306
286
|
*/
|
|
307
287
|
isPrimitive(actual, failureMessage) {
|
|
308
|
-
|
|
309
|
-
* `null` is a primitive but `typeof null` gives `'object'` so we have to special case
|
|
310
|
-
* `null` here.
|
|
311
|
-
*/
|
|
312
|
-
if (actual !== null && (typeof actual === 'object' || typeof actual === 'function')) {
|
|
288
|
+
if (!isPrimitive(actual)) {
|
|
313
289
|
throw new AssertionError(`'${stringify(actual)}' is not a Primitive.`, failureMessage);
|
|
314
290
|
}
|
|
315
291
|
return actual;
|
|
@@ -368,15 +344,11 @@ export const primitiveGuards = {
|
|
|
368
344
|
* - {@link checkWrap.isPrimitive} : the opposite check.
|
|
369
345
|
*/
|
|
370
346
|
isNotPrimitive(actual) {
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
* `null` here.
|
|
374
|
-
*/
|
|
375
|
-
if (actual !== null && (typeof actual === 'object' || typeof actual === 'function')) {
|
|
376
|
-
return actual;
|
|
347
|
+
if (isPrimitive(actual)) {
|
|
348
|
+
return undefined;
|
|
377
349
|
}
|
|
378
350
|
else {
|
|
379
|
-
return
|
|
351
|
+
return actual;
|
|
380
352
|
}
|
|
381
353
|
},
|
|
382
354
|
/**
|
|
@@ -432,11 +404,7 @@ export const primitiveGuards = {
|
|
|
432
404
|
* - {@link checkWrap.isNotPrimitive} : the opposite check.
|
|
433
405
|
*/
|
|
434
406
|
isPrimitive(actual) {
|
|
435
|
-
|
|
436
|
-
* `null` is a primitive but `typeof null` gives `'object'` so we have to special case
|
|
437
|
-
* `null` here.
|
|
438
|
-
*/
|
|
439
|
-
if (actual === null || (typeof actual !== 'object' && typeof actual !== 'function')) {
|
|
407
|
+
if (isPrimitive(actual)) {
|
|
440
408
|
return actual;
|
|
441
409
|
}
|
|
442
410
|
else {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export type { Falsy, FalsyValue, Truthy } from '../assertions/boolean.js';
|
|
2
|
+
export type { CombineTypeWithKey, CombinedParentValue, ExtractValue, WithDefinedProperties, } from '../assertions/keys.js';
|
|
2
3
|
export type { CustomOutputAsserter } from '../assertions/output.js';
|
|
3
4
|
export type { ErrorMatchOptions } from '../assertions/throws.js';
|
|
4
5
|
export type { CanBeEmpty, Empty } from '../assertions/values.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@augment-vir/assert",
|
|
3
|
-
"version": "31.
|
|
3
|
+
"version": "31.72.0",
|
|
4
4
|
"description": "A collection of assertions for test and production code alike.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"augment",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"test:update": "npm test"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@augment-vir/core": "^31.
|
|
45
|
+
"@augment-vir/core": "^31.72.0",
|
|
46
46
|
"@date-vir/duration": "^8.3.2",
|
|
47
47
|
"deep-eql": "^5.0.2",
|
|
48
48
|
"expect-type": "^1.3.0",
|