@unrift/core 0.2.1 → 0.4.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/bin/unrift.mjs +2 -1
- package/dist/esm/cli.js +19 -13
- package/dist/esm/context.d.ts +1 -2
- package/dist/esm/context.d.ts.map +1 -1
- package/dist/esm/expect.d.ts +21 -1
- package/dist/esm/expect.d.ts.map +1 -1
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +3 -0
- package/dist/esm/interface.d.ts +3 -3
- package/dist/esm/interface.d.ts.map +1 -1
- package/dist/esm/interface.js +11 -6
- package/dist/esm/matchers.d.ts.map +1 -1
- package/dist/esm/matchers.js +261 -1
- package/dist/esm/mock/auto.d.ts +27 -0
- package/dist/esm/mock/auto.d.ts.map +1 -0
- package/dist/esm/mock/auto.js +108 -0
- package/dist/esm/mock/fetch.d.ts +47 -0
- package/dist/esm/mock/fetch.d.ts.map +1 -0
- package/dist/esm/mock/fetch.js +149 -0
- package/dist/esm/mock/fs.d.ts +54 -0
- package/dist/esm/mock/fs.d.ts.map +1 -0
- package/dist/esm/mock/fs.js +125 -0
- package/dist/esm/mock/index.d.ts +70 -0
- package/dist/esm/mock/index.d.ts.map +1 -0
- package/dist/esm/mock/index.js +70 -0
- package/dist/esm/mock/module-loader.d.ts +66 -0
- package/dist/esm/mock/module-loader.d.ts.map +1 -0
- package/dist/esm/mock/module-loader.js +123 -0
- package/dist/esm/mock/module.d.ts +99 -0
- package/dist/esm/mock/module.d.ts.map +1 -0
- package/dist/esm/mock/module.js +198 -0
- package/dist/esm/mock/register-loader.d.ts +17 -0
- package/dist/esm/mock/register-loader.d.ts.map +1 -0
- package/dist/esm/mock/register-loader.js +45 -0
- package/dist/esm/mock/spy.d.ts +73 -0
- package/dist/esm/mock/spy.d.ts.map +1 -0
- package/dist/esm/mock/spy.js +307 -0
- package/dist/esm/mock/stub.d.ts +26 -0
- package/dist/esm/mock/stub.d.ts.map +1 -0
- package/dist/esm/mock/stub.js +82 -0
- package/dist/esm/mock/timers.d.ts +51 -0
- package/dist/esm/mock/timers.d.ts.map +1 -0
- package/dist/esm/mock/timers.js +581 -0
- package/dist/esm/runner.d.ts +1 -0
- package/dist/esm/runner.d.ts.map +1 -1
- package/dist/esm/runner.js +138 -28
- package/dist/esm/test.d.ts +3 -2
- package/dist/esm/test.d.ts.map +1 -1
- package/dist/esm/test.js +17 -7
- package/dist/esm/types.d.ts +0 -1
- package/dist/esm/types.d.ts.map +1 -1
- package/dist/esm/types.js +0 -1
- package/dist/esm/utils/compareEngine.d.ts.map +1 -1
- package/dist/esm/utils/compareEngine.js +32 -1
- package/dist/esm/utils/defineConfig.d.ts +0 -1
- package/dist/esm/utils/defineConfig.d.ts.map +1 -1
- package/dist/esm/utils/diff.d.ts.map +1 -1
- package/dist/esm/utils/diff.js +31 -0
- package/dist/esm/utils/discoverTestFiles.js +1 -1
- package/dist/esm/utils/helpers.d.ts +21 -0
- package/dist/esm/utils/helpers.d.ts.map +1 -1
- package/dist/esm/utils/helpers.js +97 -0
- package/dist/esm/utils/loadConfig.d.ts.map +1 -1
- package/dist/esm/utils/loadConfig.js +2 -2
- package/dist/esm/utils/toThrow.d.ts.map +1 -1
- package/dist/esm/utils/toThrow.js +2 -1
- package/package.json +8 -3
package/bin/unrift.mjs
CHANGED
package/dist/esm/cli.js
CHANGED
|
@@ -2,7 +2,13 @@
|
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
3
|
import { dirname, resolve } from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
|
-
import {
|
|
5
|
+
import { registerModuleLoader } from "./mock/register-loader.js";
|
|
6
|
+
import { runTestsCLI, watchTestsCLI } from "./runner.js";
|
|
7
|
+
import { safeRegExp } from "./utils/helpers.js";
|
|
8
|
+
// Install the module-mock loader before any test file is imported. Both the
|
|
9
|
+
// core bin and the unrift wrapper bin run this CLI, so this is the single
|
|
10
|
+
// place module mocking is bootstrapped.
|
|
11
|
+
registerModuleLoader();
|
|
6
12
|
const __cliDir = dirname(fileURLToPath(import.meta.url));
|
|
7
13
|
function readVersion() {
|
|
8
14
|
// Walk up from current file to find package.json (works from both src/ and dist/esm/)
|
|
@@ -21,15 +27,6 @@ function readVersion() {
|
|
|
21
27
|
return "0.0.0";
|
|
22
28
|
}
|
|
23
29
|
const version = readVersion();
|
|
24
|
-
function safeRegExp(source) {
|
|
25
|
-
try {
|
|
26
|
-
return new RegExp(source);
|
|
27
|
-
}
|
|
28
|
-
catch (err) {
|
|
29
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
30
|
-
throw new Error(`Invalid pattern regex "${source}": ${msg}`);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
30
|
function printHelp() {
|
|
34
31
|
console.log(`
|
|
35
32
|
Unrift Test Runner v${version}
|
|
@@ -41,6 +38,7 @@ Options:
|
|
|
41
38
|
-c, --config <path> Path to config file
|
|
42
39
|
-b, --bail Stop on first test failure
|
|
43
40
|
-t, --timeout <ms> Default test timeout in milliseconds
|
|
41
|
+
-w, --watch Re-run tests on file changes
|
|
44
42
|
-d, --debug Enable debug logging
|
|
45
43
|
-l, --list List discovered test files
|
|
46
44
|
-j, --json Output test results as JSON
|
|
@@ -53,6 +51,7 @@ Examples:
|
|
|
53
51
|
unrift math
|
|
54
52
|
unrift -c test/config.ts --bail
|
|
55
53
|
unrift --timeout 10000
|
|
54
|
+
unrift --watch
|
|
56
55
|
`);
|
|
57
56
|
}
|
|
58
57
|
function parseArgs(argv) {
|
|
@@ -66,6 +65,7 @@ function parseArgs(argv) {
|
|
|
66
65
|
let list = false;
|
|
67
66
|
let json = false;
|
|
68
67
|
let cacheClean = false;
|
|
68
|
+
let watch = false;
|
|
69
69
|
const rest = [];
|
|
70
70
|
for (let i = 0; i < argv.length; i++) {
|
|
71
71
|
const a = argv[i];
|
|
@@ -111,6 +111,10 @@ function parseArgs(argv) {
|
|
|
111
111
|
i++;
|
|
112
112
|
continue;
|
|
113
113
|
}
|
|
114
|
+
if (a === "--watch" || a === "-w") {
|
|
115
|
+
watch = true;
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
114
118
|
if (a === "--cache-clean" || a === "--clear-cache") {
|
|
115
119
|
cacheClean = true;
|
|
116
120
|
continue;
|
|
@@ -129,11 +133,12 @@ function parseArgs(argv) {
|
|
|
129
133
|
list,
|
|
130
134
|
json,
|
|
131
135
|
cacheClean,
|
|
136
|
+
watch,
|
|
132
137
|
help,
|
|
133
138
|
showVersion,
|
|
134
139
|
};
|
|
135
140
|
}
|
|
136
|
-
const { configPath, pattern, timeoutMs, bail, debug, list, json, cacheClean, help, showVersion, } = parseArgs(process.argv.slice(2));
|
|
141
|
+
const { configPath, pattern, timeoutMs, bail, debug, list, json, cacheClean, watch, help, showVersion, } = parseArgs(process.argv.slice(2));
|
|
137
142
|
if (showVersion) {
|
|
138
143
|
console.log(version);
|
|
139
144
|
process.exit(0);
|
|
@@ -142,7 +147,7 @@ if (help) {
|
|
|
142
147
|
printHelp();
|
|
143
148
|
process.exit(0);
|
|
144
149
|
}
|
|
145
|
-
|
|
150
|
+
const runOpts = {
|
|
146
151
|
pattern,
|
|
147
152
|
configPath,
|
|
148
153
|
timeoutMs,
|
|
@@ -151,7 +156,8 @@ runTestsCLI({
|
|
|
151
156
|
list,
|
|
152
157
|
json,
|
|
153
158
|
cacheClean,
|
|
154
|
-
}
|
|
159
|
+
};
|
|
160
|
+
(watch ? watchTestsCLI(runOpts) : runTestsCLI(runOpts)).catch((err) => {
|
|
155
161
|
console.error(err);
|
|
156
162
|
process.exit(1);
|
|
157
163
|
});
|
package/dist/esm/context.d.ts
CHANGED
|
@@ -4,10 +4,9 @@ export declare enum RunState {
|
|
|
4
4
|
Run = "run",
|
|
5
5
|
Idle = "idle"
|
|
6
6
|
}
|
|
7
|
-
type UnriftState = RunState;
|
|
8
7
|
interface UnriftGlobalContext {
|
|
9
8
|
currentSuite: Suite | null;
|
|
10
|
-
state:
|
|
9
|
+
state: RunState;
|
|
11
10
|
}
|
|
12
11
|
export declare const unriftGlobalContext: UnriftGlobalContext;
|
|
13
12
|
export declare function assertRegisterState(apiName: string): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC,oBAAY,QAAQ;IAClB,QAAQ,aAAa;IACrB,GAAG,QAAQ;IACX,IAAI,SAAS;CACd;AAED,
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC,oBAAY,QAAQ;IAClB,QAAQ,aAAa;IACrB,GAAG,QAAQ;IACX,IAAI,SAAS;CACd;AAED,UAAU,mBAAmB;IAC3B,YAAY,EAAE,KAAK,GAAG,IAAI,CAAC;IAC3B,KAAK,EAAE,QAAQ,CAAC;CACjB;AAED,eAAO,MAAM,mBAAmB,EAAE,mBAGjC,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,QAOlD"}
|
package/dist/esm/expect.d.ts
CHANGED
|
@@ -13,13 +13,33 @@ export interface Matchers<T> {
|
|
|
13
13
|
toBeUndefined(): void | Promise<void>;
|
|
14
14
|
toBeGreaterThan(expected: number): void | Promise<void>;
|
|
15
15
|
toBeLessThan(expected: number): void | Promise<void>;
|
|
16
|
-
toBeInstanceOf(expected:
|
|
16
|
+
toBeInstanceOf(expected: {
|
|
17
|
+
prototype: unknown;
|
|
18
|
+
}): void | Promise<void>;
|
|
17
19
|
toContain(expected: unknown): void | Promise<void>;
|
|
18
20
|
toEqual(expected: unknown): void | Promise<void>;
|
|
19
21
|
toHaveLength(expected: number): void | Promise<void>;
|
|
20
22
|
toMatch(expected: RegExp | string): void | Promise<void>;
|
|
21
23
|
toStrictEqual(expected: unknown): void | Promise<void>;
|
|
22
24
|
toThrow(expected?: unknown): void | Promise<void>;
|
|
25
|
+
toBeGreaterThanOrEqual(expected: number): void | Promise<void>;
|
|
26
|
+
toBeLessThanOrEqual(expected: number): void | Promise<void>;
|
|
27
|
+
toBeNaN(): void | Promise<void>;
|
|
28
|
+
toBeFinite(): void | Promise<void>;
|
|
29
|
+
toMatchObject(expected: Record<string, unknown>): void | Promise<void>;
|
|
30
|
+
toHaveProperty(path: string | readonly string[], value?: unknown): void | Promise<void>;
|
|
31
|
+
toHaveBeenCalled(): void | Promise<void>;
|
|
32
|
+
toHaveBeenCalledTimes(expected: number): void | Promise<void>;
|
|
33
|
+
toHaveBeenCalledWith(...args: unknown[]): void | Promise<void>;
|
|
34
|
+
toHaveBeenLastCalledWith(...args: unknown[]): void | Promise<void>;
|
|
35
|
+
toHaveBeenNthCalledWith(n: number, ...args: unknown[]): void | Promise<void>;
|
|
36
|
+
toHaveReturned(): void | Promise<void>;
|
|
37
|
+
toHaveReturnedTimes(expected: number): void | Promise<void>;
|
|
38
|
+
toHaveReturnedWith(expected: unknown): void | Promise<void>;
|
|
39
|
+
toHaveLastReturnedWith(expected: unknown): void | Promise<void>;
|
|
40
|
+
toHaveNthReturnedWith(n: number, expected: unknown): void | Promise<void>;
|
|
41
|
+
toHaveFetched(urlOrMatcher: string | RegExp | ((req: Request) => boolean)): void | Promise<void>;
|
|
42
|
+
toHaveFetchedTimes(expected: number): void | Promise<void>;
|
|
23
43
|
readonly not: Matchers<T>;
|
|
24
44
|
readonly resolves: Matchers<Awaited<T>>;
|
|
25
45
|
readonly rejects: Matchers<unknown>;
|
package/dist/esm/expect.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"expect.d.ts","sourceRoot":"","sources":["../../src/expect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,UAAU,EAAE,MAAM,SAAS,CAAC;AAK1D,wBAAgB,cAAc,CAAC,WAAW,EAAE,UAAU,QAErD;AAED;;;GAGG;AACH,MAAM,WAAW,QAAQ,CAAC,CAAC;IACzB,IAAI,CAAC,QAAQ,EAAE,CAAC,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,WAAW,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,SAAS,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,QAAQ,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,UAAU,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,aAAa,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxD,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,cAAc,
|
|
1
|
+
{"version":3,"file":"expect.d.ts","sourceRoot":"","sources":["../../src/expect.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -4,5 +4,8 @@ export { describe, it, test } from "./interface";
|
|
|
4
4
|
export { expect, extendMatchers } from "./expect";
|
|
5
5
|
export type { Matchers, ExpectInterface } from "./expect";
|
|
6
6
|
export type { MatcherContext, MatcherFn, MatcherMap, Promisable, } from "./types";
|
|
7
|
+
export { runEngine } from "./run";
|
|
7
8
|
export type { RunEngineResult } from "./run";
|
|
9
|
+
export { mock, spy, spyOn, isSpy, mockObject, mockClass, stub, mockGlobal, mockFetch, mockFetchOnce, useFakeTimers, useRealTimers, advanceTimersByTime, advanceTimersByTimeAsync, runAllTimers, runAllTimersAsync, runOnlyPendingTimers, runOnlyPendingTimersAsync, getTimerCount, setSystemTime, getRealSystemTime, doMock, unmock, listMockedSpecs, fromModule, mockFs, clearAllMocks, resetAllMocks, restoreAllMocks, } from "./mock/index";
|
|
10
|
+
export type { Spy, MockState, MockResult, MockFetch, FetchMatcher, MockResponseInit, MockFetchResponse, UseFakeTimersOptions, FakeableApi, LoaderMessage, FakeFsHandle, FakeFsState, } from "./mock/index";
|
|
8
11
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/esm/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC9E,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAElD,YAAY,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC1D,YAAY,EACV,cAAc,EACd,SAAS,EACT,UAAU,EACV,UAAU,GACX,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC9E,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAElD,YAAY,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC1D,YAAY,EACV,cAAc,EACd,SAAS,EACT,UAAU,EACV,UAAU,GACX,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClC,YAAY,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AAG7C,OAAO,EACL,IAAI,EACJ,GAAG,EACH,KAAK,EACL,KAAK,EACL,UAAU,EACV,SAAS,EACT,IAAI,EACJ,UAAU,EACV,SAAS,EACT,aAAa,EACb,aAAa,EACb,aAAa,EACb,mBAAmB,EACnB,wBAAwB,EACxB,YAAY,EACZ,iBAAiB,EACjB,oBAAoB,EACpB,yBAAyB,EACzB,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,MAAM,EACN,MAAM,EACN,eAAe,EACf,UAAU,EACV,MAAM,EACN,aAAa,EACb,aAAa,EACb,eAAe,GAChB,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,GAAG,EACH,SAAS,EACT,UAAU,EACV,SAAS,EACT,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,WAAW,EACX,aAAa,EACb,YAAY,EACZ,WAAW,GACZ,MAAM,cAAc,CAAC"}
|
package/dist/esm/index.js
CHANGED
|
@@ -2,3 +2,6 @@ export { beforeEach, afterEach, beforeAll, afterAll } from "./hooks.js";
|
|
|
2
2
|
export { defineConfig } from "./utils/defineConfig.js";
|
|
3
3
|
export { describe, it, test } from "./interface.js";
|
|
4
4
|
export { expect, extendMatchers } from "./expect.js";
|
|
5
|
+
export { runEngine } from "./run.js";
|
|
6
|
+
// Mocking suite
|
|
7
|
+
export { mock, spy, spyOn, isSpy, mockObject, mockClass, stub, mockGlobal, mockFetch, mockFetchOnce, useFakeTimers, useRealTimers, advanceTimersByTime, advanceTimersByTimeAsync, runAllTimers, runAllTimersAsync, runOnlyPendingTimers, runOnlyPendingTimersAsync, getTimerCount, setSystemTime, getRealSystemTime, doMock, unmock, listMockedSpecs, fromModule, mockFs, clearAllMocks, resetAllMocks, restoreAllMocks, } from "./mock/index.js";
|
package/dist/esm/interface.d.ts
CHANGED
|
@@ -9,9 +9,9 @@ type DescribeFn = {
|
|
|
9
9
|
todo: (description: string) => void;
|
|
10
10
|
};
|
|
11
11
|
type ItFn = {
|
|
12
|
-
(description: string, fn: PromisableFn<void
|
|
13
|
-
only: (description: string, fn: PromisableFn<void
|
|
14
|
-
skip: (description: string, fn: PromisableFn<void
|
|
12
|
+
(description: string, fn: PromisableFn<void>, timeoutMs?: number): void;
|
|
13
|
+
only: (description: string, fn: PromisableFn<void>, timeoutMs?: number) => void;
|
|
14
|
+
skip: (description: string, fn: PromisableFn<void>, timeoutMs?: number) => void;
|
|
15
15
|
todo: (description: string) => void;
|
|
16
16
|
};
|
|
17
17
|
declare const describe: DescribeFn;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/interface.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,YAAY,EAAY,MAAM,SAAS,CAAC;AAEtD;;GAEG;AAEH,KAAK,UAAU,GAAG;IAChB,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAC5C,IAAI,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IACpD,IAAI,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IACpD,IAAI,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC,CAAC;AAEF,KAAK,IAAI,GAAG;IACV,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,YAAY,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/interface.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,YAAY,EAAY,MAAM,SAAS,CAAC;AAEtD;;GAEG;AAEH,KAAK,UAAU,GAAG;IAChB,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAC5C,IAAI,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IACpD,IAAI,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IACpD,IAAI,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC,CAAC;AAEF,KAAK,IAAI,GAAG;IACV,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxE,IAAI,EAAE,CACJ,WAAW,EAAE,MAAM,EACnB,EAAE,EAAE,YAAY,CAAC,IAAI,CAAC,EACtB,SAAS,CAAC,EAAE,MAAM,KACf,IAAI,CAAC;IACV,IAAI,EAAE,CACJ,WAAW,EAAE,MAAM,EACnB,EAAE,EAAE,YAAY,CAAC,IAAI,CAAC,EACtB,SAAS,CAAC,EAAE,MAAM,KACf,IAAI,CAAC;IACV,IAAI,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC,CAAC;AA6BF,QAAA,MAAM,QAAQ,EAAE,UAC8B,CAAC;AAmB/C,QAAA,MAAM,EAAE,EAAE,IACyC,CAAC;AAOpD,QAAA,MAAM,IAAI,EAAE,IAAS,CAAC;AAEtB,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC"}
|
package/dist/esm/interface.js
CHANGED
|
@@ -9,7 +9,12 @@ function _describe(description, fn, mode) {
|
|
|
9
9
|
parent.addSuite(suite);
|
|
10
10
|
unriftGlobalContext.currentSuite = suite;
|
|
11
11
|
try {
|
|
12
|
-
fn();
|
|
12
|
+
const result = fn();
|
|
13
|
+
if (result != null &&
|
|
14
|
+
typeof result.then === "function") {
|
|
15
|
+
throw new Error(`describe() callbacks must be synchronous. ` +
|
|
16
|
+
`Move async setup into beforeAll() or beforeEach().`);
|
|
17
|
+
}
|
|
13
18
|
}
|
|
14
19
|
finally {
|
|
15
20
|
unriftGlobalContext.currentSuite = parent;
|
|
@@ -19,14 +24,14 @@ const describe = (description, fn) => _describe(description, fn, TaskMode.Defaul
|
|
|
19
24
|
describe.only = (description, fn) => _describe(description, fn, TaskMode.Only);
|
|
20
25
|
describe.skip = (description, fn) => _describe(description, fn, TaskMode.Skip);
|
|
21
26
|
describe.todo = (description) => _describe(description, () => { }, TaskMode.Todo);
|
|
22
|
-
function _it(description, fn, mode) {
|
|
27
|
+
function _it(description, fn, mode, timeoutMs) {
|
|
23
28
|
assertRegisterState("it");
|
|
24
|
-
const test = new Test(description, fn, mode);
|
|
29
|
+
const test = new Test(description, fn, mode, timeoutMs);
|
|
25
30
|
getCurrentSuite().addTest(test);
|
|
26
31
|
}
|
|
27
|
-
const it = (description, fn) => _it(description, fn, TaskMode.Default);
|
|
28
|
-
it.only = (description, fn) => _it(description, fn, TaskMode.Only);
|
|
29
|
-
it.skip = (description, fn) => _it(description, fn, TaskMode.Skip);
|
|
32
|
+
const it = (description, fn, timeoutMs) => _it(description, fn, TaskMode.Default, timeoutMs);
|
|
33
|
+
it.only = (description, fn, timeoutMs) => _it(description, fn, TaskMode.Only, timeoutMs);
|
|
34
|
+
it.skip = (description, fn, timeoutMs) => _it(description, fn, TaskMode.Skip, timeoutMs);
|
|
30
35
|
it.todo = (description) => _it(description, () => { }, TaskMode.Todo);
|
|
31
36
|
const test = it;
|
|
32
37
|
export { describe, it, test };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"matchers.d.ts","sourceRoot":"","sources":["../../src/matchers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"matchers.d.ts","sourceRoot":"","sources":["../../src/matchers.ts"],"names":[],"mappings":"AAyGA,wBAAgB,sBAAsB,SAMrC;AAED,wBAAgB,aAAa,SAE5B"}
|
package/dist/esm/matchers.js
CHANGED
|
@@ -1,8 +1,81 @@
|
|
|
1
1
|
import { expect } from "./expect.js";
|
|
2
|
+
import { isSpy } from "./mock/spy.js";
|
|
3
|
+
import { isFetchMock } from "./mock/fetch.js";
|
|
2
4
|
import { deepEqual } from "./utils/deepEqual.js";
|
|
3
5
|
import { looseEqual } from "./utils/looseEqual.js";
|
|
6
|
+
import { regexTest } from "./utils/helpers.js";
|
|
4
7
|
import { toThrow } from "./utils/toThrow.js";
|
|
5
8
|
let matchersRegistered = false;
|
|
9
|
+
function ensureSpy(received, matcherName) {
|
|
10
|
+
if (!isSpy(received)) {
|
|
11
|
+
throw new Error(`${matcherName}() requires a spy or mock function (created via spy() or spyOn()), ` +
|
|
12
|
+
`but received ${typeof received === "object" ? Object.prototype.toString.call(received) : typeof received}`);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function ensureFetchMock(received, matcherName) {
|
|
16
|
+
if (!isFetchMock(received)) {
|
|
17
|
+
throw new Error(`${matcherName}() requires \`mock.fetch\` as the received value, ` +
|
|
18
|
+
`but received ${typeof received === "object" ? Object.prototype.toString.call(received) : typeof received}`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function matchesFetchTarget(req, target) {
|
|
22
|
+
if (typeof target === "string")
|
|
23
|
+
return req.url === target;
|
|
24
|
+
if (target instanceof RegExp)
|
|
25
|
+
return regexTest(target, req.url);
|
|
26
|
+
if (typeof target === "function")
|
|
27
|
+
return Boolean(target(req));
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
function argsEqual(a, b) {
|
|
31
|
+
if (a.length !== b.length)
|
|
32
|
+
return false;
|
|
33
|
+
for (let i = 0; i < a.length; i++) {
|
|
34
|
+
if (!looseEqual(a[i], b[i]))
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
function partialMatch(received, expected) {
|
|
40
|
+
if (expected === null || typeof expected !== "object") {
|
|
41
|
+
return looseEqual(received, expected);
|
|
42
|
+
}
|
|
43
|
+
if (Array.isArray(expected)) {
|
|
44
|
+
if (!Array.isArray(received))
|
|
45
|
+
return false;
|
|
46
|
+
if (received.length !== expected.length)
|
|
47
|
+
return false;
|
|
48
|
+
return expected.every((e, i) => partialMatch(received[i], e));
|
|
49
|
+
}
|
|
50
|
+
if (received === null ||
|
|
51
|
+
typeof received !== "object" ||
|
|
52
|
+
Array.isArray(received)) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
const recv = received;
|
|
56
|
+
const exp = expected;
|
|
57
|
+
for (const key of Object.keys(exp)) {
|
|
58
|
+
if (!Object.hasOwn(recv, key))
|
|
59
|
+
return false;
|
|
60
|
+
if (!partialMatch(recv[key], exp[key]))
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
function getNestedValue(obj, path) {
|
|
66
|
+
const keys = Array.isArray(path) ? path : path.split(".");
|
|
67
|
+
let current = obj;
|
|
68
|
+
for (const key of keys) {
|
|
69
|
+
if (current === null || typeof current !== "object") {
|
|
70
|
+
return { found: false, value: undefined };
|
|
71
|
+
}
|
|
72
|
+
const record = current;
|
|
73
|
+
if (!Object.hasOwn(record, key))
|
|
74
|
+
return { found: false, value: undefined };
|
|
75
|
+
current = record[key];
|
|
76
|
+
}
|
|
77
|
+
return { found: true, value: current };
|
|
78
|
+
}
|
|
6
79
|
export function ensureInternalMatchers() {
|
|
7
80
|
if (matchersRegistered)
|
|
8
81
|
return;
|
|
@@ -123,7 +196,7 @@ function registerCoreMatchers() {
|
|
|
123
196
|
}
|
|
124
197
|
const pass = typeof expected === "string"
|
|
125
198
|
? received.includes(expected)
|
|
126
|
-
: expected
|
|
199
|
+
: regexTest(expected, received);
|
|
127
200
|
if (this.isNot ? pass : !pass)
|
|
128
201
|
throw new Error(this.diff(received, expected));
|
|
129
202
|
},
|
|
@@ -138,5 +211,192 @@ function registerCoreMatchers() {
|
|
|
138
211
|
if (!pass)
|
|
139
212
|
throw new Error(message());
|
|
140
213
|
},
|
|
214
|
+
toBeGreaterThanOrEqual(received, expected) {
|
|
215
|
+
if (typeof received !== "number") {
|
|
216
|
+
throw new Error(this.diff(received, "expected a number"));
|
|
217
|
+
}
|
|
218
|
+
const pass = received >= expected;
|
|
219
|
+
if (this.isNot ? pass : !pass) {
|
|
220
|
+
throw new Error(this.diff(received, `>= ${expected}`));
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
toBeLessThanOrEqual(received, expected) {
|
|
224
|
+
if (typeof received !== "number") {
|
|
225
|
+
throw new Error(this.diff(received, "expected a number"));
|
|
226
|
+
}
|
|
227
|
+
const pass = received <= expected;
|
|
228
|
+
if (this.isNot ? pass : !pass) {
|
|
229
|
+
throw new Error(this.diff(received, `<= ${expected}`));
|
|
230
|
+
}
|
|
231
|
+
},
|
|
232
|
+
toBeNaN(received) {
|
|
233
|
+
const pass = Number.isNaN(received);
|
|
234
|
+
if (this.isNot ? pass : !pass) {
|
|
235
|
+
throw new Error(this.diff(received, "NaN"));
|
|
236
|
+
}
|
|
237
|
+
},
|
|
238
|
+
toBeFinite(received) {
|
|
239
|
+
const pass = Number.isFinite(received);
|
|
240
|
+
if (this.isNot ? pass : !pass) {
|
|
241
|
+
throw new Error(this.diff(received, "finite number"));
|
|
242
|
+
}
|
|
243
|
+
},
|
|
244
|
+
toMatchObject(received, expected) {
|
|
245
|
+
if (received === null ||
|
|
246
|
+
typeof received !== "object" ||
|
|
247
|
+
Array.isArray(received)) {
|
|
248
|
+
throw new Error(this.diff(received, "expected a non-array object for toMatchObject()"));
|
|
249
|
+
}
|
|
250
|
+
const pass = partialMatch(received, expected);
|
|
251
|
+
if (this.isNot ? pass : !pass) {
|
|
252
|
+
throw new Error(this.diff(received, expected));
|
|
253
|
+
}
|
|
254
|
+
},
|
|
255
|
+
toHaveBeenCalled(received) {
|
|
256
|
+
ensureSpy(received, "toHaveBeenCalled");
|
|
257
|
+
const pass = received.mock.calls.length > 0;
|
|
258
|
+
if (this.isNot ? pass : !pass) {
|
|
259
|
+
throw new Error(this.diff(`${received.getMockName()} called ${received.mock.calls.length} time(s)`, "to have been called"));
|
|
260
|
+
}
|
|
261
|
+
},
|
|
262
|
+
toHaveBeenCalledTimes(received, expected) {
|
|
263
|
+
ensureSpy(received, "toHaveBeenCalledTimes");
|
|
264
|
+
if (typeof expected !== "number" || !Number.isFinite(expected)) {
|
|
265
|
+
throw new Error(this.diff(expected, "toHaveBeenCalledTimes() requires a finite number"));
|
|
266
|
+
}
|
|
267
|
+
const actual = received.mock.calls.length;
|
|
268
|
+
const pass = actual === expected;
|
|
269
|
+
if (this.isNot ? pass : !pass) {
|
|
270
|
+
throw new Error(this.diff(actual, expected));
|
|
271
|
+
}
|
|
272
|
+
},
|
|
273
|
+
toHaveBeenCalledWith(received, ...expectedArgs) {
|
|
274
|
+
ensureSpy(received, "toHaveBeenCalledWith");
|
|
275
|
+
const pass = received.mock.calls.some((call) => argsEqual(call, expectedArgs));
|
|
276
|
+
if (this.isNot ? pass : !pass) {
|
|
277
|
+
throw new Error(this.diff(received.mock.calls, expectedArgs));
|
|
278
|
+
}
|
|
279
|
+
},
|
|
280
|
+
toHaveBeenLastCalledWith(received, ...expectedArgs) {
|
|
281
|
+
ensureSpy(received, "toHaveBeenLastCalledWith");
|
|
282
|
+
const last = received.mock.lastCall;
|
|
283
|
+
const pass = last !== undefined && argsEqual(last, expectedArgs);
|
|
284
|
+
if (this.isNot ? pass : !pass) {
|
|
285
|
+
throw new Error(this.diff(last ?? "no calls", expectedArgs));
|
|
286
|
+
}
|
|
287
|
+
},
|
|
288
|
+
toHaveBeenNthCalledWith(received, n, ...expectedArgs) {
|
|
289
|
+
ensureSpy(received, "toHaveBeenNthCalledWith");
|
|
290
|
+
if (typeof n !== "number" || !Number.isInteger(n) || n < 1) {
|
|
291
|
+
throw new Error(this.diff(n, "toHaveBeenNthCalledWith() requires a 1-indexed integer"));
|
|
292
|
+
}
|
|
293
|
+
const call = received.mock.calls[n - 1];
|
|
294
|
+
const pass = call !== undefined && argsEqual(call, expectedArgs);
|
|
295
|
+
if (this.isNot ? pass : !pass) {
|
|
296
|
+
throw new Error(this.diff(call ?? `call #${n} not found`, expectedArgs));
|
|
297
|
+
}
|
|
298
|
+
},
|
|
299
|
+
toHaveReturned(received) {
|
|
300
|
+
ensureSpy(received, "toHaveReturned");
|
|
301
|
+
const pass = received.mock.results.some((r) => r.type === "return");
|
|
302
|
+
if (this.isNot ? pass : !pass) {
|
|
303
|
+
throw new Error(this.diff(`${received.mock.results.length} result(s)`, "at least one successful return"));
|
|
304
|
+
}
|
|
305
|
+
},
|
|
306
|
+
toHaveReturnedTimes(received, expected) {
|
|
307
|
+
ensureSpy(received, "toHaveReturnedTimes");
|
|
308
|
+
if (typeof expected !== "number" || !Number.isFinite(expected)) {
|
|
309
|
+
throw new Error(this.diff(expected, "toHaveReturnedTimes() requires a finite number"));
|
|
310
|
+
}
|
|
311
|
+
const actual = received.mock.results.filter((r) => r.type === "return").length;
|
|
312
|
+
const pass = actual === expected;
|
|
313
|
+
if (this.isNot ? pass : !pass) {
|
|
314
|
+
throw new Error(this.diff(actual, expected));
|
|
315
|
+
}
|
|
316
|
+
},
|
|
317
|
+
toHaveReturnedWith(received, expected) {
|
|
318
|
+
ensureSpy(received, "toHaveReturnedWith");
|
|
319
|
+
const pass = received.mock.results.some((r) => r.type === "return" && looseEqual(r.value, expected));
|
|
320
|
+
if (this.isNot ? pass : !pass) {
|
|
321
|
+
const returnValues = received.mock.results
|
|
322
|
+
.filter((r) => r.type === "return")
|
|
323
|
+
.map((r) => r.value);
|
|
324
|
+
throw new Error(this.diff(returnValues, expected));
|
|
325
|
+
}
|
|
326
|
+
},
|
|
327
|
+
toHaveLastReturnedWith(received, expected) {
|
|
328
|
+
ensureSpy(received, "toHaveLastReturnedWith");
|
|
329
|
+
const results = received.mock.results;
|
|
330
|
+
const last = results[results.length - 1];
|
|
331
|
+
const pass = last !== undefined &&
|
|
332
|
+
last.type === "return" &&
|
|
333
|
+
looseEqual(last.value, expected);
|
|
334
|
+
if (this.isNot ? pass : !pass) {
|
|
335
|
+
if (last === undefined) {
|
|
336
|
+
throw new Error(this.diff("no calls", expected));
|
|
337
|
+
}
|
|
338
|
+
if (last.type === "throw") {
|
|
339
|
+
throw new Error(this.diff("last call threw", expected));
|
|
340
|
+
}
|
|
341
|
+
throw new Error(this.diff(last.value, expected));
|
|
342
|
+
}
|
|
343
|
+
},
|
|
344
|
+
toHaveNthReturnedWith(received, n, expected) {
|
|
345
|
+
ensureSpy(received, "toHaveNthReturnedWith");
|
|
346
|
+
if (typeof n !== "number" || !Number.isInteger(n) || n < 1) {
|
|
347
|
+
throw new Error(this.diff(n, "toHaveNthReturnedWith() requires a 1-indexed integer"));
|
|
348
|
+
}
|
|
349
|
+
const result = received.mock.results[n - 1];
|
|
350
|
+
const pass = result !== undefined &&
|
|
351
|
+
result.type === "return" &&
|
|
352
|
+
looseEqual(result.value, expected);
|
|
353
|
+
if (this.isNot ? pass : !pass) {
|
|
354
|
+
if (result === undefined) {
|
|
355
|
+
throw new Error(this.diff(`call #${n} not found`, expected));
|
|
356
|
+
}
|
|
357
|
+
if (result.type === "throw") {
|
|
358
|
+
throw new Error(this.diff(`call #${n} threw`, expected));
|
|
359
|
+
}
|
|
360
|
+
throw new Error(this.diff(result.value, expected));
|
|
361
|
+
}
|
|
362
|
+
},
|
|
363
|
+
toHaveFetched(received, target) {
|
|
364
|
+
ensureFetchMock(received, "toHaveFetched");
|
|
365
|
+
const pass = received.calls.some((req) => matchesFetchTarget(req, target));
|
|
366
|
+
if (this.isNot ? pass : !pass) {
|
|
367
|
+
const urls = received.calls.map((r) => `${r.method} ${r.url}`);
|
|
368
|
+
throw new Error(this.diff(urls, target));
|
|
369
|
+
}
|
|
370
|
+
},
|
|
371
|
+
toHaveFetchedTimes(received, expected) {
|
|
372
|
+
ensureFetchMock(received, "toHaveFetchedTimes");
|
|
373
|
+
if (typeof expected !== "number" || !Number.isFinite(expected)) {
|
|
374
|
+
throw new Error(this.diff(expected, "toHaveFetchedTimes() requires a finite number"));
|
|
375
|
+
}
|
|
376
|
+
const actual = received.calls.length;
|
|
377
|
+
const pass = actual === expected;
|
|
378
|
+
if (this.isNot ? pass : !pass) {
|
|
379
|
+
throw new Error(this.diff(actual, expected));
|
|
380
|
+
}
|
|
381
|
+
},
|
|
382
|
+
toHaveProperty(received, path, ...rest) {
|
|
383
|
+
if (received === null || typeof received !== "object") {
|
|
384
|
+
throw new Error(this.diff(received, "expected an object for toHaveProperty()"));
|
|
385
|
+
}
|
|
386
|
+
const normalizedPath = path;
|
|
387
|
+
const { found, value } = getNestedValue(received, normalizedPath);
|
|
388
|
+
const hasValue = rest.length > 0;
|
|
389
|
+
const expectedValue = rest[0];
|
|
390
|
+
const pass = hasValue ? found && looseEqual(value, expectedValue) : found;
|
|
391
|
+
if (this.isNot ? pass : !pass) {
|
|
392
|
+
const pathStr = Array.isArray(normalizedPath)
|
|
393
|
+
? normalizedPath.join(".")
|
|
394
|
+
: normalizedPath;
|
|
395
|
+
if (!found) {
|
|
396
|
+
throw new Error(this.diff(Object.keys(received), `property "${pathStr}"`));
|
|
397
|
+
}
|
|
398
|
+
throw new Error(this.diff(value, expectedValue));
|
|
399
|
+
}
|
|
400
|
+
},
|
|
141
401
|
});
|
|
142
402
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-mocking helpers: `mock.object` and `mock.class`.
|
|
3
|
+
*
|
|
4
|
+
* Both walk own + prototype methods and replace each function with a spy.
|
|
5
|
+
* Restoration uses the same registry as `spyOn`, so `mock.restoreAll()`
|
|
6
|
+
* cleans up auto mocks too.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Replace every method on `obj` (own + inherited, excluding Object.prototype)
|
|
10
|
+
* with a spy. Returns the same reference, mutated in place.
|
|
11
|
+
*
|
|
12
|
+
* Cleanup happens via `mock.restoreAll()` - auto-mock spies share the same
|
|
13
|
+
* restorer registry as `spyOn`.
|
|
14
|
+
*/
|
|
15
|
+
export declare function mockObject<T extends object>(obj: T): T;
|
|
16
|
+
/**
|
|
17
|
+
* Wrap a constructor so every instance is auto-mocked, and so static
|
|
18
|
+
* methods on the constructor itself are spied too. Returns a Proxy that
|
|
19
|
+
* is `instanceof`-compatible with the original.
|
|
20
|
+
*
|
|
21
|
+
* Instance methods are spied as OWN properties on each instance (shadowing
|
|
22
|
+
* the prototype), NOT by mutating the shared prototype. This keeps call
|
|
23
|
+
* state per-instance (a.run and b.run are separate spies) and leaves the
|
|
24
|
+
* class prototype untouched - nothing to restore, nothing to leak.
|
|
25
|
+
*/
|
|
26
|
+
export declare function mockClass<T extends new (...args: any[]) => any>(Ctor: T): T;
|
|
27
|
+
//# sourceMappingURL=auto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto.d.ts","sourceRoot":"","sources":["../../../src/mock/auto.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA+CH;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAatD;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAEvB,CAAC,SAAS,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EACrC,IAAI,EAAE,CAAC,GAAG,CAAC,CA8BZ"}
|