bupkis 0.7.2 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/README.md +19 -2
- package/dist/commonjs/assertion/assertion-async.d.ts.map +1 -1
- package/dist/commonjs/assertion/assertion-async.js +37 -7
- package/dist/commonjs/assertion/assertion-async.js.map +1 -1
- package/dist/commonjs/assertion/assertion-sync.d.ts.map +1 -1
- package/dist/commonjs/assertion/assertion-sync.js +32 -8
- package/dist/commonjs/assertion/assertion-sync.js.map +1 -1
- package/dist/commonjs/assertion/assertion-types.d.ts +37 -31
- package/dist/commonjs/assertion/assertion-types.d.ts.map +1 -1
- package/dist/commonjs/assertion/assertion-types.js +0 -32
- package/dist/commonjs/assertion/assertion-types.js.map +1 -1
- package/dist/commonjs/assertion/assertion.d.ts +3 -21
- package/dist/commonjs/assertion/assertion.d.ts.map +1 -1
- package/dist/commonjs/assertion/assertion.js +42 -27
- package/dist/commonjs/assertion/assertion.js.map +1 -1
- package/dist/commonjs/assertion/create.d.ts +2 -0
- package/dist/commonjs/assertion/create.d.ts.map +1 -1
- package/dist/commonjs/assertion/create.js +38 -42
- package/dist/commonjs/assertion/create.js.map +1 -1
- package/dist/commonjs/assertion/impl/assertion-util.d.ts +16 -4
- package/dist/commonjs/assertion/impl/assertion-util.d.ts.map +1 -1
- package/dist/commonjs/assertion/impl/assertion-util.js +20 -15
- package/dist/commonjs/assertion/impl/assertion-util.js.map +1 -1
- package/dist/commonjs/assertion/impl/async-parametric.d.ts +63 -11
- package/dist/commonjs/assertion/impl/async-parametric.d.ts.map +1 -1
- package/dist/commonjs/assertion/impl/async-parametric.js +89 -52
- package/dist/commonjs/assertion/impl/async-parametric.js.map +1 -1
- package/dist/commonjs/assertion/impl/async.d.ts +116 -12
- package/dist/commonjs/assertion/impl/async.d.ts.map +1 -1
- package/dist/commonjs/assertion/impl/async.js +1 -1
- package/dist/commonjs/assertion/impl/sync-basic.d.ts.map +1 -1
- package/dist/commonjs/assertion/impl/sync-basic.js +6 -4
- package/dist/commonjs/assertion/impl/sync-basic.js.map +1 -1
- package/dist/commonjs/assertion/impl/sync-collection.d.ts.map +1 -1
- package/dist/commonjs/assertion/impl/sync-collection.js +24 -14
- package/dist/commonjs/assertion/impl/sync-collection.js.map +1 -1
- package/dist/commonjs/assertion/impl/sync-esoteric.d.ts +1 -5
- package/dist/commonjs/assertion/impl/sync-esoteric.d.ts.map +1 -1
- package/dist/commonjs/assertion/impl/sync-esoteric.js +11 -13
- package/dist/commonjs/assertion/impl/sync-esoteric.js.map +1 -1
- package/dist/commonjs/assertion/impl/sync-parametric.d.ts +27 -7
- package/dist/commonjs/assertion/impl/sync-parametric.d.ts.map +1 -1
- package/dist/commonjs/assertion/impl/sync-parametric.js +75 -51
- package/dist/commonjs/assertion/impl/sync-parametric.js.map +1 -1
- package/dist/commonjs/assertion/impl/sync.d.ts +54 -22
- package/dist/commonjs/assertion/impl/sync.d.ts.map +1 -1
- package/dist/commonjs/assertion/impl/sync.js +1 -1
- package/dist/commonjs/assertion/impl/sync.js.map +1 -1
- package/dist/commonjs/assertion/index.d.ts +1 -1
- package/dist/commonjs/assertion/index.d.ts.map +1 -1
- package/dist/commonjs/assertion/index.js +0 -1
- package/dist/commonjs/assertion/index.js.map +1 -1
- package/dist/commonjs/assertion/slotify.d.ts +1 -13
- package/dist/commonjs/assertion/slotify.d.ts.map +1 -1
- package/dist/commonjs/assertion/slotify.js +49 -16
- package/dist/commonjs/assertion/slotify.js.map +1 -1
- package/dist/commonjs/bootstrap.d.ts +85 -17
- package/dist/commonjs/bootstrap.d.ts.map +1 -1
- package/dist/commonjs/bootstrap.js +1 -0
- package/dist/commonjs/bootstrap.js.map +1 -1
- package/dist/commonjs/diff.d.ts +51 -0
- package/dist/commonjs/diff.d.ts.map +1 -0
- package/dist/commonjs/diff.js +279 -0
- package/dist/commonjs/diff.js.map +1 -0
- package/dist/commonjs/error.d.ts +37 -18
- package/dist/commonjs/error.d.ts.map +1 -1
- package/dist/commonjs/error.js +44 -30
- package/dist/commonjs/error.js.map +1 -1
- package/dist/commonjs/expect.d.ts.map +1 -1
- package/dist/commonjs/expect.js +131 -78
- package/dist/commonjs/expect.js.map +1 -1
- package/dist/commonjs/guards.d.ts +24 -10
- package/dist/commonjs/guards.d.ts.map +1 -1
- package/dist/commonjs/guards.js +56 -39
- package/dist/commonjs/guards.js.map +1 -1
- package/dist/commonjs/index.d.ts +85 -17
- package/dist/commonjs/index.d.ts.map +1 -1
- package/dist/commonjs/internal-schema.d.ts +25 -0
- package/dist/commonjs/internal-schema.d.ts.map +1 -0
- package/dist/commonjs/internal-schema.js +209 -0
- package/dist/commonjs/internal-schema.js.map +1 -0
- package/dist/commonjs/schema.d.ts.map +1 -1
- package/dist/commonjs/schema.js +3 -2
- package/dist/commonjs/schema.js.map +1 -1
- package/dist/commonjs/use.js +22 -8
- package/dist/commonjs/use.js.map +1 -1
- package/dist/commonjs/util.d.ts +1 -0
- package/dist/commonjs/util.d.ts.map +1 -1
- package/dist/commonjs/util.js +14 -10
- package/dist/commonjs/util.js.map +1 -1
- package/dist/commonjs/value-to-schema.d.ts +1 -0
- package/dist/commonjs/value-to-schema.d.ts.map +1 -1
- package/dist/commonjs/value-to-schema.js +19 -12
- package/dist/commonjs/value-to-schema.js.map +1 -1
- package/dist/esm/assertion/assertion-async.d.ts.map +1 -1
- package/dist/esm/assertion/assertion-async.js +37 -7
- package/dist/esm/assertion/assertion-async.js.map +1 -1
- package/dist/esm/assertion/assertion-sync.d.ts.map +1 -1
- package/dist/esm/assertion/assertion-sync.js +32 -8
- package/dist/esm/assertion/assertion-sync.js.map +1 -1
- package/dist/esm/assertion/assertion-types.d.ts +37 -31
- package/dist/esm/assertion/assertion-types.d.ts.map +1 -1
- package/dist/esm/assertion/assertion-types.js +1 -31
- package/dist/esm/assertion/assertion-types.js.map +1 -1
- package/dist/esm/assertion/assertion.d.ts +3 -21
- package/dist/esm/assertion/assertion.d.ts.map +1 -1
- package/dist/esm/assertion/assertion.js +42 -27
- package/dist/esm/assertion/assertion.js.map +1 -1
- package/dist/esm/assertion/create.d.ts +2 -0
- package/dist/esm/assertion/create.d.ts.map +1 -1
- package/dist/esm/assertion/create.js +37 -41
- package/dist/esm/assertion/create.js.map +1 -1
- package/dist/esm/assertion/impl/assertion-util.d.ts +16 -4
- package/dist/esm/assertion/impl/assertion-util.d.ts.map +1 -1
- package/dist/esm/assertion/impl/assertion-util.js +20 -15
- package/dist/esm/assertion/impl/assertion-util.js.map +1 -1
- package/dist/esm/assertion/impl/async-parametric.d.ts +63 -11
- package/dist/esm/assertion/impl/async-parametric.d.ts.map +1 -1
- package/dist/esm/assertion/impl/async-parametric.js +89 -52
- package/dist/esm/assertion/impl/async-parametric.js.map +1 -1
- package/dist/esm/assertion/impl/async.d.ts +116 -12
- package/dist/esm/assertion/impl/async.d.ts.map +1 -1
- package/dist/esm/assertion/impl/async.js +2 -2
- package/dist/esm/assertion/impl/async.js.map +1 -1
- package/dist/esm/assertion/impl/sync-basic.d.ts.map +1 -1
- package/dist/esm/assertion/impl/sync-basic.js +6 -4
- package/dist/esm/assertion/impl/sync-basic.js.map +1 -1
- package/dist/esm/assertion/impl/sync-collection.d.ts.map +1 -1
- package/dist/esm/assertion/impl/sync-collection.js +24 -14
- package/dist/esm/assertion/impl/sync-collection.js.map +1 -1
- package/dist/esm/assertion/impl/sync-esoteric.d.ts +1 -5
- package/dist/esm/assertion/impl/sync-esoteric.d.ts.map +1 -1
- package/dist/esm/assertion/impl/sync-esoteric.js +11 -13
- package/dist/esm/assertion/impl/sync-esoteric.js.map +1 -1
- package/dist/esm/assertion/impl/sync-parametric.d.ts +27 -7
- package/dist/esm/assertion/impl/sync-parametric.d.ts.map +1 -1
- package/dist/esm/assertion/impl/sync-parametric.js +75 -51
- package/dist/esm/assertion/impl/sync-parametric.js.map +1 -1
- package/dist/esm/assertion/impl/sync.d.ts +54 -22
- package/dist/esm/assertion/impl/sync.d.ts.map +1 -1
- package/dist/esm/assertion/impl/sync.js +2 -2
- package/dist/esm/assertion/impl/sync.js.map +1 -1
- package/dist/esm/assertion/index.d.ts +1 -1
- package/dist/esm/assertion/index.d.ts.map +1 -1
- package/dist/esm/assertion/index.js +0 -1
- package/dist/esm/assertion/index.js.map +1 -1
- package/dist/esm/assertion/slotify.d.ts +1 -13
- package/dist/esm/assertion/slotify.d.ts.map +1 -1
- package/dist/esm/assertion/slotify.js +50 -17
- package/dist/esm/assertion/slotify.js.map +1 -1
- package/dist/esm/bootstrap.d.ts +85 -17
- package/dist/esm/bootstrap.d.ts.map +1 -1
- package/dist/esm/bootstrap.js +1 -0
- package/dist/esm/bootstrap.js.map +1 -1
- package/dist/esm/diff.d.ts +51 -0
- package/dist/esm/diff.d.ts.map +1 -0
- package/dist/esm/diff.js +273 -0
- package/dist/esm/diff.js.map +1 -0
- package/dist/esm/error.d.ts +37 -18
- package/dist/esm/error.d.ts.map +1 -1
- package/dist/esm/error.js +41 -27
- package/dist/esm/error.js.map +1 -1
- package/dist/esm/expect.d.ts.map +1 -1
- package/dist/esm/expect.js +133 -80
- package/dist/esm/expect.js.map +1 -1
- package/dist/esm/guards.d.ts +24 -10
- package/dist/esm/guards.d.ts.map +1 -1
- package/dist/esm/guards.js +52 -36
- package/dist/esm/guards.js.map +1 -1
- package/dist/esm/index.d.ts +85 -17
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/internal-schema.d.ts +25 -0
- package/dist/esm/internal-schema.d.ts.map +1 -0
- package/dist/esm/internal-schema.js +203 -0
- package/dist/esm/internal-schema.js.map +1 -0
- package/dist/esm/schema.d.ts.map +1 -1
- package/dist/esm/schema.js +3 -2
- package/dist/esm/schema.js.map +1 -1
- package/dist/esm/use.js +19 -6
- package/dist/esm/use.js.map +1 -1
- package/dist/esm/util.d.ts +1 -0
- package/dist/esm/util.d.ts.map +1 -1
- package/dist/esm/util.js +14 -10
- package/dist/esm/util.js.map +1 -1
- package/dist/esm/value-to-schema.d.ts +1 -0
- package/dist/esm/value-to-schema.d.ts.map +1 -1
- package/dist/esm/value-to-schema.js +20 -13
- package/dist/esm/value-to-schema.js.map +1 -1
- package/package.json +29 -11
- package/src/assertion/assertion-async.ts +42 -14
- package/src/assertion/assertion-sync.ts +40 -17
- package/src/assertion/assertion-types.ts +55 -45
- package/src/assertion/assertion.ts +49 -32
- package/src/assertion/create.ts +46 -65
- package/src/assertion/impl/assertion-util.ts +31 -18
- package/src/assertion/impl/async-parametric.ts +93 -52
- package/src/assertion/impl/async.ts +2 -2
- package/src/assertion/impl/sync-basic.ts +7 -4
- package/src/assertion/impl/sync-collection.ts +34 -14
- package/src/assertion/impl/sync-esoteric.ts +17 -13
- package/src/assertion/impl/sync-parametric.ts +79 -52
- package/src/assertion/impl/sync.ts +2 -2
- package/src/assertion/index.ts +1 -1
- package/src/assertion/slotify.ts +67 -21
- package/src/bootstrap.ts +1 -0
- package/src/diff.ts +343 -0
- package/src/error.ts +66 -31
- package/src/expect.ts +195 -129
- package/src/guards.ts +74 -48
- package/src/internal-schema.ts +246 -0
- package/src/schema.ts +4 -2
- package/src/use.ts +21 -7
- package/src/util.ts +15 -12
- package/src/value-to-schema.ts +21 -13
|
@@ -5,33 +5,47 @@
|
|
|
5
5
|
* @packageDocumentation
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
type TrapResult =
|
|
9
|
+
| { error: unknown; result?: never }
|
|
10
|
+
| { error?: never; result: unknown };
|
|
11
|
+
|
|
8
12
|
/**
|
|
9
13
|
* Executes & traps a `Promise` rejected from an async function, capturing the
|
|
10
14
|
* error.
|
|
11
15
|
*
|
|
16
|
+
* @function
|
|
12
17
|
* @param fn The function to execute that may throw an error or return a
|
|
13
18
|
* `Promise`
|
|
14
|
-
* @returns Rejection
|
|
19
|
+
* @returns Rejection or whatever was fulfilled
|
|
15
20
|
*/
|
|
16
|
-
export const trapAsyncFnError = async (
|
|
21
|
+
export const trapAsyncFnError = async (
|
|
22
|
+
fn: () => unknown,
|
|
23
|
+
): Promise<TrapResult> => {
|
|
17
24
|
try {
|
|
18
|
-
await fn();
|
|
19
|
-
|
|
20
|
-
|
|
25
|
+
const result = await fn();
|
|
26
|
+
return { result };
|
|
27
|
+
} catch (error) {
|
|
28
|
+
return {
|
|
29
|
+
error: error ?? new TypeError(`Function rejected with undefined: ${fn}`),
|
|
30
|
+
};
|
|
21
31
|
}
|
|
22
32
|
};
|
|
23
33
|
|
|
24
34
|
/**
|
|
25
35
|
* Awaits & traps a Promise, capturing any rejection error.
|
|
26
36
|
*
|
|
37
|
+
* @function
|
|
27
38
|
* @param promise The `Promise` to trap
|
|
28
|
-
* @returns
|
|
39
|
+
* @returns Result object
|
|
29
40
|
*/
|
|
30
|
-
export const trapPromiseError = async (
|
|
41
|
+
export const trapPromiseError = async (
|
|
42
|
+
promise: PromiseLike<unknown>,
|
|
43
|
+
): Promise<TrapResult> => {
|
|
31
44
|
try {
|
|
32
|
-
await promise;
|
|
33
|
-
|
|
34
|
-
|
|
45
|
+
const result = await promise;
|
|
46
|
+
return { result };
|
|
47
|
+
} catch (error) {
|
|
48
|
+
return { error: error ?? new TypeError('Promise rejected with undefined') };
|
|
35
49
|
}
|
|
36
50
|
};
|
|
37
51
|
|
|
@@ -41,16 +55,15 @@ export const trapPromiseError = async (promise: PromiseLike<unknown>) => {
|
|
|
41
55
|
*
|
|
42
56
|
* @remarks
|
|
43
57
|
* Avoids throwing `undefined` for some reason.
|
|
58
|
+
* @function
|
|
44
59
|
* @param fn Function to execute
|
|
45
|
-
* @returns
|
|
60
|
+
* @returns Result object
|
|
46
61
|
*/
|
|
47
|
-
export const trapError = (fn: () => unknown):
|
|
62
|
+
export const trapError = (fn: () => unknown): TrapResult => {
|
|
48
63
|
try {
|
|
49
|
-
fn();
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
return err;
|
|
64
|
+
const result = fn();
|
|
65
|
+
return { result };
|
|
66
|
+
} catch (error) {
|
|
67
|
+
return { error: error ?? new TypeError(`Function threw undefined: ${fn}`) };
|
|
55
68
|
}
|
|
56
69
|
};
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
import { inspect } from 'node:util';
|
|
17
17
|
import { z } from 'zod/v4';
|
|
18
18
|
|
|
19
|
-
import {
|
|
19
|
+
import { InvalidObjectSchemaError } from '../../error.js';
|
|
20
20
|
import { isA, isNonNullObject, isString } from '../../guards.js';
|
|
21
21
|
import {
|
|
22
22
|
ConstructibleSchema,
|
|
@@ -56,7 +56,7 @@ export const functionResolveAssertion = createAsyncAssertion(
|
|
|
56
56
|
}
|
|
57
57
|
},
|
|
58
58
|
{
|
|
59
|
-
anchor: 'to-resolve',
|
|
59
|
+
anchor: 'promise-to-resolve',
|
|
60
60
|
category: 'promise',
|
|
61
61
|
},
|
|
62
62
|
);
|
|
@@ -86,6 +86,10 @@ export const promiseResolveAssertion = createAsyncAssertion(
|
|
|
86
86
|
};
|
|
87
87
|
}
|
|
88
88
|
},
|
|
89
|
+
{
|
|
90
|
+
anchor: 'promise-to-resolve',
|
|
91
|
+
category: 'promise',
|
|
92
|
+
},
|
|
89
93
|
);
|
|
90
94
|
|
|
91
95
|
/**
|
|
@@ -103,14 +107,14 @@ export const promiseResolveAssertion = createAsyncAssertion(
|
|
|
103
107
|
export const functionRejectAssertion = createAsyncAssertion(
|
|
104
108
|
[FunctionSchema, 'to reject'],
|
|
105
109
|
async (subject) => {
|
|
106
|
-
|
|
107
|
-
|
|
110
|
+
const { error, result } = await trapAsyncFnError(subject);
|
|
111
|
+
if (error === undefined) {
|
|
108
112
|
return {
|
|
109
113
|
actual: 'function fulfilled',
|
|
110
|
-
expected: 'function
|
|
111
|
-
message:
|
|
114
|
+
expected: 'function rejected',
|
|
115
|
+
message: `Expected function to reject, but it fulfilled with ${inspect(result)}`,
|
|
112
116
|
};
|
|
113
|
-
}
|
|
117
|
+
}
|
|
114
118
|
},
|
|
115
119
|
);
|
|
116
120
|
|
|
@@ -129,14 +133,14 @@ export const functionRejectAssertion = createAsyncAssertion(
|
|
|
129
133
|
export const promiseRejectAssertion = createAsyncAssertion(
|
|
130
134
|
[WrappedPromiseLikeSchema, 'to reject'],
|
|
131
135
|
async (subject) => {
|
|
132
|
-
|
|
133
|
-
|
|
136
|
+
const { error, result } = await trapPromiseError(subject);
|
|
137
|
+
if (error === undefined) {
|
|
134
138
|
return {
|
|
135
|
-
actual: '
|
|
136
|
-
expected: '
|
|
137
|
-
message:
|
|
139
|
+
actual: 'Promise fulfilled',
|
|
140
|
+
expected: 'Promise rejected',
|
|
141
|
+
message: `Expected Promise to reject, but it fulfilled with ${inspect(result)}`,
|
|
138
142
|
};
|
|
139
|
-
}
|
|
143
|
+
}
|
|
140
144
|
},
|
|
141
145
|
);
|
|
142
146
|
|
|
@@ -167,11 +171,29 @@ export const functionRejectWithTypeAssertion = createAsyncAssertion(
|
|
|
167
171
|
ConstructibleSchema,
|
|
168
172
|
],
|
|
169
173
|
async (subject, ctor) => {
|
|
170
|
-
const error = await trapAsyncFnError(subject);
|
|
171
|
-
if (
|
|
172
|
-
return
|
|
174
|
+
const { error, result } = await trapAsyncFnError(subject);
|
|
175
|
+
if (error === undefined) {
|
|
176
|
+
return {
|
|
177
|
+
actual: 'function fulfilled',
|
|
178
|
+
expect: 'function rejected',
|
|
179
|
+
message: `Expected function to reject, but it fulfilled with ${inspect(result)}`,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
if (!isA(error, ctor)) {
|
|
183
|
+
if (isNonNullObject(error)) {
|
|
184
|
+
const err = error as object;
|
|
185
|
+
return {
|
|
186
|
+
actual: err.constructor.name,
|
|
187
|
+
expected: ctor.name,
|
|
188
|
+
message: `Expected function to reject with an instance of ${ctor.name}, but it rejected with a ${err.constructor.name}`,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
actual: typeof error,
|
|
193
|
+
expected: ctor.name,
|
|
194
|
+
message: `Expected function to reject with an instance of ${ctor.name}, but it rejected with a value of type ${typeof error}: ${inspect(error)}`,
|
|
195
|
+
};
|
|
173
196
|
}
|
|
174
|
-
return isA(error, ctor);
|
|
175
197
|
},
|
|
176
198
|
);
|
|
177
199
|
|
|
@@ -202,11 +224,29 @@ export const promiseRejectWithTypeAssertion = createAsyncAssertion(
|
|
|
202
224
|
ConstructibleSchema,
|
|
203
225
|
],
|
|
204
226
|
async (subject, ctor) => {
|
|
205
|
-
const error = await trapPromiseError(subject);
|
|
206
|
-
if (
|
|
207
|
-
return
|
|
227
|
+
const { error, result } = await trapPromiseError(subject);
|
|
228
|
+
if (error === undefined) {
|
|
229
|
+
return {
|
|
230
|
+
actual: 'Promise fulfilled',
|
|
231
|
+
expect: 'Promise rejected',
|
|
232
|
+
message: `Expected Promise to reject, but it fulfilled with ${inspect(result)}`,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
if (!isA(error, ctor)) {
|
|
236
|
+
if (isNonNullObject(error)) {
|
|
237
|
+
const err = error as object;
|
|
238
|
+
return {
|
|
239
|
+
actual: err.constructor.name,
|
|
240
|
+
expected: ctor.name,
|
|
241
|
+
message: `Expected Promise to reject with an instance of ${ctor.name}, but it rejected with a ${err.constructor.name}`,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
return {
|
|
245
|
+
actual: typeof error,
|
|
246
|
+
expected: ctor.name,
|
|
247
|
+
message: `Expected Promise to reject with an instance of ${ctor.name}, but it rejected with a value of type ${typeof error}: ${inspect(error)}`,
|
|
248
|
+
};
|
|
208
249
|
}
|
|
209
|
-
return isA(error, ctor);
|
|
210
250
|
},
|
|
211
251
|
);
|
|
212
252
|
|
|
@@ -239,12 +279,12 @@ export const promiseRejectWithTypeAssertion = createAsyncAssertion(
|
|
|
239
279
|
export const functionRejectWithErrorSatisfyingAssertion = createAsyncAssertion(
|
|
240
280
|
[FunctionSchema, ['to reject with error satisfying'], z.any()],
|
|
241
281
|
async (subject, param) => {
|
|
242
|
-
const error = await trapAsyncFnError(subject);
|
|
243
|
-
if (
|
|
282
|
+
const { error, result } = await trapAsyncFnError(subject);
|
|
283
|
+
if (error === undefined) {
|
|
244
284
|
return {
|
|
245
285
|
actual: 'function fulfilled',
|
|
246
286
|
expect: 'function to reject',
|
|
247
|
-
message:
|
|
287
|
+
message: `Expected function to reject, but it fulfilled with ${inspect(result)}`,
|
|
248
288
|
};
|
|
249
289
|
}
|
|
250
290
|
|
|
@@ -267,16 +307,16 @@ export const functionRejectWithErrorSatisfyingAssertion = createAsyncAssertion(
|
|
|
267
307
|
}
|
|
268
308
|
/* c8 ignore next 5 */
|
|
269
309
|
if (!schema) {
|
|
270
|
-
throw new
|
|
310
|
+
throw new InvalidObjectSchemaError(
|
|
271
311
|
`Invalid parameter schema: ${inspect(param, { depth: 2 })}`,
|
|
272
312
|
{ schema: param },
|
|
273
313
|
);
|
|
274
314
|
}
|
|
275
315
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
}
|
|
316
|
+
return {
|
|
317
|
+
schema,
|
|
318
|
+
subject: error,
|
|
319
|
+
};
|
|
280
320
|
},
|
|
281
321
|
);
|
|
282
322
|
|
|
@@ -309,12 +349,12 @@ export const functionRejectWithErrorSatisfyingAssertion = createAsyncAssertion(
|
|
|
309
349
|
export const promiseRejectWithErrorSatisfyingAssertion = createAsyncAssertion(
|
|
310
350
|
[WrappedPromiseLikeSchema, ['to reject with error satisfying'], z.any()],
|
|
311
351
|
async (subject, param) => {
|
|
312
|
-
const error = await trapPromiseError(subject);
|
|
313
|
-
if (
|
|
352
|
+
const { error, result } = await trapPromiseError(subject);
|
|
353
|
+
if (error === undefined) {
|
|
314
354
|
return {
|
|
315
|
-
actual: '
|
|
316
|
-
expect: '
|
|
317
|
-
message:
|
|
355
|
+
actual: 'Promise fulfilled',
|
|
356
|
+
expect: 'Promise rejected',
|
|
357
|
+
message: `Expected Promise to reject, but it fulfilled with ${inspect(result)}`,
|
|
318
358
|
};
|
|
319
359
|
}
|
|
320
360
|
let schema: undefined | z.ZodType;
|
|
@@ -336,16 +376,16 @@ export const promiseRejectWithErrorSatisfyingAssertion = createAsyncAssertion(
|
|
|
336
376
|
}
|
|
337
377
|
/* c8 ignore next 5 */
|
|
338
378
|
if (!schema) {
|
|
339
|
-
throw new
|
|
379
|
+
throw new InvalidObjectSchemaError(
|
|
340
380
|
`Invalid parameter schema: ${inspect(param, { depth: 2 })}`,
|
|
341
381
|
{ schema: param },
|
|
342
382
|
);
|
|
343
383
|
}
|
|
344
384
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
}
|
|
385
|
+
return {
|
|
386
|
+
schema,
|
|
387
|
+
subject: error,
|
|
388
|
+
};
|
|
349
389
|
},
|
|
350
390
|
);
|
|
351
391
|
|
|
@@ -375,7 +415,7 @@ export const promiseRejectWithErrorSatisfyingAssertion = createAsyncAssertion(
|
|
|
375
415
|
*
|
|
376
416
|
* @group Parametric Assertions (Async)
|
|
377
417
|
*/
|
|
378
|
-
export const
|
|
418
|
+
export const promiseResolveWithValueSatisfyingAssertion = createAsyncAssertion(
|
|
379
419
|
[
|
|
380
420
|
WrappedPromiseLikeSchema,
|
|
381
421
|
['to fulfill with value satisfying', 'to resolve with value satisfying'],
|
|
@@ -387,19 +427,20 @@ export const promiseFulfillWithValueSatisfyingAssertion = createAsyncAssertion(
|
|
|
387
427
|
value = await promise;
|
|
388
428
|
} catch (err) {
|
|
389
429
|
return {
|
|
390
|
-
actual:
|
|
391
|
-
expect: '
|
|
392
|
-
message: `Expected
|
|
430
|
+
actual: 'Promise rejected',
|
|
431
|
+
expect: 'Promise to fulfill',
|
|
432
|
+
message: `Expected Promise to fulfill, but it rejected with ${inspect(
|
|
393
433
|
err,
|
|
394
434
|
)}`,
|
|
395
435
|
};
|
|
396
436
|
}
|
|
397
437
|
|
|
398
438
|
const schema = valueToSchema(param, valueToSchemaOptionsForSatisfies);
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
439
|
+
|
|
440
|
+
return {
|
|
441
|
+
schema,
|
|
442
|
+
subject: value,
|
|
443
|
+
};
|
|
403
444
|
},
|
|
404
445
|
);
|
|
405
446
|
|
|
@@ -442,7 +483,7 @@ export const functionFulfillWithValueSatisfyingAssertion = createAsyncAssertion(
|
|
|
442
483
|
} catch (err) {
|
|
443
484
|
return {
|
|
444
485
|
actual: 'function rejected',
|
|
445
|
-
expect: 'function
|
|
486
|
+
expect: 'function fulfilled',
|
|
446
487
|
message: `Expected function to fulfill, but it rejected with ${inspect(
|
|
447
488
|
err,
|
|
448
489
|
)}`,
|
|
@@ -450,9 +491,9 @@ export const functionFulfillWithValueSatisfyingAssertion = createAsyncAssertion(
|
|
|
450
491
|
}
|
|
451
492
|
|
|
452
493
|
const schema = valueToSchema(param, valueToSchemaOptionsForSatisfies);
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
}
|
|
494
|
+
return {
|
|
495
|
+
schema,
|
|
496
|
+
subject: value,
|
|
497
|
+
};
|
|
457
498
|
},
|
|
458
499
|
);
|
|
@@ -13,11 +13,11 @@ import {
|
|
|
13
13
|
functionRejectWithErrorSatisfyingAssertion,
|
|
14
14
|
functionRejectWithTypeAssertion,
|
|
15
15
|
functionResolveAssertion,
|
|
16
|
-
promiseFulfillWithValueSatisfyingAssertion,
|
|
17
16
|
promiseRejectAssertion,
|
|
18
17
|
promiseRejectWithErrorSatisfyingAssertion,
|
|
19
18
|
promiseRejectWithTypeAssertion,
|
|
20
19
|
promiseResolveAssertion,
|
|
20
|
+
promiseResolveWithValueSatisfyingAssertion,
|
|
21
21
|
} from './async-parametric.js';
|
|
22
22
|
|
|
23
23
|
/**
|
|
@@ -34,7 +34,7 @@ export const AsyncParametricAssertions = [
|
|
|
34
34
|
promiseRejectWithTypeAssertion,
|
|
35
35
|
functionRejectWithErrorSatisfyingAssertion,
|
|
36
36
|
promiseRejectWithErrorSatisfyingAssertion,
|
|
37
|
-
|
|
37
|
+
promiseResolveWithValueSatisfyingAssertion,
|
|
38
38
|
functionFulfillWithValueSatisfyingAssertion,
|
|
39
39
|
] as const;
|
|
40
40
|
|
|
@@ -27,6 +27,8 @@ import {
|
|
|
27
27
|
} from '../../schema.js';
|
|
28
28
|
import { createAssertion } from '../create.js';
|
|
29
29
|
|
|
30
|
+
const { ownKeys } = Reflect;
|
|
31
|
+
|
|
30
32
|
/**
|
|
31
33
|
* Asserts that the subject is a string value.
|
|
32
34
|
*
|
|
@@ -39,7 +41,10 @@ import { createAssertion } from '../create.js';
|
|
|
39
41
|
*
|
|
40
42
|
* @group Basic Assertions
|
|
41
43
|
*/
|
|
42
|
-
export const stringAssertion = createAssertion(['to be a string'], z.string()
|
|
44
|
+
export const stringAssertion = createAssertion(['to be a string'], z.string(), {
|
|
45
|
+
anchor: 'unknown-to-be-a-string',
|
|
46
|
+
category: 'primitives',
|
|
47
|
+
});
|
|
43
48
|
|
|
44
49
|
/**
|
|
45
50
|
* Asserts that the subject is a finite number value.
|
|
@@ -571,9 +576,7 @@ export const emptyArrayAssertion = createAssertion(
|
|
|
571
576
|
*/
|
|
572
577
|
export const emptyObjectAssertion = createAssertion(
|
|
573
578
|
[z.record(z.any(), z.unknown()), 'to be empty'],
|
|
574
|
-
z
|
|
575
|
-
.record(z.any(), z.unknown())
|
|
576
|
-
.refine((obj) => Reflect.ownKeys(obj).length === 0),
|
|
579
|
+
z.record(z.any(), z.unknown()).refine((obj) => ownKeys(obj).length === 0),
|
|
577
580
|
);
|
|
578
581
|
|
|
579
582
|
/**
|
|
@@ -32,6 +32,8 @@ import {
|
|
|
32
32
|
import { has } from '../../util.js';
|
|
33
33
|
import { createAssertion } from '../create.js';
|
|
34
34
|
|
|
35
|
+
const { hasOwn, keys } = Object;
|
|
36
|
+
|
|
35
37
|
/**
|
|
36
38
|
* Asserts that a Map or WeakMap contains a specific key. For WeakMap, the key
|
|
37
39
|
* must be an object.
|
|
@@ -101,7 +103,9 @@ export const mapContainsAssertion = createAssertion(
|
|
|
101
103
|
export const mapSizeAssertion = createAssertion(
|
|
102
104
|
[z.map(z.unknown(), z.unknown()), 'to have size', NonNegativeIntegerSchema],
|
|
103
105
|
(subject, expectedSize): AssertionFailure | boolean => {
|
|
104
|
-
if (subject.size === expectedSize)
|
|
106
|
+
if (subject.size === expectedSize) {
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
105
109
|
return {
|
|
106
110
|
actual: subject.size,
|
|
107
111
|
expected: expectedSize,
|
|
@@ -242,7 +246,9 @@ export const emptySetAssertion = createAssertion(
|
|
|
242
246
|
export const arrayContainsAssertion = createAssertion(
|
|
243
247
|
[z.array(z.any()), ['to contain', 'to include'], z.any()],
|
|
244
248
|
(subject, value): AssertionFailure | boolean => {
|
|
245
|
-
if (subject.includes(value))
|
|
249
|
+
if (subject.includes(value)) {
|
|
250
|
+
return true;
|
|
251
|
+
}
|
|
246
252
|
return {
|
|
247
253
|
actual: subject,
|
|
248
254
|
expected: `array containing ${String(value)}`,
|
|
@@ -266,7 +272,9 @@ export const arrayContainsAssertion = createAssertion(
|
|
|
266
272
|
export const arraySizeAssertion = createAssertion(
|
|
267
273
|
[z.array(z.any()), 'to have size', NonNegativeIntegerSchema],
|
|
268
274
|
(subject, expectedSize): AssertionFailure | boolean => {
|
|
269
|
-
if (subject.length === expectedSize)
|
|
275
|
+
if (subject.length === expectedSize) {
|
|
276
|
+
return true;
|
|
277
|
+
}
|
|
270
278
|
return {
|
|
271
279
|
actual: subject.length,
|
|
272
280
|
expected: expectedSize,
|
|
@@ -339,7 +347,7 @@ export const objectKeysAssertion = createAssertion(
|
|
|
339
347
|
z.array(z.string()).nonempty(),
|
|
340
348
|
],
|
|
341
349
|
(subject, keys) => {
|
|
342
|
-
const missing = keys.filter((k) => !
|
|
350
|
+
const missing = keys.filter((k) => !hasOwn(subject, k));
|
|
343
351
|
if (missing.length > 0) {
|
|
344
352
|
return {
|
|
345
353
|
actual: `missing keys: ${missing.join(', ')}`,
|
|
@@ -439,7 +447,7 @@ export const objectExactKeyAssertion = createAssertion(
|
|
|
439
447
|
],
|
|
440
448
|
(_, key) =>
|
|
441
449
|
NonCollectionObjectSchema.transform((v) => ({ ...v })).refine(
|
|
442
|
-
(value) =>
|
|
450
|
+
(value) => hasOwn(value, key),
|
|
443
451
|
{ error: `Expected object to have own exact key "${String(key)}"` },
|
|
444
452
|
),
|
|
445
453
|
);
|
|
@@ -459,7 +467,7 @@ export const objectExactKeyAssertion = createAssertion(
|
|
|
459
467
|
export const objectSizeAssertion = createAssertion(
|
|
460
468
|
[z.looseObject({}), 'to have size', NonNegativeIntegerSchema],
|
|
461
469
|
(subject, expectedSize) => {
|
|
462
|
-
const actual =
|
|
470
|
+
const actual = keys(subject).length;
|
|
463
471
|
if (actual !== expectedSize) {
|
|
464
472
|
return {
|
|
465
473
|
actual,
|
|
@@ -713,9 +721,11 @@ export const setSymmetricDifferenceEqualityAssertion = createAssertion(
|
|
|
713
721
|
export const mapKeyAssertion = createAssertion(
|
|
714
722
|
[z.map(z.unknown(), z.unknown()), 'to have key', z.unknown()],
|
|
715
723
|
(map, key): AssertionFailure | boolean => {
|
|
716
|
-
if (map.has(key))
|
|
724
|
+
if (map.has(key)) {
|
|
725
|
+
return true;
|
|
726
|
+
}
|
|
717
727
|
return {
|
|
718
|
-
actual:
|
|
728
|
+
actual: [...map.keys()],
|
|
719
729
|
expected: key,
|
|
720
730
|
message: `Expected Map to have key`,
|
|
721
731
|
};
|
|
@@ -739,10 +749,12 @@ export const mapValueAssertion = createAssertion(
|
|
|
739
749
|
[z.map(z.unknown(), z.unknown()), 'to have value', z.unknown()],
|
|
740
750
|
(map, value): AssertionFailure | boolean => {
|
|
741
751
|
for (const mapValue of map.values()) {
|
|
742
|
-
if (mapValue === value)
|
|
752
|
+
if (mapValue === value) {
|
|
753
|
+
return true;
|
|
754
|
+
}
|
|
743
755
|
}
|
|
744
756
|
return {
|
|
745
|
-
actual:
|
|
757
|
+
actual: [...map.values()],
|
|
746
758
|
expected: value,
|
|
747
759
|
message: `Expected Map to have value`,
|
|
748
760
|
};
|
|
@@ -781,7 +793,9 @@ export const mapEntryAssertion = createAssertion(
|
|
|
781
793
|
// At this point, if it's a WeakMap, we know key is a WeakKey
|
|
782
794
|
const actualValue =
|
|
783
795
|
map instanceof WeakMap ? map.get(key as WeakKey) : map.get(key);
|
|
784
|
-
if (actualValue === value)
|
|
796
|
+
if (actualValue === value) {
|
|
797
|
+
return true;
|
|
798
|
+
}
|
|
785
799
|
|
|
786
800
|
const hasKey =
|
|
787
801
|
map instanceof WeakMap ? map.has(key as WeakKey) : map.has(key);
|
|
@@ -867,7 +881,9 @@ export const collectionSizeGreaterThanAssertion = createAssertion(
|
|
|
867
881
|
NonNegativeIntegerSchema,
|
|
868
882
|
],
|
|
869
883
|
(collection, minSize): AssertionFailure | boolean => {
|
|
870
|
-
if (collection.size > minSize)
|
|
884
|
+
if (collection.size > minSize) {
|
|
885
|
+
return true;
|
|
886
|
+
}
|
|
871
887
|
return {
|
|
872
888
|
actual: collection.size,
|
|
873
889
|
expected: `size greater than ${minSize}`,
|
|
@@ -895,7 +911,9 @@ export const collectionSizeLessThanAssertion = createAssertion(
|
|
|
895
911
|
NonNegativeIntegerSchema,
|
|
896
912
|
],
|
|
897
913
|
(collection, maxSize): AssertionFailure | boolean => {
|
|
898
|
-
if (collection.size < maxSize)
|
|
914
|
+
if (collection.size < maxSize) {
|
|
915
|
+
return true;
|
|
916
|
+
}
|
|
899
917
|
return {
|
|
900
918
|
actual: collection.size,
|
|
901
919
|
expected: `size less than ${maxSize}`,
|
|
@@ -924,7 +942,9 @@ export const collectionSizeBetweenAssertion = createAssertion(
|
|
|
924
942
|
],
|
|
925
943
|
(collection, [min, max]): AssertionFailure | boolean => {
|
|
926
944
|
const size = collection.size;
|
|
927
|
-
if (size >= min && size <= max)
|
|
945
|
+
if (size >= min && size <= max) {
|
|
946
|
+
return true;
|
|
947
|
+
}
|
|
928
948
|
return {
|
|
929
949
|
actual: size,
|
|
930
950
|
expected: `size between ${min} and ${max} (inclusive)`,
|
|
@@ -12,9 +12,12 @@
|
|
|
12
12
|
|
|
13
13
|
import { z } from 'zod/v4';
|
|
14
14
|
|
|
15
|
+
import { isNonNullObject } from '../../guards.js';
|
|
15
16
|
import { DictionarySchema, PropertyKeySchema } from '../../schema.js';
|
|
16
17
|
import { createAssertion } from '../create.js';
|
|
17
18
|
|
|
19
|
+
const { getOwnPropertyDescriptor, isExtensible, isFrozen, isSealed } = Object;
|
|
20
|
+
|
|
18
21
|
/**
|
|
19
22
|
* Asserts that an object has a null prototype (i.e.,
|
|
20
23
|
* `Object.getPrototypeOf(obj) === null`).
|
|
@@ -72,7 +75,7 @@ export const enumerablePropertyAssertion = createAssertion(
|
|
|
72
75
|
z.unknown().nonoptional(),
|
|
73
76
|
],
|
|
74
77
|
(subject, obj) => {
|
|
75
|
-
if (!
|
|
78
|
+
if (!getOwnPropertyDescriptor(obj, subject)?.enumerable) {
|
|
76
79
|
return {
|
|
77
80
|
actual: false,
|
|
78
81
|
expected: true,
|
|
@@ -112,15 +115,16 @@ export const enumerablePropertyAssertion = createAssertion(
|
|
|
112
115
|
*/
|
|
113
116
|
export const enumerablePropertyAssertion2 = createAssertion(
|
|
114
117
|
[z.unknown().nonoptional(), 'to have enumerable property', PropertyKeySchema],
|
|
115
|
-
(
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
118
|
+
(_subject, key) =>
|
|
119
|
+
z.custom(
|
|
120
|
+
(value) =>
|
|
121
|
+
isNonNullObject(value) &&
|
|
122
|
+
key in value &&
|
|
123
|
+
!!getOwnPropertyDescriptor(value, key)?.enumerable,
|
|
124
|
+
{
|
|
125
|
+
error: `Expected property "${String(key)}" to be enumerable`,
|
|
126
|
+
},
|
|
127
|
+
),
|
|
124
128
|
);
|
|
125
129
|
|
|
126
130
|
/**
|
|
@@ -150,7 +154,7 @@ export const enumerablePropertyAssertion2 = createAssertion(
|
|
|
150
154
|
*/
|
|
151
155
|
export const sealedAssertion = createAssertion(
|
|
152
156
|
['to be sealed'],
|
|
153
|
-
z.any().refine((obj) =>
|
|
157
|
+
z.any().refine((obj) => isSealed(obj)),
|
|
154
158
|
);
|
|
155
159
|
|
|
156
160
|
/**
|
|
@@ -181,7 +185,7 @@ export const sealedAssertion = createAssertion(
|
|
|
181
185
|
* @group Esoteric Assertions
|
|
182
186
|
*/
|
|
183
187
|
export const frozenAssertion = createAssertion(['to be frozen'], (subject) => {
|
|
184
|
-
if (!
|
|
188
|
+
if (!isFrozen(subject)) {
|
|
185
189
|
return {
|
|
186
190
|
actual: false,
|
|
187
191
|
expected: true,
|
|
@@ -221,5 +225,5 @@ export const frozenAssertion = createAssertion(['to be frozen'], (subject) => {
|
|
|
221
225
|
*/
|
|
222
226
|
export const extensibleAssertion = createAssertion(
|
|
223
227
|
['to be extensible'],
|
|
224
|
-
z.any().refine((obj) =>
|
|
228
|
+
z.any().refine((obj) => isExtensible(obj)),
|
|
225
229
|
);
|