@rspack/test-tools 1.5.8 → 1.6.0-beta.1
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/case/builtin.js +0 -22
- package/dist/case/cache.d.ts +1 -1
- package/dist/case/cache.js +5 -5
- package/dist/case/common.d.ts +1 -0
- package/dist/case/common.js +17 -10
- package/dist/case/config.js +5 -3
- package/dist/case/diagnostic.d.ts +2 -2
- package/dist/case/diagnostic.js +2 -3
- package/dist/case/error.d.ts +1 -0
- package/dist/case/error.js +25 -6
- package/dist/case/esm-output.js +28 -2
- package/dist/case/example.d.ts +1 -0
- package/dist/case/example.js +57 -0
- package/dist/case/hash.js +1 -2
- package/dist/case/hook.js +3 -4
- package/dist/case/hot-step.d.ts +1 -1
- package/dist/case/hot-step.js +12 -13
- package/dist/case/hot.d.ts +5 -4
- package/dist/case/hot.js +61 -83
- package/dist/case/incremental.d.ts +2 -2
- package/dist/case/incremental.js +8 -27
- package/dist/case/index.d.ts +12 -1
- package/dist/case/index.js +7 -1
- package/dist/case/multi-compiler.d.ts +18 -0
- package/dist/case/multi-compiler.js +98 -0
- package/dist/case/normal.d.ts +2 -0
- package/dist/case/normal.js +22 -12
- package/dist/case/runner.d.ts +1 -1
- package/dist/case/runner.js +4 -3
- package/dist/case/stats-api.d.ts +9 -0
- package/dist/case/stats-output.js +5 -4
- package/dist/case/watch.d.ts +5 -5
- package/dist/case/watch.js +11 -16
- package/dist/compare/compare.js +6 -3
- package/dist/helper/directory.js +1 -1
- package/dist/helper/expect/error.js +1 -1
- package/dist/helper/expect/placeholder.js +7 -7
- package/dist/helper/expect/to-match-file-snapshot.d.ts +0 -1
- package/dist/helper/hot-update/loader.d.ts +2 -1
- package/dist/helper/hot-update/loader.js +5 -30
- package/dist/helper/hot-update/plugin.d.ts +1 -1
- package/dist/helper/hot-update/plugin.js +14 -13
- package/dist/helper/legacy/LogTestPlugin.d.ts +6 -0
- package/dist/helper/legacy/LogTestPlugin.js +35 -0
- package/dist/helper/legacy/asModule.js +0 -2
- package/dist/helper/legacy/createLazyTestEnv.d.ts +1 -0
- package/dist/helper/legacy/createLazyTestEnv.js +4 -3
- package/dist/helper/legacy/supportsTextDecoder.js +9 -0
- package/dist/helper/read-config-file.d.ts +2 -2
- package/dist/helper/read-config-file.js +5 -2
- package/dist/helper/setup-env.js +18 -2
- package/dist/helper/util/checkStats.d.ts +0 -1
- package/dist/helper/util/checkStats.js +0 -18
- package/dist/helper/util/expectWarningFactory.js +2 -4
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/jest/ignore-snapshot-default-reporter.d.ts +2 -0
- package/dist/jest/ignore-snapshot-default-reporter.js +57 -0
- package/dist/jest/ignore-snapshot-summary-reporter.d.ts +2 -0
- package/dist/jest/ignore-snapshot-summary-reporter.js +24 -0
- package/dist/jest/patch-node-env.d.ts +5 -0
- package/dist/jest/patch-node-env.js +18 -0
- package/dist/jest/slash.d.ts +2 -0
- package/dist/jest/slash.js +16 -0
- package/dist/runner/node/index.js +12 -3
- package/dist/runner/web/index.d.ts +20 -7
- package/dist/runner/web/index.js +293 -18
- package/dist/test/creator.js +15 -10
- package/dist/test/tester.d.ts +1 -0
- package/dist/test/tester.js +21 -4
- package/dist/type.d.ts +14 -5
- package/dist/type.js +1 -6
- package/jest.d.ts +2 -0
- package/package.json +10 -41
- package/dist/helper/legacy/FakeDocument.d.ts +0 -54
- package/dist/helper/legacy/FakeDocument.js +0 -280
- package/dist/helper/legacy/createLogger.d.ts +0 -23
- package/dist/helper/legacy/createLogger.js +0 -20
- package/dist/helper/legacy/supportsBlob.js +0 -10
- package/dist/helper/legacy/supportsClassFields.d.ts +0 -2
- package/dist/helper/legacy/supportsClassFields.js +0 -11
- package/dist/helper/legacy/supportsES6.d.ts +0 -2
- package/dist/helper/legacy/supportsES6.js +0 -11
- package/dist/helper/legacy/supportsForOf.d.ts +0 -2
- package/dist/helper/legacy/supportsForOf.js +0 -11
- package/dist/helper/legacy/supportsIteratorDestructuring.d.ts +0 -2
- package/dist/helper/legacy/supportsIteratorDestructuring.js +0 -11
- package/dist/helper/legacy/supportsLogicalAssignment.d.ts +0 -2
- package/dist/helper/legacy/supportsLogicalAssignment.js +0 -11
- package/dist/helper/legacy/supportsObjectDestructuring.d.ts +0 -2
- package/dist/helper/legacy/supportsObjectDestructuring.js +0 -11
- package/dist/helper/legacy/supportsOptionalCatchBinding.d.ts +0 -2
- package/dist/helper/legacy/supportsOptionalCatchBinding.js +0 -11
- package/dist/helper/legacy/supportsOptionalChaining.d.ts +0 -2
- package/dist/helper/legacy/supportsOptionalChaining.js +0 -11
- package/dist/helper/legacy/supportsRequireInModule.d.ts +0 -2
- package/dist/helper/legacy/supportsRequireInModule.js +0 -5
- package/dist/helper/legacy/supportsResponse.d.ts +0 -2
- package/dist/helper/legacy/supportsResponse.js +0 -10
- package/dist/helper/legacy/supportsSpread.d.ts +0 -2
- package/dist/helper/legacy/supportsSpread.js +0 -12
- package/dist/helper/legacy/supportsTemplateStrings.d.ts +0 -2
- package/dist/helper/legacy/supportsTemplateStrings.js +0 -11
- package/dist/helper/legacy/supportsWebAssembly.d.ts +0 -2
- package/dist/helper/legacy/supportsWebAssembly.js +0 -10
- package/dist/helper/legacy/supportsWorker.d.ts +0 -2
- package/dist/helper/legacy/supportsWorker.js +0 -17
- package/dist/helper/legacy/walkCssTokens.d.ts +0 -40
- package/dist/helper/legacy/walkCssTokens.js +0 -761
- package/dist/helper/legacy/warmup-webpack.d.ts +0 -1
- package/dist/helper/legacy/warmup-webpack.js +0 -26
- package/dist/helper/loaders/hot-update.d.ts +0 -1
- package/dist/helper/loaders/hot-update.js +0 -40
- package/dist/helper/plugins/hot-update.d.ts +0 -7
- package/dist/helper/plugins/hot-update.js +0 -40
- package/dist/helper/plugins/index.d.ts +0 -1
- package/dist/helper/plugins/index.js +0 -17
- package/dist/helper/util/currentWatchStep.d.ts +0 -1
- package/dist/helper/util/currentWatchStep.js +0 -2
- package/dist/helper/util/identifier.d.ts +0 -76
- package/dist/helper/util/identifier.js +0 -339
- package/dist/helper/util/replaceMitteDiagnostic.d.ts +0 -2
- package/dist/helper/util/replaceMitteDiagnostic.js +0 -17
- package/dist/reporter/diff-html.d.ts +0 -15
- package/dist/reporter/diff-html.js +0 -69
- package/dist/reporter/diff-stats.d.ts +0 -24
- package/dist/reporter/diff-stats.js +0 -131
- package/dist/reporter/index.d.ts +0 -2
- package/dist/reporter/index.js +0 -18
- package/dist/runner/web/fake.d.ts +0 -15
- package/dist/runner/web/fake.js +0 -213
- package/dist/runner/web/jsdom.d.ts +0 -24
- package/dist/runner/web/jsdom.js +0 -228
- /package/dist/helper/legacy/{supportsBlob.d.ts → supportsTextDecoder.d.ts} +0 -0
package/dist/index.js
CHANGED
|
@@ -18,7 +18,6 @@ __exportStar(require("./case"), exports);
|
|
|
18
18
|
__exportStar(require("./compare"), exports);
|
|
19
19
|
__exportStar(require("./helper"), exports);
|
|
20
20
|
__exportStar(require("./plugin"), exports);
|
|
21
|
-
__exportStar(require("./reporter"), exports);
|
|
22
21
|
__exportStar(require("./runner"), exports);
|
|
23
22
|
__exportStar(require("./test/context"), exports);
|
|
24
23
|
__exportStar(require("./test/creator"), exports);
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
const { DefaultReporter } = require("@jest/reporters");
|
|
4
|
+
const chalk = require.cache[require.resolve("@jest/reporters")].require("chalk");
|
|
5
|
+
const jestUtil = require.cache[require.resolve("@jest/reporters")].require("jest-util");
|
|
6
|
+
const ARROW = " \u203A ";
|
|
7
|
+
const DOT = " \u2022 ";
|
|
8
|
+
const FAIL_COLOR = chalk.bold.red;
|
|
9
|
+
const SNAPSHOT_ADDED = chalk.bold.green;
|
|
10
|
+
const SNAPSHOT_UPDATED = chalk.bold.green;
|
|
11
|
+
const SNAPSHOT_OUTDATED = chalk.bold.yellow;
|
|
12
|
+
function getSnapshotStatus(snapshot, afterUpdate) {
|
|
13
|
+
const statuses = [];
|
|
14
|
+
if (snapshot.added) {
|
|
15
|
+
statuses.push(SNAPSHOT_ADDED(`${ARROW + jestUtil.pluralize("snapshot", snapshot.added)} written.`));
|
|
16
|
+
}
|
|
17
|
+
if (snapshot.updated) {
|
|
18
|
+
statuses.push(SNAPSHOT_UPDATED(`${ARROW + jestUtil.pluralize("snapshot", snapshot.updated)} updated.`));
|
|
19
|
+
}
|
|
20
|
+
if (snapshot.unmatched) {
|
|
21
|
+
statuses.push(FAIL_COLOR(`${ARROW + jestUtil.pluralize("snapshot", snapshot.unmatched)} failed.`));
|
|
22
|
+
}
|
|
23
|
+
if (snapshot.unchecked) {
|
|
24
|
+
if (afterUpdate) {
|
|
25
|
+
statuses.push(SNAPSHOT_UPDATED(`${ARROW + jestUtil.pluralize("snapshot", snapshot.unchecked)} removed.`));
|
|
26
|
+
for (const key of snapshot.uncheckedKeys) {
|
|
27
|
+
statuses.push(` ${DOT}${key}`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
statuses.push(`${SNAPSHOT_OUTDATED(`${ARROW + jestUtil.pluralize("snapshot", snapshot.unchecked)} obsolete`)}.`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (snapshot.fileDeleted) {
|
|
35
|
+
statuses.push(SNAPSHOT_UPDATED(`${ARROW}snapshot file removed.`));
|
|
36
|
+
}
|
|
37
|
+
return statuses;
|
|
38
|
+
}
|
|
39
|
+
const isUpdate = process.argv.includes("-u") || process.argv.includes("--updateSnapshot");
|
|
40
|
+
const isFiltering = process.argv.includes("-t") || process.argv.includes("--testNamePattern");
|
|
41
|
+
const isVerbose = process.argv.includes("--verbose");
|
|
42
|
+
if (!isVerbose && !isUpdate && isFiltering) {
|
|
43
|
+
class IgnoreSnapshotDefaultReporter extends DefaultReporter {
|
|
44
|
+
printTestFileFailureMessage(_testPath, _config, result) {
|
|
45
|
+
if (result.failureMessage) {
|
|
46
|
+
this.log(result.failureMessage);
|
|
47
|
+
}
|
|
48
|
+
const didUpdate = this._globalConfig.updateSnapshot === "all";
|
|
49
|
+
const snapshotStatuses = getSnapshotStatus(result.snapshot, didUpdate);
|
|
50
|
+
snapshotStatuses.forEach(this.log);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
module.exports = IgnoreSnapshotDefaultReporter;
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
module.exports = DefaultReporter;
|
|
57
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
const { SummaryReporter } = require("@jest/reporters");
|
|
4
|
+
const chalk = require.cache[require.resolve("@jest/reporters")].require("chalk");
|
|
5
|
+
const isUpdate = process.argv.includes("-u") || process.argv.includes("--updateSnapshot");
|
|
6
|
+
const isFiltering = process.argv.includes("-t") || process.argv.includes("--testNamePattern");
|
|
7
|
+
const isVerbose = process.argv.includes("--verbose");
|
|
8
|
+
if (!isVerbose && !isUpdate && isFiltering) {
|
|
9
|
+
class IgnoreSnapshotSummaryReporter extends SummaryReporter {
|
|
10
|
+
_printSnapshotSummary(snapshots, globalConfig) {
|
|
11
|
+
if (snapshots.added ||
|
|
12
|
+
snapshots.filesRemoved ||
|
|
13
|
+
snapshots.unchecked ||
|
|
14
|
+
snapshots.unmatched ||
|
|
15
|
+
snapshots.updated) {
|
|
16
|
+
this.log(chalk.bold.yellow("Some snapshots are obsoleted, flush with `npm run test -- -u` if necessary.\n"));
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
module.exports = IgnoreSnapshotSummaryReporter;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
module.exports = SummaryReporter;
|
|
24
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
// Copied from <https://github.com/webpack/webpack/blob/main/test/patch-node-env.js>
|
|
4
|
+
//
|
|
5
|
+
const NodeEnvironment =
|
|
6
|
+
// For jest@29
|
|
7
|
+
require("jest-environment-node").TestEnvironment ||
|
|
8
|
+
// For jest@27
|
|
9
|
+
require("jest-environment-node");
|
|
10
|
+
class CustomEnvironment extends NodeEnvironment {
|
|
11
|
+
// Workaround for `Symbol('JEST_STATE_SYMBOL')`
|
|
12
|
+
async handleTestEvent(event, state) {
|
|
13
|
+
if (!this.global.JEST_STATE_SYMBOL) {
|
|
14
|
+
this.global.JEST_STATE_SYMBOL = state;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
module.exports = CustomEnvironment;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
/**
|
|
4
|
+
* The following code is copied from
|
|
5
|
+
* https://github.com/sindresorhus/slash/blob/98b618f5a3bfcb5dd374b204868818845b87bb2f/index.js
|
|
6
|
+
*
|
|
7
|
+
* MIT Licensed
|
|
8
|
+
* Author Sindre Sorhus @sindresorhus
|
|
9
|
+
*/
|
|
10
|
+
module.exports = function slash(path) {
|
|
11
|
+
const isExtendedLengthPath = path.startsWith("\\\\?\\");
|
|
12
|
+
if (isExtendedLengthPath) {
|
|
13
|
+
return path;
|
|
14
|
+
}
|
|
15
|
+
return path.replace(/\\/g, "/");
|
|
16
|
+
};
|
|
@@ -42,6 +42,7 @@ const node_path_1 = __importDefault(require("node:path"));
|
|
|
42
42
|
const node_url_1 = require("node:url");
|
|
43
43
|
const node_vm_1 = __importStar(require("node:vm"));
|
|
44
44
|
const asModule_1 = __importDefault(require("../../helper/legacy/asModule"));
|
|
45
|
+
const createFakeWorker_1 = __importDefault(require("../../helper/legacy/createFakeWorker"));
|
|
45
46
|
const urlToRelativePath_1 = __importDefault(require("../../helper/legacy/urlToRelativePath"));
|
|
46
47
|
const type_1 = require("../../type");
|
|
47
48
|
const isRelativePath = (p) => /^\.\.?\//.test(p);
|
|
@@ -163,8 +164,12 @@ class NodeRunner {
|
|
|
163
164
|
Symbol,
|
|
164
165
|
Buffer,
|
|
165
166
|
setImmediate,
|
|
167
|
+
self: this.globalContext,
|
|
166
168
|
__MODE__: this._options.compilerOptions.mode,
|
|
167
169
|
__SNAPSHOT__: node_path_1.default.join(this._options.source, "__snapshot__"),
|
|
170
|
+
Worker: (0, createFakeWorker_1.default)(this._options.env, {
|
|
171
|
+
outputDirectory: this._options.dist
|
|
172
|
+
}),
|
|
168
173
|
...this._options.env
|
|
169
174
|
};
|
|
170
175
|
return baseModuleScope;
|
|
@@ -303,7 +308,7 @@ class NodeRunner {
|
|
|
303
308
|
};
|
|
304
309
|
this.requireCache[file.path] = m;
|
|
305
310
|
if (!this._options.runInNewContext) {
|
|
306
|
-
file.content = `Object.assign(global, _globalAssign)
|
|
311
|
+
file.content = `Object.assign(global, _globalAssign);${file.content}`;
|
|
307
312
|
}
|
|
308
313
|
const currentModuleScope = this.createModuleScope(this.getRequire(), m, file);
|
|
309
314
|
if (this._options.testConfig.moduleScope) {
|
|
@@ -352,6 +357,12 @@ class NodeRunner {
|
|
|
352
357
|
if (file.content.includes("__STATS__")) {
|
|
353
358
|
esmContext.__STATS__ = this._options.stats?.();
|
|
354
359
|
}
|
|
360
|
+
if (file.content.includes("__STATS_I__")) {
|
|
361
|
+
const statsIndex = this._options.stats?.()?.__index__;
|
|
362
|
+
if (typeof statsIndex === "number") {
|
|
363
|
+
esmContext.__STATS_I__ = statsIndex;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
355
366
|
let esm = esmCache.get(file.path);
|
|
356
367
|
if (!esm) {
|
|
357
368
|
esm = new node_vm_1.SourceTextModule(file.content, {
|
|
@@ -385,8 +396,6 @@ class NodeRunner {
|
|
|
385
396
|
}), referencingModule.context, true);
|
|
386
397
|
});
|
|
387
398
|
}
|
|
388
|
-
if (esm.instantiate)
|
|
389
|
-
esm.instantiate();
|
|
390
399
|
await esm.evaluate();
|
|
391
400
|
if (context.esmMode === type_1.EEsmMode.Evaluated) {
|
|
392
401
|
return esm;
|
|
@@ -1,14 +1,27 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type
|
|
1
|
+
import type { ECompilerType, TRunnerFile, TRunnerRequirer } from "../../type";
|
|
2
|
+
import { type INodeRunnerOptions, NodeRunner } from "../node";
|
|
3
3
|
export interface IWebRunnerOptions<T extends ECompilerType = ECompilerType.Rspack> extends INodeRunnerOptions<T> {
|
|
4
|
-
|
|
4
|
+
location: string;
|
|
5
5
|
}
|
|
6
|
-
export declare class WebRunner<T extends ECompilerType = ECompilerType.Rspack>
|
|
6
|
+
export declare class WebRunner<T extends ECompilerType = ECompilerType.Rspack> extends NodeRunner<T> {
|
|
7
7
|
protected _webOptions: IWebRunnerOptions<T>;
|
|
8
|
-
|
|
9
|
-
private implement;
|
|
8
|
+
private dom;
|
|
10
9
|
constructor(_webOptions: IWebRunnerOptions<T>);
|
|
11
10
|
run(file: string): Promise<unknown>;
|
|
12
|
-
getRequire(): import("../../type").TRunnerRequirer;
|
|
13
11
|
getGlobal(name: string): unknown;
|
|
12
|
+
protected createResourceLoader(): {
|
|
13
|
+
fetch(url: string, _: {
|
|
14
|
+
element: HTMLScriptElement;
|
|
15
|
+
}): any;
|
|
16
|
+
};
|
|
17
|
+
private urlToPath;
|
|
18
|
+
protected createBaseModuleScope(): import("../../type").IModuleScope;
|
|
19
|
+
protected getModuleContent(file: TRunnerFile): [
|
|
20
|
+
{
|
|
21
|
+
exports: Record<string, unknown>;
|
|
22
|
+
},
|
|
23
|
+
string
|
|
24
|
+
];
|
|
25
|
+
protected createJSDOMRequirer(): TRunnerRequirer;
|
|
26
|
+
protected createRunner(): void;
|
|
14
27
|
}
|
package/dist/runner/web/index.js
CHANGED
|
@@ -1,32 +1,307 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.WebRunner = void 0;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
|
|
7
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
+
const node_url_1 = require("node:url");
|
|
10
|
+
const node_vm_1 = require("node:vm");
|
|
11
|
+
const jsdom_1 = require("jsdom");
|
|
12
|
+
const helper_1 = require("../../helper");
|
|
13
|
+
const EventSourceForNode_1 = __importDefault(require("../../helper/legacy/EventSourceForNode"));
|
|
14
|
+
const urlToRelativePath_1 = __importDefault(require("../../helper/legacy/urlToRelativePath"));
|
|
15
|
+
const node_1 = require("../node");
|
|
16
|
+
const EVAL_LOCATION_REGEX = /<anonymous>:(\d+)/;
|
|
17
|
+
// Compatibility code to suppress iconv-lite warnings
|
|
18
|
+
require("iconv-lite").skipDecodeWarning = true;
|
|
19
|
+
const FAKE_HOSTS = [
|
|
20
|
+
"https://example.com/public/path",
|
|
21
|
+
"https://example.com",
|
|
22
|
+
"https://test.cases/path/",
|
|
23
|
+
"https://test.cases/server/",
|
|
24
|
+
"https://test.cases"
|
|
25
|
+
];
|
|
26
|
+
const FAKE_TEST_ROOT_HOST = "https://test.cases/root/";
|
|
27
|
+
class WebRunner extends node_1.NodeRunner {
|
|
8
28
|
constructor(_webOptions) {
|
|
29
|
+
super(_webOptions);
|
|
9
30
|
this._webOptions = _webOptions;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
31
|
+
const virtualConsole = new jsdom_1.VirtualConsole({});
|
|
32
|
+
virtualConsole.sendTo(console, {
|
|
33
|
+
omitJSDOMErrors: true
|
|
34
|
+
});
|
|
35
|
+
this.dom = new jsdom_1.JSDOM(`
|
|
36
|
+
<!doctype html>
|
|
37
|
+
<html>
|
|
38
|
+
<head></head>
|
|
39
|
+
<body></body>
|
|
40
|
+
</html>
|
|
41
|
+
`, {
|
|
42
|
+
url: this._webOptions.location,
|
|
43
|
+
resources: this.createResourceLoader(),
|
|
44
|
+
runScripts: "dangerously",
|
|
45
|
+
virtualConsole
|
|
46
|
+
});
|
|
47
|
+
this.dom.window.console = console;
|
|
48
|
+
// compat with FakeDocument
|
|
49
|
+
this.dom.window.eval(`
|
|
50
|
+
Object.defineProperty(document.head, "_children", {
|
|
51
|
+
get: function() {
|
|
52
|
+
return Array.from(document.head.children).map(function(ele) {
|
|
53
|
+
var type = ele.tagName.toLowerCase();
|
|
54
|
+
return new Proxy(ele, {
|
|
55
|
+
get(target, prop, receiver) {
|
|
56
|
+
if (prop === "_type") {
|
|
57
|
+
return target.tagName.toLowerCase();
|
|
58
|
+
}
|
|
59
|
+
if (prop === "_href") {
|
|
60
|
+
return Reflect.get(target, "href", receiver);
|
|
61
|
+
}
|
|
62
|
+
return Reflect.get(target, prop, receiver);
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
});
|
|
14
66
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
67
|
+
});
|
|
68
|
+
`);
|
|
69
|
+
if (this._options.compilerOptions.node !== false) {
|
|
70
|
+
const vmContext = this.dom.getInternalVMContext();
|
|
71
|
+
vmContext.global = {};
|
|
20
72
|
}
|
|
21
73
|
}
|
|
22
74
|
run(file) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
75
|
+
if (!file.endsWith(".js") && !file.endsWith(".mjs")) {
|
|
76
|
+
const cssElement = this.dom.window.document.createElement("link");
|
|
77
|
+
cssElement.href = file;
|
|
78
|
+
cssElement.rel = "stylesheet";
|
|
79
|
+
this.dom.window.document.head.appendChild(cssElement);
|
|
80
|
+
return Promise.resolve();
|
|
81
|
+
}
|
|
82
|
+
return super.run(file);
|
|
27
83
|
}
|
|
28
84
|
getGlobal(name) {
|
|
29
|
-
return this.
|
|
85
|
+
return this.globalContext[name];
|
|
86
|
+
}
|
|
87
|
+
createResourceLoader() {
|
|
88
|
+
const that = this;
|
|
89
|
+
class CustomResourceLoader extends jsdom_1.ResourceLoader {
|
|
90
|
+
fetch(url, _) {
|
|
91
|
+
const filePath = that.urlToPath(url);
|
|
92
|
+
let finalCode;
|
|
93
|
+
if (node_path_1.default.extname(filePath) === ".js") {
|
|
94
|
+
const currentDirectory = node_path_1.default.dirname(filePath);
|
|
95
|
+
const file = that.getFile(filePath, currentDirectory);
|
|
96
|
+
if (!file) {
|
|
97
|
+
throw new Error(`File not found: ${filePath}`);
|
|
98
|
+
}
|
|
99
|
+
const [_m, code] = that.getModuleContent(file);
|
|
100
|
+
finalCode = code;
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
finalCode = node_fs_1.default.readFileSync(filePath);
|
|
104
|
+
}
|
|
105
|
+
try {
|
|
106
|
+
that.dom.window["__LINK_SHEET__"] ??= {};
|
|
107
|
+
that.dom.window["__LINK_SHEET__"][url] = finalCode.toString();
|
|
108
|
+
return Promise.resolve(finalCode);
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
console.error(err);
|
|
112
|
+
if (err.code === "ENOENT") {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
throw err;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return new CustomResourceLoader();
|
|
120
|
+
}
|
|
121
|
+
urlToPath(url) {
|
|
122
|
+
if (url.startsWith("file://")) {
|
|
123
|
+
return (0, node_url_1.fileURLToPath)(url);
|
|
124
|
+
}
|
|
125
|
+
if (url.startsWith(FAKE_TEST_ROOT_HOST)) {
|
|
126
|
+
return node_path_1.default.resolve(__TEST_PATH__, `./${url.slice(FAKE_TEST_ROOT_HOST.length)}`);
|
|
127
|
+
}
|
|
128
|
+
let dist = url;
|
|
129
|
+
for (const host of FAKE_HOSTS) {
|
|
130
|
+
if (url.startsWith(host)) {
|
|
131
|
+
dist = url.slice(host.length);
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return node_path_1.default.resolve(this._webOptions.dist, `./${dist}`).split("?")[0];
|
|
136
|
+
}
|
|
137
|
+
createBaseModuleScope() {
|
|
138
|
+
const moduleScope = super.createBaseModuleScope();
|
|
139
|
+
moduleScope.EventSource = EventSourceForNode_1.default;
|
|
140
|
+
moduleScope.fetch = async (url) => {
|
|
141
|
+
try {
|
|
142
|
+
const buffer = await new Promise((resolve, reject) => node_fs_1.default.readFile(this.urlToPath(url), (err, b) => err ? reject(err) : resolve(b)));
|
|
143
|
+
return {
|
|
144
|
+
status: 200,
|
|
145
|
+
ok: true,
|
|
146
|
+
json: async () => JSON.parse(buffer.toString("utf-8"))
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
catch (err) {
|
|
150
|
+
if (err.code === "ENOENT") {
|
|
151
|
+
return {
|
|
152
|
+
status: 404,
|
|
153
|
+
ok: false
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
throw err;
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
moduleScope.URL = URL;
|
|
160
|
+
moduleScope.importScripts = (url) => {
|
|
161
|
+
this._options.env.expect(url).toMatch(/^https:\/\/test\.cases\/path\//);
|
|
162
|
+
this.requirers.get("entry")(this._options.dist, (0, urlToRelativePath_1.default)(url));
|
|
163
|
+
};
|
|
164
|
+
moduleScope.getComputedStyle = (element) => {
|
|
165
|
+
const computedStyle = this.dom.window.getComputedStyle(element);
|
|
166
|
+
const getPropertyValue = computedStyle.getPropertyValue.bind(computedStyle);
|
|
167
|
+
return {
|
|
168
|
+
...computedStyle,
|
|
169
|
+
getPropertyValue(v) {
|
|
170
|
+
return getPropertyValue(v);
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
};
|
|
174
|
+
moduleScope.window = this.dom.window;
|
|
175
|
+
moduleScope.document = this.dom.window.document;
|
|
176
|
+
moduleScope.getLinkSheet = (link) => {
|
|
177
|
+
return this.dom.window["__LINK_SHEET__"][link.href];
|
|
178
|
+
};
|
|
179
|
+
return moduleScope;
|
|
180
|
+
}
|
|
181
|
+
getModuleContent(file) {
|
|
182
|
+
const m = {
|
|
183
|
+
exports: {}
|
|
184
|
+
};
|
|
185
|
+
const currentModuleScope = this.createModuleScope(this.getRequire(), m, file);
|
|
186
|
+
if (this._options.testConfig.moduleScope) {
|
|
187
|
+
this._options.testConfig.moduleScope(currentModuleScope, this._options.stats, this._options.compilerOptions);
|
|
188
|
+
}
|
|
189
|
+
if (file.content.includes("__STATS__")) {
|
|
190
|
+
currentModuleScope.__STATS__ = this._options.stats?.();
|
|
191
|
+
}
|
|
192
|
+
if (file.content.includes("__STATS_I__")) {
|
|
193
|
+
const statsIndex = this._options.stats?.()?.__index__;
|
|
194
|
+
if (typeof statsIndex === "number") {
|
|
195
|
+
currentModuleScope.__STATS_I__ = statsIndex;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
const createLocatedError = (e, file) => {
|
|
199
|
+
const match = (e.stack || e.message).match(EVAL_LOCATION_REGEX);
|
|
200
|
+
if (match) {
|
|
201
|
+
const [, line] = match;
|
|
202
|
+
const realLine = Number(line) - 34;
|
|
203
|
+
const codeLines = file.content.split("\n");
|
|
204
|
+
const lineContents = [
|
|
205
|
+
...codeLines
|
|
206
|
+
.slice(Math.max(0, realLine - 3), Math.max(0, realLine - 1))
|
|
207
|
+
.map(line => `│ ${line}`),
|
|
208
|
+
`│> ${codeLines[realLine - 1]}`,
|
|
209
|
+
...codeLines.slice(realLine, realLine + 2).map(line => `│ ${line}`)
|
|
210
|
+
];
|
|
211
|
+
const message = `Error in JSDOM when running file '${file.path}' at line ${realLine}: ${e.message}\n${lineContents.join("\n")}`;
|
|
212
|
+
const finalError = new Error(message);
|
|
213
|
+
finalError.stack = undefined;
|
|
214
|
+
return finalError;
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
return e;
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
const originIt = currentModuleScope.it;
|
|
221
|
+
currentModuleScope.it = (description, fn) => {
|
|
222
|
+
originIt(description, async () => {
|
|
223
|
+
try {
|
|
224
|
+
await fn();
|
|
225
|
+
}
|
|
226
|
+
catch (err) {
|
|
227
|
+
throw createLocatedError(err, file);
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
};
|
|
231
|
+
const scopeKey = (0, helper_1.escapeSep)(file.path);
|
|
232
|
+
const args = Object.keys(currentModuleScope).filter(arg => !["window", "self", "globalThis", "console"].includes(arg));
|
|
233
|
+
const argValues = args
|
|
234
|
+
.map(arg => `window["${scopeKey}"]["${arg}"]`)
|
|
235
|
+
.join(", ");
|
|
236
|
+
this.dom.window[scopeKey] = currentModuleScope;
|
|
237
|
+
this.dom.window["__GLOBAL_SHARED__"] = this.globalContext;
|
|
238
|
+
this.dom.window["__FILE__"] = file;
|
|
239
|
+
this.dom.window["__CREATE_LOCATED_ERROR__"] = createLocatedError;
|
|
240
|
+
return [
|
|
241
|
+
m,
|
|
242
|
+
`// hijack document.currentScript for auto public path
|
|
243
|
+
var $$g$$ = new Proxy(window, {
|
|
244
|
+
get(target, prop, receiver) {
|
|
245
|
+
if (prop === "document") {
|
|
246
|
+
return new Proxy(window.document, {
|
|
247
|
+
get(target, prop, receiver) {
|
|
248
|
+
if (prop === "currentScript") {
|
|
249
|
+
var script = target.createElement("script");
|
|
250
|
+
script.src = "https://test.cases/path/${(0, helper_1.escapeSep)(file.subPath)}index.js";
|
|
251
|
+
return script;
|
|
252
|
+
}
|
|
253
|
+
return Reflect.get(target, prop, receiver);
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
return Reflect.get(target, prop, receiver);
|
|
258
|
+
},
|
|
259
|
+
});
|
|
260
|
+
var $$self$$ = new Proxy(window, {
|
|
261
|
+
get(target, prop, receiver) {
|
|
262
|
+
if (prop === "__HMR_UPDATED_RUNTIME__") {
|
|
263
|
+
return window["__GLOBAL_SHARED__"]["__HMR_UPDATED_RUNTIME__"];
|
|
264
|
+
}
|
|
265
|
+
return Reflect.get(target, prop, receiver);
|
|
266
|
+
},
|
|
267
|
+
set(target, prop, value, receiver) {
|
|
268
|
+
if (prop === "__HMR_UPDATED_RUNTIME__") {
|
|
269
|
+
window["__GLOBAL_SHARED__"]["__HMR_UPDATED_RUNTIME__"] = value;
|
|
270
|
+
}
|
|
271
|
+
return Reflect.set(target, prop, value, receiver);
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
(function(window, self, globalThis, console, ${args.join(", ")}) {
|
|
275
|
+
try {
|
|
276
|
+
${file.content}
|
|
277
|
+
} catch (err) {
|
|
278
|
+
throw __CREATE_LOCATED_ERROR__(err, __FILE__);
|
|
279
|
+
}
|
|
280
|
+
})($$g$$, $$self$$, $$g$$, window["console"], ${argValues});`
|
|
281
|
+
];
|
|
282
|
+
}
|
|
283
|
+
createJSDOMRequirer() {
|
|
284
|
+
return (currentDirectory, modulePath, context = {}) => {
|
|
285
|
+
const file = context.file || this.getFile(modulePath, currentDirectory);
|
|
286
|
+
if (!file) {
|
|
287
|
+
return this.requirers.get("miss")(currentDirectory, modulePath);
|
|
288
|
+
}
|
|
289
|
+
if (file.path in this.requireCache) {
|
|
290
|
+
return this.requireCache[file.path].exports;
|
|
291
|
+
}
|
|
292
|
+
const [m, code] = this.getModuleContent(file);
|
|
293
|
+
this.preExecute(code, file);
|
|
294
|
+
const script = new node_vm_1.Script(code);
|
|
295
|
+
const vmContext = this.dom.getInternalVMContext();
|
|
296
|
+
script.runInContext(vmContext);
|
|
297
|
+
this.postExecute(m, file);
|
|
298
|
+
this.requireCache[file.path] = m;
|
|
299
|
+
return m.exports;
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
createRunner() {
|
|
303
|
+
super.createRunner();
|
|
304
|
+
this.requirers.set("cjs", this.createJSDOMRequirer());
|
|
30
305
|
}
|
|
31
306
|
}
|
|
32
307
|
exports.WebRunner = WebRunner;
|
package/dist/test/creator.js
CHANGED
|
@@ -97,17 +97,19 @@ class BasicCaseCreator {
|
|
|
97
97
|
: index
|
|
98
98
|
? `step [${index}] should pass`
|
|
99
99
|
: "should pass";
|
|
100
|
-
it(description,
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
100
|
+
it(description, async () => {
|
|
101
|
+
const e = await stepSignal;
|
|
102
|
+
if (e) {
|
|
103
|
+
throw e;
|
|
104
|
+
}
|
|
105
|
+
}, options.timeout || 300000);
|
|
105
106
|
chain = chain.then(async () => {
|
|
106
107
|
try {
|
|
107
108
|
env.clear();
|
|
108
109
|
await tester.compile();
|
|
109
110
|
await tester.check(env);
|
|
110
111
|
await env.run();
|
|
112
|
+
await tester.after();
|
|
111
113
|
const context = tester.getContext();
|
|
112
114
|
if (!tester.next() && context.hasError()) {
|
|
113
115
|
const errors = context
|
|
@@ -170,7 +172,7 @@ class BasicCaseCreator {
|
|
|
170
172
|
.join("\n\n");
|
|
171
173
|
throw new Error(`Case "${name}" failed at step ${tester.step + 1}:\n${errors}`);
|
|
172
174
|
}
|
|
173
|
-
}, options.timeout ||
|
|
175
|
+
}, options.timeout || 60000);
|
|
174
176
|
const env = this.createEnv(testConfig, options);
|
|
175
177
|
}
|
|
176
178
|
afterAll(async () => {
|
|
@@ -215,8 +217,11 @@ class BasicCaseCreator {
|
|
|
215
217
|
try {
|
|
216
218
|
await runFn(fn);
|
|
217
219
|
}
|
|
218
|
-
catch (
|
|
219
|
-
|
|
220
|
+
catch (err) {
|
|
221
|
+
const e = err;
|
|
222
|
+
const message = `Error: ${description} failed:\n${e.message}`;
|
|
223
|
+
e.message = message;
|
|
224
|
+
throw e;
|
|
220
225
|
}
|
|
221
226
|
for (const after of afterTasks) {
|
|
222
227
|
await runFn(after);
|
|
@@ -237,7 +242,8 @@ class BasicCaseCreator {
|
|
|
237
242
|
expect(typeof fn === "function");
|
|
238
243
|
afterTasks.push(fn);
|
|
239
244
|
},
|
|
240
|
-
jest
|
|
245
|
+
jest: global.jest || global.rstest,
|
|
246
|
+
rstest: global.rstest
|
|
241
247
|
};
|
|
242
248
|
}
|
|
243
249
|
createEnv(testConfig, options) {
|
|
@@ -255,7 +261,6 @@ class BasicCaseCreator {
|
|
|
255
261
|
clean(folders) {
|
|
256
262
|
for (const f of folders) {
|
|
257
263
|
(0, rimraf_1.rimrafSync)(f);
|
|
258
|
-
node_fs_1.default.mkdirSync(f, { recursive: true });
|
|
259
264
|
}
|
|
260
265
|
}
|
|
261
266
|
skip(name, reason) {
|
package/dist/test/tester.d.ts
CHANGED