@rspack-debug/test-tools 1.3.14

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.
Files changed (262) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +17 -0
  3. package/dist/case/builtin.d.ts +1 -0
  4. package/dist/case/builtin.js +39 -0
  5. package/dist/case/cache.d.ts +2 -0
  6. package/dist/case/cache.js +34 -0
  7. package/dist/case/compiler.d.ts +6 -0
  8. package/dist/case/compiler.js +17 -0
  9. package/dist/case/config.d.ts +3 -0
  10. package/dist/case/config.js +39 -0
  11. package/dist/case/defaults.d.ts +6 -0
  12. package/dist/case/defaults.js +39 -0
  13. package/dist/case/diagnostic.d.ts +1 -0
  14. package/dist/case/diagnostic.js +29 -0
  15. package/dist/case/diff.d.ts +3 -0
  16. package/dist/case/diff.js +126 -0
  17. package/dist/case/error.d.ts +6 -0
  18. package/dist/case/error.js +21 -0
  19. package/dist/case/hash.d.ts +3 -0
  20. package/dist/case/hash.js +30 -0
  21. package/dist/case/hook.d.ts +6 -0
  22. package/dist/case/hook.js +35 -0
  23. package/dist/case/hot-step.d.ts +2 -0
  24. package/dist/case/hot-step.js +32 -0
  25. package/dist/case/hot.d.ts +2 -0
  26. package/dist/case/hot.js +32 -0
  27. package/dist/case/index.d.ts +19 -0
  28. package/dist/case/index.js +35 -0
  29. package/dist/case/new-incremental.d.ts +6 -0
  30. package/dist/case/new-incremental.js +100 -0
  31. package/dist/case/normal.d.ts +1 -0
  32. package/dist/case/normal.js +29 -0
  33. package/dist/case/serial.d.ts +3 -0
  34. package/dist/case/serial.js +34 -0
  35. package/dist/case/stats-api.d.ts +6 -0
  36. package/dist/case/stats-api.js +21 -0
  37. package/dist/case/stats-output.d.ts +1 -0
  38. package/dist/case/stats-output.js +22 -0
  39. package/dist/case/treeshaking.d.ts +1 -0
  40. package/dist/case/treeshaking.js +23 -0
  41. package/dist/case/watch.d.ts +1 -0
  42. package/dist/case/watch.js +53 -0
  43. package/dist/compare/comparator.d.ts +17 -0
  44. package/dist/compare/comparator.js +52 -0
  45. package/dist/compare/compare.d.ts +17 -0
  46. package/dist/compare/compare.js +175 -0
  47. package/dist/compare/format-code.d.ts +16 -0
  48. package/dist/compare/format-code.js +239 -0
  49. package/dist/compare/index.d.ts +5 -0
  50. package/dist/compare/index.js +21 -0
  51. package/dist/compare/replace-module-argument.d.ts +1 -0
  52. package/dist/compare/replace-module-argument.js +8 -0
  53. package/dist/compare/replace-runtime-module-name.d.ts +1 -0
  54. package/dist/compare/replace-runtime-module-name.js +71 -0
  55. package/dist/compiler.d.ts +28 -0
  56. package/dist/compiler.js +111 -0
  57. package/dist/helper/directory.d.ts +12 -0
  58. package/dist/helper/directory.js +81 -0
  59. package/dist/helper/expect/diff.d.ts +3 -0
  60. package/dist/helper/expect/diff.js +21 -0
  61. package/dist/helper/expect/error.d.ts +5 -0
  62. package/dist/helper/expect/error.js +51 -0
  63. package/dist/helper/expect/placeholder.d.ts +1 -0
  64. package/dist/helper/expect/placeholder.js +41 -0
  65. package/dist/helper/expect/rspack.d.ts +3 -0
  66. package/dist/helper/expect/rspack.js +14 -0
  67. package/dist/helper/expect/to-be-typeof.d.ts +4 -0
  68. package/dist/helper/expect/to-be-typeof.js +12 -0
  69. package/dist/helper/expect/to-end-with.d.ts +4 -0
  70. package/dist/helper/expect/to-end-with.js +11 -0
  71. package/dist/helper/expect/to-match-file-snapshot.d.ts +23 -0
  72. package/dist/helper/expect/to-match-file-snapshot.js +108 -0
  73. package/dist/helper/hot-update/index.d.ts +1 -0
  74. package/dist/helper/hot-update/index.js +5 -0
  75. package/dist/helper/hot-update/loader.d.ts +1 -0
  76. package/dist/helper/hot-update/loader.js +32 -0
  77. package/dist/helper/hot-update/plugin.d.ts +17 -0
  78. package/dist/helper/hot-update/plugin.js +133 -0
  79. package/dist/helper/index.d.ts +7 -0
  80. package/dist/helper/index.js +23 -0
  81. package/dist/helper/legacy/EventSourceForNode.d.ts +8 -0
  82. package/dist/helper/legacy/EventSourceForNode.js +40 -0
  83. package/dist/helper/legacy/FakeDocument.d.ts +54 -0
  84. package/dist/helper/legacy/FakeDocument.js +278 -0
  85. package/dist/helper/legacy/asModule.d.ts +3 -0
  86. package/dist/helper/legacy/asModule.js +25 -0
  87. package/dist/helper/legacy/captureStdio.d.ts +8 -0
  88. package/dist/helper/legacy/captureStdio.js +32 -0
  89. package/dist/helper/legacy/checkArrayExpectation.d.ts +2 -0
  90. package/dist/helper/legacy/checkArrayExpectation.js +111 -0
  91. package/dist/helper/legacy/copyDiff.d.ts +2 -0
  92. package/dist/helper/legacy/copyDiff.js +33 -0
  93. package/dist/helper/legacy/createFakeWorker.d.ts +13 -0
  94. package/dist/helper/legacy/createFakeWorker.js +80 -0
  95. package/dist/helper/legacy/createLazyTestEnv.d.ts +10 -0
  96. package/dist/helper/legacy/createLazyTestEnv.js +116 -0
  97. package/dist/helper/legacy/createLogger.d.ts +23 -0
  98. package/dist/helper/legacy/createLogger.js +20 -0
  99. package/dist/helper/legacy/currentScript.d.ts +6 -0
  100. package/dist/helper/legacy/currentScript.js +8 -0
  101. package/dist/helper/legacy/fakeSystem.d.ts +9 -0
  102. package/dist/helper/legacy/fakeSystem.js +124 -0
  103. package/dist/helper/legacy/parseResource.d.ts +6 -0
  104. package/dist/helper/legacy/parseResource.js +15 -0
  105. package/dist/helper/legacy/supportsImportFn.d.ts +1 -0
  106. package/dist/helper/legacy/supportsImportFn.js +15 -0
  107. package/dist/helper/legacy/supportsWorker.d.ts +2 -0
  108. package/dist/helper/legacy/supportsWorker.js +17 -0
  109. package/dist/helper/legacy/urlToRelativePath.d.ts +2 -0
  110. package/dist/helper/legacy/urlToRelativePath.js +7 -0
  111. package/dist/helper/legacy/walkCssTokens.d.ts +40 -0
  112. package/dist/helper/legacy/walkCssTokens.js +761 -0
  113. package/dist/helper/legacy/warmup-webpack.d.ts +1 -0
  114. package/dist/helper/legacy/warmup-webpack.js +26 -0
  115. package/dist/helper/loaders/hot-update.d.ts +1 -0
  116. package/dist/helper/loaders/hot-update.js +40 -0
  117. package/dist/helper/parse-modules.d.ts +7 -0
  118. package/dist/helper/parse-modules.js +73 -0
  119. package/dist/helper/plugins/hot-update.d.ts +7 -0
  120. package/dist/helper/plugins/hot-update.js +40 -0
  121. package/dist/helper/plugins/index.d.ts +1 -0
  122. package/dist/helper/plugins/index.js +17 -0
  123. package/dist/helper/read-config-file.d.ts +2 -0
  124. package/dist/helper/read-config-file.js +13 -0
  125. package/dist/helper/serializers.d.ts +2 -0
  126. package/dist/helper/serializers.js +52 -0
  127. package/dist/helper/setup-env.d.ts +1 -0
  128. package/dist/helper/setup-env.js +80 -0
  129. package/dist/helper/setup-expect.d.ts +1 -0
  130. package/dist/helper/setup-expect.js +16 -0
  131. package/dist/helper/update-snapshot.d.ts +1 -0
  132. package/dist/helper/update-snapshot.js +6 -0
  133. package/dist/helper/util/checkSourceMap.d.ts +1 -0
  134. package/dist/helper/util/checkSourceMap.js +96 -0
  135. package/dist/helper/util/checkStats.d.ts +2 -0
  136. package/dist/helper/util/checkStats.js +43 -0
  137. package/dist/helper/util/currentWatchStep.d.ts +1 -0
  138. package/dist/helper/util/currentWatchStep.js +2 -0
  139. package/dist/helper/util/expectWarningFactory.d.ts +2 -0
  140. package/dist/helper/util/expectWarningFactory.js +21 -0
  141. package/dist/helper/util/filterUtil.d.ts +8 -0
  142. package/dist/helper/util/filterUtil.js +50 -0
  143. package/dist/helper/util/identifier.d.ts +76 -0
  144. package/dist/helper/util/identifier.js +339 -0
  145. package/dist/helper/util/replaceMitteDiagnostic.d.ts +2 -0
  146. package/dist/helper/util/replaceMitteDiagnostic.js +17 -0
  147. package/dist/helper/win.d.ts +1 -0
  148. package/dist/helper/win.js +10 -0
  149. package/dist/index.d.ts +12 -0
  150. package/dist/index.js +28 -0
  151. package/dist/plugin/index.d.ts +4 -0
  152. package/dist/plugin/index.js +20 -0
  153. package/dist/plugin/lazy-compilation-test-plugin.d.ts +4 -0
  154. package/dist/plugin/lazy-compilation-test-plugin.js +67 -0
  155. package/dist/plugin/rspack-diff-config-plugin.d.ts +7 -0
  156. package/dist/plugin/rspack-diff-config-plugin.js +42 -0
  157. package/dist/plugin/webpack-diff-config-plugin.d.ts +7 -0
  158. package/dist/plugin/webpack-diff-config-plugin.js +41 -0
  159. package/dist/plugin/webpack-module-placeholder-plugin.d.ts +3 -0
  160. package/dist/plugin/webpack-module-placeholder-plugin.js +107 -0
  161. package/dist/processor/basic.d.ts +24 -0
  162. package/dist/processor/basic.js +146 -0
  163. package/dist/processor/builtin.d.ts +9 -0
  164. package/dist/processor/builtin.js +171 -0
  165. package/dist/processor/cache.d.ts +20 -0
  166. package/dist/processor/cache.js +127 -0
  167. package/dist/processor/config.d.ts +11 -0
  168. package/dist/processor/config.js +81 -0
  169. package/dist/processor/defaults.d.ts +30 -0
  170. package/dist/processor/defaults.js +72 -0
  171. package/dist/processor/diagnostic.d.ts +15 -0
  172. package/dist/processor/diagnostic.js +102 -0
  173. package/dist/processor/diff.d.ts +30 -0
  174. package/dist/processor/diff.js +140 -0
  175. package/dist/processor/error.d.ts +23 -0
  176. package/dist/processor/error.js +95 -0
  177. package/dist/processor/hash.d.ts +10 -0
  178. package/dist/processor/hash.js +63 -0
  179. package/dist/processor/hook.d.ts +44 -0
  180. package/dist/processor/hook.js +204 -0
  181. package/dist/processor/hot-new-incremental.d.ts +14 -0
  182. package/dist/processor/hot-new-incremental.js +43 -0
  183. package/dist/processor/hot-step.d.ts +18 -0
  184. package/dist/processor/hot-step.js +299 -0
  185. package/dist/processor/hot.d.ts +17 -0
  186. package/dist/processor/hot.js +138 -0
  187. package/dist/processor/index.d.ts +20 -0
  188. package/dist/processor/index.js +36 -0
  189. package/dist/processor/multi.d.ts +17 -0
  190. package/dist/processor/multi.js +73 -0
  191. package/dist/processor/normal.d.ts +12 -0
  192. package/dist/processor/normal.js +150 -0
  193. package/dist/processor/simple.d.ts +23 -0
  194. package/dist/processor/simple.js +49 -0
  195. package/dist/processor/snapshot.d.ts +12 -0
  196. package/dist/processor/snapshot.js +62 -0
  197. package/dist/processor/stats-api.d.ts +18 -0
  198. package/dist/processor/stats-api.js +48 -0
  199. package/dist/processor/stats.d.ts +18 -0
  200. package/dist/processor/stats.js +206 -0
  201. package/dist/processor/treeshaking.d.ts +10 -0
  202. package/dist/processor/treeshaking.js +33 -0
  203. package/dist/processor/watch.d.ts +29 -0
  204. package/dist/processor/watch.js +234 -0
  205. package/dist/reporter/diff-html.d.ts +15 -0
  206. package/dist/reporter/diff-html.js +69 -0
  207. package/dist/reporter/diff-stats.d.ts +24 -0
  208. package/dist/reporter/diff-stats.js +131 -0
  209. package/dist/reporter/index.d.ts +2 -0
  210. package/dist/reporter/index.js +18 -0
  211. package/dist/runner/basic.d.ts +10 -0
  212. package/dist/runner/basic.js +63 -0
  213. package/dist/runner/cache.d.ts +5 -0
  214. package/dist/runner/cache.js +90 -0
  215. package/dist/runner/hot-step.d.ts +5 -0
  216. package/dist/runner/hot-step.js +87 -0
  217. package/dist/runner/hot.d.ts +5 -0
  218. package/dist/runner/hot.js +83 -0
  219. package/dist/runner/index.d.ts +9 -0
  220. package/dist/runner/index.js +25 -0
  221. package/dist/runner/multiple.d.ts +11 -0
  222. package/dist/runner/multiple.js +38 -0
  223. package/dist/runner/normal.d.ts +5 -0
  224. package/dist/runner/normal.js +20 -0
  225. package/dist/runner/runner/basic.d.ts +30 -0
  226. package/dist/runner/runner/basic.js +107 -0
  227. package/dist/runner/runner/cjs.d.ts +14 -0
  228. package/dist/runner/runner/cjs.js +151 -0
  229. package/dist/runner/runner/esm.d.ts +7 -0
  230. package/dist/runner/runner/esm.js +125 -0
  231. package/dist/runner/runner/index.d.ts +8 -0
  232. package/dist/runner/runner/index.js +24 -0
  233. package/dist/runner/runner/normal.d.ts +9 -0
  234. package/dist/runner/runner/normal.js +23 -0
  235. package/dist/runner/runner/watch.d.ts +16 -0
  236. package/dist/runner/runner/watch.js +27 -0
  237. package/dist/runner/runner/web/fake.d.ts +18 -0
  238. package/dist/runner/runner/web/fake.js +143 -0
  239. package/dist/runner/runner/web/jsdom.d.ts +26 -0
  240. package/dist/runner/runner/web/jsdom.js +219 -0
  241. package/dist/runner/runner/web.d.ts +15 -0
  242. package/dist/runner/runner/web.js +32 -0
  243. package/dist/runner/type.d.ts +42 -0
  244. package/dist/runner/type.js +9 -0
  245. package/dist/runner/watch.d.ts +7 -0
  246. package/dist/runner/watch.js +60 -0
  247. package/dist/test/context.d.ts +26 -0
  248. package/dist/test/context.js +108 -0
  249. package/dist/test/creator.d.ts +46 -0
  250. package/dist/test/creator.js +310 -0
  251. package/dist/test/simple.d.ts +5 -0
  252. package/dist/test/simple.js +43 -0
  253. package/dist/test/tester.d.ts +17 -0
  254. package/dist/test/tester.js +88 -0
  255. package/dist/type.d.ts +168 -0
  256. package/dist/type.js +22 -0
  257. package/jest.d.ts +25 -0
  258. package/package.json +116 -0
  259. package/template/diff.bundle.css +1 -0
  260. package/template/diff.bundle.js +144 -0
  261. package/template/diff.html +14 -0
  262. package/template/editor.worker.js +1 -0
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.TestContext = void 0;
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const compiler_1 = require("../compiler");
9
+ class TestContext {
10
+ constructor(config) {
11
+ this.config = config;
12
+ this.errors = new Map();
13
+ this.compilers = new Map();
14
+ this.store = new Map();
15
+ this.runners = new Map();
16
+ this.runnerFactory = null;
17
+ }
18
+ getSource(sub) {
19
+ if (sub) {
20
+ return node_path_1.default.resolve(this.config.src, sub);
21
+ }
22
+ return this.config.src;
23
+ }
24
+ getDist(sub) {
25
+ if (sub) {
26
+ return node_path_1.default.resolve(this.config.dist, sub);
27
+ }
28
+ return this.config.dist;
29
+ }
30
+ getTemp(sub) {
31
+ if (!this.config.temp)
32
+ return null;
33
+ if (sub) {
34
+ return node_path_1.default.resolve(this.config.temp, sub);
35
+ }
36
+ return this.config.temp;
37
+ }
38
+ getCompiler(name, type) {
39
+ let compiler = this.compilers.get(name);
40
+ if (!compiler) {
41
+ if (!type) {
42
+ throw new Error("Compiler does not exists");
43
+ }
44
+ compiler = new compiler_1.TestCompilerManager(type, this.config.compilerFactories);
45
+ this.compilers.set(name, compiler);
46
+ }
47
+ return compiler;
48
+ }
49
+ getRunnerFactory(name) {
50
+ if (!this.runnerFactory &&
51
+ typeof this.config.runnerFactory === "function") {
52
+ this.runnerFactory = new this.config.runnerFactory(name, this);
53
+ }
54
+ return this.runnerFactory;
55
+ }
56
+ getRunner(key) {
57
+ return this.runners.get(key) || null;
58
+ }
59
+ setRunner(key, runner) {
60
+ this.runners.set(key, runner);
61
+ }
62
+ getTestConfig() {
63
+ return this.config.testConfig || {};
64
+ }
65
+ setValue(name, key, value) {
66
+ if (!this.store.has(name)) {
67
+ this.store.set(name, {});
68
+ }
69
+ const scope = this.store.get(name);
70
+ scope[key] = value;
71
+ }
72
+ getValue(name, key) {
73
+ if (!this.store.has(name)) {
74
+ this.store.set(name, {});
75
+ }
76
+ const scope = this.store.get(name);
77
+ return scope[key];
78
+ }
79
+ hasError(name) {
80
+ if (name) {
81
+ return this.getError(name).length > 0;
82
+ }
83
+ return !!Array.from(this.errors.values()).reduce((res, arr) => res + arr.length, 0);
84
+ }
85
+ emitError(name, err) {
86
+ const errors = this.errors.get(name) || [];
87
+ errors.push(typeof err === "string" ? new Error(err) : err);
88
+ this.errors.set(name, errors);
89
+ }
90
+ getNames() {
91
+ return Array.from(this.compilers.keys());
92
+ }
93
+ getError(name) {
94
+ if (name) {
95
+ return this.errors.get(name) || [];
96
+ }
97
+ return Array.prototype.concat(...this.errors.values());
98
+ }
99
+ clearError(name) {
100
+ if (name) {
101
+ this.errors.delete(name);
102
+ }
103
+ else {
104
+ this.errors.clear();
105
+ }
106
+ }
107
+ }
108
+ exports.TestContext = TestContext;
@@ -0,0 +1,46 @@
1
+ import type { ECompilerType, ITestContext, ITestEnv, ITestProcessor, ITester, TRunnerFactory, TTestConfig } from "../type";
2
+ declare global {
3
+ var testFilter: string | undefined;
4
+ }
5
+ interface IConcurrentTestEnv {
6
+ clear: () => void;
7
+ run: () => Promise<void>;
8
+ }
9
+ export interface IBasicCaseCreatorOptions<T extends ECompilerType> {
10
+ clean?: boolean;
11
+ describe?: boolean;
12
+ timeout?: number;
13
+ contextValue?: Record<string, unknown>;
14
+ steps: (creatorConfig: IBasicCaseCreatorOptions<T> & {
15
+ name: string;
16
+ src: string;
17
+ dist: string;
18
+ temp: string | void;
19
+ }) => ITestProcessor[];
20
+ testConfig?: (testConfig: TTestConfig<T>) => void;
21
+ description?: (name: string, step: number) => string;
22
+ runner?: new (name: string, context: ITestContext) => TRunnerFactory<ECompilerType>;
23
+ [key: string]: unknown;
24
+ concurrent?: boolean | number;
25
+ }
26
+ export declare class BasicCaseCreator<T extends ECompilerType> {
27
+ protected _options: IBasicCaseCreatorOptions<T>;
28
+ protected currentConcurrent: number;
29
+ protected tasks: [string, () => void][];
30
+ constructor(_options: IBasicCaseCreatorOptions<T>);
31
+ create(name: string, src: string, dist: string, temp?: string): ITester | undefined;
32
+ protected shouldRun(name: string): boolean;
33
+ protected describeConcurrent(name: string, tester: ITester, testConfig: TTestConfig<T>): void;
34
+ protected describe(name: string, tester: ITester, testConfig: TTestConfig<T>): void;
35
+ protected createConcurrentEnv(): ITestEnv & IConcurrentTestEnv;
36
+ protected createEnv(testConfig: TTestConfig<T>): ITestEnv;
37
+ protected clean(folders: string[]): void;
38
+ protected skip(name: string, reason: string | boolean): void;
39
+ protected readTestConfig(src: string): TTestConfig<T>;
40
+ protected checkSkipped(src: string, testConfig: TTestConfig<T>): boolean | string;
41
+ protected createTester(name: string, src: string, dist: string, temp: string | void, testConfig: TTestConfig<T>): ITester;
42
+ protected tryRunTask(): void;
43
+ protected getMaxConcurrent(): number;
44
+ protected registerConcurrentTask(name: string, starter: () => void): () => void;
45
+ }
46
+ export {};
@@ -0,0 +1,310 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.BasicCaseCreator = void 0;
7
+ const node_fs_1 = __importDefault(require("node:fs"));
8
+ const node_path_1 = __importDefault(require("node:path"));
9
+ const rimraf_1 = require("rimraf");
10
+ const createLazyTestEnv_1 = __importDefault(require("../helper/legacy/createLazyTestEnv"));
11
+ const tester_1 = require("./tester");
12
+ const DEFAULT_MAX_CONCURRENT = 5;
13
+ class BasicCaseCreator {
14
+ constructor(_options) {
15
+ this._options = _options;
16
+ this.currentConcurrent = 0;
17
+ this.tasks = [];
18
+ }
19
+ create(name, src, dist, temp) {
20
+ const testConfig = this.readTestConfig(src);
21
+ if (typeof this._options.testConfig === "function") {
22
+ this._options.testConfig(testConfig);
23
+ }
24
+ const skipped = this.checkSkipped(src, testConfig);
25
+ if (skipped) {
26
+ this.skip(name, skipped);
27
+ return;
28
+ }
29
+ if (this._options.clean) {
30
+ this.clean([dist, temp || ""].filter(Boolean));
31
+ }
32
+ const run = this.shouldRun(name);
33
+ const tester = this.createTester(name, src, dist, temp, testConfig);
34
+ const concurrent = testConfig.concurrent ?? this._options.concurrent ?? false;
35
+ if (this._options.describe) {
36
+ if (run) {
37
+ if (concurrent) {
38
+ describe(name, () => this.describeConcurrent(name, tester, testConfig));
39
+ }
40
+ else {
41
+ describe(name, () => this.describe(name, tester, testConfig));
42
+ }
43
+ }
44
+ else {
45
+ describe.skip(name, () => {
46
+ it.skip("skipped", () => { });
47
+ });
48
+ }
49
+ }
50
+ else {
51
+ if (run) {
52
+ if (concurrent) {
53
+ this.describeConcurrent(name, tester, testConfig);
54
+ }
55
+ else {
56
+ this.describe(name, tester, testConfig);
57
+ }
58
+ }
59
+ else {
60
+ it.skip("skipped", () => { });
61
+ }
62
+ }
63
+ return tester;
64
+ }
65
+ shouldRun(name) {
66
+ // TODO: more flexible filter
67
+ if (typeof global.testFilter !== "string" || !global.testFilter) {
68
+ return true;
69
+ }
70
+ return name.includes(global.testFilter);
71
+ }
72
+ describeConcurrent(name, tester, testConfig) {
73
+ beforeAll(async () => {
74
+ await tester.prepare();
75
+ });
76
+ let starter = null;
77
+ let chain = new Promise((resolve, reject) => {
78
+ starter = resolve;
79
+ });
80
+ const ender = this.registerConcurrentTask(name, starter);
81
+ const env = this.createConcurrentEnv();
82
+ for (let index = 0; index < tester.total; index++) {
83
+ let stepSignalResolve = null;
84
+ const stepSignal = new Promise((resolve, reject) => {
85
+ stepSignalResolve = resolve;
86
+ }).catch(e => {
87
+ // prevent unhandled rejection
88
+ });
89
+ const description = typeof this._options.description === "function"
90
+ ? this._options.description(name, index)
91
+ : index
92
+ ? `step [${index}] should pass`
93
+ : "should pass";
94
+ it(description, cb => {
95
+ stepSignal.then((e) => {
96
+ cb(e);
97
+ });
98
+ }, this._options.timeout || 180000);
99
+ chain = chain.then(async () => {
100
+ try {
101
+ env.clear();
102
+ await tester.compile();
103
+ await tester.check(env);
104
+ await env.run();
105
+ const context = tester.getContext();
106
+ if (!tester.next() && context.hasError()) {
107
+ const errors = context
108
+ .getError()
109
+ .map(i => `${i.stack}`.split("\n").join("\t\n"))
110
+ .join("\n\n");
111
+ throw new Error(`Case "${name}" failed at step ${tester.step + 1}:\n${errors}`);
112
+ }
113
+ stepSignalResolve();
114
+ }
115
+ catch (e) {
116
+ stepSignalResolve(e);
117
+ return Promise.reject();
118
+ }
119
+ }, e => {
120
+ // bailout
121
+ stepSignalResolve();
122
+ return Promise.reject();
123
+ });
124
+ }
125
+ chain
126
+ .catch(e => {
127
+ // bailout error
128
+ // prevent unhandled rejection
129
+ })
130
+ .finally(() => {
131
+ ender();
132
+ });
133
+ afterAll(async () => {
134
+ await tester.resume();
135
+ });
136
+ }
137
+ describe(name, tester, testConfig) {
138
+ beforeAll(async () => {
139
+ await tester.prepare();
140
+ });
141
+ let bailout = false;
142
+ for (let index = 0; index < tester.total; index++) {
143
+ const description = typeof this._options.description === "function"
144
+ ? this._options.description(name, index)
145
+ : `step ${index ? `[${index}]` : ""} should pass`;
146
+ it(description, async () => {
147
+ if (bailout) {
148
+ throw `Case "${name}" step ${index + 1} bailout because ${tester.step + 1} failed`;
149
+ }
150
+ await tester.compile();
151
+ await tester.check(env);
152
+ const context = tester.getContext();
153
+ if (!tester.next() && context.hasError()) {
154
+ bailout = true;
155
+ const errors = context
156
+ .getError()
157
+ .map(i => `${i.stack}`.split("\n").join("\t\n"))
158
+ .join("\n\n");
159
+ throw new Error(`Case "${name}" failed at step ${tester.step + 1}:\n${errors}`);
160
+ }
161
+ }, this._options.timeout || 30000);
162
+ const env = this.createEnv(testConfig);
163
+ }
164
+ afterAll(async () => {
165
+ await tester.resume();
166
+ });
167
+ }
168
+ createConcurrentEnv() {
169
+ const tasks = [];
170
+ const beforeTasks = [];
171
+ const afterTasks = [];
172
+ return {
173
+ clear: () => {
174
+ tasks.length = 0;
175
+ beforeTasks.length = 0;
176
+ afterTasks.length = 0;
177
+ },
178
+ run: async () => {
179
+ const runFn = async (fn) => {
180
+ if (fn.length) {
181
+ await new Promise((resolve, reject) => {
182
+ fn(e => {
183
+ if (e) {
184
+ reject(e);
185
+ }
186
+ else {
187
+ resolve();
188
+ }
189
+ });
190
+ });
191
+ }
192
+ else {
193
+ const res = fn();
194
+ if (typeof res?.then === "function") {
195
+ await res;
196
+ }
197
+ }
198
+ };
199
+ for (const [description, fn] of tasks) {
200
+ for (const before of beforeTasks) {
201
+ await runFn(before);
202
+ }
203
+ try {
204
+ await runFn(fn);
205
+ }
206
+ catch (e) {
207
+ throw new Error(`Error: ${description} failed\n${e.stack}`);
208
+ }
209
+ for (const after of afterTasks) {
210
+ await runFn(after);
211
+ }
212
+ }
213
+ },
214
+ expect,
215
+ it: (description, fn) => {
216
+ expect(typeof description === "string");
217
+ expect(typeof fn === "function");
218
+ tasks.push([description, fn]);
219
+ },
220
+ beforeEach: (fn) => {
221
+ expect(typeof fn === "function");
222
+ beforeTasks.push(fn);
223
+ },
224
+ afterEach: (fn) => {
225
+ expect(typeof fn === "function");
226
+ afterTasks.push(fn);
227
+ },
228
+ jest
229
+ };
230
+ }
231
+ createEnv(testConfig) {
232
+ if (typeof this._options.runner === "function" && !testConfig.noTest) {
233
+ return (0, createLazyTestEnv_1.default)(10000);
234
+ }
235
+ return {
236
+ expect,
237
+ it,
238
+ beforeEach,
239
+ afterEach,
240
+ jest
241
+ };
242
+ }
243
+ clean(folders) {
244
+ for (const f of folders) {
245
+ (0, rimraf_1.rimrafSync)(f);
246
+ node_fs_1.default.mkdirSync(f, { recursive: true });
247
+ }
248
+ }
249
+ skip(name, reason) {
250
+ describe.skip(name, () => {
251
+ it(typeof reason === "string" ? `filtered by ${reason}` : "filtered", () => { });
252
+ });
253
+ }
254
+ readTestConfig(src) {
255
+ const testConfigFile = node_path_1.default.join(src, "test.config.js");
256
+ return node_fs_1.default.existsSync(testConfigFile) ? require(testConfigFile) : {};
257
+ }
258
+ checkSkipped(src, testConfig) {
259
+ const filterPath = node_path_1.default.join(src, "test.filter.js");
260
+ // no test.filter.js, should not skip
261
+ if (!node_fs_1.default.existsSync(filterPath)) {
262
+ return false;
263
+ }
264
+ // test.filter.js exists, skip if it returns false|string|array
265
+ const filtered = require(filterPath)(this._options, testConfig);
266
+ if (typeof filtered === "string" || Array.isArray(filtered)) {
267
+ return true;
268
+ }
269
+ return !filtered;
270
+ }
271
+ createTester(name, src, dist, temp, testConfig) {
272
+ return new tester_1.Tester({
273
+ name,
274
+ src,
275
+ dist,
276
+ testConfig,
277
+ contextValue: this._options.contextValue,
278
+ runnerFactory: this._options.runner,
279
+ steps: this._options.steps({
280
+ ...this._options,
281
+ name,
282
+ src,
283
+ dist,
284
+ temp
285
+ })
286
+ });
287
+ }
288
+ tryRunTask() {
289
+ while (this.tasks.length !== 0 &&
290
+ this.currentConcurrent < this.getMaxConcurrent()) {
291
+ const [_name, starter] = this.tasks.shift();
292
+ this.currentConcurrent++;
293
+ starter();
294
+ }
295
+ }
296
+ getMaxConcurrent() {
297
+ return typeof this._options.concurrent === "number"
298
+ ? this._options.concurrent
299
+ : DEFAULT_MAX_CONCURRENT;
300
+ }
301
+ registerConcurrentTask(name, starter) {
302
+ this.tasks.push([name, starter]);
303
+ this.tryRunTask();
304
+ return () => {
305
+ this.currentConcurrent--;
306
+ this.tryRunTask();
307
+ };
308
+ }
309
+ }
310
+ exports.BasicCaseCreator = BasicCaseCreator;
@@ -0,0 +1,5 @@
1
+ import type { ITestContext, ITestEnv, ITestProcessor } from "../type";
2
+ export declare function getSimpleProcessorRunner(src: string, dist: string, options?: {
3
+ env?: () => ITestEnv;
4
+ context?: (src: string, dist: string) => ITestContext;
5
+ }): (name: string, processor: ITestProcessor) => Promise<void>;
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getSimpleProcessorRunner = getSimpleProcessorRunner;
4
+ const context_1 = require("./context");
5
+ const CONTEXT_MAP = new Map();
6
+ function getSimpleProcessorRunner(src, dist, options = {}) {
7
+ const createEnv = options.env || (() => ({ expect, it, beforeEach, afterEach, jest }));
8
+ const createContext = options.context ||
9
+ ((src, dist) => new context_1.TestContext({ src, dist }));
10
+ const key = `src: ${src}, dist: ${dist}`;
11
+ if (!CONTEXT_MAP.has(key)) {
12
+ const context = createContext(src, dist);
13
+ const runner = async function run(name, processor) {
14
+ try {
15
+ await processor.beforeAll?.(context);
16
+ await processor.before?.(context);
17
+ await processor.config?.(context);
18
+ await processor.compiler?.(context);
19
+ await processor.build?.(context);
20
+ }
21
+ catch (e) {
22
+ context.emitError(name, e);
23
+ }
24
+ finally {
25
+ if (!context.hasError()) {
26
+ await processor.run?.(createEnv(), context);
27
+ }
28
+ await processor.check?.(createEnv(), context);
29
+ await processor.after?.(context);
30
+ await processor.afterAll?.(context);
31
+ }
32
+ if (context.hasError()) {
33
+ const errors = context
34
+ .getError()
35
+ .map(i => `${i.stack}`.split("\n").join("\t\n"))
36
+ .join("\n\n");
37
+ throw new Error(`Case "${name}" failed:\n${errors}`);
38
+ }
39
+ };
40
+ CONTEXT_MAP.set(key, runner);
41
+ }
42
+ return CONTEXT_MAP.get(key);
43
+ }
@@ -0,0 +1,17 @@
1
+ import type { ITestContext, ITestEnv, ITester, ITesterConfig } from "../type";
2
+ export declare class Tester implements ITester {
3
+ private config;
4
+ private context;
5
+ private steps;
6
+ step: number;
7
+ total: number;
8
+ constructor(config: ITesterConfig);
9
+ getContext(): ITestContext;
10
+ prepare(): Promise<void>;
11
+ compile(): Promise<void>;
12
+ check(env: ITestEnv): Promise<void>;
13
+ next(): boolean;
14
+ resume(): Promise<void>;
15
+ private runStepMethods;
16
+ private runCheckStepMethods;
17
+ }
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Tester = void 0;
4
+ const context_1 = require("./context");
5
+ class Tester {
6
+ constructor(config) {
7
+ this.config = config;
8
+ this.steps = [];
9
+ this.step = 0;
10
+ this.total = 0;
11
+ this.context = new context_1.TestContext(config);
12
+ this.steps = config.steps || [];
13
+ this.step = 0;
14
+ this.total = config.steps?.length || 0;
15
+ if (config.contextValue) {
16
+ for (const [key, value] of Array.from(Object.entries(config.contextValue))) {
17
+ this.context.setValue(config.name, key, value);
18
+ }
19
+ }
20
+ }
21
+ getContext() {
22
+ return this.context;
23
+ }
24
+ async prepare() {
25
+ for (const i of this.steps) {
26
+ if (typeof i.beforeAll === "function") {
27
+ await i.beforeAll(this.context);
28
+ }
29
+ }
30
+ }
31
+ async compile() {
32
+ const currentStep = this.steps[this.step];
33
+ if (!currentStep)
34
+ return;
35
+ await this.runStepMethods(currentStep, [
36
+ "before",
37
+ "config",
38
+ "compiler",
39
+ "build"
40
+ ]);
41
+ }
42
+ async check(env) {
43
+ const currentStep = this.steps[this.step];
44
+ if (!currentStep)
45
+ return;
46
+ await this.runCheckStepMethods(currentStep, env, this.context.hasError() ? ["check"] : ["run", "check"]);
47
+ await this.runStepMethods(currentStep, ["after"], true);
48
+ }
49
+ next() {
50
+ if (this.context.hasError()) {
51
+ return false;
52
+ }
53
+ if (this.steps[this.step + 1]) {
54
+ this.step++;
55
+ return true;
56
+ }
57
+ return false;
58
+ }
59
+ async resume() {
60
+ for (const i of this.steps) {
61
+ if (typeof i.afterAll === "function") {
62
+ await i.afterAll(this.context);
63
+ }
64
+ }
65
+ }
66
+ async runStepMethods(step, methods, force = false) {
67
+ for (const i of methods) {
68
+ if (!force && this.context.hasError())
69
+ return;
70
+ if (typeof step[i] === "function") {
71
+ try {
72
+ await step[i](this.context);
73
+ }
74
+ catch (e) {
75
+ this.context.emitError(this.config.name, e);
76
+ }
77
+ }
78
+ }
79
+ }
80
+ async runCheckStepMethods(step, env, methods) {
81
+ for (const i of methods) {
82
+ if (typeof step[i] === "function") {
83
+ await step[i](env, this.context);
84
+ }
85
+ }
86
+ }
87
+ }
88
+ exports.Tester = Tester;