@japa/runner 3.0.4 → 3.1.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/build/chunk-52OY4QRJ.js +284 -0
- package/build/chunk-52OY4QRJ.js.map +1 -0
- package/build/chunk-IKX2FPUC.js +505 -0
- package/build/chunk-IKX2FPUC.js.map +1 -0
- package/build/chunk-OBDV3O36.js +18 -0
- package/build/chunk-OBDV3O36.js.map +1 -0
- package/build/chunk-PKOB3ULJ.js +270 -0
- package/build/chunk-PKOB3ULJ.js.map +1 -0
- package/build/factories/main.js +214 -29
- package/build/factories/main.js.map +1 -0
- package/build/index.js +243 -202
- package/build/index.js.map +1 -0
- package/build/modules/core/main.d.ts +0 -1
- package/build/modules/core/main.js +22 -121
- package/build/modules/core/main.js.map +1 -0
- package/build/src/files_manager.d.ts +1 -1
- package/build/src/reporters/main.js +12 -37
- package/build/src/reporters/main.js.map +1 -0
- package/build/src/types.d.ts +8 -0
- package/build/src/types.js +15 -9
- package/build/src/types.js.map +1 -0
- package/package.json +42 -26
- package/build/factories/create_diverse_tests.js +0 -106
- package/build/factories/runner.js +0 -93
- package/build/modules/core/reporters/base.js +0 -183
- package/build/modules/core/types.js +0 -9
- package/build/src/cli_parser.js +0 -75
- package/build/src/config_manager.js +0 -168
- package/build/src/create_test.js +0 -53
- package/build/src/debug.js +0 -10
- package/build/src/exceptions_manager.js +0 -85
- package/build/src/files_manager.js +0 -57
- package/build/src/helpers.js +0 -34
- package/build/src/hooks.js +0 -46
- package/build/src/planner.js +0 -98
- package/build/src/plugins/retry.js +0 -72
- package/build/src/reporters/dot.js +0 -41
- package/build/src/reporters/ndjson.js +0 -86
- package/build/src/reporters/spec.js +0 -152
- package/build/src/validator.js +0 -85
package/build/index.js
CHANGED
|
@@ -1,214 +1,255 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
import
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
import {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
import
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
1
|
+
import {
|
|
2
|
+
CliParser,
|
|
3
|
+
ConfigManager,
|
|
4
|
+
GlobalHooks,
|
|
5
|
+
Planner,
|
|
6
|
+
createTest,
|
|
7
|
+
createTestGroup,
|
|
8
|
+
debug_default,
|
|
9
|
+
validator_default
|
|
10
|
+
} from "./chunk-IKX2FPUC.js";
|
|
11
|
+
import {
|
|
12
|
+
colors
|
|
13
|
+
} from "./chunk-52OY4QRJ.js";
|
|
14
|
+
import {
|
|
15
|
+
Emitter,
|
|
16
|
+
Runner,
|
|
17
|
+
Suite
|
|
18
|
+
} from "./chunk-PKOB3ULJ.js";
|
|
19
|
+
import "./chunk-OBDV3O36.js";
|
|
20
|
+
|
|
21
|
+
// index.ts
|
|
22
|
+
import { fileURLToPath } from "node:url";
|
|
23
|
+
import { ErrorsPrinter as ErrorsPrinter2 } from "@japa/errors-printer";
|
|
24
|
+
|
|
25
|
+
// src/plugins/retry.ts
|
|
26
|
+
import { join } from "node:path";
|
|
27
|
+
import findCacheDirectory from "find-cache-dir";
|
|
28
|
+
import { mkdir, readFile, unlink, writeFile } from "node:fs/promises";
|
|
29
|
+
var CACHE_DIR = findCacheDirectory({ name: "@japa/runner" });
|
|
30
|
+
var SUMMARY_FILE = CACHE_DIR ? join(CACHE_DIR, "summary.json") : void 0;
|
|
31
|
+
async function getFailedTests() {
|
|
32
|
+
try {
|
|
33
|
+
const summary = await readFile(SUMMARY_FILE, "utf-8");
|
|
34
|
+
return JSON.parse(summary);
|
|
35
|
+
} catch (error) {
|
|
36
|
+
if (error.code === "ENOENT") {
|
|
37
|
+
return {};
|
|
38
|
+
}
|
|
39
|
+
throw new Error("Unable to read failed tests cache file", { cause: error });
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
async function cacheFailedTests(tests) {
|
|
43
|
+
await mkdir(CACHE_DIR, { recursive: true });
|
|
44
|
+
await writeFile(SUMMARY_FILE, JSON.stringify({ tests }));
|
|
45
|
+
}
|
|
46
|
+
var retryPlugin = async function retry({ config, cliArgs: cliArgs2 }) {
|
|
47
|
+
if (!SUMMARY_FILE) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
config.teardown.push(async (runner) => {
|
|
51
|
+
const summary = runner.getSummary();
|
|
52
|
+
await cacheFailedTests(summary.failedTestsTitles);
|
|
53
|
+
});
|
|
54
|
+
if (cliArgs2.failed) {
|
|
55
|
+
try {
|
|
56
|
+
const { tests } = await getFailedTests();
|
|
57
|
+
if (!tests || !tests.length) {
|
|
58
|
+
console.log(colors.bgYellow().black(" No failing tests found. Running all the tests "));
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
config.filters.tests = tests;
|
|
62
|
+
} catch (error) {
|
|
63
|
+
console.log(colors.bgRed().black(" Unable to read failed tests. Running all the tests "));
|
|
64
|
+
console.log(colors.red(error));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
44
67
|
};
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
68
|
+
|
|
69
|
+
// src/exceptions_manager.ts
|
|
70
|
+
import { ErrorsPrinter } from "@japa/errors-printer";
|
|
71
|
+
var ExceptionsManager = class {
|
|
72
|
+
#exceptionsBuffer = [];
|
|
73
|
+
#rejectionsBuffer = [];
|
|
74
|
+
#state = "watching";
|
|
75
|
+
#errorsPrinter = new ErrorsPrinter({ stackLinesCount: 2, framesMaxLimit: 4 });
|
|
76
|
+
hasErrors = false;
|
|
77
|
+
/**
|
|
78
|
+
* Monitors unhandled exceptions and rejections. The exceptions
|
|
79
|
+
* are stacked in a buffer, so that we do not clutter the
|
|
80
|
+
* tests output and once the tests are over, we will
|
|
81
|
+
* print them to the console.
|
|
82
|
+
*
|
|
83
|
+
* In case the tests are completed, we will print errors as they
|
|
84
|
+
* happen.
|
|
85
|
+
*/
|
|
86
|
+
monitor() {
|
|
87
|
+
process.on("uncaughtException", async (error) => {
|
|
88
|
+
this.hasErrors = true;
|
|
89
|
+
if (this.#state === "watching") {
|
|
90
|
+
this.#exceptionsBuffer.push(error);
|
|
91
|
+
} else {
|
|
92
|
+
this.#errorsPrinter.printSectionBorder("[Unhandled Error]");
|
|
93
|
+
await this.#errorsPrinter.printError(error);
|
|
94
|
+
process.exitCode = 1;
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
process.on("unhandledRejection", async (error) => {
|
|
98
|
+
this.hasErrors = true;
|
|
99
|
+
if (this.#state === "watching") {
|
|
100
|
+
this.#rejectionsBuffer.push(error);
|
|
101
|
+
} else {
|
|
102
|
+
this.#errorsPrinter.printSectionBorder("[Unhandled Rejection]");
|
|
103
|
+
await this.#errorsPrinter.printError(error);
|
|
104
|
+
process.exitCode = 1;
|
|
105
|
+
}
|
|
57
106
|
});
|
|
58
|
-
|
|
59
|
-
|
|
107
|
+
}
|
|
108
|
+
async flow() {
|
|
109
|
+
if (this.#state === "flowing") {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
this.#state = "flowing";
|
|
113
|
+
if (this.#exceptionsBuffer.length) {
|
|
114
|
+
let exceptionsCount = this.#exceptionsBuffer.length;
|
|
115
|
+
let exceptionsIndex = this.#exceptionsBuffer.length;
|
|
116
|
+
this.#errorsPrinter.printSectionHeader("Unhandled Errors");
|
|
117
|
+
for (let exception of this.#exceptionsBuffer) {
|
|
118
|
+
await this.#errorsPrinter.printError(exception);
|
|
119
|
+
this.#errorsPrinter.printSectionBorder(`[${++exceptionsIndex}/${exceptionsCount}]`);
|
|
120
|
+
}
|
|
121
|
+
this.#exceptionsBuffer = [];
|
|
122
|
+
}
|
|
123
|
+
if (this.#rejectionsBuffer.length) {
|
|
124
|
+
let rejectionsCount = this.#exceptionsBuffer.length;
|
|
125
|
+
let rejectionsIndex = this.#exceptionsBuffer.length;
|
|
126
|
+
this.#errorsPrinter.printSectionBorder("Unhandled Rejections");
|
|
127
|
+
for (let rejection of this.#rejectionsBuffer) {
|
|
128
|
+
await this.#errorsPrinter.printError(rejection);
|
|
129
|
+
this.#errorsPrinter.printSectionBorder(`[${++rejectionsIndex}/${rejectionsCount}]`);
|
|
130
|
+
}
|
|
131
|
+
this.#rejectionsBuffer = [];
|
|
60
132
|
}
|
|
61
|
-
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
// index.ts
|
|
137
|
+
var emitter = new Emitter();
|
|
138
|
+
var activeTest;
|
|
139
|
+
var cliArgs = {};
|
|
140
|
+
var runnerConfig;
|
|
141
|
+
var executionPlanState = {
|
|
142
|
+
phase: "idle"
|
|
143
|
+
};
|
|
144
|
+
function test(title, callback) {
|
|
145
|
+
validator_default.ensureIsInPlanningPhase(executionPlanState.phase);
|
|
146
|
+
const testInstance = createTest(title, emitter, runnerConfig.refiner, executionPlanState);
|
|
147
|
+
testInstance.setup((t) => {
|
|
148
|
+
activeTest = t;
|
|
149
|
+
return () => {
|
|
150
|
+
activeTest = void 0;
|
|
151
|
+
};
|
|
152
|
+
});
|
|
153
|
+
if (callback) {
|
|
154
|
+
testInstance.run(callback);
|
|
155
|
+
}
|
|
156
|
+
return testInstance;
|
|
62
157
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
158
|
+
test.group = function(title, callback) {
|
|
159
|
+
validator_default.ensureIsInPlanningPhase(executionPlanState.phase);
|
|
160
|
+
executionPlanState.group = createTestGroup(
|
|
161
|
+
title,
|
|
162
|
+
emitter,
|
|
163
|
+
runnerConfig.refiner,
|
|
164
|
+
executionPlanState
|
|
165
|
+
);
|
|
166
|
+
callback(executionPlanState.group);
|
|
167
|
+
executionPlanState.group = void 0;
|
|
71
168
|
};
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
*/
|
|
75
|
-
export function getActiveTest() {
|
|
76
|
-
return activeTest;
|
|
169
|
+
function getActiveTest() {
|
|
170
|
+
return activeTest;
|
|
77
171
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
* will be used by Japa to compute the configuration
|
|
81
|
-
*/
|
|
82
|
-
export function processCLIArgs(argv) {
|
|
83
|
-
cliArgs = new CliParser().parse(argv);
|
|
172
|
+
function processCLIArgs(argv) {
|
|
173
|
+
cliArgs = new CliParser().parse(argv);
|
|
84
174
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
* call configure method before the run method.
|
|
88
|
-
*
|
|
89
|
-
* Do note: The CLI flags will overwrite the options provided
|
|
90
|
-
* to the configure method.
|
|
91
|
-
*/
|
|
92
|
-
export function configure(options) {
|
|
93
|
-
runnerConfig = new ConfigManager(options, cliArgs).hydrate();
|
|
175
|
+
function configure(options) {
|
|
176
|
+
runnerConfig = new ConfigManager(options, cliArgs).hydrate();
|
|
94
177
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
178
|
+
async function run() {
|
|
179
|
+
if (cliArgs.help) {
|
|
180
|
+
console.log(new CliParser().getHelp());
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
validator_default.ensureIsConfigured(runnerConfig);
|
|
184
|
+
executionPlanState.phase = "planning";
|
|
185
|
+
const runner = new Runner(emitter);
|
|
186
|
+
const globalHooks = new GlobalHooks();
|
|
187
|
+
const exceptionsManager = new ExceptionsManager();
|
|
188
|
+
try {
|
|
189
|
+
await retryPlugin({ config: runnerConfig, runner, emitter, cliArgs });
|
|
190
|
+
for (let plugin of runnerConfig.plugins) {
|
|
191
|
+
debug_default('executing "%s" plugin', plugin.name || "anonymous");
|
|
192
|
+
await plugin({ runner, emitter, cliArgs, config: runnerConfig });
|
|
106
193
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
runner.registerReporter(reporter);
|
|
136
|
-
});
|
|
137
|
-
refinerFilters.forEach((filter) => {
|
|
138
|
-
debug('apply %s filters "%O" ', filter.layer, filter.filters);
|
|
139
|
-
config.refiner.add(filter.layer, filter.filters);
|
|
140
|
-
});
|
|
141
|
-
config.refiner.matchAllTags(cliArgs.matchAll ?? false);
|
|
142
|
-
runner.onSuite(config.configureSuite);
|
|
143
|
-
/**
|
|
144
|
-
* Step 4: Running the setup hooks
|
|
145
|
-
*/
|
|
146
|
-
debug('executing global hooks');
|
|
147
|
-
globalHooks.apply(config);
|
|
148
|
-
await globalHooks.setup(runner);
|
|
149
|
-
/**
|
|
150
|
-
* Step 5: Register suites and import test files
|
|
151
|
-
*/
|
|
152
|
-
for (let suite of suites) {
|
|
153
|
-
/**
|
|
154
|
-
* Creating and configuring the suite
|
|
155
|
-
*/
|
|
156
|
-
executionPlanState.suite = new Suite(suite.name, emitter, config.refiner);
|
|
157
|
-
executionPlanState.retries = suite.retries;
|
|
158
|
-
executionPlanState.timeout = suite.timeout;
|
|
159
|
-
if (typeof suite.configure === 'function') {
|
|
160
|
-
suite.configure(executionPlanState.suite);
|
|
161
|
-
}
|
|
162
|
-
runner.add(executionPlanState.suite);
|
|
163
|
-
/**
|
|
164
|
-
* Importing suite files
|
|
165
|
-
*/
|
|
166
|
-
for (let fileURL of suite.filesURLs) {
|
|
167
|
-
executionPlanState.file = fileURLToPath(fileURL);
|
|
168
|
-
debug('importing test file %s', executionPlanState.file);
|
|
169
|
-
await config.importer(fileURL);
|
|
170
|
-
}
|
|
171
|
-
/**
|
|
172
|
-
* Resetting global state
|
|
173
|
-
*/
|
|
174
|
-
executionPlanState.suite = undefined;
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* Onto execution phase
|
|
178
|
-
*/
|
|
179
|
-
executionPlanState.phase = 'executing';
|
|
180
|
-
/**
|
|
181
|
-
* Monitor for unhandled erorrs and rejections
|
|
182
|
-
*/
|
|
183
|
-
exceptionsManager.monitor();
|
|
184
|
-
await runner.start();
|
|
185
|
-
await runner.exec();
|
|
186
|
-
await globalHooks.teardown(null, runner);
|
|
187
|
-
await runner.end();
|
|
188
|
-
/**
|
|
189
|
-
* Print unhandled errors
|
|
190
|
-
*/
|
|
191
|
-
await exceptionsManager.flow();
|
|
192
|
-
const summary = runner.getSummary();
|
|
193
|
-
if (summary.hasError || exceptionsManager.hasErrors) {
|
|
194
|
-
process.exitCode = 1;
|
|
195
|
-
}
|
|
196
|
-
if (config.forceExit) {
|
|
197
|
-
process.exit();
|
|
198
|
-
}
|
|
194
|
+
const { config, reporters, suites, refinerFilters } = await new Planner(runnerConfig).plan();
|
|
195
|
+
reporters.forEach((reporter) => {
|
|
196
|
+
debug_default('registering "%s" reporter', reporter.name);
|
|
197
|
+
runner.registerReporter(reporter);
|
|
198
|
+
});
|
|
199
|
+
refinerFilters.forEach((filter) => {
|
|
200
|
+
debug_default('apply %s filters "%O" ', filter.layer, filter.filters);
|
|
201
|
+
config.refiner.add(filter.layer, filter.filters);
|
|
202
|
+
});
|
|
203
|
+
config.refiner.matchAllTags(cliArgs.matchAll ?? false);
|
|
204
|
+
runner.onSuite(config.configureSuite);
|
|
205
|
+
debug_default("executing global hooks");
|
|
206
|
+
globalHooks.apply(config);
|
|
207
|
+
await globalHooks.setup(runner);
|
|
208
|
+
for (let suite of suites) {
|
|
209
|
+
executionPlanState.suite = new Suite(suite.name, emitter, config.refiner);
|
|
210
|
+
executionPlanState.retries = suite.retries;
|
|
211
|
+
executionPlanState.timeout = suite.timeout;
|
|
212
|
+
if (typeof suite.configure === "function") {
|
|
213
|
+
suite.configure(executionPlanState.suite);
|
|
214
|
+
}
|
|
215
|
+
runner.add(executionPlanState.suite);
|
|
216
|
+
for (let fileURL of suite.filesURLs) {
|
|
217
|
+
executionPlanState.file = fileURLToPath(fileURL);
|
|
218
|
+
debug_default("importing test file %s", executionPlanState.file);
|
|
219
|
+
await config.importer(fileURL);
|
|
220
|
+
}
|
|
221
|
+
executionPlanState.suite = void 0;
|
|
199
222
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
223
|
+
executionPlanState.phase = "executing";
|
|
224
|
+
exceptionsManager.monitor();
|
|
225
|
+
await runner.start();
|
|
226
|
+
await runner.exec();
|
|
227
|
+
await globalHooks.teardown(null, runner);
|
|
228
|
+
await runner.end();
|
|
229
|
+
await exceptionsManager.flow();
|
|
230
|
+
const summary = runner.getSummary();
|
|
231
|
+
if (summary.hasError || exceptionsManager.hasErrors) {
|
|
232
|
+
process.exitCode = 1;
|
|
233
|
+
}
|
|
234
|
+
if (config.forceExit) {
|
|
235
|
+
process.exit();
|
|
213
236
|
}
|
|
237
|
+
} catch (error) {
|
|
238
|
+
await globalHooks.teardown(error, runner);
|
|
239
|
+
const printer = new ErrorsPrinter2();
|
|
240
|
+
await printer.printError(error);
|
|
241
|
+
await exceptionsManager.flow();
|
|
242
|
+
process.exitCode = 1;
|
|
243
|
+
if (runnerConfig.forceExit) {
|
|
244
|
+
process.exit();
|
|
245
|
+
}
|
|
246
|
+
}
|
|
214
247
|
}
|
|
248
|
+
export {
|
|
249
|
+
configure,
|
|
250
|
+
getActiveTest,
|
|
251
|
+
processCLIArgs,
|
|
252
|
+
run,
|
|
253
|
+
test
|
|
254
|
+
};
|
|
255
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../index.ts","../src/plugins/retry.ts","../src/exceptions_manager.ts"],"sourcesContent":["/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport { fileURLToPath } from 'node:url'\nimport { ErrorsPrinter } from '@japa/errors-printer'\nimport type { TestExecutor } from '@japa/core/types'\n\nimport debug from './src/debug.js'\nimport validator from './src/validator.js'\nimport { Planner } from './src/planner.js'\nimport { GlobalHooks } from './src/hooks.js'\nimport { CliParser } from './src/cli_parser.js'\nimport { retryPlugin } from './src/plugins/retry.js'\nimport { ConfigManager } from './src/config_manager.js'\nimport { ExceptionsManager } from './src/exceptions_manager.js'\nimport { createTest, createTestGroup } from './src/create_test.js'\nimport type { CLIArgs, Config, NormalizedConfig } from './src/types.js'\nimport { Emitter, Group, Runner, Suite, Test, TestContext } from './modules/core/main.js'\n\n/**\n * Global emitter instance used by the test\n */\nconst emitter = new Emitter()\n\n/**\n * The current active test\n */\nlet activeTest: Test<any> | undefined\n\n/**\n * Parsed commandline arguments\n */\nlet cliArgs: CLIArgs = {}\n\n/**\n * Hydrated config\n */\nlet runnerConfig: NormalizedConfig | undefined\n\n/**\n * The state refers to the phase where we configure suites and import\n * test files. We stick this metadata to the test instance one can\n * later reference within the test.\n */\nconst executionPlanState: {\n phase: 'idle' | 'planning' | 'executing'\n file?: string\n suite?: Suite\n group?: Group\n timeout?: number\n retries?: number\n} = {\n phase: 'idle',\n}\n\n/**\n * Create a Japa test. Defining a test without the callback\n * will create a todo test.\n */\nexport function test(title: string, callback?: TestExecutor<TestContext, undefined>) {\n validator.ensureIsInPlanningPhase(executionPlanState.phase)\n\n const testInstance = createTest(title, emitter, runnerConfig!.refiner, executionPlanState)\n testInstance.setup((t) => {\n activeTest = t\n return () => {\n activeTest = undefined\n }\n })\n\n if (callback) {\n testInstance.run(callback)\n }\n\n return testInstance\n}\n\n/**\n * Create a Japa test group\n */\ntest.group = function (title: string, callback: (group: Group) => void) {\n validator.ensureIsInPlanningPhase(executionPlanState.phase)\n\n executionPlanState.group = createTestGroup(\n title,\n emitter,\n runnerConfig!.refiner,\n executionPlanState\n )\n callback(executionPlanState.group)\n executionPlanState.group = undefined\n}\n\n/**\n * Get the test of currently running test\n */\nexport function getActiveTest() {\n return activeTest\n}\n\n/**\n * Make Japa process command line arguments. Later the parsed output\n * will be used by Japa to compute the configuration\n */\nexport function processCLIArgs(argv: string[]) {\n cliArgs = new CliParser().parse(argv)\n}\n\n/**\n * Configure the tests runner with inline configuration. You must\n * call configure method before the run method.\n *\n * Do note: The CLI flags will overwrite the options provided\n * to the configure method.\n */\nexport function configure(options: Config) {\n runnerConfig = new ConfigManager(options, cliArgs).hydrate()\n}\n\n/**\n * Execute Japa tests. Calling this function will import the test\n * files behind the scenes\n */\nexport async function run() {\n /**\n * Display help when help flag is used\n */\n if (cliArgs.help) {\n console.log(new CliParser().getHelp())\n return\n }\n\n validator.ensureIsConfigured(runnerConfig)\n\n executionPlanState.phase = 'planning'\n const runner = new Runner(emitter)\n const globalHooks = new GlobalHooks()\n const exceptionsManager = new ExceptionsManager()\n\n try {\n /**\n * Executing the retry plugin as the first thing\n */\n await retryPlugin({ config: runnerConfig!, runner, emitter, cliArgs })\n\n /**\n * Step 1: Executing plugins before creating a plan, so that it can mutate\n * the config\n */\n for (let plugin of runnerConfig!.plugins) {\n debug('executing \"%s\" plugin', plugin.name || 'anonymous')\n await plugin({ runner, emitter, cliArgs, config: runnerConfig! })\n }\n\n /**\n * Step 2: Creating an execution plan. The output is the result of\n * applying all the filters and validations.\n */\n const { config, reporters, suites, refinerFilters } = await new Planner(runnerConfig!).plan()\n\n /**\n * Step 3: Registering reporters and filters with the runner\n */\n reporters.forEach((reporter) => {\n debug('registering \"%s\" reporter', reporter.name)\n runner.registerReporter(reporter)\n })\n refinerFilters.forEach((filter) => {\n debug('apply %s filters \"%O\" ', filter.layer, filter.filters)\n config.refiner.add(filter.layer, filter.filters)\n })\n config.refiner.matchAllTags(cliArgs.matchAll ?? false)\n runner.onSuite(config.configureSuite)\n\n /**\n * Step 4: Running the setup hooks\n */\n debug('executing global hooks')\n globalHooks.apply(config)\n await globalHooks.setup(runner)\n\n /**\n * Step 5: Register suites and import test files\n */\n for (let suite of suites) {\n /**\n * Creating and configuring the suite\n */\n executionPlanState.suite = new Suite(suite.name, emitter, config.refiner)\n executionPlanState.retries = suite.retries\n executionPlanState.timeout = suite.timeout\n if (typeof suite.configure === 'function') {\n suite.configure(executionPlanState.suite)\n }\n runner.add(executionPlanState.suite)\n\n /**\n * Importing suite files\n */\n for (let fileURL of suite.filesURLs) {\n executionPlanState.file = fileURLToPath(fileURL)\n debug('importing test file %s', executionPlanState.file)\n await config.importer(fileURL)\n }\n\n /**\n * Resetting global state\n */\n executionPlanState.suite = undefined\n }\n\n /**\n * Onto execution phase\n */\n executionPlanState.phase = 'executing'\n\n /**\n * Monitor for unhandled erorrs and rejections\n */\n exceptionsManager.monitor()\n\n await runner.start()\n await runner.exec()\n\n await globalHooks.teardown(null, runner)\n await runner.end()\n\n /**\n * Print unhandled errors\n */\n await exceptionsManager.flow()\n\n const summary = runner.getSummary()\n if (summary.hasError || exceptionsManager.hasErrors) {\n process.exitCode = 1\n }\n if (config.forceExit) {\n process.exit()\n }\n } catch (error) {\n await globalHooks.teardown(error, runner)\n const printer = new ErrorsPrinter()\n await printer.printError(error)\n\n /**\n * Print unhandled errors in case the code inside\n * the try block never got triggered\n */\n await exceptionsManager.flow()\n\n process.exitCode = 1\n if (runnerConfig!.forceExit) {\n process.exit()\n }\n }\n}\n","/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport { join } from 'node:path'\nimport findCacheDirectory from 'find-cache-dir'\nimport { mkdir, readFile, unlink, writeFile } from 'node:fs/promises'\n\nimport { colors } from '../helpers.js'\nimport type { PluginFn } from '../types.js'\n\n/**\n * Paths to the cache directory and the summary file\n */\nconst CACHE_DIR = findCacheDirectory({ name: '@japa/runner' })\nconst SUMMARY_FILE = CACHE_DIR ? join(CACHE_DIR, 'summary.json') : undefined\n\n/**\n * Returns an object with the title of the tests failed during\n * the last run.\n */\nexport async function getFailedTests(): Promise<{ tests?: string[] }> {\n try {\n const summary = await readFile(SUMMARY_FILE!, 'utf-8')\n return JSON.parse(summary)\n } catch (error) {\n if (error.code === 'ENOENT') {\n return {}\n }\n throw new Error('Unable to read failed tests cache file', { cause: error })\n }\n}\n\n/**\n * Writes failing tests to the cache directory\n */\nexport async function cacheFailedTests(tests: string[]) {\n await mkdir(CACHE_DIR!, { recursive: true })\n await writeFile(SUMMARY_FILE!, JSON.stringify({ tests: tests }))\n}\n\n/**\n * Clears the cache dir\n */\nexport async function clearCache() {\n await unlink(SUMMARY_FILE!)\n}\n\n/**\n * Exposes the API to run failing tests using the \"failed\" CLI flag.\n */\nexport const retryPlugin: PluginFn = async function retry({ config, cliArgs }) {\n if (!SUMMARY_FILE) {\n return\n }\n\n config.teardown.push(async (runner) => {\n const summary = runner.getSummary()\n await cacheFailedTests(summary.failedTestsTitles)\n })\n\n if (cliArgs.failed) {\n try {\n const { tests } = await getFailedTests()\n if (!tests || !tests.length) {\n console.log(colors.bgYellow().black(' No failing tests found. Running all the tests '))\n return\n }\n config.filters.tests = tests\n } catch (error) {\n console.log(colors.bgRed().black(' Unable to read failed tests. Running all the tests '))\n console.log(colors.red(error))\n }\n }\n}\n","/*\n * @japa/runner\n *\n * (c) Japa\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport { ErrorsPrinter } from '@japa/errors-printer'\n\n/**\n * Handles uncaught exceptions and prints them to the\n * console\n */\nexport class ExceptionsManager {\n #exceptionsBuffer: any[] = []\n #rejectionsBuffer: any[] = []\n #state: 'watching' | 'flowing' = 'watching'\n #errorsPrinter = new ErrorsPrinter({ stackLinesCount: 2, framesMaxLimit: 4 })\n\n hasErrors: boolean = false\n\n /**\n * Monitors unhandled exceptions and rejections. The exceptions\n * are stacked in a buffer, so that we do not clutter the\n * tests output and once the tests are over, we will\n * print them to the console.\n *\n * In case the tests are completed, we will print errors as they\n * happen.\n */\n monitor() {\n process.on('uncaughtException', async (error) => {\n this.hasErrors = true\n if (this.#state === 'watching') {\n this.#exceptionsBuffer.push(error)\n } else {\n this.#errorsPrinter.printSectionBorder('[Unhandled Error]')\n await this.#errorsPrinter.printError(error)\n process.exitCode = 1\n }\n })\n\n process.on('unhandledRejection', async (error) => {\n this.hasErrors = true\n if (this.#state === 'watching') {\n this.#rejectionsBuffer.push(error)\n } else {\n this.#errorsPrinter.printSectionBorder('[Unhandled Rejection]')\n await this.#errorsPrinter.printError(error)\n process.exitCode = 1\n }\n })\n }\n\n async flow() {\n if (this.#state === 'flowing') {\n return\n }\n\n this.#state = 'flowing'\n\n /**\n * Print exceptions\n */\n if (this.#exceptionsBuffer.length) {\n let exceptionsCount = this.#exceptionsBuffer.length\n let exceptionsIndex = this.#exceptionsBuffer.length\n this.#errorsPrinter.printSectionHeader('Unhandled Errors')\n for (let exception of this.#exceptionsBuffer) {\n await this.#errorsPrinter.printError(exception)\n this.#errorsPrinter.printSectionBorder(`[${++exceptionsIndex}/${exceptionsCount}]`)\n }\n this.#exceptionsBuffer = []\n }\n\n /**\n * Print rejections\n */\n if (this.#rejectionsBuffer.length) {\n let rejectionsCount = this.#exceptionsBuffer.length\n let rejectionsIndex = this.#exceptionsBuffer.length\n this.#errorsPrinter.printSectionBorder('Unhandled Rejections')\n for (let rejection of this.#rejectionsBuffer) {\n await this.#errorsPrinter.printError(rejection)\n this.#errorsPrinter.printSectionBorder(`[${++rejectionsIndex}/${rejectionsCount}]`)\n }\n this.#rejectionsBuffer = []\n }\n }\n}\n"],"mappings":"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","names":["ErrorsPrinter","cliArgs","ErrorsPrinter"]}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/// <reference types="node" resolution-mode="require"/>
|
|
2
1
|
import { Emitter, Refiner, Test as BaseTest, Suite as BaseSuite, Group as BaseGroup, Runner as BaseRunner, TestContext as BaseTestContext } from '@japa/core';
|
|
3
2
|
import { BaseReporter } from './reporters/base.js';
|
|
4
3
|
import type { DataSetNode, TestHooksCleanupHandler } from './types.js';
|
|
@@ -1,121 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
import
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
test.cleanup(cleanupCallback);
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Test class represents an individual test and exposes API to tweak
|
|
29
|
-
* its runtime behavior.
|
|
30
|
-
*/
|
|
31
|
-
export class Test extends BaseTest {
|
|
32
|
-
/**
|
|
33
|
-
* @inheritdoc
|
|
34
|
-
*/
|
|
35
|
-
static executedCallbacks = [];
|
|
36
|
-
/**
|
|
37
|
-
* @inheritdoc
|
|
38
|
-
*/
|
|
39
|
-
static executingCallbacks = [];
|
|
40
|
-
/**
|
|
41
|
-
* Assert the test callback throws an exception when a certain
|
|
42
|
-
* error message and optionally is an instance of a given
|
|
43
|
-
* Error class.
|
|
44
|
-
*/
|
|
45
|
-
throws(message, errorConstructor) {
|
|
46
|
-
const errorInPoint = new AssertionError({});
|
|
47
|
-
const existingExecutor = this.options.executor;
|
|
48
|
-
if (!existingExecutor) {
|
|
49
|
-
throw new Error('Cannot use "test.throws" method without a test callback');
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Overwriting existing callback
|
|
53
|
-
*/
|
|
54
|
-
this.options.executor = async (...args) => {
|
|
55
|
-
let raisedException;
|
|
56
|
-
try {
|
|
57
|
-
await existingExecutor(...args);
|
|
58
|
-
}
|
|
59
|
-
catch (error) {
|
|
60
|
-
raisedException = error;
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Notify no exception has been raised
|
|
64
|
-
*/
|
|
65
|
-
if (!raisedException) {
|
|
66
|
-
errorInPoint.message = 'Expected test to throw an exception';
|
|
67
|
-
throw errorInPoint;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Constructor mis-match
|
|
71
|
-
*/
|
|
72
|
-
if (errorConstructor && !(raisedException instanceof errorConstructor)) {
|
|
73
|
-
errorInPoint.message = `Expected test to throw "${inspect(errorConstructor)}"`;
|
|
74
|
-
throw errorInPoint;
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Error does not have a message property
|
|
78
|
-
*/
|
|
79
|
-
const exceptionMessage = raisedException.message;
|
|
80
|
-
if (!exceptionMessage || typeof exceptionMessage !== 'string') {
|
|
81
|
-
errorInPoint.message = 'Expected test to throw an exception with message property';
|
|
82
|
-
throw errorInPoint;
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Message does not match
|
|
86
|
-
*/
|
|
87
|
-
if (typeof message === 'string') {
|
|
88
|
-
if (exceptionMessage !== message) {
|
|
89
|
-
errorInPoint.message = `Expected test to throw "${message}". Instead received "${raisedException.message}"`;
|
|
90
|
-
errorInPoint.actual = raisedException.message;
|
|
91
|
-
errorInPoint.expected = message;
|
|
92
|
-
throw errorInPoint;
|
|
93
|
-
}
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
if (!message.test(exceptionMessage)) {
|
|
97
|
-
errorInPoint.message = `Expected test error to match "${message}" regular expression`;
|
|
98
|
-
throw errorInPoint;
|
|
99
|
-
}
|
|
100
|
-
};
|
|
101
|
-
return this;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* TestGroup is used to bulk configure a collection of tests and
|
|
106
|
-
* define lifecycle hooks for them
|
|
107
|
-
*/
|
|
108
|
-
export class Group extends BaseGroup {
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* A suite is a collection of tests created around a given
|
|
112
|
-
* testing type. For example: A suite for unit tests, a
|
|
113
|
-
* suite for functional tests and so on.
|
|
114
|
-
*/
|
|
115
|
-
export class Suite extends BaseSuite {
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Runner class is used to execute the tests
|
|
119
|
-
*/
|
|
120
|
-
export class Runner extends BaseRunner {
|
|
121
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
BaseReporter,
|
|
3
|
+
Emitter,
|
|
4
|
+
Group,
|
|
5
|
+
Refiner,
|
|
6
|
+
Runner,
|
|
7
|
+
Suite,
|
|
8
|
+
Test,
|
|
9
|
+
TestContext
|
|
10
|
+
} from "../../chunk-PKOB3ULJ.js";
|
|
11
|
+
import "../../chunk-OBDV3O36.js";
|
|
12
|
+
export {
|
|
13
|
+
BaseReporter,
|
|
14
|
+
Emitter,
|
|
15
|
+
Group,
|
|
16
|
+
Refiner,
|
|
17
|
+
Runner,
|
|
18
|
+
Suite,
|
|
19
|
+
Test,
|
|
20
|
+
TestContext
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=main.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -9,7 +9,7 @@ export declare class FilesManager {
|
|
|
9
9
|
* Returns a collection of files from the user defined
|
|
10
10
|
* glob or the implementation function
|
|
11
11
|
*/
|
|
12
|
-
getFiles(cwd: string, files: TestFiles): Promise<URL[]>;
|
|
12
|
+
getFiles(cwd: string, files: TestFiles, excludes: string[]): Promise<URL[]>;
|
|
13
13
|
/**
|
|
14
14
|
* Applies file name filter on a collection of file
|
|
15
15
|
* URLs
|