bupkis 0.1.2 → 0.3.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 +28 -0
- package/README.md +16 -16
- package/dist/commonjs/assertion/assertion-async.d.ts +2 -1
- package/dist/commonjs/assertion/assertion-async.d.ts.map +1 -1
- package/dist/commonjs/assertion/assertion-async.js +84 -2
- package/dist/commonjs/assertion/assertion-async.js.map +1 -1
- package/dist/commonjs/assertion/assertion-sync.d.ts +1 -1
- package/dist/commonjs/assertion/assertion-sync.d.ts.map +1 -1
- package/dist/commonjs/assertion/assertion-sync.js +5 -1
- package/dist/commonjs/assertion/assertion-sync.js.map +1 -1
- package/dist/commonjs/assertion/assertion-types.d.ts +39 -84
- package/dist/commonjs/assertion/assertion-types.d.ts.map +1 -1
- package/dist/commonjs/assertion/assertion.d.ts +1 -1
- package/dist/commonjs/assertion/assertion.d.ts.map +1 -1
- package/dist/commonjs/assertion/assertion.js +1 -14
- package/dist/commonjs/assertion/assertion.js.map +1 -1
- package/dist/commonjs/assertion/create.d.ts +5 -33
- package/dist/commonjs/assertion/create.d.ts.map +1 -1
- package/dist/commonjs/assertion/create.js +17 -6
- package/dist/commonjs/assertion/create.js.map +1 -1
- package/dist/commonjs/assertion/impl/async.d.ts +122 -21
- package/dist/commonjs/assertion/impl/async.d.ts.map +1 -1
- package/dist/commonjs/assertion/impl/async.js +114 -90
- package/dist/commonjs/assertion/impl/async.js.map +1 -1
- package/dist/commonjs/assertion/impl/callback.d.ts +104 -0
- package/dist/commonjs/assertion/impl/callback.d.ts.map +1 -0
- package/dist/commonjs/assertion/impl/callback.js +694 -0
- package/dist/commonjs/assertion/impl/callback.js.map +1 -0
- package/dist/commonjs/assertion/impl/index.d.ts +1 -1
- package/dist/commonjs/assertion/impl/index.d.ts.map +1 -1
- package/dist/commonjs/assertion/impl/index.js.map +1 -1
- package/dist/commonjs/assertion/impl/sync-esoteric.js +1 -1
- package/dist/commonjs/assertion/impl/sync-esoteric.js.map +1 -1
- package/dist/commonjs/assertion/impl/sync-parametric.d.ts +37 -34
- package/dist/commonjs/assertion/impl/sync-parametric.d.ts.map +1 -1
- package/dist/commonjs/assertion/impl/sync-parametric.js +32 -47
- package/dist/commonjs/assertion/impl/sync-parametric.js.map +1 -1
- package/dist/commonjs/assertion/impl/sync.d.ts +105 -58
- package/dist/commonjs/assertion/impl/sync.d.ts.map +1 -1
- package/dist/commonjs/assertion/impl/sync.js +4 -1
- package/dist/commonjs/assertion/impl/sync.js.map +1 -1
- package/dist/commonjs/bootstrap.d.ts +199 -85
- package/dist/commonjs/bootstrap.d.ts.map +1 -1
- package/dist/commonjs/bootstrap.js +19 -10
- package/dist/commonjs/bootstrap.js.map +1 -1
- package/dist/commonjs/constant.js +7 -1
- package/dist/commonjs/constant.js.map +1 -1
- package/dist/commonjs/error.d.ts +32 -5
- package/dist/commonjs/error.d.ts.map +1 -1
- package/dist/commonjs/error.js +60 -5
- package/dist/commonjs/error.js.map +1 -1
- package/dist/commonjs/expect.d.ts +130 -3
- package/dist/commonjs/expect.d.ts.map +1 -1
- package/dist/commonjs/expect.js +116 -1
- package/dist/commonjs/expect.js.map +1 -1
- package/dist/commonjs/guards.d.ts +45 -20
- package/dist/commonjs/guards.d.ts.map +1 -1
- package/dist/commonjs/guards.js +56 -40
- package/dist/commonjs/guards.js.map +1 -1
- package/dist/commonjs/index.d.ts +241 -86
- package/dist/commonjs/index.d.ts.map +1 -1
- package/dist/commonjs/index.js +44 -42
- package/dist/commonjs/index.js.map +1 -1
- package/dist/commonjs/metadata.d.ts +1 -27
- package/dist/commonjs/metadata.d.ts.map +1 -1
- package/dist/commonjs/metadata.js +16 -15
- package/dist/commonjs/metadata.js.map +1 -1
- package/dist/commonjs/schema.d.ts +76 -33
- package/dist/commonjs/schema.d.ts.map +1 -1
- package/dist/commonjs/schema.js +77 -34
- package/dist/commonjs/schema.js.map +1 -1
- package/dist/commonjs/types.d.ts +480 -39
- package/dist/commonjs/types.d.ts.map +1 -1
- package/dist/commonjs/types.js +12 -2
- package/dist/commonjs/types.js.map +1 -1
- package/dist/commonjs/util.d.ts +72 -49
- package/dist/commonjs/util.d.ts.map +1 -1
- package/dist/commonjs/util.js +175 -155
- package/dist/commonjs/util.js.map +1 -1
- package/dist/commonjs/value-to-schema.d.ts +122 -0
- package/dist/commonjs/value-to-schema.d.ts.map +1 -0
- package/dist/commonjs/value-to-schema.js +309 -0
- package/dist/commonjs/value-to-schema.js.map +1 -0
- package/dist/esm/assertion/assertion-async.d.ts +2 -1
- package/dist/esm/assertion/assertion-async.d.ts.map +1 -1
- package/dist/esm/assertion/assertion-async.js +85 -3
- package/dist/esm/assertion/assertion-async.js.map +1 -1
- package/dist/esm/assertion/assertion-sync.d.ts +1 -1
- package/dist/esm/assertion/assertion-sync.d.ts.map +1 -1
- package/dist/esm/assertion/assertion-sync.js +6 -2
- package/dist/esm/assertion/assertion-sync.js.map +1 -1
- package/dist/esm/assertion/assertion-types.d.ts +39 -84
- package/dist/esm/assertion/assertion-types.d.ts.map +1 -1
- package/dist/esm/assertion/assertion.d.ts +1 -1
- package/dist/esm/assertion/assertion.d.ts.map +1 -1
- package/dist/esm/assertion/assertion.js +1 -14
- package/dist/esm/assertion/assertion.js.map +1 -1
- package/dist/esm/assertion/create.d.ts +5 -33
- package/dist/esm/assertion/create.d.ts.map +1 -1
- package/dist/esm/assertion/create.js +14 -4
- package/dist/esm/assertion/create.js.map +1 -1
- package/dist/esm/assertion/impl/async.d.ts +122 -21
- package/dist/esm/assertion/impl/async.d.ts.map +1 -1
- package/dist/esm/assertion/impl/async.js +113 -89
- package/dist/esm/assertion/impl/async.js.map +1 -1
- package/dist/esm/assertion/impl/callback.d.ts +104 -0
- package/dist/esm/assertion/impl/callback.d.ts.map +1 -0
- package/dist/esm/assertion/impl/callback.js +691 -0
- package/dist/esm/assertion/impl/callback.js.map +1 -0
- package/dist/esm/assertion/impl/index.d.ts +1 -1
- package/dist/esm/assertion/impl/index.d.ts.map +1 -1
- package/dist/esm/assertion/impl/index.js +1 -1
- package/dist/esm/assertion/impl/index.js.map +1 -1
- package/dist/esm/assertion/impl/sync-esoteric.js +2 -2
- package/dist/esm/assertion/impl/sync-esoteric.js.map +1 -1
- package/dist/esm/assertion/impl/sync-parametric.d.ts +37 -34
- package/dist/esm/assertion/impl/sync-parametric.d.ts.map +1 -1
- package/dist/esm/assertion/impl/sync-parametric.js +32 -47
- package/dist/esm/assertion/impl/sync-parametric.js.map +1 -1
- package/dist/esm/assertion/impl/sync.d.ts +105 -58
- package/dist/esm/assertion/impl/sync.d.ts.map +1 -1
- package/dist/esm/assertion/impl/sync.js +3 -1
- package/dist/esm/assertion/impl/sync.js.map +1 -1
- package/dist/esm/bootstrap.d.ts +199 -85
- package/dist/esm/bootstrap.d.ts.map +1 -1
- package/dist/esm/bootstrap.js +19 -10
- package/dist/esm/bootstrap.js.map +1 -1
- package/dist/esm/constant.js +6 -0
- package/dist/esm/constant.js.map +1 -1
- package/dist/esm/error.d.ts +32 -5
- package/dist/esm/error.d.ts.map +1 -1
- package/dist/esm/error.js +59 -5
- package/dist/esm/error.js.map +1 -1
- package/dist/esm/expect.d.ts +130 -3
- package/dist/esm/expect.d.ts.map +1 -1
- package/dist/esm/expect.js +117 -2
- package/dist/esm/expect.js.map +1 -1
- package/dist/esm/guards.d.ts +45 -20
- package/dist/esm/guards.d.ts.map +1 -1
- package/dist/esm/guards.js +48 -31
- package/dist/esm/guards.js.map +1 -1
- package/dist/esm/index.d.ts +241 -86
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +46 -7
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/metadata.d.ts +1 -27
- package/dist/esm/metadata.d.ts.map +1 -1
- package/dist/esm/metadata.js +2 -1
- package/dist/esm/metadata.js.map +1 -1
- package/dist/esm/schema.d.ts +76 -33
- package/dist/esm/schema.d.ts.map +1 -1
- package/dist/esm/schema.js +77 -34
- package/dist/esm/schema.js.map +1 -1
- package/dist/esm/types.d.ts +480 -39
- package/dist/esm/types.d.ts.map +1 -1
- package/dist/esm/types.js +12 -2
- package/dist/esm/types.js.map +1 -1
- package/dist/esm/util.d.ts +72 -49
- package/dist/esm/util.d.ts.map +1 -1
- package/dist/esm/util.js +159 -153
- package/dist/esm/util.js.map +1 -1
- package/dist/esm/value-to-schema.d.ts +122 -0
- package/dist/esm/value-to-schema.d.ts.map +1 -0
- package/dist/esm/value-to-schema.js +305 -0
- package/dist/esm/value-to-schema.js.map +1 -0
- package/package.json +94 -17
- package/src/assertion/assertion-async.ts +113 -3
- package/src/assertion/assertion-sync.ts +5 -2
- package/src/assertion/assertion-types.ts +52 -45
- package/src/assertion/assertion.ts +2 -17
- package/src/assertion/create.ts +16 -65
- package/src/assertion/impl/async.ts +132 -92
- package/src/assertion/impl/callback.ts +882 -0
- package/src/assertion/impl/index.ts +1 -1
- package/src/assertion/impl/sync-esoteric.ts +2 -2
- package/src/assertion/impl/sync-parametric.ts +41 -49
- package/src/assertion/impl/sync.ts +3 -0
- package/src/bootstrap.ts +21 -11
- package/src/constant.ts +8 -0
- package/src/error.ts +75 -4
- package/src/expect.ts +275 -20
- package/src/guards.ts +74 -69
- package/src/index.ts +72 -11
- package/src/metadata.ts +3 -4
- package/src/schema.ts +80 -36
- package/src/types.ts +625 -72
- package/src/util.ts +174 -222
- package/src/value-to-schema.ts +464 -0
- package/dist/commonjs/api.d.ts +0 -93
- package/dist/commonjs/api.d.ts.map +0 -1
- package/dist/commonjs/api.js +0 -8
- package/dist/commonjs/api.js.map +0 -1
- package/dist/esm/api.d.ts +0 -93
- package/dist/esm/api.d.ts.map +0 -1
- package/dist/esm/api.js +0 -7
- package/dist/esm/api.js.map +0 -1
- package/src/api.ts +0 -149
- package/src/schema.md +0 -15
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { AsyncAssertions } from './async.js';
|
|
2
|
-
export { SyncAssertions } from './sync.js';
|
|
2
|
+
export { SyncAssertions as SyncAssertions } from './sync.js';
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { z } from 'zod/v4';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { DictionarySchema, PropertyKeySchema } from '../../schema.js';
|
|
4
4
|
import { createAssertion } from '../create.js';
|
|
5
5
|
|
|
6
6
|
export const EsotericAssertions = [
|
|
7
|
-
createAssertion(['to have a null prototype'],
|
|
7
|
+
createAssertion(['to have a null prototype'], DictionarySchema),
|
|
8
8
|
createAssertion(
|
|
9
9
|
[PropertyKeySchema, 'to be an enumerable property of', z.looseObject({})],
|
|
10
10
|
(subject, obj) =>
|
|
@@ -11,7 +11,11 @@ import {
|
|
|
11
11
|
StrongSetSchema,
|
|
12
12
|
WrappedPromiseLikeSchema,
|
|
13
13
|
} from '../../schema.js';
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
valueToSchema,
|
|
16
|
+
valueToSchemaOptionsForDeepEqual,
|
|
17
|
+
valueToSchemaOptionsForSatisfies,
|
|
18
|
+
} from '../../value-to-schema.js';
|
|
15
19
|
import { createAssertion } from '../create.js';
|
|
16
20
|
|
|
17
21
|
const trapError = (fn: () => unknown): unknown => {
|
|
@@ -135,7 +139,7 @@ export const ParametricAssertions = [
|
|
|
135
139
|
|
|
136
140
|
// Number range and approximation assertions
|
|
137
141
|
createAssertion(
|
|
138
|
-
[z.number(), 'to be within', z.number(), z.number()],
|
|
142
|
+
[z.number(), ['to be within', 'to be between'], z.number(), z.number()],
|
|
139
143
|
(subject, min, max) => {
|
|
140
144
|
if (subject < min || subject > max) {
|
|
141
145
|
return {
|
|
@@ -304,19 +308,19 @@ export const ParametricAssertions = [
|
|
|
304
308
|
}
|
|
305
309
|
},
|
|
306
310
|
),
|
|
307
|
-
// @ts-expect-error fix later
|
|
308
311
|
createAssertion(
|
|
309
312
|
[
|
|
310
313
|
z.looseObject({}),
|
|
311
314
|
['to deep equal', 'to deeply equal'],
|
|
312
315
|
z.looseObject({}),
|
|
313
316
|
],
|
|
314
|
-
(_, expected) => valueToSchema(expected,
|
|
317
|
+
(_, expected) => valueToSchema(expected, valueToSchemaOptionsForDeepEqual),
|
|
315
318
|
),
|
|
316
|
-
// @ts-expect-error fix later
|
|
317
319
|
createAssertion(
|
|
318
320
|
[ArrayLikeSchema, ['to deep equal', 'to deeply equal'], ArrayLikeSchema],
|
|
319
|
-
(_, expected) =>
|
|
321
|
+
(_, expected) => {
|
|
322
|
+
return valueToSchema(expected, valueToSchemaOptionsForDeepEqual);
|
|
323
|
+
},
|
|
320
324
|
),
|
|
321
325
|
createAssertion([FunctionSchema, 'to throw'], (subject) => {
|
|
322
326
|
const error = trapError(subject);
|
|
@@ -376,10 +380,7 @@ export const ParametricAssertions = [
|
|
|
376
380
|
.or(z.coerce.string().regex(param))
|
|
377
381
|
.safeParse(error).success;
|
|
378
382
|
} else if (isNonNullObject(param)) {
|
|
379
|
-
const schema = valueToSchema(param,
|
|
380
|
-
literalPrimitives: true,
|
|
381
|
-
strict: true,
|
|
382
|
-
});
|
|
383
|
+
const schema = valueToSchema(param, valueToSchemaOptionsForSatisfies);
|
|
383
384
|
return schema.safeParse(error).success;
|
|
384
385
|
} else {
|
|
385
386
|
throw new TypeError(`Invalid parameter schema: ${inspect(param)}`);
|
|
@@ -396,6 +397,7 @@ export const ParametricAssertions = [
|
|
|
396
397
|
],
|
|
397
398
|
(subject, ctor, param) => {
|
|
398
399
|
const error = trapError(subject);
|
|
400
|
+
|
|
399
401
|
if (!isA(error, ctor)) {
|
|
400
402
|
return {
|
|
401
403
|
actual: error,
|
|
@@ -405,47 +407,32 @@ export const ParametricAssertions = [
|
|
|
405
407
|
: `Expected function to throw an instance of ${ctor.name}, but it threw a non-object value: ${error as unknown}`,
|
|
406
408
|
};
|
|
407
409
|
}
|
|
408
|
-
|
|
410
|
+
let schema: undefined | z.ZodType;
|
|
411
|
+
// TODO: can valueToSchema handle the first two conditional branches?
|
|
409
412
|
if (isString(param)) {
|
|
410
|
-
|
|
413
|
+
schema = z
|
|
411
414
|
.looseObject({
|
|
412
|
-
message: z.coerce.string().
|
|
415
|
+
message: z.coerce.string().pipe(z.literal(param)),
|
|
413
416
|
})
|
|
414
|
-
.or(z.coerce.string().
|
|
415
|
-
.safeParse(error);
|
|
416
|
-
if (!result.success) {
|
|
417
|
-
return {
|
|
418
|
-
actual: isError(error) ? error.message : String(error),
|
|
419
|
-
expected: `error with message containing "${param}"`,
|
|
420
|
-
message: `Expected error message to contain "${param}", but got: ${isError(error) ? error.message : String(error)}`,
|
|
421
|
-
};
|
|
422
|
-
}
|
|
417
|
+
.or(z.coerce.string().pipe(z.literal(param)));
|
|
423
418
|
} else if (isA(param, RegExp)) {
|
|
424
|
-
|
|
419
|
+
schema = z
|
|
425
420
|
.looseObject({
|
|
426
421
|
message: z.coerce.string().regex(param),
|
|
427
422
|
})
|
|
428
|
-
.or(z.coerce.string().regex(param))
|
|
429
|
-
.safeParse(error);
|
|
430
|
-
if (!result.success) {
|
|
431
|
-
return {
|
|
432
|
-
actual: isError(error) ? error.message : String(error),
|
|
433
|
-
expected: `error with message matching ${param}`,
|
|
434
|
-
message: `Expected error message to match ${param}, but got: ${isError(error) ? error.message : String(error)}`,
|
|
435
|
-
};
|
|
436
|
-
}
|
|
423
|
+
.or(z.coerce.string().regex(param));
|
|
437
424
|
} else if (isNonNullObject(param)) {
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
425
|
+
schema = valueToSchema(param, valueToSchemaOptionsForSatisfies);
|
|
426
|
+
}
|
|
427
|
+
if (!schema) {
|
|
428
|
+
throw new TypeError(
|
|
429
|
+
`Invalid parameter schema: ${inspect(param, { depth: 2 })}`,
|
|
430
|
+
);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
const result = schema.safeParse(error);
|
|
434
|
+
if (!result.success) {
|
|
435
|
+
return result.error;
|
|
449
436
|
}
|
|
450
437
|
},
|
|
451
438
|
),
|
|
@@ -455,7 +442,15 @@ export const ParametricAssertions = [
|
|
|
455
442
|
['includes', 'contains', 'to include', 'to contain'],
|
|
456
443
|
z.string(),
|
|
457
444
|
],
|
|
458
|
-
(subject, expected) =>
|
|
445
|
+
(subject, expected) => {
|
|
446
|
+
if (!subject.includes(expected)) {
|
|
447
|
+
return {
|
|
448
|
+
actual: subject,
|
|
449
|
+
expected: `string including "${expected}"`,
|
|
450
|
+
message: `Expected "${subject}" to include "${expected}"`,
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
},
|
|
459
454
|
),
|
|
460
455
|
|
|
461
456
|
createAssertion([z.string(), 'to match', RegExpSchema], (subject, regex) =>
|
|
@@ -467,14 +462,11 @@ export const ParametricAssertions = [
|
|
|
467
462
|
['to satisfy', 'to be like'],
|
|
468
463
|
z.looseObject({}),
|
|
469
464
|
],
|
|
470
|
-
(_subject, shape) =>
|
|
471
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
472
|
-
valueToSchema(shape) as unknown as z.ZodType<{}, z.core.$loose>,
|
|
465
|
+
(_subject, shape) => valueToSchema(shape, valueToSchemaOptionsForSatisfies),
|
|
473
466
|
),
|
|
474
467
|
createAssertion(
|
|
475
468
|
[ArrayLikeSchema, ['to satisfy', 'to be like'], ArrayLikeSchema],
|
|
476
|
-
(_subject, shape) =>
|
|
477
|
-
valueToSchema(shape) as unknown as typeof ArrayLikeSchema,
|
|
469
|
+
(_subject, shape) => valueToSchema(shape, valueToSchemaOptionsForSatisfies),
|
|
478
470
|
),
|
|
479
471
|
createAssertion(
|
|
480
472
|
[FunctionSchema, 'to have arity', z.number().int().nonnegative()],
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* @packageDocumentation
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
+
import { CallbackSyncAssertions } from './callback.js';
|
|
12
13
|
import { BasicAssertions } from './sync-basic.js';
|
|
13
14
|
import { CollectionAssertions } from './sync-collection.js';
|
|
14
15
|
import { EsotericAssertions } from './sync-esoteric.js';
|
|
@@ -19,10 +20,12 @@ export const SyncAssertions = [
|
|
|
19
20
|
...BasicAssertions,
|
|
20
21
|
...EsotericAssertions,
|
|
21
22
|
...ParametricAssertions,
|
|
23
|
+
...CallbackSyncAssertions,
|
|
22
24
|
] as const;
|
|
23
25
|
|
|
24
26
|
export {
|
|
25
27
|
BasicAssertions,
|
|
28
|
+
CallbackSyncAssertions,
|
|
26
29
|
CollectionAssertions,
|
|
27
30
|
EsotericAssertions,
|
|
28
31
|
ParametricAssertions,
|
package/src/bootstrap.ts
CHANGED
|
@@ -1,23 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Factory function for creating the main assertion functions.
|
|
3
3
|
*
|
|
4
|
-
* This module provides the
|
|
5
|
-
* and asynchronous assertion engines.
|
|
6
|
-
* previously split between `expect.ts` and `expect-async.ts`.
|
|
4
|
+
* This module provides the {@link bootstrap} function that creates both
|
|
5
|
+
* synchronous and asynchronous assertion engines.
|
|
7
6
|
*
|
|
8
7
|
* @packageDocumentation
|
|
9
8
|
*/
|
|
10
9
|
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import { AsyncAssertions } from './assertion/index.js';
|
|
10
|
+
import { AsyncAssertions, SyncAssertions } from './assertion/index.js';
|
|
11
|
+
import { type Expect, type ExpectAsync } from './types.js';
|
|
14
12
|
import { createUse } from './use.js';
|
|
15
13
|
|
|
16
14
|
/**
|
|
17
15
|
* Factory function that creates both synchronous and asynchronous assertion
|
|
18
16
|
* engines.
|
|
19
17
|
*
|
|
20
|
-
* @returns Object containing
|
|
18
|
+
* @returns Object containing {@link expect} and {@link expectAsync} functions
|
|
21
19
|
* @internal
|
|
22
20
|
*/
|
|
23
21
|
const bootstrap = (): {
|
|
@@ -34,9 +32,21 @@ const bootstrap = (): {
|
|
|
34
32
|
|
|
35
33
|
const api = bootstrap();
|
|
36
34
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
35
|
+
const {
|
|
36
|
+
/**
|
|
37
|
+
* The main synchronous assertion function which can execute only built-in
|
|
38
|
+
* assertions.
|
|
39
|
+
*
|
|
40
|
+
* @function
|
|
41
|
+
*/
|
|
42
|
+
expect,
|
|
43
|
+
/**
|
|
44
|
+
* The main asynchronous assertion function which can execute only built-in
|
|
45
|
+
* assertions.
|
|
46
|
+
*
|
|
47
|
+
* @function
|
|
48
|
+
*/
|
|
49
|
+
expectAsync,
|
|
50
|
+
} = api;
|
|
41
51
|
|
|
42
52
|
export { expect, expectAsync };
|
package/src/constant.ts
CHANGED
|
@@ -26,6 +26,14 @@ export const kStringLiteral: unique symbol = Symbol('bupkis:string-literal');
|
|
|
26
26
|
|
|
27
27
|
export const kBupkisAssertionError: unique symbol = Symbol('bupkis-error');
|
|
28
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Symbol used to flag a `FailAssertionError`
|
|
31
|
+
*
|
|
32
|
+
* @internal
|
|
33
|
+
*/
|
|
34
|
+
export const kBupkisFailAssertionError: unique symbol =
|
|
35
|
+
Symbol('bupkis-fail-error');
|
|
36
|
+
|
|
29
37
|
/**
|
|
30
38
|
* Symbol used to flag a `NegatedAssertionError`
|
|
31
39
|
*
|
package/src/error.ts
CHANGED
|
@@ -7,25 +7,94 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { AssertionError as NodeAssertionError } from 'node:assert';
|
|
10
|
+
import { z } from 'zod/v4';
|
|
10
11
|
|
|
11
12
|
import {
|
|
12
13
|
kBupkisAssertionError,
|
|
14
|
+
kBupkisFailAssertionError,
|
|
13
15
|
kBupkisNegatedAssertionError,
|
|
14
16
|
} from './constant.js';
|
|
15
17
|
import { isA } from './guards.js';
|
|
18
|
+
import { type AssertionParts, type ParsedValues } from './types.js';
|
|
16
19
|
|
|
17
20
|
/**
|
|
18
21
|
* _BUPKIS_' s custom `AssertionError` class, which is just a thin wrapper
|
|
19
22
|
* around Node.js' {@link NodeAssertionError AssertionError}.
|
|
20
|
-
*
|
|
21
|
-
* @public
|
|
22
23
|
*/
|
|
23
24
|
export class AssertionError extends NodeAssertionError {
|
|
25
|
+
/**
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
24
28
|
[kBupkisAssertionError] = true;
|
|
25
29
|
|
|
26
|
-
|
|
30
|
+
override name = 'AssertionError';
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Translates a {@link z.ZodError} into an {@link AssertionError} with a
|
|
34
|
+
* human-friendly message.
|
|
35
|
+
*
|
|
36
|
+
* @remarks
|
|
37
|
+
* This does not handle parameterized assertions with more than one parameter
|
|
38
|
+
* too cleanly; it's unclear how a test runner would display the expected
|
|
39
|
+
* values. This will probably need a fix in the future.
|
|
40
|
+
* @param stackStartFn The function to start the stack trace from
|
|
41
|
+
* @param zodError The original `ZodError`
|
|
42
|
+
* @param values Values which caused the error
|
|
43
|
+
* @returns New `AssertionError`
|
|
44
|
+
*/
|
|
45
|
+
static fromZodError<Parts extends AssertionParts>(
|
|
46
|
+
zodError: z.ZodError,
|
|
47
|
+
stackStartFn: (...args: any[]) => any,
|
|
48
|
+
values: ParsedValues<Parts>,
|
|
49
|
+
): AssertionError {
|
|
50
|
+
const flat = z.flattenError(zodError);
|
|
51
|
+
|
|
52
|
+
let pretty = flat.formErrors.join('; ');
|
|
53
|
+
for (const [keypath, errors] of Object.entries(flat.fieldErrors)) {
|
|
54
|
+
pretty += `; ${keypath}: ${(errors as unknown[]).join('; ')}`;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const [actual, ...expected] = values as unknown as [unknown, ...unknown[]];
|
|
58
|
+
|
|
59
|
+
return new AssertionError({
|
|
60
|
+
actual,
|
|
61
|
+
expected: expected.length === 1 ? expected[0] : expected,
|
|
62
|
+
message: `Assertion ${this} failed: ${pretty}`,
|
|
63
|
+
operator: `${this}`,
|
|
64
|
+
stackStartFn,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Type guard for an instance of this error.
|
|
70
|
+
*
|
|
71
|
+
* @param value Some value
|
|
72
|
+
* @returns `true` if `value` is an instance of `AssertionError`
|
|
73
|
+
*/
|
|
74
|
+
static isAssertionError(value: unknown): value is AssertionError {
|
|
27
75
|
return (
|
|
28
|
-
isA(
|
|
76
|
+
isA(value, NodeAssertionError) &&
|
|
77
|
+
Object.hasOwn(value, kBupkisAssertionError)
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Variant of an {@link AssertionError} that is thrown when
|
|
84
|
+
* {@link bupkis!expect.fail} is called.
|
|
85
|
+
*/
|
|
86
|
+
export class FailAssertionError extends AssertionError {
|
|
87
|
+
/**
|
|
88
|
+
* @internal
|
|
89
|
+
*/
|
|
90
|
+
[kBupkisFailAssertionError] = true;
|
|
91
|
+
|
|
92
|
+
override name = 'FailAssertionError';
|
|
93
|
+
|
|
94
|
+
static isFailAssertionError(err: unknown): err is FailAssertionError {
|
|
95
|
+
return (
|
|
96
|
+
isA(err, FailAssertionError) &&
|
|
97
|
+
Object.hasOwn(err, kBupkisFailAssertionError)
|
|
29
98
|
);
|
|
30
99
|
}
|
|
31
100
|
}
|
|
@@ -38,6 +107,8 @@ export class AssertionError extends NodeAssertionError {
|
|
|
38
107
|
export class NegatedAssertionError extends AssertionError {
|
|
39
108
|
[kBupkisNegatedAssertionError] = true;
|
|
40
109
|
|
|
110
|
+
override name = 'NegatedAssertionError';
|
|
111
|
+
|
|
41
112
|
static isNegatedAssertionError(err: unknown): err is NegatedAssertionError {
|
|
42
113
|
return (
|
|
43
114
|
isA(err, AssertionError) &&
|