@unrift/core 0.0.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/LICENSE +21 -0
- package/bin/unrift.mjs +5 -0
- package/dist/cjs/index.cjs +31 -0
- package/dist/esm/cli.d.ts +3 -0
- package/dist/esm/cli.d.ts.map +1 -0
- package/dist/esm/cli.js +87 -0
- package/dist/esm/context.d.ts +15 -0
- package/dist/esm/context.d.ts.map +1 -0
- package/dist/esm/context.js +16 -0
- package/dist/esm/expect.d.ts +27 -0
- package/dist/esm/expect.d.ts.map +1 -0
- package/dist/esm/expect.js +43 -0
- package/dist/esm/hooks.d.ts +8 -0
- package/dist/esm/hooks.d.ts.map +1 -0
- package/dist/esm/hooks.js +18 -0
- package/dist/esm/index.d.ts +7 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +4 -0
- package/dist/esm/injected/globals.d.ts +4 -0
- package/dist/esm/injected/globals.d.ts.map +1 -0
- package/dist/esm/injected/globals.js +6 -0
- package/dist/esm/interface.d.ts +18 -0
- package/dist/esm/interface.d.ts.map +1 -0
- package/dist/esm/interface.js +29 -0
- package/dist/esm/matchers.d.ts +2 -0
- package/dist/esm/matchers.d.ts.map +1 -0
- package/dist/esm/matchers.js +81 -0
- package/dist/esm/run.d.ts +21 -0
- package/dist/esm/run.d.ts.map +1 -0
- package/dist/esm/run.js +57 -0
- package/dist/esm/runner.d.ts +14 -0
- package/dist/esm/runner.d.ts.map +1 -0
- package/dist/esm/runner.js +207 -0
- package/dist/esm/suite.d.ts +58 -0
- package/dist/esm/suite.d.ts.map +1 -0
- package/dist/esm/suite.js +281 -0
- package/dist/esm/test.d.ts +18 -0
- package/dist/esm/test.d.ts.map +1 -0
- package/dist/esm/test.js +52 -0
- package/dist/esm/types.d.ts +24 -0
- package/dist/esm/types.d.ts.map +1 -0
- package/dist/esm/types.js +16 -0
- package/dist/esm/utils/colors.d.ts +7 -0
- package/dist/esm/utils/colors.d.ts.map +1 -0
- package/dist/esm/utils/colors.js +12 -0
- package/dist/esm/utils/deepEqual.d.ts +9 -0
- package/dist/esm/utils/deepEqual.d.ts.map +1 -0
- package/dist/esm/utils/deepEqual.js +201 -0
- package/dist/esm/utils/defineConfig.d.ts +12 -0
- package/dist/esm/utils/defineConfig.d.ts.map +1 -0
- package/dist/esm/utils/defineConfig.js +3 -0
- package/dist/esm/utils/discoverTestFiles.d.ts +3 -0
- package/dist/esm/utils/discoverTestFiles.d.ts.map +1 -0
- package/dist/esm/utils/discoverTestFiles.js +22 -0
- package/dist/esm/utils/helpers.d.ts +13 -0
- package/dist/esm/utils/helpers.d.ts.map +1 -0
- package/dist/esm/utils/helpers.js +29 -0
- package/dist/esm/utils/loadConfig.d.ts +9 -0
- package/dist/esm/utils/loadConfig.d.ts.map +1 -0
- package/dist/esm/utils/loadConfig.js +89 -0
- package/dist/esm/utils/looseEqual.d.ts +2 -0
- package/dist/esm/utils/looseEqual.d.ts.map +1 -0
- package/dist/esm/utils/looseEqual.js +205 -0
- package/dist/esm/utils/toThrow.d.ts +11 -0
- package/dist/esm/utils/toThrow.d.ts.map +1 -0
- package/dist/esm/utils/toThrow.js +93 -0
- package/dist/esm/utils/transform.d.ts +10 -0
- package/dist/esm/utils/transform.d.ts.map +1 -0
- package/dist/esm/utils/transform.js +213 -0
- package/package.json +60 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Elijah Kotyluk
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/bin/unrift.mjs
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
let esm;
|
|
4
|
+
|
|
5
|
+
function load() {
|
|
6
|
+
if (!esm) {
|
|
7
|
+
esm = require('node:module')
|
|
8
|
+
.createRequire(__filename)('../esm/index.js');
|
|
9
|
+
}
|
|
10
|
+
return esm;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
module.exports = new Proxy({}, {
|
|
14
|
+
get(_t, p) {
|
|
15
|
+
return load()[p];
|
|
16
|
+
},
|
|
17
|
+
has(_t, p) {
|
|
18
|
+
return p in load();
|
|
19
|
+
},
|
|
20
|
+
ownKeys() {
|
|
21
|
+
return Reflect.ownKeys(load());
|
|
22
|
+
},
|
|
23
|
+
getOwnPropertyDescriptor(_t, p) {
|
|
24
|
+
return {
|
|
25
|
+
configurable: true,
|
|
26
|
+
enumerable: true,
|
|
27
|
+
writable: false,
|
|
28
|
+
value: load()[p],
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/esm/cli.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { runTestsCLI } from "./runner.js";
|
|
3
|
+
function safeRegExp(source) {
|
|
4
|
+
try {
|
|
5
|
+
return new RegExp(source);
|
|
6
|
+
}
|
|
7
|
+
catch (err) {
|
|
8
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
9
|
+
throw new Error(`Invalid pattern regex "${source}": ${msg}`);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function printHelp() {
|
|
13
|
+
console.log(`
|
|
14
|
+
Unrift Test Runner
|
|
15
|
+
|
|
16
|
+
Usage:
|
|
17
|
+
unrift [pattern] [options]
|
|
18
|
+
|
|
19
|
+
Options:
|
|
20
|
+
-c, --config <path> Path to config file
|
|
21
|
+
-d, --debug Enable debug logging
|
|
22
|
+
-l, --list List discovered test files
|
|
23
|
+
-j, --json Output test results as JSON
|
|
24
|
+
--cache-clean Clear transform cache
|
|
25
|
+
-h, --help Show help
|
|
26
|
+
|
|
27
|
+
Examples:
|
|
28
|
+
unrift
|
|
29
|
+
unrift math
|
|
30
|
+
unrift -c test/config.ts --debug
|
|
31
|
+
`);
|
|
32
|
+
}
|
|
33
|
+
function parseArgs(argv) {
|
|
34
|
+
let configPath;
|
|
35
|
+
let pattern;
|
|
36
|
+
let debug = false;
|
|
37
|
+
let help = false;
|
|
38
|
+
let list = false;
|
|
39
|
+
let json = false;
|
|
40
|
+
let cacheClean = false;
|
|
41
|
+
const rest = [];
|
|
42
|
+
for (let i = 0; i < argv.length; i++) {
|
|
43
|
+
const a = argv[i];
|
|
44
|
+
if (a === "--help" || a === "-h") {
|
|
45
|
+
help = true;
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (a === "--config" || a === "-c") {
|
|
49
|
+
const next = argv[i + 1];
|
|
50
|
+
if (!next)
|
|
51
|
+
throw new Error(`${a} requires a path`);
|
|
52
|
+
configPath = next;
|
|
53
|
+
i++;
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if (a === "--debug" || a === "-d") {
|
|
57
|
+
debug = true;
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
if (a === "--list" || a === "-l") {
|
|
61
|
+
list = true;
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (a === "--json" || a === "-j") {
|
|
65
|
+
json = true;
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
if (a === "--cache-clean" || a === "--clear-cache") {
|
|
69
|
+
cacheClean = true;
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
// First non-flag arg is pattern
|
|
73
|
+
rest.push(a);
|
|
74
|
+
}
|
|
75
|
+
if (rest[0])
|
|
76
|
+
pattern = safeRegExp(rest[0]);
|
|
77
|
+
return { configPath, pattern, debug, list, json, cacheClean, help };
|
|
78
|
+
}
|
|
79
|
+
const { configPath, pattern, debug, list, json, cacheClean, help } = parseArgs(process.argv.slice(2));
|
|
80
|
+
if (help) {
|
|
81
|
+
printHelp();
|
|
82
|
+
process.exit(0);
|
|
83
|
+
}
|
|
84
|
+
runTestsCLI({ pattern, configPath, debug, list, json, cacheClean }).catch((err) => {
|
|
85
|
+
console.error(err);
|
|
86
|
+
process.exit(1);
|
|
87
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Suite } from "./suite";
|
|
2
|
+
export declare enum RunState {
|
|
3
|
+
Register = "register",
|
|
4
|
+
Run = "run",
|
|
5
|
+
Idle = "idle"
|
|
6
|
+
}
|
|
7
|
+
type UnriftState = RunState;
|
|
8
|
+
interface UnriftGlobalContext {
|
|
9
|
+
currentSuite: Suite | null;
|
|
10
|
+
state: UnriftState;
|
|
11
|
+
}
|
|
12
|
+
export declare const unriftGlobalContext: UnriftGlobalContext;
|
|
13
|
+
export declare function assertRegisterState(apiName: string): void;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +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,KAAK,WAAW,GAAG,QAAQ,CAAC;AAE5B,UAAU,mBAAmB;IAC3B,YAAY,EAAE,KAAK,GAAG,IAAI,CAAC;IAC3B,KAAK,EAAE,WAAW,CAAC;CACpB;AAED,eAAO,MAAM,mBAAmB,EAAE,mBAGjC,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,QAOlD"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export var RunState;
|
|
2
|
+
(function (RunState) {
|
|
3
|
+
RunState["Register"] = "register";
|
|
4
|
+
RunState["Run"] = "run";
|
|
5
|
+
RunState["Idle"] = "idle";
|
|
6
|
+
})(RunState || (RunState = {}));
|
|
7
|
+
export const unriftGlobalContext = {
|
|
8
|
+
currentSuite: null,
|
|
9
|
+
state: RunState.Register,
|
|
10
|
+
};
|
|
11
|
+
export function assertRegisterState(apiName) {
|
|
12
|
+
if (unriftGlobalContext.state !== RunState.Register) {
|
|
13
|
+
throw new Error(`Unrift: ${apiName}() can only be called during test registration (module import time). ` +
|
|
14
|
+
`You likely called it inside a running test or hook.`);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { MatcherMap } from "./types";
|
|
2
|
+
export declare function extendMatchers(newMatchers: MatcherMap): void;
|
|
3
|
+
/**
|
|
4
|
+
* Built-in matchers
|
|
5
|
+
* @TODO add more matchers and extract to separate package.
|
|
6
|
+
*/
|
|
7
|
+
export interface Matchers<T> {
|
|
8
|
+
toBe(expected: T): void | Promise<void>;
|
|
9
|
+
toBeDefined(): void | Promise<void>;
|
|
10
|
+
toBeFalsy(): void | Promise<void>;
|
|
11
|
+
toBeNull(): void | Promise<void>;
|
|
12
|
+
toBeTruthy(): void | Promise<void>;
|
|
13
|
+
toBeUndefined(): void | Promise<void>;
|
|
14
|
+
toEqual(expected: unknown): void | Promise<void>;
|
|
15
|
+
toMatch(expected: RegExp | string): void | Promise<void>;
|
|
16
|
+
toStrictEqual(expected: unknown): void | Promise<void>;
|
|
17
|
+
toThrow(expected?: unknown): void | Promise<void>;
|
|
18
|
+
readonly not: Matchers<T>;
|
|
19
|
+
}
|
|
20
|
+
export interface Matchers<T> {
|
|
21
|
+
}
|
|
22
|
+
export interface ExpectInterface {
|
|
23
|
+
<T>(value: T): Matchers<T>;
|
|
24
|
+
extend<M extends MatcherMap>(m: M): void;
|
|
25
|
+
}
|
|
26
|
+
export declare const expect: ExpectInterface;
|
|
27
|
+
//# sourceMappingURL=expect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expect.d.ts","sourceRoot":"","sources":["../../src/expect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,UAAU,EAAE,MAAM,SAAS,CAAC;AAI1D,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,OAAO,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,aAAa,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD,OAAO,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAElD,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;CAC3B;AAID,MAAM,WAAW,QAAQ,CAAC,CAAC;CAAI;AAE/B,MAAM,WAAW,eAAe;IAC9B,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC3B,MAAM,CAAC,CAAC,SAAS,UAAU,EAAE,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;CAC1C;AAED,eAAO,MAAM,MAAM,EAAE,eAyCjB,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const matcherRegistry = Object.create(null);
|
|
2
|
+
export function extendMatchers(newMatchers) {
|
|
3
|
+
for (const key in newMatchers)
|
|
4
|
+
matcherRegistry[key] = newMatchers[key];
|
|
5
|
+
}
|
|
6
|
+
export const expect = (() => {
|
|
7
|
+
function expectFn(received) {
|
|
8
|
+
function makeExpectation(isNot) {
|
|
9
|
+
const ctx = {
|
|
10
|
+
isNot,
|
|
11
|
+
diff(a, b) {
|
|
12
|
+
return ("\n Received: " +
|
|
13
|
+
JSON.stringify(a, null, 2) +
|
|
14
|
+
"\n Expected: " +
|
|
15
|
+
JSON.stringify(b, null, 2));
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
const matcherFns = {};
|
|
19
|
+
for (const name in matcherRegistry) {
|
|
20
|
+
const fn = matcherRegistry[name];
|
|
21
|
+
matcherFns[name] = (...args) => fn.call(ctx, received, ...args);
|
|
22
|
+
}
|
|
23
|
+
return new Proxy(matcherFns, {
|
|
24
|
+
get(target, prop) {
|
|
25
|
+
if (prop === "not")
|
|
26
|
+
return makeExpectation(!isNot);
|
|
27
|
+
if (typeof prop === "string" && !(prop in target)) {
|
|
28
|
+
throw new Error(`Unknown matcher: ${prop}`);
|
|
29
|
+
}
|
|
30
|
+
return target[prop];
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return makeExpectation(false);
|
|
35
|
+
}
|
|
36
|
+
expectFn.extend = extendMatchers;
|
|
37
|
+
return expectFn;
|
|
38
|
+
})();
|
|
39
|
+
Object.defineProperty(expect, "matchers", {
|
|
40
|
+
get() {
|
|
41
|
+
return matcherRegistry;
|
|
42
|
+
},
|
|
43
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type PromisableFn } from "./types";
|
|
2
|
+
type HookFn = PromisableFn<void>;
|
|
3
|
+
export declare function beforeAll(...hooks: HookFn[]): void;
|
|
4
|
+
export declare function afterAll(...hooks: HookFn[]): void;
|
|
5
|
+
export declare function beforeEach(...hooks: HookFn[]): void;
|
|
6
|
+
export declare function afterEach(...hooks: HookFn[]): void;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/hooks.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,KAAK,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;AAEjC,wBAAgB,SAAS,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAGlD;AAED,wBAAgB,QAAQ,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAGjD;AAED,wBAAgB,UAAU,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAGnD;AAED,wBAAgB,SAAS,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAGlD"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { assertRegisterState } from "./context.js";
|
|
2
|
+
import { getCurrentSuite } from "./suite.js";
|
|
3
|
+
export function beforeAll(...hooks) {
|
|
4
|
+
assertRegisterState("beforeAll");
|
|
5
|
+
getCurrentSuite().beforeAllHooks.push(...hooks);
|
|
6
|
+
}
|
|
7
|
+
export function afterAll(...hooks) {
|
|
8
|
+
assertRegisterState("afterAll");
|
|
9
|
+
getCurrentSuite().afterAllHooks.push(...hooks);
|
|
10
|
+
}
|
|
11
|
+
export function beforeEach(...hooks) {
|
|
12
|
+
assertRegisterState("beforeEach");
|
|
13
|
+
getCurrentSuite().beforeEachHooks.push(...hooks);
|
|
14
|
+
}
|
|
15
|
+
export function afterEach(...hooks) {
|
|
16
|
+
assertRegisterState("afterEach");
|
|
17
|
+
getCurrentSuite().afterEachHooks.push(...hooks);
|
|
18
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { beforeEach, afterEach, beforeAll, afterAll } from "./hooks";
|
|
2
|
+
export { defineConfig, type UnriftConfigOptions } from "./utils/defineConfig";
|
|
3
|
+
export { describe, it } from "./interface";
|
|
4
|
+
export { expect, extendMatchers } from "./expect";
|
|
5
|
+
export type { Matchers, ExpectInterface } from "./expect";
|
|
6
|
+
export type { MatcherContext, MatcherFn, MatcherMap } from "./types";
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +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,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAElD,YAAY,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC1D,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"globals.d.ts","sourceRoot":"","sources":["../../../src/injected/globals.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,gBAAgB,QAAiC,CAAC;AAC/D,eAAO,MAAM,eAAe,gBAAiC,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { fileURLToPath } from "node:url";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { createRequire } from "node:module";
|
|
4
|
+
export const injectedDirname = path.dirname(fileURLToPath(import.meta.url));
|
|
5
|
+
export const injectedFilename = fileURLToPath(import.meta.url);
|
|
6
|
+
export const injectedRequire = createRequire(import.meta.url);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type PromisableFn } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* @TODO expose test and suite aliases
|
|
4
|
+
*/
|
|
5
|
+
type DescribeFn = {
|
|
6
|
+
(description: string, fn: () => void): void;
|
|
7
|
+
only: (description: string, fn: () => void) => void;
|
|
8
|
+
skip: (description: string, fn: () => void) => void;
|
|
9
|
+
};
|
|
10
|
+
type ItFn = {
|
|
11
|
+
(description: string, fn: PromisableFn<void>): void;
|
|
12
|
+
only: (description: string, fn: PromisableFn<void>) => void;
|
|
13
|
+
skip: (description: string, fn: PromisableFn<void>) => void;
|
|
14
|
+
};
|
|
15
|
+
declare const describe: DescribeFn;
|
|
16
|
+
declare const it: ItFn;
|
|
17
|
+
export { describe, it };
|
|
18
|
+
//# sourceMappingURL=interface.d.ts.map
|
|
@@ -0,0 +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;CACrD,CAAC;AAEF,KAAK,IAAI,GAAG;IACV,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,YAAY,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACpD,IAAI,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,YAAY,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC;IAC5D,IAAI,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,YAAY,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC;CAC7D,CAAC;AAmBF,QAAA,MAAM,QAAQ,EAAE,UAC8B,CAAC;AAY/C,QAAA,MAAM,EAAE,EAAE,IAAkE,CAAC;AAI7E,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { assertRegisterState, unriftGlobalContext } from "./context.js";
|
|
2
|
+
import { getCurrentSuite, Suite } from "./suite.js";
|
|
3
|
+
import { Test } from "./test.js";
|
|
4
|
+
import { TaskMode } from "./types.js";
|
|
5
|
+
function _describe(description, fn, mode) {
|
|
6
|
+
assertRegisterState("describe");
|
|
7
|
+
const parent = getCurrentSuite();
|
|
8
|
+
const suite = new Suite(description, parent, mode);
|
|
9
|
+
parent.addSuite(suite);
|
|
10
|
+
unriftGlobalContext.currentSuite = suite;
|
|
11
|
+
try {
|
|
12
|
+
fn();
|
|
13
|
+
}
|
|
14
|
+
finally {
|
|
15
|
+
unriftGlobalContext.currentSuite = parent;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
const describe = (description, fn) => _describe(description, fn, TaskMode.Default);
|
|
19
|
+
describe.only = (description, fn) => _describe(description, fn, TaskMode.Only);
|
|
20
|
+
describe.skip = (description, fn) => _describe(description, fn, TaskMode.Skip);
|
|
21
|
+
function _it(description, fn, mode) {
|
|
22
|
+
assertRegisterState("it");
|
|
23
|
+
const test = new Test(description, fn, mode);
|
|
24
|
+
getCurrentSuite().addTest(test);
|
|
25
|
+
}
|
|
26
|
+
const it = (description, fn) => _it(description, fn, TaskMode.Default);
|
|
27
|
+
it.only = (description, fn) => _it(description, fn, TaskMode.Only);
|
|
28
|
+
it.skip = (description, fn) => _it(description, fn, TaskMode.Skip);
|
|
29
|
+
export { describe, it };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matchers.d.ts","sourceRoot":"","sources":["../../src/matchers.ts"],"names":[],"mappings":"AAUA,wBAAgB,sBAAsB,SAMrC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { expect } from "./expect.js";
|
|
2
|
+
import { deepEqual } from "./utils/deepEqual.js";
|
|
3
|
+
import { looseEqual } from "./utils/looseEqual.js";
|
|
4
|
+
import { toThrow } from "./utils/toThrow.js";
|
|
5
|
+
let matchersRegistered = false;
|
|
6
|
+
export function ensureInternalMatchers() {
|
|
7
|
+
if (matchersRegistered)
|
|
8
|
+
return;
|
|
9
|
+
registerCoreMatchers();
|
|
10
|
+
matchersRegistered = true;
|
|
11
|
+
}
|
|
12
|
+
function registerCoreMatchers() {
|
|
13
|
+
expect.extend({
|
|
14
|
+
toBe(received, expected) {
|
|
15
|
+
const pass = Object.is(received, expected);
|
|
16
|
+
if (this.isNot ? pass : !pass) {
|
|
17
|
+
throw new Error(this.diff(received, expected));
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
toBeDefined(received) {
|
|
21
|
+
const pass = received !== undefined;
|
|
22
|
+
if (this.isNot ? pass : !pass) {
|
|
23
|
+
throw new Error(this.diff(received, "defined value"));
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
toBeFalsy(received) {
|
|
27
|
+
const pass = !received;
|
|
28
|
+
if (this.isNot ? pass : !pass) {
|
|
29
|
+
throw new Error(this.diff(received, "falsy value"));
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
toBeTruthy(received) {
|
|
33
|
+
const pass = Boolean(received);
|
|
34
|
+
if (this.isNot ? pass : !pass) {
|
|
35
|
+
throw new Error(this.diff(received, "truthy value"));
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
toBeNull(received) {
|
|
39
|
+
const pass = received === null;
|
|
40
|
+
if (this.isNot ? pass : !pass) {
|
|
41
|
+
throw new Error(this.diff(received, null));
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
toBeUndefined(received) {
|
|
45
|
+
const pass = received === undefined;
|
|
46
|
+
if (this.isNot ? pass : !pass) {
|
|
47
|
+
throw new Error(this.diff(received, undefined));
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
toEqual(received, expected) {
|
|
51
|
+
const pass = looseEqual(received, expected);
|
|
52
|
+
if (this.isNot ? pass : !pass) {
|
|
53
|
+
throw new Error(this.diff(received, expected));
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
toMatch(received, expected) {
|
|
57
|
+
if (typeof received !== "string") {
|
|
58
|
+
throw new Error(this.diff(received, "Value must be a string to use toMatch()"));
|
|
59
|
+
}
|
|
60
|
+
if (!(typeof expected === "string" || expected instanceof RegExp)) {
|
|
61
|
+
throw new Error(this.diff(expected, "Expected must be a string or RegExp"));
|
|
62
|
+
}
|
|
63
|
+
const pass = typeof expected === "string"
|
|
64
|
+
? received.includes(expected)
|
|
65
|
+
: expected.test(received);
|
|
66
|
+
if (this.isNot ? pass : !pass)
|
|
67
|
+
throw new Error(this.diff(received, expected));
|
|
68
|
+
},
|
|
69
|
+
toStrictEqual(received, expected) {
|
|
70
|
+
const pass = deepEqual(received, expected);
|
|
71
|
+
if (this.isNot ? pass : !pass) {
|
|
72
|
+
throw new Error(this.diff(received, expected));
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
toThrow(received, expected) {
|
|
76
|
+
const { pass, message } = toThrow(received, expected, this.isNot);
|
|
77
|
+
if (!pass)
|
|
78
|
+
throw new Error(message());
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { TaskStatus } from "./types";
|
|
2
|
+
type RunEngineOptions = {
|
|
3
|
+
files: string[];
|
|
4
|
+
timeoutMs?: number;
|
|
5
|
+
bail?: boolean;
|
|
6
|
+
matchers?: string[];
|
|
7
|
+
};
|
|
8
|
+
type RunEngineResult = {
|
|
9
|
+
isOnly: boolean;
|
|
10
|
+
timeoutMs?: number;
|
|
11
|
+
bail: boolean;
|
|
12
|
+
results: Array<{
|
|
13
|
+
description: string;
|
|
14
|
+
status: TaskStatus;
|
|
15
|
+
error?: Error;
|
|
16
|
+
durationMs: number;
|
|
17
|
+
}>;
|
|
18
|
+
};
|
|
19
|
+
export declare function runEngine(options: RunEngineOptions): Promise<RunEngineResult>;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=run.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/run.ts"],"names":[],"mappings":"AAGA,OAAO,EAAY,UAAU,EAAE,MAAM,SAAS,CAAC;AAG/C,KAAK,gBAAgB,GAAG;IACtB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,KAAK,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,UAAU,CAAC;QACnB,KAAK,CAAC,EAAE,KAAK,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;CACJ,CAAC;AAYF,wBAAsB,SAAS,CAC7B,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,CA2D1B"}
|
package/dist/esm/run.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { clearContext, computeOnlyFlags, rootSuite, Suite } from "./suite.js";
|
|
2
|
+
import { ensureInternalMatchers } from "./matchers.js";
|
|
3
|
+
import { RunState, unriftGlobalContext } from "./context.js";
|
|
4
|
+
import { TaskMode } from "./types.js";
|
|
5
|
+
import { toImportUrl } from "./utils/transform.js";
|
|
6
|
+
async function loadMatcherModules(specifiers) {
|
|
7
|
+
for (const spec of specifiers ?? []) {
|
|
8
|
+
await import(spec);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
function normalizePath(p) {
|
|
12
|
+
return p.replace(/\\/g, "/");
|
|
13
|
+
}
|
|
14
|
+
export async function runEngine(options) {
|
|
15
|
+
const { files } = options;
|
|
16
|
+
clearContext();
|
|
17
|
+
ensureInternalMatchers();
|
|
18
|
+
await loadMatcherModules(options.matchers);
|
|
19
|
+
const timeoutMs = options.timeoutMs;
|
|
20
|
+
const bail = options.bail ?? false;
|
|
21
|
+
unriftGlobalContext.state = RunState.Register;
|
|
22
|
+
try {
|
|
23
|
+
for (const file of files) {
|
|
24
|
+
const fileSuite = new Suite(normalizePath(file), rootSuite, TaskMode.Default);
|
|
25
|
+
rootSuite.addSuite(fileSuite);
|
|
26
|
+
unriftGlobalContext.currentSuite = fileSuite;
|
|
27
|
+
try {
|
|
28
|
+
await import(toImportUrl(file, "bundle-test"));
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
32
|
+
fileSuite.errors.push({
|
|
33
|
+
label: "import",
|
|
34
|
+
error,
|
|
35
|
+
});
|
|
36
|
+
fileSuite.markSubtreeSkipped();
|
|
37
|
+
}
|
|
38
|
+
finally {
|
|
39
|
+
unriftGlobalContext.currentSuite = rootSuite;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const isOnly = computeOnlyFlags(rootSuite);
|
|
43
|
+
unriftGlobalContext.state = RunState.Run;
|
|
44
|
+
await rootSuite.run({ timeoutMs, bail }, { bailed: false }, isOnly, false);
|
|
45
|
+
const results = rootSuite.getResults();
|
|
46
|
+
return {
|
|
47
|
+
isOnly,
|
|
48
|
+
timeoutMs,
|
|
49
|
+
bail,
|
|
50
|
+
results,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
finally {
|
|
54
|
+
unriftGlobalContext.state = RunState.Idle;
|
|
55
|
+
unriftGlobalContext.currentSuite = rootSuite;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
interface RunnerOptions {
|
|
2
|
+
configPath?: string;
|
|
3
|
+
testDir?: string;
|
|
4
|
+
pattern?: RegExp;
|
|
5
|
+
timeoutMs?: number;
|
|
6
|
+
bail?: boolean;
|
|
7
|
+
debug?: boolean;
|
|
8
|
+
list?: boolean;
|
|
9
|
+
json?: boolean;
|
|
10
|
+
cacheClean?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare function runTestsCLI(options?: RunnerOptions): Promise<void>;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/runner.ts"],"names":[],"mappings":"AAeA,UAAU,aAAa;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAyGD,wBAAsB,WAAW,CAAC,OAAO,GAAE,aAAkB,iBA4M5D"}
|