@c9up/helix 0.1.3 → 0.1.5
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/dist/cli/coverage/aggregate.d.ts +24 -0
- package/dist/cli/coverage/aggregate.d.ts.map +1 -0
- package/dist/cli/coverage/aggregate.js +215 -0
- package/dist/cli/coverage/aggregate.js.map +1 -0
- package/dist/cli/coverage/collect.d.ts +13 -0
- package/dist/cli/coverage/collect.d.ts.map +1 -0
- package/dist/cli/coverage/collect.js +66 -0
- package/dist/cli/coverage/collect.js.map +1 -0
- package/dist/cli/coverage/diff/base.d.ts +17 -0
- package/dist/cli/coverage/diff/base.d.ts.map +1 -0
- package/dist/cli/coverage/diff/base.js +44 -0
- package/dist/cli/coverage/diff/base.js.map +1 -0
- package/dist/cli/coverage/diff/index.d.ts +25 -0
- package/dist/cli/coverage/diff/index.d.ts.map +1 -0
- package/dist/cli/coverage/diff/index.js +119 -0
- package/dist/cli/coverage/diff/index.js.map +1 -0
- package/dist/cli/coverage/diff/overlay.d.ts +19 -0
- package/dist/cli/coverage/diff/overlay.d.ts.map +1 -0
- package/dist/cli/coverage/diff/overlay.js +58 -0
- package/dist/cli/coverage/diff/overlay.js.map +1 -0
- package/dist/cli/coverage/diff/parse.d.ts +27 -0
- package/dist/cli/coverage/diff/parse.d.ts.map +1 -0
- package/dist/cli/coverage/diff/parse.js +105 -0
- package/dist/cli/coverage/diff/parse.js.map +1 -0
- package/dist/cli/coverage/diff/reporters.d.ts +12 -0
- package/dist/cli/coverage/diff/reporters.d.ts.map +1 -0
- package/dist/cli/coverage/diff/reporters.js +59 -0
- package/dist/cli/coverage/diff/reporters.js.map +1 -0
- package/dist/cli/coverage/diff/types.d.ts +46 -0
- package/dist/cli/coverage/diff/types.d.ts.map +1 -0
- package/dist/cli/coverage/diff/types.js +15 -0
- package/dist/cli/coverage/diff/types.js.map +1 -0
- package/dist/cli/coverage/filter.d.ts +13 -0
- package/dist/cli/coverage/filter.d.ts.map +1 -0
- package/dist/cli/coverage/filter.js +60 -0
- package/dist/cli/coverage/filter.js.map +1 -0
- package/dist/cli/coverage/glob.d.ts +4 -0
- package/dist/cli/coverage/glob.d.ts.map +1 -0
- package/dist/cli/coverage/glob.js +0 -0
- package/dist/cli/coverage/glob.js.map +1 -0
- package/dist/cli/coverage/index.d.ts +40 -0
- package/dist/cli/coverage/index.d.ts.map +1 -0
- package/dist/cli/coverage/index.js +85 -0
- package/dist/cli/coverage/index.js.map +1 -0
- package/dist/cli/coverage/reporters/json.d.ts +13 -0
- package/dist/cli/coverage/reporters/json.d.ts.map +1 -0
- package/dist/cli/coverage/reporters/json.js +37 -0
- package/dist/cli/coverage/reporters/json.js.map +1 -0
- package/dist/cli/coverage/reporters/lcov.d.ts +13 -0
- package/dist/cli/coverage/reporters/lcov.d.ts.map +1 -0
- package/dist/cli/coverage/reporters/lcov.js +51 -0
- package/dist/cli/coverage/reporters/lcov.js.map +1 -0
- package/dist/cli/coverage/reporters/text.d.ts +8 -0
- package/dist/cli/coverage/reporters/text.d.ts.map +1 -0
- package/dist/cli/coverage/reporters/text.js +39 -0
- package/dist/cli/coverage/reporters/text.js.map +1 -0
- package/dist/cli/coverage/thresholds.d.ts +14 -0
- package/dist/cli/coverage/thresholds.d.ts.map +1 -0
- package/dist/cli/coverage/thresholds.js +58 -0
- package/dist/cli/coverage/thresholds.js.map +1 -0
- package/dist/cli/coverage/types.d.ts +118 -0
- package/dist/cli/coverage/types.d.ts.map +1 -0
- package/dist/cli/coverage/types.js +8 -0
- package/dist/cli/coverage/types.js.map +1 -0
- package/dist/cli/discover.d.ts +27 -0
- package/dist/cli/discover.d.ts.map +1 -0
- package/dist/cli/discover.js +142 -0
- package/dist/cli/discover.js.map +1 -0
- package/dist/cli/native.d.ts +43 -0
- package/dist/cli/native.d.ts.map +1 -0
- package/dist/cli/native.js +64 -0
- package/dist/cli/native.js.map +1 -0
- package/dist/cli/pool.d.ts +55 -0
- package/dist/cli/pool.d.ts.map +1 -0
- package/dist/cli/pool.js +404 -0
- package/dist/cli/pool.js.map +1 -0
- package/dist/cli/reporter.d.ts +51 -0
- package/dist/cli/reporter.d.ts.map +1 -0
- package/dist/cli/reporter.js +124 -0
- package/dist/cli/reporter.js.map +1 -0
- package/dist/cli/run.d.ts +61 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/run.js +302 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/cli/summary.d.ts +18 -0
- package/dist/cli/summary.d.ts.map +1 -0
- package/dist/cli/summary.js +20 -0
- package/dist/cli/summary.js.map +1 -0
- package/dist/cli/watch/loop.d.ts +26 -0
- package/dist/cli/watch/loop.d.ts.map +1 -0
- package/dist/cli/watch/loop.js +133 -0
- package/dist/cli/watch/loop.js.map +1 -0
- package/dist/cli/watch/types.d.ts +22 -0
- package/dist/cli/watch/types.d.ts.map +1 -0
- package/dist/cli/watch/types.js +6 -0
- package/dist/cli/watch/types.js.map +1 -0
- package/dist/cli/watch/watcher.d.ts +25 -0
- package/dist/cli/watch/watcher.d.ts.map +1 -0
- package/dist/cli/watch/watcher.js +122 -0
- package/dist/cli/watch/watcher.js.map +1 -0
- package/dist/container/index.d.ts +7 -0
- package/dist/container/index.d.ts.map +1 -0
- package/dist/container/index.js +6 -0
- package/dist/container/index.js.map +1 -0
- package/{src/container/override.ts → dist/container/override.d.ts} +6 -46
- package/dist/container/override.d.ts.map +1 -0
- package/dist/container/override.js +67 -0
- package/dist/container/override.js.map +1 -0
- package/{src/container/spy.ts → dist/container/spy.d.ts} +2 -6
- package/dist/container/spy.d.ts.map +1 -0
- package/dist/container/spy.js +23 -0
- package/dist/container/spy.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/{src/index.ts → dist/index.js} +2 -25
- package/dist/index.js.map +1 -0
- package/dist/runtime/assertion-error.d.ts +20 -0
- package/dist/runtime/assertion-error.d.ts.map +1 -0
- package/dist/runtime/assertion-error.js +23 -0
- package/dist/runtime/assertion-error.js.map +1 -0
- package/dist/runtime/cli-worker.d.ts +25 -0
- package/dist/runtime/cli-worker.d.ts.map +1 -0
- package/dist/runtime/cli-worker.js +128 -0
- package/dist/runtime/cli-worker.js.map +1 -0
- package/dist/runtime/equals.d.ts +25 -0
- package/dist/runtime/equals.d.ts.map +1 -0
- package/dist/runtime/equals.js +343 -0
- package/dist/runtime/equals.js.map +1 -0
- package/dist/runtime/expect.d.ts +32 -0
- package/dist/runtime/expect.d.ts.map +1 -0
- package/dist/runtime/expect.js +121 -0
- package/dist/runtime/expect.js.map +1 -0
- package/{src/runtime/index.ts → dist/runtime/index.d.ts} +5 -27
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +17 -0
- package/dist/runtime/index.js.map +1 -0
- package/{src/runtime/lifecycle.ts → dist/runtime/lifecycle.d.ts} +2 -8
- package/dist/runtime/lifecycle.d.ts.map +1 -0
- package/dist/runtime/lifecycle.js +10 -0
- package/dist/runtime/lifecycle.js.map +1 -0
- package/dist/runtime/matchers.d.ts +42 -0
- package/dist/runtime/matchers.d.ts.map +1 -0
- package/dist/runtime/matchers.js +375 -0
- package/dist/runtime/matchers.js.map +1 -0
- package/dist/runtime/run.d.ts +55 -0
- package/dist/runtime/run.d.ts.map +1 -0
- package/dist/runtime/run.js +456 -0
- package/dist/runtime/run.js.map +1 -0
- package/dist/runtime/suite.d.ts +91 -0
- package/dist/runtime/suite.d.ts.map +1 -0
- package/dist/runtime/suite.js +206 -0
- package/dist/runtime/suite.js.map +1 -0
- package/dist/runtime/test-context.d.ts +25 -0
- package/dist/runtime/test-context.d.ts.map +1 -0
- package/dist/runtime/test-context.js +52 -0
- package/dist/runtime/test-context.js.map +1 -0
- package/dist/runtime/vi/fake-timers.d.ts +48 -0
- package/dist/runtime/vi/fake-timers.d.ts.map +1 -0
- package/dist/runtime/vi/fake-timers.js +317 -0
- package/dist/runtime/vi/fake-timers.js.map +1 -0
- package/dist/runtime/vi/index.d.ts +70 -0
- package/dist/runtime/vi/index.d.ts.map +1 -0
- package/dist/runtime/vi/index.js +209 -0
- package/dist/runtime/vi/index.js.map +1 -0
- package/dist/runtime/vi/spy.d.ts +54 -0
- package/dist/runtime/vi/spy.d.ts.map +1 -0
- package/dist/runtime/vi/spy.js +159 -0
- package/dist/runtime/vi/spy.js.map +1 -0
- package/dist/runtime/vi/spyOn.d.ts +28 -0
- package/dist/runtime/vi/spyOn.d.ts.map +1 -0
- package/dist/runtime/vi/spyOn.js +121 -0
- package/dist/runtime/vi/spyOn.js.map +1 -0
- package/dist/runtime/vi/system-time.d.ts +30 -0
- package/dist/runtime/vi/system-time.d.ts.map +1 -0
- package/dist/runtime/vi/system-time.js +100 -0
- package/dist/runtime/vi/system-time.js.map +1 -0
- package/dist/runtime/worker.d.ts +26 -0
- package/dist/runtime/worker.d.ts.map +1 -0
- package/dist/runtime/worker.js +195 -0
- package/dist/runtime/worker.js.map +1 -0
- package/dist/time/freeze.d.ts +80 -0
- package/dist/time/freeze.d.ts.map +1 -0
- package/dist/time/freeze.js +184 -0
- package/dist/time/freeze.js.map +1 -0
- package/{src/time/index.ts → dist/time/index.d.ts} +1 -1
- package/dist/time/index.d.ts.map +1 -0
- package/dist/time/index.js +15 -0
- package/dist/time/index.js.map +1 -0
- package/index.darwin-arm64.node +0 -0
- package/index.darwin-x64.node +0 -0
- package/index.linux-arm64-gnu.node +0 -0
- package/index.linux-x64-gnu.node +0 -0
- package/index.win32-x64-msvc.node +0 -0
- package/package.json +2 -2
- package/src/cli/coverage/aggregate.ts +0 -231
- package/src/cli/coverage/collect.ts +0 -63
- package/src/cli/coverage/diff/base.ts +0 -46
- package/src/cli/coverage/diff/index.ts +0 -160
- package/src/cli/coverage/diff/overlay.ts +0 -62
- package/src/cli/coverage/diff/parse.ts +0 -121
- package/src/cli/coverage/diff/reporters.ts +0 -82
- package/src/cli/coverage/diff/types.ts +0 -46
- package/src/cli/coverage/filter.ts +0 -71
- package/src/cli/coverage/glob.ts +0 -0
- package/src/cli/coverage/index.ts +0 -126
- package/src/cli/coverage/reporters/json.ts +0 -40
- package/src/cli/coverage/reporters/lcov.ts +0 -54
- package/src/cli/coverage/reporters/text.ts +0 -48
- package/src/cli/coverage/thresholds.ts +0 -73
- package/src/cli/coverage/types.ts +0 -93
- package/src/cli/discover.ts +0 -174
- package/src/cli/native.ts +0 -104
- package/src/cli/pool.ts +0 -486
- package/src/cli/reporter.ts +0 -155
- package/src/cli/run.ts +0 -440
- package/src/cli/summary.ts +0 -42
- package/src/cli/watch/loop.ts +0 -159
- package/src/cli/watch/types.ts +0 -22
- package/src/cli/watch/watcher.ts +0 -145
- package/src/container/index.ts +0 -16
- package/src/runtime/assertion-error.ts +0 -38
- package/src/runtime/cli-worker.ts +0 -140
- package/src/runtime/equals.ts +0 -400
- package/src/runtime/expect.ts +0 -173
- package/src/runtime/matchers.ts +0 -452
- package/src/runtime/run.ts +0 -573
- package/src/runtime/suite.ts +0 -310
- package/src/runtime/test-context.ts +0 -59
- package/src/runtime/vi/fake-timers.ts +0 -410
- package/src/runtime/vi/index.ts +0 -254
- package/src/runtime/vi/spy.ts +0 -224
- package/src/runtime/vi/spyOn.ts +0 -155
- package/src/runtime/vi/system-time.ts +0 -121
- package/src/runtime/worker.ts +0 -239
- package/src/time/freeze.ts +0 -229
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `expect(value)` engine — chainable assertion API compatible with Vitest.
|
|
3
|
+
*
|
|
4
|
+
* Supports:
|
|
5
|
+
* - All matchers in `./matchers.ts`
|
|
6
|
+
* - `.not.<matcher>()` — inverts pass/fail
|
|
7
|
+
* - `.resolves.<matcher>()` / `.rejects.<matcher>()` — async awaits on received
|
|
8
|
+
* - All four combinations: `.resolves.not`, `.rejects.not`, `.not.resolves`, `.not.rejects`
|
|
9
|
+
*/
|
|
10
|
+
import { AssertionError } from "./assertion-error.js";
|
|
11
|
+
import { matchers } from "./matchers.js";
|
|
12
|
+
function evaluate(ctx, name, args) {
|
|
13
|
+
const matcher = matchers[name];
|
|
14
|
+
let result;
|
|
15
|
+
try {
|
|
16
|
+
result = matcher(ctx.received, ...args);
|
|
17
|
+
}
|
|
18
|
+
catch (err) {
|
|
19
|
+
// A matcher threw unexpectedly (e.g. a user-supplied constructor with
|
|
20
|
+
// a throwing `Symbol.hasInstance`). Surface it as a normal assertion
|
|
21
|
+
// failure so reporters can render it uniformly.
|
|
22
|
+
const why = err instanceof Error ? err.message : String(err);
|
|
23
|
+
throw new AssertionError({
|
|
24
|
+
message: `matcher ${name} threw: ${why}`,
|
|
25
|
+
actual: ctx.received,
|
|
26
|
+
expected: args.length === 1 ? args[0] : args,
|
|
27
|
+
operator: ctx.negate ? `not.${name}` : name,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
const pass = ctx.negate ? !result.pass : result.pass;
|
|
31
|
+
if (pass)
|
|
32
|
+
return;
|
|
33
|
+
const prefix = ctx.negate ? "expected NOT: " : "";
|
|
34
|
+
throw new AssertionError({
|
|
35
|
+
message: `${prefix}${result.message()}`,
|
|
36
|
+
actual: ctx.received,
|
|
37
|
+
expected: args,
|
|
38
|
+
operator: ctx.negate ? `not.${name}` : name,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
const matcherNames = Object.keys(matchers);
|
|
42
|
+
function buildSync(received, negate) {
|
|
43
|
+
const api = {};
|
|
44
|
+
for (const name of matcherNames) {
|
|
45
|
+
const fn = (...args) => evaluate({ received, negate }, name, args);
|
|
46
|
+
Reflect.set(api, name, fn);
|
|
47
|
+
}
|
|
48
|
+
return api;
|
|
49
|
+
}
|
|
50
|
+
function buildAsync(received, mode, negate) {
|
|
51
|
+
const api = {};
|
|
52
|
+
for (const name of matcherNames) {
|
|
53
|
+
const fn = async (...args) => {
|
|
54
|
+
if (!received ||
|
|
55
|
+
typeof received.then !== "function") {
|
|
56
|
+
throw new AssertionError({
|
|
57
|
+
message: `expected a Promise (for .${mode}), got ${typeof received}`,
|
|
58
|
+
operator: `${mode}.${name}`,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
let resolved;
|
|
62
|
+
let rejected;
|
|
63
|
+
let didReject = false;
|
|
64
|
+
try {
|
|
65
|
+
resolved = await received;
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
rejected = err;
|
|
69
|
+
didReject = true;
|
|
70
|
+
}
|
|
71
|
+
if (mode === "resolves") {
|
|
72
|
+
if (didReject) {
|
|
73
|
+
throw new AssertionError({
|
|
74
|
+
message: `expected promise to resolve, but it rejected with ${String(rejected)}`,
|
|
75
|
+
operator: `resolves.${name}`,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
evaluate({ received: resolved, negate }, name, args);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (!didReject) {
|
|
82
|
+
throw new AssertionError({
|
|
83
|
+
message: `expected promise to reject, but it resolved with ${String(resolved)}`,
|
|
84
|
+
operator: `rejects.${name}`,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
// `.rejects.toThrow(...)` feeds the rejection into toThrow's
|
|
88
|
+
// function-scoped contract by wrapping it in a rethrowing thunk.
|
|
89
|
+
const target = name === "toThrow"
|
|
90
|
+
? () => {
|
|
91
|
+
throw rejected;
|
|
92
|
+
}
|
|
93
|
+
: rejected;
|
|
94
|
+
evaluate({ received: target, negate }, name, args);
|
|
95
|
+
};
|
|
96
|
+
Reflect.set(api, name, fn);
|
|
97
|
+
}
|
|
98
|
+
return api;
|
|
99
|
+
}
|
|
100
|
+
export function expect(received) {
|
|
101
|
+
const base = buildSync(received, false);
|
|
102
|
+
// `.not` returns a chain that negates every matcher. It also exposes
|
|
103
|
+
// `.resolves` / `.rejects` so `expect(p).not.resolves.toBe(x)` works, matching
|
|
104
|
+
// Vitest's full surface.
|
|
105
|
+
const notSync = Object.assign(buildSync(received, true), {
|
|
106
|
+
resolves: buildAsync(received, "resolves", true),
|
|
107
|
+
rejects: buildAsync(received, "rejects", true),
|
|
108
|
+
});
|
|
109
|
+
const resolves = Object.assign(buildAsync(received, "resolves", false), {
|
|
110
|
+
not: buildAsync(received, "resolves", true),
|
|
111
|
+
});
|
|
112
|
+
const rejects = Object.assign(buildAsync(received, "rejects", false), {
|
|
113
|
+
not: buildAsync(received, "rejects", true),
|
|
114
|
+
});
|
|
115
|
+
return Object.assign(base, {
|
|
116
|
+
not: notSync,
|
|
117
|
+
resolves,
|
|
118
|
+
rejects,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=expect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expect.js","sourceRoot":"","sources":["../../src/runtime/expect.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
* get the full DSL. The runtime is orchestrator-agnostic: a Node child
|
|
6
6
|
* process, a Bun worker, or a Rust-spawned worker all load the same module.
|
|
7
7
|
*/
|
|
8
|
-
|
|
9
8
|
export type { AssertionErrorInit } from "./assertion-error.js";
|
|
10
9
|
export { AssertionError, isAssertionError } from "./assertion-error.js";
|
|
11
10
|
export type { EqualsOptions } from "./equals.js";
|
|
@@ -13,38 +12,17 @@ export { equals, partialEquals } from "./equals.js";
|
|
|
13
12
|
export type { Assertion } from "./expect.js";
|
|
14
13
|
export { expect } from "./expect.js";
|
|
15
14
|
export type { Hook, HookType } from "./lifecycle.js";
|
|
16
|
-
export {
|
|
17
|
-
addHook,
|
|
18
|
-
afterAll,
|
|
19
|
-
afterEach,
|
|
20
|
-
beforeAll,
|
|
21
|
-
beforeEach,
|
|
22
|
-
} from "./lifecycle.js";
|
|
15
|
+
export { addHook, afterAll, afterEach, beforeAll, beforeEach, } from "./lifecycle.js";
|
|
23
16
|
export type { MatcherName, MatcherResult, SpyLike } from "./matchers.js";
|
|
24
17
|
export { matchers } from "./matchers.js";
|
|
25
|
-
export type {
|
|
26
|
-
FileResult,
|
|
27
|
-
SerializedError,
|
|
28
|
-
SuiteResult,
|
|
29
|
-
TestResult,
|
|
30
|
-
} from "./run.js";
|
|
18
|
+
export type { FileResult, SerializedError, SuiteResult, TestResult, } from "./run.js";
|
|
31
19
|
export { executeRoot } from "./run.js";
|
|
32
20
|
export type { RunMode, SuiteNode, TestFn, TestNode } from "./suite.js";
|
|
33
|
-
export {
|
|
34
|
-
describe,
|
|
35
|
-
getRoot,
|
|
36
|
-
it,
|
|
37
|
-
resetRoot,
|
|
38
|
-
test,
|
|
39
|
-
} from "./suite.js";
|
|
21
|
+
export { describe, getRoot, it, resetRoot, test, } from "./suite.js";
|
|
40
22
|
export type { Vi } from "./vi/index.js";
|
|
41
23
|
export { vi, withViContext } from "./vi/index.js";
|
|
42
|
-
export type {
|
|
43
|
-
CreateSpyOptions,
|
|
44
|
-
MockCallResult,
|
|
45
|
-
MockInternals,
|
|
46
|
-
Spy,
|
|
47
|
-
} from "./vi/spy.js";
|
|
24
|
+
export type { CreateSpyOptions, MockCallResult, MockInternals, Spy, } from "./vi/spy.js";
|
|
48
25
|
export type { SpyOnOptions } from "./vi/spyOn.js";
|
|
49
26
|
export type { RunFileOptions } from "./worker.js";
|
|
50
27
|
export { runTestFile } from "./worker.js";
|
|
28
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,YAAY,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACpD,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EACN,OAAO,EACP,QAAQ,EACR,SAAS,EACT,SAAS,EACT,UAAU,GACV,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,YAAY,EACX,UAAU,EACV,eAAe,EACf,WAAW,EACX,UAAU,GACV,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,EACN,QAAQ,EACR,OAAO,EACP,EAAE,EACF,SAAS,EACT,IAAI,GACJ,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,EAAE,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,EAAE,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAClD,YAAY,EACX,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,GAAG,GACH,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@c9up/helix/runtime` — public surface of the Vitest-compatible test runtime.
|
|
3
|
+
*
|
|
4
|
+
* Test files can `import { describe, test, expect } from "@c9up/helix"` and
|
|
5
|
+
* get the full DSL. The runtime is orchestrator-agnostic: a Node child
|
|
6
|
+
* process, a Bun worker, or a Rust-spawned worker all load the same module.
|
|
7
|
+
*/
|
|
8
|
+
export { AssertionError, isAssertionError } from "./assertion-error.js";
|
|
9
|
+
export { equals, partialEquals } from "./equals.js";
|
|
10
|
+
export { expect } from "./expect.js";
|
|
11
|
+
export { addHook, afterAll, afterEach, beforeAll, beforeEach, } from "./lifecycle.js";
|
|
12
|
+
export { matchers } from "./matchers.js";
|
|
13
|
+
export { executeRoot } from "./run.js";
|
|
14
|
+
export { describe, getRoot, it, resetRoot, test, } from "./suite.js";
|
|
15
|
+
export { vi, withViContext } from "./vi/index.js";
|
|
16
|
+
export { runTestFile } from "./worker.js";
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEpD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EACN,OAAO,EACP,QAAQ,EACR,SAAS,EACT,SAAS,EACT,UAAU,GACV,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAOzC,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAEvC,OAAO,EACN,QAAQ,EACR,OAAO,EACP,EAAE,EACF,SAAS,EACT,IAAI,GACJ,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,EAAE,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AASlD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -6,12 +6,6 @@
|
|
|
6
6
|
* stable import path for reporters/plugins that want hooks without the full
|
|
7
7
|
* DSL surface.
|
|
8
8
|
*/
|
|
9
|
-
|
|
10
9
|
export type { Hook, HookType } from "./suite.js";
|
|
11
|
-
export {
|
|
12
|
-
|
|
13
|
-
afterAll,
|
|
14
|
-
afterEach,
|
|
15
|
-
beforeAll,
|
|
16
|
-
beforeEach,
|
|
17
|
-
} from "./suite.js";
|
|
10
|
+
export { addHook, afterAll, afterEach, beforeAll, beforeEach, } from "./suite.js";
|
|
11
|
+
//# sourceMappingURL=lifecycle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../src/runtime/lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EACN,OAAO,EACP,QAAQ,EACR,SAAS,EACT,SAAS,EACT,UAAU,GACV,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public re-exports for lifecycle hooks.
|
|
3
|
+
*
|
|
4
|
+
* The actual registration lives in `./suite.ts` (hooks are attached to the
|
|
5
|
+
* currently-active suite on the collection stack). This module exists as a
|
|
6
|
+
* stable import path for reporters/plugins that want hooks without the full
|
|
7
|
+
* DSL surface.
|
|
8
|
+
*/
|
|
9
|
+
export { addHook, afterAll, afterEach, beforeAll, beforeEach, } from "./suite.js";
|
|
10
|
+
//# sourceMappingURL=lifecycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../src/runtime/lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EACN,OAAO,EACP,QAAQ,EACR,SAAS,EACT,SAAS,EACT,UAAU,GACV,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Matcher signature. Returns `{ pass, message }`:
|
|
3
|
+
* - `pass`: whether the assertion holds.
|
|
4
|
+
* - `message`: diagnostic message for the failure path. Called lazily to
|
|
5
|
+
* avoid formatting cost when the matcher passes.
|
|
6
|
+
*/
|
|
7
|
+
export interface MatcherResult {
|
|
8
|
+
pass: boolean;
|
|
9
|
+
message(): string;
|
|
10
|
+
}
|
|
11
|
+
export type Matcher<Args extends unknown[] = unknown[]> = (received: unknown, ...args: Args) => MatcherResult;
|
|
12
|
+
export interface SpyLike {
|
|
13
|
+
__helixIsSpy: true;
|
|
14
|
+
calls: unknown[][];
|
|
15
|
+
callCount: number;
|
|
16
|
+
}
|
|
17
|
+
export declare const matchers: {
|
|
18
|
+
toBe(received: unknown, expected: unknown): MatcherResult;
|
|
19
|
+
toEqual(received: unknown, expected: unknown): MatcherResult;
|
|
20
|
+
toMatchObject(received: unknown, expected: unknown): MatcherResult;
|
|
21
|
+
toContain(received: unknown, item: unknown): MatcherResult;
|
|
22
|
+
toMatch(received: unknown, expected: RegExp | string): MatcherResult;
|
|
23
|
+
toHaveLength(received: unknown, length: number): MatcherResult;
|
|
24
|
+
toBeDefined(received: unknown): MatcherResult;
|
|
25
|
+
toBeUndefined(received: unknown): MatcherResult;
|
|
26
|
+
toBeNull(received: unknown): MatcherResult;
|
|
27
|
+
toBeInstanceOf(received: unknown, ctor: unknown): MatcherResult;
|
|
28
|
+
toBeGreaterThan(received: unknown, expected: number | bigint): MatcherResult;
|
|
29
|
+
toBeGreaterThanOrEqual(received: unknown, expected: number | bigint): MatcherResult;
|
|
30
|
+
toBeLessThan(received: unknown, expected: number | bigint): MatcherResult;
|
|
31
|
+
toBeLessThanOrEqual(received: unknown, expected: number | bigint): MatcherResult;
|
|
32
|
+
toBeTruthy(received: unknown): MatcherResult;
|
|
33
|
+
toBeFalsy(received: unknown): MatcherResult;
|
|
34
|
+
toBeNaN(received: unknown): MatcherResult;
|
|
35
|
+
toThrow(received: unknown, expected?: string | RegExp | Error | (new (...args: unknown[]) => Error)): MatcherResult;
|
|
36
|
+
toHaveBeenCalled(received: unknown): MatcherResult;
|
|
37
|
+
toHaveBeenCalledTimes(received: unknown, n: number): MatcherResult;
|
|
38
|
+
toHaveBeenCalledWith(received: unknown, ...expectedArgs: unknown[]): MatcherResult;
|
|
39
|
+
toHaveBeenCalledOnce(received: unknown): MatcherResult;
|
|
40
|
+
};
|
|
41
|
+
export type MatcherName = keyof typeof matchers;
|
|
42
|
+
//# sourceMappingURL=matchers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matchers.d.ts","sourceRoot":"","sources":["../../src/runtime/matchers.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,IAAI,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,OAAO,CAAC,IAAI,SAAS,OAAO,EAAE,GAAG,OAAO,EAAE,IAAI,CACzD,QAAQ,EAAE,OAAO,EACjB,GAAG,IAAI,EAAE,IAAI,KACT,aAAa,CAAC;AAEnB,MAAM,WAAW,OAAO;IACvB,YAAY,EAAE,IAAI,CAAC;IACnB,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CAClB;AAuCD,eAAO,MAAM,QAAQ;mBACL,OAAO,YAAY,OAAO,GAAG,aAAa;sBASvC,OAAO,YAAY,OAAO,GAAG,aAAa;4BASpC,OAAO,YAAY,OAAO,GAAG,aAAa;wBAS9C,OAAO,QAAQ,OAAO,GAAG,aAAa;sBAyBxC,OAAO,YAAY,MAAM,GAAG,MAAM,GAAG,aAAa;2BAmB7C,OAAO,UAAU,MAAM,GAAG,aAAa;0BAYxC,OAAO,GAAG,aAAa;4BAOrB,OAAO,GAAG,aAAa;uBAO5B,OAAO,GAAG,aAAa;6BAOjB,OAAO,QAAQ,OAAO,GAAG,aAAa;8BA+BrC,OAAO,YAAY,MAAM,GAAG,MAAM,GAAG,aAAa;qCAcjE,OAAO,YACP,MAAM,GAAG,MAAM,GACvB,aAAa;2BAaO,OAAO,YAAY,MAAM,GAAG,MAAM,GAAG,aAAa;kCAc9D,OAAO,YACP,MAAM,GAAG,MAAM,GACvB,aAAa;yBAaK,OAAO,GAAG,aAAa;wBAOxB,OAAO,GAAG,aAAa;sBAOzB,OAAO,GAAG,aAAa;sBAQ9B,OAAO,aACN,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,CAAC,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,KAAK,CAAC,GACtE,aAAa;+BA4CW,OAAO,GAAG,aAAa;oCAelB,OAAO,KAAK,MAAM,GAAG,aAAa;mCAgBvD,OAAO,mBACA,OAAO,EAAE,GACxB,aAAa;mCAkBe,OAAO,GAAG,aAAa;CActD,CAAC;AA+DF,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,QAAQ,CAAC"}
|
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
import { equals, partialEquals } from "./equals.js";
|
|
2
|
+
function isSpy(value) {
|
|
3
|
+
// Spies are callable, so `typeof` can be "function" OR "object".
|
|
4
|
+
if (!value || (typeof value !== "object" && typeof value !== "function")) {
|
|
5
|
+
return false;
|
|
6
|
+
}
|
|
7
|
+
const v = value;
|
|
8
|
+
return (v.__helixIsSpy === true &&
|
|
9
|
+
Array.isArray(v.calls) &&
|
|
10
|
+
typeof v.callCount === "number");
|
|
11
|
+
}
|
|
12
|
+
function repr(value, maxLen = 200) {
|
|
13
|
+
try {
|
|
14
|
+
if (typeof value === "string") {
|
|
15
|
+
const s = JSON.stringify(value);
|
|
16
|
+
return s.length > maxLen ? `${s.slice(0, maxLen)}..."` : s;
|
|
17
|
+
}
|
|
18
|
+
if (typeof value === "function") {
|
|
19
|
+
const src = value.toString();
|
|
20
|
+
return src.length > 40 ? `${src.slice(0, 40)}...` : src;
|
|
21
|
+
}
|
|
22
|
+
if (value === undefined)
|
|
23
|
+
return "undefined";
|
|
24
|
+
if (value === null)
|
|
25
|
+
return "null";
|
|
26
|
+
if (typeof value === "bigint")
|
|
27
|
+
return `${value}n`;
|
|
28
|
+
if (typeof value === "object") {
|
|
29
|
+
const json = JSON.stringify(value);
|
|
30
|
+
if (json === undefined)
|
|
31
|
+
return String(value);
|
|
32
|
+
return json.length > maxLen ? `${json.slice(0, maxLen)}...` : json;
|
|
33
|
+
}
|
|
34
|
+
return String(value);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return String(value);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export const matchers = {
|
|
41
|
+
toBe(received, expected) {
|
|
42
|
+
const pass = Object.is(received, expected);
|
|
43
|
+
return {
|
|
44
|
+
pass,
|
|
45
|
+
message: () => `expected ${repr(received)} to be ${repr(expected)} (strict equality)`,
|
|
46
|
+
};
|
|
47
|
+
},
|
|
48
|
+
toEqual(received, expected) {
|
|
49
|
+
const pass = equals(received, expected);
|
|
50
|
+
return {
|
|
51
|
+
pass,
|
|
52
|
+
message: () => `expected ${repr(received)} to deep-equal ${repr(expected)}`,
|
|
53
|
+
};
|
|
54
|
+
},
|
|
55
|
+
toMatchObject(received, expected) {
|
|
56
|
+
const pass = partialEquals(received, expected);
|
|
57
|
+
return {
|
|
58
|
+
pass,
|
|
59
|
+
message: () => `expected ${repr(received)} to match subset ${repr(expected)}`,
|
|
60
|
+
};
|
|
61
|
+
},
|
|
62
|
+
toContain(received, item) {
|
|
63
|
+
let pass = false;
|
|
64
|
+
if (typeof received === "string" && typeof item === "string") {
|
|
65
|
+
pass = received.includes(item);
|
|
66
|
+
}
|
|
67
|
+
else if (Array.isArray(received)) {
|
|
68
|
+
// Deep equality so `.toContain({id:1})` works on arrays of objects.
|
|
69
|
+
pass = received.some((x) => equals(x, item));
|
|
70
|
+
}
|
|
71
|
+
else if (received instanceof Set) {
|
|
72
|
+
// Deep equality: consistent with the Array branch.
|
|
73
|
+
for (const v of received) {
|
|
74
|
+
if (equals(v, item)) {
|
|
75
|
+
pass = true;
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// NB: `toContain` intentionally does not support `Map` — its semantics
|
|
81
|
+
// (keys? values? entries?) are ambiguous. Users should use
|
|
82
|
+
// `expect([...map.keys()]).toContain(k)` explicitly.
|
|
83
|
+
return {
|
|
84
|
+
pass,
|
|
85
|
+
message: () => `expected ${repr(received)} to contain ${repr(item)}`,
|
|
86
|
+
};
|
|
87
|
+
},
|
|
88
|
+
toMatch(received, expected) {
|
|
89
|
+
if (typeof received !== "string") {
|
|
90
|
+
return {
|
|
91
|
+
pass: false,
|
|
92
|
+
message: () => `expected a string, got ${typeof received} (${repr(received)})`,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
const pass = expected instanceof RegExp
|
|
96
|
+
? expected.test(received)
|
|
97
|
+
: received.includes(expected);
|
|
98
|
+
return {
|
|
99
|
+
pass,
|
|
100
|
+
message: () => `expected "${received}" to match ${expected instanceof RegExp ? expected : `"${expected}"`}`,
|
|
101
|
+
};
|
|
102
|
+
},
|
|
103
|
+
toHaveLength(received, length) {
|
|
104
|
+
const actual = received && typeof received.length === "number"
|
|
105
|
+
? received.length
|
|
106
|
+
: undefined;
|
|
107
|
+
return {
|
|
108
|
+
pass: actual === length,
|
|
109
|
+
message: () => `expected length ${length}, got ${actual === undefined ? "no .length" : actual} (value: ${repr(received)})`,
|
|
110
|
+
};
|
|
111
|
+
},
|
|
112
|
+
toBeDefined(received) {
|
|
113
|
+
return {
|
|
114
|
+
pass: received !== undefined,
|
|
115
|
+
message: () => `expected value to be defined, got undefined`,
|
|
116
|
+
};
|
|
117
|
+
},
|
|
118
|
+
toBeUndefined(received) {
|
|
119
|
+
return {
|
|
120
|
+
pass: received === undefined,
|
|
121
|
+
message: () => `expected value to be undefined, got ${repr(received)}`,
|
|
122
|
+
};
|
|
123
|
+
},
|
|
124
|
+
toBeNull(received) {
|
|
125
|
+
return {
|
|
126
|
+
pass: received === null,
|
|
127
|
+
message: () => `expected null, got ${repr(received)}`,
|
|
128
|
+
};
|
|
129
|
+
},
|
|
130
|
+
toBeInstanceOf(received, ctor) {
|
|
131
|
+
if (typeof ctor !== "function") {
|
|
132
|
+
return {
|
|
133
|
+
pass: false,
|
|
134
|
+
message: () => `expected a constructor, got ${typeof ctor}`,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
// Arrow functions and bound functions without `prototype` are not
|
|
138
|
+
// constructible; `x instanceof arrowFn` throws TypeError. Reject
|
|
139
|
+
// upfront with a clean AssertionError instead of leaking the raw error.
|
|
140
|
+
const ctorFn = ctor;
|
|
141
|
+
if (ctorFn.prototype === undefined) {
|
|
142
|
+
return {
|
|
143
|
+
pass: false,
|
|
144
|
+
message: () => `expected a constructor (function with a prototype), got ${ctorFn.name ?? "anonymous"} (arrow / bound fn?)`,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
let pass = false;
|
|
148
|
+
try {
|
|
149
|
+
pass = received instanceof ctor;
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
pass = false;
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
pass,
|
|
156
|
+
message: () => `expected ${repr(received)} to be instance of ${ctorFn.name ?? "anonymous"}`,
|
|
157
|
+
};
|
|
158
|
+
},
|
|
159
|
+
toBeGreaterThan(received, expected) {
|
|
160
|
+
if (typeof received !== "number" && typeof received !== "bigint") {
|
|
161
|
+
return {
|
|
162
|
+
pass: false,
|
|
163
|
+
message: () => `expected a number or bigint, got ${typeof received}`,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
return {
|
|
167
|
+
pass: compareGt(received, expected),
|
|
168
|
+
message: () => `expected ${received} to be > ${expected}`,
|
|
169
|
+
};
|
|
170
|
+
},
|
|
171
|
+
toBeGreaterThanOrEqual(received, expected) {
|
|
172
|
+
if (typeof received !== "number" && typeof received !== "bigint") {
|
|
173
|
+
return {
|
|
174
|
+
pass: false,
|
|
175
|
+
message: () => `expected a number or bigint, got ${typeof received}`,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
return {
|
|
179
|
+
pass: compareGte(received, expected),
|
|
180
|
+
message: () => `expected ${received} to be >= ${expected}`,
|
|
181
|
+
};
|
|
182
|
+
},
|
|
183
|
+
toBeLessThan(received, expected) {
|
|
184
|
+
if (typeof received !== "number" && typeof received !== "bigint") {
|
|
185
|
+
return {
|
|
186
|
+
pass: false,
|
|
187
|
+
message: () => `expected a number or bigint, got ${typeof received}`,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
return {
|
|
191
|
+
pass: compareLt(received, expected),
|
|
192
|
+
message: () => `expected ${received} to be < ${expected}`,
|
|
193
|
+
};
|
|
194
|
+
},
|
|
195
|
+
toBeLessThanOrEqual(received, expected) {
|
|
196
|
+
if (typeof received !== "number" && typeof received !== "bigint") {
|
|
197
|
+
return {
|
|
198
|
+
pass: false,
|
|
199
|
+
message: () => `expected a number or bigint, got ${typeof received}`,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
return {
|
|
203
|
+
pass: compareLte(received, expected),
|
|
204
|
+
message: () => `expected ${received} to be <= ${expected}`,
|
|
205
|
+
};
|
|
206
|
+
},
|
|
207
|
+
toBeTruthy(received) {
|
|
208
|
+
return {
|
|
209
|
+
pass: Boolean(received),
|
|
210
|
+
message: () => `expected ${repr(received)} to be truthy`,
|
|
211
|
+
};
|
|
212
|
+
},
|
|
213
|
+
toBeFalsy(received) {
|
|
214
|
+
return {
|
|
215
|
+
pass: !received,
|
|
216
|
+
message: () => `expected ${repr(received)} to be falsy`,
|
|
217
|
+
};
|
|
218
|
+
},
|
|
219
|
+
toBeNaN(received) {
|
|
220
|
+
return {
|
|
221
|
+
pass: typeof received === "number" && Number.isNaN(received),
|
|
222
|
+
message: () => `expected ${repr(received)} to be NaN`,
|
|
223
|
+
};
|
|
224
|
+
},
|
|
225
|
+
toThrow(received, expected) {
|
|
226
|
+
if (typeof received !== "function") {
|
|
227
|
+
return {
|
|
228
|
+
pass: false,
|
|
229
|
+
message: () => `expected a function, got ${typeof received}`,
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
let error;
|
|
233
|
+
let returned;
|
|
234
|
+
try {
|
|
235
|
+
returned = received();
|
|
236
|
+
}
|
|
237
|
+
catch (err) {
|
|
238
|
+
error = err;
|
|
239
|
+
}
|
|
240
|
+
if (error === undefined &&
|
|
241
|
+
returned &&
|
|
242
|
+
typeof returned.then === "function") {
|
|
243
|
+
// Swallow the rejection so it doesn't become an unhandledRejection.
|
|
244
|
+
returned.catch(() => { });
|
|
245
|
+
return {
|
|
246
|
+
pass: false,
|
|
247
|
+
message: () => `expected function to throw synchronously, but it returned a Promise — use \`expect(fn()).rejects.toThrow(...)\` for async`,
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
if (error === undefined) {
|
|
251
|
+
return {
|
|
252
|
+
pass: false,
|
|
253
|
+
message: () => `expected function to throw, but it returned normally`,
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
if (expected === undefined) {
|
|
257
|
+
return { pass: true, message: () => `` };
|
|
258
|
+
}
|
|
259
|
+
const pass = matchThrownError(error, expected);
|
|
260
|
+
return {
|
|
261
|
+
pass,
|
|
262
|
+
message: () => `expected function to throw matching ${reprExpected(expected)}, got ${repr(error)}`,
|
|
263
|
+
};
|
|
264
|
+
},
|
|
265
|
+
toHaveBeenCalled(received) {
|
|
266
|
+
if (!isSpy(received)) {
|
|
267
|
+
return {
|
|
268
|
+
pass: false,
|
|
269
|
+
message: () => `toHaveBeenCalled requires a spy (from vi.fn/vi.spyOn); got ${repr(received)}`,
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
return {
|
|
273
|
+
pass: received.callCount > 0,
|
|
274
|
+
message: () => `expected spy to have been called at least once, but it wasn't`,
|
|
275
|
+
};
|
|
276
|
+
},
|
|
277
|
+
toHaveBeenCalledTimes(received, n) {
|
|
278
|
+
if (!isSpy(received)) {
|
|
279
|
+
return {
|
|
280
|
+
pass: false,
|
|
281
|
+
message: () => `toHaveBeenCalledTimes requires a spy; got ${repr(received)}`,
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
return {
|
|
285
|
+
pass: received.callCount === n,
|
|
286
|
+
message: () => `expected spy to be called ${n} times, got ${received.callCount}`,
|
|
287
|
+
};
|
|
288
|
+
},
|
|
289
|
+
toHaveBeenCalledWith(received, ...expectedArgs) {
|
|
290
|
+
if (!isSpy(received)) {
|
|
291
|
+
return {
|
|
292
|
+
pass: false,
|
|
293
|
+
message: () => `toHaveBeenCalledWith requires a spy; got ${repr(received)}`,
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
const pass = received.calls.some((actualArgs) => equals(actualArgs, expectedArgs));
|
|
297
|
+
return {
|
|
298
|
+
pass,
|
|
299
|
+
message: () => `expected spy to have been called with ${repr(expectedArgs)}\nActual calls: ${repr(received.calls)}`,
|
|
300
|
+
};
|
|
301
|
+
},
|
|
302
|
+
toHaveBeenCalledOnce(received) {
|
|
303
|
+
if (!isSpy(received)) {
|
|
304
|
+
return {
|
|
305
|
+
pass: false,
|
|
306
|
+
message: () => `toHaveBeenCalledOnce requires a spy; got ${repr(received)}`,
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
return {
|
|
310
|
+
pass: received.callCount === 1,
|
|
311
|
+
message: () => `expected spy to have been called exactly once, got ${received.callCount} calls`,
|
|
312
|
+
};
|
|
313
|
+
},
|
|
314
|
+
};
|
|
315
|
+
/**
|
|
316
|
+
* Cross-type numeric comparison: JS's `>` / `>=` operators accept mixed
|
|
317
|
+
* `number` and `bigint` operands, but TypeScript refuses the union. These
|
|
318
|
+
* helpers narrow through typeof so the comparison is fully typed.
|
|
319
|
+
*/
|
|
320
|
+
function compareGt(a, b) {
|
|
321
|
+
if (typeof a === "number" && typeof b === "number")
|
|
322
|
+
return a > b;
|
|
323
|
+
if (typeof a === "bigint" && typeof b === "bigint")
|
|
324
|
+
return a > b;
|
|
325
|
+
// Mixed number/bigint — JS's `>` operator accepts it at runtime. Coerce
|
|
326
|
+
// both sides to a common `number` view for the comparison; BigInt values
|
|
327
|
+
// outside Number range lose precision only when larger than 2^53, which
|
|
328
|
+
// is acceptable for ordering.
|
|
329
|
+
return Number(a) > Number(b);
|
|
330
|
+
}
|
|
331
|
+
function compareGte(a, b) {
|
|
332
|
+
if (typeof a === "number" && typeof b === "number")
|
|
333
|
+
return a >= b;
|
|
334
|
+
if (typeof a === "bigint" && typeof b === "bigint")
|
|
335
|
+
return a >= b;
|
|
336
|
+
return Number(a) >= Number(b);
|
|
337
|
+
}
|
|
338
|
+
function compareLt(a, b) {
|
|
339
|
+
if (typeof a === "number" && typeof b === "number")
|
|
340
|
+
return a < b;
|
|
341
|
+
if (typeof a === "bigint" && typeof b === "bigint")
|
|
342
|
+
return a < b;
|
|
343
|
+
return Number(a) < Number(b);
|
|
344
|
+
}
|
|
345
|
+
function compareLte(a, b) {
|
|
346
|
+
if (typeof a === "number" && typeof b === "number")
|
|
347
|
+
return a <= b;
|
|
348
|
+
if (typeof a === "bigint" && typeof b === "bigint")
|
|
349
|
+
return a <= b;
|
|
350
|
+
return Number(a) <= Number(b);
|
|
351
|
+
}
|
|
352
|
+
function matchThrownError(error, expected) {
|
|
353
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
354
|
+
if (typeof expected === "string")
|
|
355
|
+
return msg.includes(expected);
|
|
356
|
+
if (expected instanceof RegExp)
|
|
357
|
+
return expected.test(msg);
|
|
358
|
+
if (expected instanceof Error) {
|
|
359
|
+
return (error instanceof Error &&
|
|
360
|
+
msg === expected.message &&
|
|
361
|
+
Object.getPrototypeOf(error) === Object.getPrototypeOf(expected));
|
|
362
|
+
}
|
|
363
|
+
// Ctor.
|
|
364
|
+
return error instanceof expected;
|
|
365
|
+
}
|
|
366
|
+
function reprExpected(expected) {
|
|
367
|
+
if (typeof expected === "string")
|
|
368
|
+
return `"${expected}"`;
|
|
369
|
+
if (expected instanceof RegExp)
|
|
370
|
+
return String(expected);
|
|
371
|
+
if (expected instanceof Error)
|
|
372
|
+
return `${expected.constructor.name}("${expected.message}")`;
|
|
373
|
+
return expected.name ?? "anonymous";
|
|
374
|
+
}
|
|
375
|
+
//# sourceMappingURL=matchers.js.map
|