@japa/runner 3.0.0-8 → 3.0.0-9
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/examples/dot.d.ts +1 -0
- package/build/examples/dot.js +11 -0
- package/build/examples/ndjson.d.ts +1 -0
- package/build/examples/ndjson.js +11 -0
- package/build/examples/spec.d.ts +1 -0
- package/build/examples/spec.js +11 -0
- package/build/factories/create_diverse_tests.d.ts +6 -0
- package/build/factories/create_diverse_tests.js +106 -0
- package/build/factories/main.d.ts +5 -42
- package/build/factories/main.js +24 -208
- package/build/factories/runner.d.ts +26 -0
- package/build/factories/runner.js +93 -0
- package/build/index.d.ts +9 -14
- package/build/index.js +202 -237
- package/build/modules/core/main.d.ts +63 -3
- package/build/modules/core/main.js +121 -21
- package/build/modules/core/reporters/base.d.ts +41 -0
- package/build/modules/core/reporters/base.js +183 -0
- package/build/modules/core/types.d.ts +5 -0
- package/build/modules/core/types.js +9 -0
- package/build/src/cli_parser.d.ts +14 -0
- package/build/src/cli_parser.js +75 -0
- package/build/src/config_manager.d.ts +18 -0
- package/build/src/config_manager.js +168 -0
- package/build/src/create_test.d.ts +21 -0
- package/build/src/create_test.js +53 -0
- package/build/src/debug.d.ts +3 -0
- package/build/src/debug.js +10 -0
- package/build/src/exceptions_manager.d.ts +19 -0
- package/build/src/exceptions_manager.js +85 -0
- package/build/src/files_manager.d.ts +18 -0
- package/build/src/files_manager.js +57 -0
- package/build/src/helpers.d.ts +15 -0
- package/build/src/helpers.js +34 -0
- package/build/src/hooks.d.ts +20 -0
- package/build/src/hooks.js +46 -0
- package/build/src/planner.d.ts +25 -0
- package/build/src/planner.js +98 -0
- package/build/src/plugins/retry.d.ts +20 -0
- package/build/src/plugins/retry.js +66 -0
- package/build/src/reporters/dot.d.ts +15 -0
- package/build/src/reporters/dot.js +41 -0
- package/build/src/reporters/main.d.ts +4 -9
- package/build/src/reporters/main.js +37 -11
- package/build/src/reporters/ndjson.d.ts +15 -0
- package/build/src/reporters/ndjson.js +86 -0
- package/build/src/reporters/spec.d.ts +13 -0
- package/build/src/reporters/spec.js +152 -0
- package/build/src/types.d.ts +19 -23
- package/build/src/types.js +9 -14
- package/build/src/validator.d.ts +30 -0
- package/build/src/validator.js +85 -0
- package/build/tests/base_reporter.spec.d.ts +1 -0
- package/build/tests/base_reporter.spec.js +111 -0
- package/build/tests/cli_parser.spec.d.ts +1 -0
- package/build/tests/cli_parser.spec.js +265 -0
- package/build/tests/config_manager.spec.d.ts +1 -0
- package/build/tests/config_manager.spec.js +741 -0
- package/build/tests/core.spec.d.ts +1 -0
- package/build/tests/core.spec.js +31 -0
- package/build/tests/files_manager.spec.d.ts +1 -0
- package/build/tests/files_manager.spec.js +153 -0
- package/build/tests/planner.spec.d.ts +1 -0
- package/build/tests/planner.spec.js +510 -0
- package/build/tests/runner.spec.d.ts +1 -0
- package/build/tests/runner.spec.js +442 -0
- package/build/tests_helpers/main.d.ts +7 -0
- package/build/tests_helpers/main.js +34 -0
- package/package.json +2 -17
- package/build/chunk-7THDHQFT.js +0 -283
- package/build/chunk-HN4AVHWN.js +0 -17
- package/build/chunk-MCOW34SG.js +0 -269
- package/build/chunk-W5IABAQU.js +0 -502
- package/build/main-63126780.d.ts +0 -109
package/build/index.js
CHANGED
|
@@ -1,249 +1,214 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
} from
|
|
11
|
-
import
|
|
12
|
-
|
|
13
|
-
} from
|
|
14
|
-
import {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
} from
|
|
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
|
-
|
|
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
|
-
const { tests } = await getFailedTests();
|
|
56
|
-
if (!tests || !tests.length) {
|
|
57
|
-
console.log(colors.bgYellow().black(" No failing tests found. Running all the tests "));
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
config.filters.tests = tests;
|
|
61
|
-
}
|
|
1
|
+
/*
|
|
2
|
+
* @japa/runner
|
|
3
|
+
*
|
|
4
|
+
* (c) Japa
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
9
|
+
import { fileURLToPath } from 'node:url';
|
|
10
|
+
import { ErrorsPrinter } from '@japa/errors-printer';
|
|
11
|
+
import debug from './src/debug.js';
|
|
12
|
+
import validator from './src/validator.js';
|
|
13
|
+
import { Planner } from './src/planner.js';
|
|
14
|
+
import { GlobalHooks } from './src/hooks.js';
|
|
15
|
+
import { CliParser } from './src/cli_parser.js';
|
|
16
|
+
import { retryPlugin } from './src/plugins/retry.js';
|
|
17
|
+
import { ConfigManager } from './src/config_manager.js';
|
|
18
|
+
import { ExceptionsManager } from './src/exceptions_manager.js';
|
|
19
|
+
import { createTest, createTestGroup } from './src/create_test.js';
|
|
20
|
+
import { Emitter, Runner, Suite } from './modules/core/main.js';
|
|
21
|
+
/**
|
|
22
|
+
* Global emitter instance used by the test
|
|
23
|
+
*/
|
|
24
|
+
const emitter = new Emitter();
|
|
25
|
+
/**
|
|
26
|
+
* The current active test
|
|
27
|
+
*/
|
|
28
|
+
let activeTest;
|
|
29
|
+
/**
|
|
30
|
+
* Parsed commandline arguments
|
|
31
|
+
*/
|
|
32
|
+
let cliArgs = {};
|
|
33
|
+
/**
|
|
34
|
+
* Hydrated config
|
|
35
|
+
*/
|
|
36
|
+
let runnerConfig;
|
|
37
|
+
/**
|
|
38
|
+
* The state refers to the phase where we configure suites and import
|
|
39
|
+
* test files. We stick this metadata to the test instance one can
|
|
40
|
+
* later reference within the test.
|
|
41
|
+
*/
|
|
42
|
+
const executionPlanState = {
|
|
43
|
+
phase: 'idle',
|
|
62
44
|
};
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
* tests output and once the tests are over, we will
|
|
76
|
-
* print them to the console.
|
|
77
|
-
*
|
|
78
|
-
* In case the tests are completed, we will print errors as they
|
|
79
|
-
* happen.
|
|
80
|
-
*/
|
|
81
|
-
monitor() {
|
|
82
|
-
process.on("uncaughtException", async (error) => {
|
|
83
|
-
this.hasErrors = true;
|
|
84
|
-
if (this.#state === "watching") {
|
|
85
|
-
this.#exceptionsBuffer.push(error);
|
|
86
|
-
} else {
|
|
87
|
-
this.#errorsPrinter.printSectionBorder("[Unhandled Error]");
|
|
88
|
-
await this.#errorsPrinter.printError(error);
|
|
89
|
-
process.exitCode = 1;
|
|
90
|
-
}
|
|
45
|
+
/**
|
|
46
|
+
* Create a Japa test. Defining a test without the callback
|
|
47
|
+
* will create a todo test.
|
|
48
|
+
*/
|
|
49
|
+
export function test(title, callback) {
|
|
50
|
+
validator.ensureIsInPlanningPhase(executionPlanState.phase);
|
|
51
|
+
const testInstance = createTest(title, emitter, runnerConfig.refiner, executionPlanState);
|
|
52
|
+
testInstance.setup((t) => {
|
|
53
|
+
activeTest = t;
|
|
54
|
+
return () => {
|
|
55
|
+
activeTest = undefined;
|
|
56
|
+
};
|
|
91
57
|
});
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
if (this.#state === "watching") {
|
|
95
|
-
this.#rejectionsBuffer.push(error);
|
|
96
|
-
} else {
|
|
97
|
-
this.#errorsPrinter.printSectionBorder("[Unhandled Rejection]");
|
|
98
|
-
await this.#errorsPrinter.printError(error);
|
|
99
|
-
process.exitCode = 1;
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
async flow() {
|
|
104
|
-
if (this.#state === "flowing") {
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
this.#state = "flowing";
|
|
108
|
-
if (this.#exceptionsBuffer.length) {
|
|
109
|
-
let exceptionsCount = this.#exceptionsBuffer.length;
|
|
110
|
-
let exceptionsIndex = this.#exceptionsBuffer.length;
|
|
111
|
-
this.#errorsPrinter.printSectionHeader("Unhandled Errors");
|
|
112
|
-
for (let exception of this.#exceptionsBuffer) {
|
|
113
|
-
await this.#errorsPrinter.printError(exception);
|
|
114
|
-
this.#errorsPrinter.printSectionBorder(`[${++exceptionsIndex}/${exceptionsCount}]`);
|
|
115
|
-
}
|
|
116
|
-
this.#exceptionsBuffer = [];
|
|
117
|
-
}
|
|
118
|
-
if (this.#rejectionsBuffer.length) {
|
|
119
|
-
let rejectionsCount = this.#exceptionsBuffer.length;
|
|
120
|
-
let rejectionsIndex = this.#exceptionsBuffer.length;
|
|
121
|
-
this.#errorsPrinter.printSectionBorder("Unhandled Rejections");
|
|
122
|
-
for (let rejection of this.#rejectionsBuffer) {
|
|
123
|
-
await this.#errorsPrinter.printError(rejection);
|
|
124
|
-
this.#errorsPrinter.printSectionBorder(`[${++rejectionsIndex}/${rejectionsCount}]`);
|
|
125
|
-
}
|
|
126
|
-
this.#rejectionsBuffer = [];
|
|
58
|
+
if (callback) {
|
|
59
|
+
testInstance.run(callback);
|
|
127
60
|
}
|
|
128
|
-
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
// index.ts
|
|
132
|
-
var emitter = new Emitter();
|
|
133
|
-
var activeTest;
|
|
134
|
-
var cliArgs = {};
|
|
135
|
-
var runnerConfig;
|
|
136
|
-
var executionPlanState = {
|
|
137
|
-
phase: "idle"
|
|
138
|
-
};
|
|
139
|
-
function test(title, callback) {
|
|
140
|
-
validator_default.ensureIsInPlanningPhase(executionPlanState.phase);
|
|
141
|
-
const testInstance = createTest(title, emitter, runnerConfig.refiner, executionPlanState);
|
|
142
|
-
testInstance.setup((t) => {
|
|
143
|
-
activeTest = t;
|
|
144
|
-
return () => {
|
|
145
|
-
activeTest = void 0;
|
|
146
|
-
};
|
|
147
|
-
});
|
|
148
|
-
if (callback) {
|
|
149
|
-
testInstance.run(callback);
|
|
150
|
-
}
|
|
151
|
-
return testInstance;
|
|
61
|
+
return testInstance;
|
|
152
62
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
runnerConfig.refiner,
|
|
159
|
-
executionPlanState
|
|
160
|
-
|
|
161
|
-
callback(executionPlanState.group);
|
|
162
|
-
executionPlanState.group = void 0;
|
|
63
|
+
/**
|
|
64
|
+
* Create a Japa test group
|
|
65
|
+
*/
|
|
66
|
+
test.group = function (title, callback) {
|
|
67
|
+
validator.ensureIsInPlanningPhase(executionPlanState.phase);
|
|
68
|
+
executionPlanState.group = createTestGroup(title, emitter, runnerConfig.refiner, executionPlanState);
|
|
69
|
+
callback(executionPlanState.group);
|
|
70
|
+
executionPlanState.group = undefined;
|
|
163
71
|
};
|
|
164
|
-
|
|
165
|
-
|
|
72
|
+
/**
|
|
73
|
+
* Get the test of currently running test
|
|
74
|
+
*/
|
|
75
|
+
export function getActiveTest() {
|
|
76
|
+
return activeTest;
|
|
166
77
|
}
|
|
167
|
-
|
|
168
|
-
|
|
78
|
+
/**
|
|
79
|
+
* Make Japa process command line arguments. Later the parsed output
|
|
80
|
+
* will be used by Japa to compute the configuration
|
|
81
|
+
*/
|
|
82
|
+
export function processCLIArgs(argv) {
|
|
83
|
+
cliArgs = new CliParser().parse(argv);
|
|
169
84
|
}
|
|
170
|
-
|
|
171
|
-
|
|
85
|
+
/**
|
|
86
|
+
* Configure the tests runner with inline configuration. You must
|
|
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();
|
|
172
94
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
await retryPlugin({ config: runnerConfig, runner, emitter, cliArgs });
|
|
185
|
-
for (let plugin of runnerConfig.plugins) {
|
|
186
|
-
debug_default('executing "%s" plugin', plugin.name || "anonymous");
|
|
187
|
-
await plugin({ runner, emitter, cliArgs, config: runnerConfig });
|
|
188
|
-
}
|
|
189
|
-
const { config, reporters, suites, refinerFilters } = await new Planner(runnerConfig).plan();
|
|
190
|
-
reporters.forEach((reporter) => {
|
|
191
|
-
debug_default('registering "%s" reporter', reporter.name);
|
|
192
|
-
runner.registerReporter(reporter);
|
|
193
|
-
});
|
|
194
|
-
refinerFilters.forEach((filter) => {
|
|
195
|
-
debug_default('apply %s filters "%O" ', filter.layer, filter.filters);
|
|
196
|
-
config.refiner.add(filter.layer, filter.filters);
|
|
197
|
-
});
|
|
198
|
-
config.refiner.matchAllTags(cliArgs.matchAll ?? false);
|
|
199
|
-
runner.onSuite(config.configureSuite);
|
|
200
|
-
debug_default("executing global hooks");
|
|
201
|
-
globalHooks.apply(config);
|
|
202
|
-
await globalHooks.setup(runner);
|
|
203
|
-
for (let suite of suites) {
|
|
204
|
-
executionPlanState.suite = new Suite(suite.name, emitter, config.refiner);
|
|
205
|
-
executionPlanState.retries = suite.retries;
|
|
206
|
-
executionPlanState.timeout = suite.timeout;
|
|
207
|
-
if (typeof suite.configure === "function") {
|
|
208
|
-
suite.configure(executionPlanState.suite);
|
|
209
|
-
}
|
|
210
|
-
runner.add(executionPlanState.suite);
|
|
211
|
-
for (let fileURL of suite.filesURLs) {
|
|
212
|
-
executionPlanState.file = fileURLToPath(fileURL);
|
|
213
|
-
debug_default("importing test file %s", executionPlanState.file);
|
|
214
|
-
await config.importer(fileURL);
|
|
215
|
-
}
|
|
216
|
-
executionPlanState.suite = void 0;
|
|
217
|
-
}
|
|
218
|
-
executionPlanState.phase = "executing";
|
|
219
|
-
exceptionsManager.monitor();
|
|
220
|
-
await runner.start();
|
|
221
|
-
await runner.exec();
|
|
222
|
-
await globalHooks.teardown(null, runner);
|
|
223
|
-
await runner.end();
|
|
224
|
-
await exceptionsManager.flow();
|
|
225
|
-
const summary = runner.getSummary();
|
|
226
|
-
if (summary.hasError || exceptionsManager.hasErrors) {
|
|
227
|
-
process.exitCode = 1;
|
|
95
|
+
/**
|
|
96
|
+
* Execute Japa tests. Calling this function will import the test
|
|
97
|
+
* files behind the scenes
|
|
98
|
+
*/
|
|
99
|
+
export async function run() {
|
|
100
|
+
/**
|
|
101
|
+
* Display help when help flag is used
|
|
102
|
+
*/
|
|
103
|
+
if (cliArgs.help) {
|
|
104
|
+
console.log(new CliParser().getHelp());
|
|
105
|
+
return;
|
|
228
106
|
}
|
|
229
|
-
|
|
230
|
-
|
|
107
|
+
validator.ensureIsConfigured(runnerConfig);
|
|
108
|
+
executionPlanState.phase = 'planning';
|
|
109
|
+
const runner = new Runner(emitter);
|
|
110
|
+
const globalHooks = new GlobalHooks();
|
|
111
|
+
const exceptionsManager = new ExceptionsManager();
|
|
112
|
+
try {
|
|
113
|
+
/**
|
|
114
|
+
* Executing the retry plugin as the first thing
|
|
115
|
+
*/
|
|
116
|
+
await retryPlugin({ config: runnerConfig, runner, emitter, cliArgs });
|
|
117
|
+
/**
|
|
118
|
+
* Step 1: Executing plugins before creating a plan, so that it can mutate
|
|
119
|
+
* the config
|
|
120
|
+
*/
|
|
121
|
+
for (let plugin of runnerConfig.plugins) {
|
|
122
|
+
debug('executing "%s" plugin', plugin.name || 'anonymous');
|
|
123
|
+
await plugin({ runner, emitter, cliArgs, config: runnerConfig });
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Step 2: Creating an execution plan. The output is the result of
|
|
127
|
+
* applying all the filters and validations.
|
|
128
|
+
*/
|
|
129
|
+
const { config, reporters, suites, refinerFilters } = await new Planner(runnerConfig).plan();
|
|
130
|
+
/**
|
|
131
|
+
* Step 3: Registering reporters and filters with the runner
|
|
132
|
+
*/
|
|
133
|
+
reporters.forEach((reporter) => {
|
|
134
|
+
debug('registering "%s" reporter', reporter.name);
|
|
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
|
+
}
|
|
231
199
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
200
|
+
catch (error) {
|
|
201
|
+
await globalHooks.teardown(error, runner);
|
|
202
|
+
const printer = new ErrorsPrinter();
|
|
203
|
+
await printer.printError(error);
|
|
204
|
+
/**
|
|
205
|
+
* Print unhandled errors in case the code inside
|
|
206
|
+
* the try block never got triggered
|
|
207
|
+
*/
|
|
208
|
+
await exceptionsManager.flow();
|
|
209
|
+
process.exitCode = 1;
|
|
210
|
+
if (runnerConfig.forceExit) {
|
|
211
|
+
process.exit();
|
|
212
|
+
}
|
|
240
213
|
}
|
|
241
|
-
}
|
|
242
214
|
}
|
|
243
|
-
export {
|
|
244
|
-
configure,
|
|
245
|
-
getActiveTest,
|
|
246
|
-
processCLIArgs,
|
|
247
|
-
run,
|
|
248
|
-
test
|
|
249
|
-
};
|
|
@@ -1,3 +1,63 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import '
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
import { Emitter, Refiner, Test as BaseTest, Suite as BaseSuite, Group as BaseGroup, Runner as BaseRunner, TestContext as BaseTestContext } from '@japa/core';
|
|
3
|
+
import { BaseReporter } from './reporters/base.js';
|
|
4
|
+
import type { DataSetNode, TestHooksCleanupHandler } from './types.js';
|
|
5
|
+
declare module '@japa/core' {
|
|
6
|
+
interface Test<Context extends Record<any, any>, TestData extends DataSetNode = undefined> {
|
|
7
|
+
throws(message: string | RegExp, errorConstructor?: any): this;
|
|
8
|
+
}
|
|
9
|
+
interface TestContext {
|
|
10
|
+
cleanup: (cleanupCallback: TestHooksCleanupHandler<TestContext>) => void;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export { Emitter, Refiner, BaseReporter };
|
|
14
|
+
/**
|
|
15
|
+
* Test context carries context data for a given test.
|
|
16
|
+
*/
|
|
17
|
+
export declare class TestContext extends BaseTestContext {
|
|
18
|
+
test: Test;
|
|
19
|
+
/**
|
|
20
|
+
* Register a cleanup function that runs after the test finishes
|
|
21
|
+
* successfully or with an error.
|
|
22
|
+
*/
|
|
23
|
+
cleanup: (cleanupCallback: TestHooksCleanupHandler<TestContext>) => void;
|
|
24
|
+
constructor(test: Test);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Test class represents an individual test and exposes API to tweak
|
|
28
|
+
* its runtime behavior.
|
|
29
|
+
*/
|
|
30
|
+
export declare class Test<TestData extends DataSetNode = undefined> extends BaseTest<TestContext, TestData> {
|
|
31
|
+
/**
|
|
32
|
+
* @inheritdoc
|
|
33
|
+
*/
|
|
34
|
+
static executedCallbacks: never[];
|
|
35
|
+
/**
|
|
36
|
+
* @inheritdoc
|
|
37
|
+
*/
|
|
38
|
+
static executingCallbacks: never[];
|
|
39
|
+
/**
|
|
40
|
+
* Assert the test callback throws an exception when a certain
|
|
41
|
+
* error message and optionally is an instance of a given
|
|
42
|
+
* Error class.
|
|
43
|
+
*/
|
|
44
|
+
throws(message: string | RegExp, errorConstructor?: any): this;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* TestGroup is used to bulk configure a collection of tests and
|
|
48
|
+
* define lifecycle hooks for them
|
|
49
|
+
*/
|
|
50
|
+
export declare class Group extends BaseGroup<TestContext> {
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* A suite is a collection of tests created around a given
|
|
54
|
+
* testing type. For example: A suite for unit tests, a
|
|
55
|
+
* suite for functional tests and so on.
|
|
56
|
+
*/
|
|
57
|
+
export declare class Suite extends BaseSuite<TestContext> {
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Runner class is used to execute the tests
|
|
61
|
+
*/
|
|
62
|
+
export declare class Runner extends BaseRunner<TestContext> {
|
|
63
|
+
}
|
|
@@ -1,21 +1,121 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
} from
|
|
11
|
-
import
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
1
|
+
/*
|
|
2
|
+
* @japa/runner
|
|
3
|
+
*
|
|
4
|
+
* (c) Japa
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
9
|
+
import { Emitter, Refiner, Test as BaseTest, Suite as BaseSuite, Group as BaseGroup, Runner as BaseRunner, TestContext as BaseTestContext, } from '@japa/core';
|
|
10
|
+
import { inspect } from 'node:util';
|
|
11
|
+
import { AssertionError } from 'node:assert';
|
|
12
|
+
import { BaseReporter } from './reporters/base.js';
|
|
13
|
+
export { Emitter, Refiner, BaseReporter };
|
|
14
|
+
/**
|
|
15
|
+
* Test context carries context data for a given test.
|
|
16
|
+
*/
|
|
17
|
+
export class TestContext extends BaseTestContext {
|
|
18
|
+
test;
|
|
19
|
+
constructor(test) {
|
|
20
|
+
super();
|
|
21
|
+
this.test = test;
|
|
22
|
+
this.cleanup = (cleanupCallback) => {
|
|
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
|
+
}
|