@japa/runner 2.5.1 → 3.0.0-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +1 -1
- package/build/factories/main.d.ts +3 -0
- package/build/factories/main.d.ts.map +1 -0
- package/build/factories/main.js +2 -0
- package/build/factories/runner.d.ts +10 -0
- package/build/factories/runner.d.ts.map +1 -0
- package/build/factories/runner.js +155 -0
- package/build/index.d.ts +8 -29
- package/build/index.js +93 -466
- package/build/modules/core/main.d.ts +29 -0
- package/build/modules/core/main.d.ts.map +1 -0
- package/build/modules/core/main.js +68 -0
- package/build/modules/core/reporters/base.d.ts +21 -0
- package/build/modules/core/reporters/base.d.ts.map +1 -0
- package/build/modules/core/reporters/base.js +136 -0
- package/build/modules/core/types.d.ts +6 -0
- package/build/modules/core/types.d.ts.map +1 -0
- package/build/modules/core/types.js +1 -0
- package/build/src/cli_parser.d.ts +6 -0
- package/build/src/cli_parser.d.ts.map +1 -0
- package/build/src/cli_parser.js +49 -0
- package/build/src/config_manager.d.ts +7 -0
- package/build/src/config_manager.d.ts.map +1 -0
- package/build/src/config_manager.js +115 -0
- package/build/src/create_test.d.ts +16 -0
- package/build/src/create_test.d.ts.map +1 -0
- package/build/src/create_test.js +33 -0
- package/build/src/debug.d.ts +2 -1
- package/build/src/debug.d.ts.map +1 -0
- package/build/src/debug.js +2 -12
- package/build/src/exceptions_manager.d.ts +7 -0
- package/build/src/exceptions_manager.d.ts.map +1 -0
- package/build/src/exceptions_manager.js +58 -0
- package/build/src/files_manager.d.ts +7 -0
- package/build/src/files_manager.d.ts.map +1 -0
- package/build/src/files_manager.js +28 -0
- package/build/src/helpers.d.ts +23 -0
- package/build/src/helpers.d.ts.map +1 -0
- package/build/src/helpers.js +2 -0
- package/build/src/hooks.d.ts +9 -0
- package/build/src/hooks.d.ts.map +1 -0
- package/build/src/hooks.js +26 -0
- package/build/src/planner.d.ts +18 -0
- package/build/src/planner.d.ts.map +1 -0
- package/build/src/planner.js +67 -0
- package/build/src/plugins/retry.d.ts +8 -0
- package/build/src/plugins/retry.d.ts.map +1 -0
- package/build/src/plugins/retry.js +42 -0
- package/build/src/reporters/dot.d.ts +7 -0
- package/build/src/reporters/dot.d.ts.map +1 -0
- package/build/src/reporters/dot.js +24 -0
- package/build/src/reporters/main.d.ts +5 -0
- package/build/src/reporters/main.d.ts.map +1 -0
- package/build/src/reporters/main.js +21 -0
- package/build/src/reporters/ndjson.d.ts +12 -0
- package/build/src/reporters/ndjson.d.ts.map +1 -0
- package/build/src/reporters/ndjson.js +61 -0
- package/build/src/reporters/spec.d.ts +11 -0
- package/build/src/reporters/spec.d.ts.map +1 -0
- package/build/src/reporters/spec.js +103 -0
- package/build/src/types.d.ts +48 -49
- package/build/src/types.d.ts.map +1 -0
- package/build/src/types.js +1 -10
- package/build/src/validator.d.ts +11 -0
- package/build/src/validator.d.ts.map +1 -0
- package/build/src/validator.js +46 -0
- package/package.json +78 -83
- package/build/src/core/main.d.ts +0 -49
- package/build/src/core/main.js +0 -87
package/build/index.js
CHANGED
|
@@ -1,492 +1,119 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
import { fileURLToPath } from 'node:url';
|
|
2
|
+
import { ErrorsPrinter } from '@japa/errors-printer';
|
|
3
|
+
import debug from './src/debug.js';
|
|
4
|
+
import validator from './src/validator.js';
|
|
5
|
+
import { Planner } from './src/planner.js';
|
|
6
|
+
import { GlobalHooks } from './src/hooks.js';
|
|
7
|
+
import { CliParser } from './src/cli_parser.js';
|
|
8
|
+
import { retryPlugin } from './src/plugins/retry.js';
|
|
9
|
+
import { ConfigManager } from './src/config_manager.js';
|
|
10
|
+
import { ExceptionsManager } from './src/exceptions_manager.js';
|
|
11
|
+
import { createTest, createTestGroup } from './src/create_test.js';
|
|
12
|
+
import { Emitter, Runner, Suite } from './modules/core/main.js';
|
|
13
|
+
const emitter = new Emitter();
|
|
14
|
+
let activeTest;
|
|
15
|
+
let cliArgs = {};
|
|
16
|
+
let runnerConfig;
|
|
17
|
+
const executionPlanState = {
|
|
18
|
+
phase: 'idle',
|
|
12
19
|
};
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const cliui_1 = require("@poppinss/cliui");
|
|
22
|
-
const errors_printer_1 = require("@japa/errors-printer");
|
|
23
|
-
const core_1 = require("@japa/core");
|
|
24
|
-
const main_1 = require("./src/core/main");
|
|
25
|
-
Object.defineProperty(exports, "Test", { enumerable: true, get: function () { return main_1.Test; } });
|
|
26
|
-
Object.defineProperty(exports, "TestContext", { enumerable: true, get: function () { return main_1.TestContext; } });
|
|
27
|
-
Object.defineProperty(exports, "Group", { enumerable: true, get: function () { return main_1.Group; } });
|
|
28
|
-
Object.defineProperty(exports, "Suite", { enumerable: true, get: function () { return main_1.Suite; } });
|
|
29
|
-
Object.defineProperty(exports, "Runner", { enumerable: true, get: function () { return main_1.Runner; } });
|
|
30
|
-
const debug_1 = __importDefault(require("./src/debug"));
|
|
31
|
-
/**
|
|
32
|
-
* Filtering layers allowed by the refiner
|
|
33
|
-
*/
|
|
34
|
-
const refinerFilteringLayers = ['tests', 'groups', 'tags'];
|
|
35
|
-
/**
|
|
36
|
-
* Reference to the recently imported file. We pass it to the
|
|
37
|
-
* test and the group both
|
|
38
|
-
*/
|
|
39
|
-
let recentlyImportedFile;
|
|
40
|
-
/**
|
|
41
|
-
* Global timeout for tests. Fetched from runner options or suites
|
|
42
|
-
* options
|
|
43
|
-
*/
|
|
44
|
-
let globalTimeout;
|
|
45
|
-
/**
|
|
46
|
-
* Function to create the test context for the test
|
|
47
|
-
*/
|
|
48
|
-
const getContext = (testInstance) => new main_1.TestContext(testInstance);
|
|
49
|
-
/**
|
|
50
|
-
* The global reference to the tests emitter
|
|
51
|
-
*/
|
|
52
|
-
const emitter = new core_1.Emitter();
|
|
53
|
-
/**
|
|
54
|
-
* Active suite for tests
|
|
55
|
-
*/
|
|
56
|
-
let activeSuite;
|
|
57
|
-
/**
|
|
58
|
-
* Currently active group
|
|
59
|
-
*/
|
|
60
|
-
let activeGroup;
|
|
61
|
-
/**
|
|
62
|
-
* Configuration options
|
|
63
|
-
*/
|
|
64
|
-
let runnerOptions;
|
|
65
|
-
/**
|
|
66
|
-
* Ensure the configure method has been called
|
|
67
|
-
*/
|
|
68
|
-
function ensureIsConfigured(message) {
|
|
69
|
-
if (!runnerOptions) {
|
|
70
|
-
throw new Error(message);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Validate suites filter to ensure a wrong suite is not
|
|
75
|
-
* mentioned
|
|
76
|
-
*/
|
|
77
|
-
function validateSuitesFilter() {
|
|
78
|
-
if (!('suites' in runnerOptions)) {
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
if (!runnerOptions.filters.suites || !runnerOptions.filters.suites.length) {
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
const suites = runnerOptions.suites.map(({ name }) => name);
|
|
85
|
-
const invalidSuites = runnerOptions.filters.suites.filter((suite) => !suites.includes(suite));
|
|
86
|
-
if (invalidSuites.length) {
|
|
87
|
-
throw new Error(`Unrecognized suite "${invalidSuites[0]}". Make sure to define it in the config first`);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Process command line argument into a string value
|
|
92
|
-
*/
|
|
93
|
-
function processAsString(argv, flagName, onMatch) {
|
|
94
|
-
const flag = argv[flagName];
|
|
95
|
-
if (flag) {
|
|
96
|
-
onMatch((Array.isArray(flag) ? flag : flag.split(',')).map((tag) => tag.trim()));
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Find if the file path matches the files filter array.
|
|
101
|
-
* The ending of the file is matched
|
|
102
|
-
*/
|
|
103
|
-
function isFileAllowed(filePath, filters) {
|
|
104
|
-
if (!filters.files || !filters.files.length) {
|
|
105
|
-
return true;
|
|
106
|
-
}
|
|
107
|
-
return !!filters.files.find((matcher) => {
|
|
108
|
-
if (filePath.endsWith(matcher)) {
|
|
109
|
-
return true;
|
|
110
|
-
}
|
|
111
|
-
return filePath.replace((0, path_1.extname)(filePath), '').endsWith(matcher);
|
|
20
|
+
export function test(title, callback) {
|
|
21
|
+
validator.ensureIsInPlanningPhase(executionPlanState.phase);
|
|
22
|
+
const testInstance = createTest(title, emitter, runnerConfig.refiner, executionPlanState);
|
|
23
|
+
testInstance.setup((t) => {
|
|
24
|
+
activeTest = t;
|
|
25
|
+
return () => {
|
|
26
|
+
activeTest = undefined;
|
|
27
|
+
};
|
|
112
28
|
});
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
* Returns "true" when no filters are applied or the name is part
|
|
116
|
-
* of the applied filter.
|
|
117
|
-
*/
|
|
118
|
-
function isSuiteAllowed(suite, filters) {
|
|
119
|
-
if (!filters.suites || !filters.suites.length) {
|
|
120
|
-
return true;
|
|
121
|
-
}
|
|
122
|
-
return filters.suites.includes(suite.name);
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* Collect files using the files collector function or by processing
|
|
126
|
-
* the glob pattern.
|
|
127
|
-
*
|
|
128
|
-
* The return value is further filtered against the `--files` filter.
|
|
129
|
-
*/
|
|
130
|
-
async function collectFiles(files) {
|
|
131
|
-
if (Array.isArray(files) || typeof files === 'string') {
|
|
132
|
-
const collectedFiles = await (0, fast_glob_1.default)(files, {
|
|
133
|
-
absolute: true,
|
|
134
|
-
onlyFiles: true,
|
|
135
|
-
cwd: runnerOptions.cwd,
|
|
136
|
-
});
|
|
137
|
-
return collectedFiles.filter((file) => isFileAllowed(file, runnerOptions.filters));
|
|
138
|
-
}
|
|
139
|
-
else if (typeof files === 'function') {
|
|
140
|
-
const collectedFiles = await files();
|
|
141
|
-
return collectedFiles.filter((file) => isFileAllowed(file, runnerOptions.filters));
|
|
142
|
-
}
|
|
143
|
-
throw new Error('Invalid value for "files" property. Expected a string, array or a function');
|
|
144
|
-
}
|
|
145
|
-
/**
|
|
146
|
-
* Import test files using the configured importer.
|
|
147
|
-
*/
|
|
148
|
-
async function importFiles(files) {
|
|
149
|
-
for (let file of files) {
|
|
150
|
-
recentlyImportedFile = file;
|
|
151
|
-
await runnerOptions.importer(file);
|
|
29
|
+
if (callback) {
|
|
30
|
+
testInstance.run(callback);
|
|
152
31
|
}
|
|
32
|
+
return testInstance;
|
|
153
33
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
163
|
-
else {
|
|
164
|
-
(0, debug_1.default)('executed tests and waiting for "process.beforeExit" event');
|
|
165
|
-
return new Promise((resolve) => {
|
|
166
|
-
async function beforeExit() {
|
|
167
|
-
process.removeListener('beforeExit', beforeExit);
|
|
168
|
-
(0, debug_1.default)('received "process.beforeExit" event, ending tests');
|
|
169
|
-
await runner.end();
|
|
170
|
-
resolve();
|
|
171
|
-
}
|
|
172
|
-
process.on('beforeExit', beforeExit);
|
|
173
|
-
});
|
|
174
|
-
}
|
|
34
|
+
test.group = function (title, callback) {
|
|
35
|
+
validator.ensureIsInPlanningPhase(executionPlanState.phase);
|
|
36
|
+
executionPlanState.group = createTestGroup(title, emitter, runnerConfig.refiner, executionPlanState);
|
|
37
|
+
callback(executionPlanState.group);
|
|
38
|
+
executionPlanState.group = undefined;
|
|
39
|
+
};
|
|
40
|
+
export function getActiveTest() {
|
|
41
|
+
return activeTest;
|
|
175
42
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
*/
|
|
179
|
-
function showHelp() {
|
|
180
|
-
const green = cliui_1.logger.colors.green.bind(cliui_1.logger.colors);
|
|
181
|
-
const grey = cliui_1.logger.colors.grey.bind(cliui_1.logger.colors);
|
|
182
|
-
console.log(`@japa/runner v2.3.0
|
|
183
|
-
|
|
184
|
-
Options:
|
|
185
|
-
${green('--tests')} ${grey('Specify test titles')}
|
|
186
|
-
${green('--tags')} ${grey('Specify test tags')}
|
|
187
|
-
${green('--groups')} ${grey('Specify group titles')}
|
|
188
|
-
${green('--ignore-tags')} ${grey('Specify negated tags')}
|
|
189
|
-
${green('--files')} ${grey('Specify files to match and run')}
|
|
190
|
-
${green('--force-exit')} ${grey('Enable/disable force exit')}
|
|
191
|
-
${green('--timeout')} ${grey('Define timeout for all the tests')}
|
|
192
|
-
${green('-h, --help')} ${grey('Display this message')}
|
|
193
|
-
|
|
194
|
-
Examples:
|
|
195
|
-
${grey('$ node bin/test.js --tags="@github"')}
|
|
196
|
-
${grey('$ node bin/test.js --files="example.spec.js" --force-exit')}`);
|
|
43
|
+
export function processCLIArgs(argv) {
|
|
44
|
+
cliArgs = new CliParser().parse(argv);
|
|
197
45
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
*/
|
|
201
|
-
function configure(options) {
|
|
202
|
-
const defaultOptions = {
|
|
203
|
-
cliArgs: {},
|
|
204
|
-
cwd: process.cwd(),
|
|
205
|
-
files: [],
|
|
206
|
-
suites: [],
|
|
207
|
-
plugins: [],
|
|
208
|
-
reporters: [],
|
|
209
|
-
timeout: 2000,
|
|
210
|
-
filters: {},
|
|
211
|
-
setup: [],
|
|
212
|
-
teardown: [],
|
|
213
|
-
importer: (filePath) => (0, inclusion_1.default)((0, url_1.pathToFileURL)(filePath).href),
|
|
214
|
-
refiner: new core_1.Refiner({}),
|
|
215
|
-
forceExit: false,
|
|
216
|
-
configureSuite: () => { },
|
|
217
|
-
};
|
|
218
|
-
runnerOptions = Object.assign(defaultOptions, options);
|
|
46
|
+
export function configure(options) {
|
|
47
|
+
runnerConfig = new ConfigManager(options, cliArgs).hydrate();
|
|
219
48
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
*
|
|
225
|
-
* * --tests=Specify test titles
|
|
226
|
-
* * --tags=Specify test tags
|
|
227
|
-
* * --groups=Specify group titles
|
|
228
|
-
* * --ignore-tags=Specify negated tags
|
|
229
|
-
* * --files=Specify files to match and run
|
|
230
|
-
* * --force-exit=Enable/disable force exit
|
|
231
|
-
* * --timeout=Define timeout for all the tests
|
|
232
|
-
* * -h, --help=Show help
|
|
233
|
-
*/
|
|
234
|
-
function processCliArgs(argv) {
|
|
235
|
-
const parsed = (0, getopts_1.default)(argv, {
|
|
236
|
-
string: ['tests', 'tags', 'groups', 'ignoreTags', 'files', 'timeout'],
|
|
237
|
-
boolean: ['forceExit', 'help'],
|
|
238
|
-
alias: {
|
|
239
|
-
ignoreTags: 'ignore-tags',
|
|
240
|
-
forceExit: 'force-exit',
|
|
241
|
-
help: 'h',
|
|
242
|
-
},
|
|
243
|
-
});
|
|
244
|
-
const config = {
|
|
245
|
-
filters: {},
|
|
246
|
-
cliArgs: parsed,
|
|
247
|
-
};
|
|
248
|
-
processAsString(parsed, 'tags', (tags) => (config.filters.tags = tags));
|
|
249
|
-
processAsString(parsed, 'ignoreTags', (tags) => {
|
|
250
|
-
config.filters.tags = config.filters.tags || [];
|
|
251
|
-
tags.forEach((tag) => config.filters.tags.push(`!${tag}`));
|
|
252
|
-
});
|
|
253
|
-
processAsString(parsed, 'groups', (groups) => (config.filters.groups = groups));
|
|
254
|
-
processAsString(parsed, 'tests', (tests) => (config.filters.tests = tests));
|
|
255
|
-
processAsString(parsed, 'files', (files) => (config.filters.files = files));
|
|
256
|
-
/**
|
|
257
|
-
* Show help
|
|
258
|
-
*/
|
|
259
|
-
if (parsed.help) {
|
|
260
|
-
showHelp();
|
|
261
|
-
process.exit(0);
|
|
262
|
-
}
|
|
263
|
-
/**
|
|
264
|
-
* Get suites
|
|
265
|
-
*/
|
|
266
|
-
if (parsed._.length) {
|
|
267
|
-
processAsString({ suites: parsed._ }, 'suites', (suites) => (config.filters.suites = suites));
|
|
268
|
-
}
|
|
269
|
-
/**
|
|
270
|
-
* Get timeout
|
|
271
|
-
*/
|
|
272
|
-
if (parsed.timeout) {
|
|
273
|
-
const value = Number(parsed.timeout);
|
|
274
|
-
if (!isNaN(value)) {
|
|
275
|
-
config.timeout = value;
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
/**
|
|
279
|
-
* Get forceExit
|
|
280
|
-
*/
|
|
281
|
-
if (parsed.forceExit) {
|
|
282
|
-
config.forceExit = true;
|
|
49
|
+
export async function run() {
|
|
50
|
+
if (cliArgs.help) {
|
|
51
|
+
console.log(new CliParser().getHelp());
|
|
52
|
+
return;
|
|
283
53
|
}
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
*/
|
|
290
|
-
async function run() {
|
|
291
|
-
const runner = new main_1.Runner(emitter);
|
|
292
|
-
runner.manageUnHandledExceptions();
|
|
293
|
-
runner.onSuite(runnerOptions.configureSuite);
|
|
294
|
-
const hooks = new hooks_1.Hooks();
|
|
295
|
-
let setupRunner;
|
|
296
|
-
let teardownRunner;
|
|
54
|
+
validator.ensureIsConfigured(runnerConfig);
|
|
55
|
+
executionPlanState.phase = 'planning';
|
|
56
|
+
const runner = new Runner(emitter);
|
|
57
|
+
const globalHooks = new GlobalHooks();
|
|
58
|
+
const exceptionsManager = new ExceptionsManager();
|
|
297
59
|
try {
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
* Plugins can also mutate config. So we process the config after
|
|
303
|
-
* running plugins only
|
|
304
|
-
*/
|
|
305
|
-
for (let plugin of runnerOptions.plugins) {
|
|
306
|
-
(0, debug_1.default)('running plugin "%s"', plugin.name || 'anonymous');
|
|
307
|
-
await plugin(runnerOptions, runner, { Test: main_1.Test, TestContext: main_1.TestContext, Group: main_1.Group });
|
|
60
|
+
await retryPlugin({ config: runnerConfig, runner, emitter, cliArgs });
|
|
61
|
+
for (let plugin of runnerConfig.plugins) {
|
|
62
|
+
debug('executing "%s" plugin', plugin.name || 'anonymous');
|
|
63
|
+
await plugin({ runner, emitter, cliArgs, config: runnerConfig });
|
|
308
64
|
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
*/
|
|
313
|
-
runnerOptions.reporters.forEach((reporter) => {
|
|
314
|
-
(0, debug_1.default)('registering reporter "%s"', reporter.name || 'anonymous');
|
|
65
|
+
const { config, reporters, suites, refinerFilters } = await new Planner(runnerConfig).plan();
|
|
66
|
+
reporters.forEach((reporter) => {
|
|
67
|
+
debug('registering "%s" reporter', reporter.name);
|
|
315
68
|
runner.registerReporter(reporter);
|
|
316
69
|
});
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
/**
|
|
333
|
-
* Step 4: Entertain files property and import test files
|
|
334
|
-
* as part of the default suite
|
|
335
|
-
*/
|
|
336
|
-
if ('files' in runnerOptions && runnerOptions.files.length) {
|
|
337
|
-
(0, debug_1.default)('collecting files for %O globs', runnerOptions.files);
|
|
338
|
-
/**
|
|
339
|
-
* Create a default suite for files with no suite
|
|
340
|
-
*/
|
|
341
|
-
globalTimeout = runnerOptions.timeout;
|
|
342
|
-
const files = await collectFiles(runnerOptions.files);
|
|
343
|
-
/**
|
|
344
|
-
* Create and register suite when files are collected.
|
|
345
|
-
*/
|
|
346
|
-
if (files.length) {
|
|
347
|
-
activeSuite = new main_1.Suite('default', emitter, runnerOptions.refiner);
|
|
348
|
-
runner.add(activeSuite);
|
|
349
|
-
await importFiles(files);
|
|
70
|
+
refinerFilters.forEach((filter) => {
|
|
71
|
+
debug('apply %s filters "%O" ', filter.layer, filter.filters);
|
|
72
|
+
config.refiner.add(filter.layer, filter.filters);
|
|
73
|
+
});
|
|
74
|
+
config.refiner.matchAllTags(cliArgs.matchAll ?? false);
|
|
75
|
+
runner.onSuite(config.configureSuite);
|
|
76
|
+
debug('executing global hooks');
|
|
77
|
+
globalHooks.apply(config);
|
|
78
|
+
await globalHooks.setup(runner);
|
|
79
|
+
for (let suite of suites) {
|
|
80
|
+
executionPlanState.suite = new Suite(suite.name, emitter, config.refiner);
|
|
81
|
+
executionPlanState.retries = suite.retries;
|
|
82
|
+
executionPlanState.timeout = suite.timeout;
|
|
83
|
+
if (typeof suite.configure === 'function') {
|
|
84
|
+
suite.configure(executionPlanState.suite);
|
|
350
85
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
if ('suites' in runnerOptions) {
|
|
357
|
-
for (let suite of runnerOptions.suites) {
|
|
358
|
-
if (isSuiteAllowed(suite, runnerOptions.filters)) {
|
|
359
|
-
if (suite.timeout !== undefined) {
|
|
360
|
-
globalTimeout = suite.timeout;
|
|
361
|
-
}
|
|
362
|
-
else {
|
|
363
|
-
globalTimeout = runnerOptions.timeout;
|
|
364
|
-
}
|
|
365
|
-
(0, debug_1.default)('collecting "%s" suite files for %O globs', suite.name, suite.files);
|
|
366
|
-
const files = await collectFiles(suite.files);
|
|
367
|
-
/**
|
|
368
|
-
* Only register the suite and import files when the suite
|
|
369
|
-
* files glob + filter has returned one or more files.
|
|
370
|
-
*/
|
|
371
|
-
if (files.length) {
|
|
372
|
-
activeSuite = new main_1.Suite(suite.name, emitter, runnerOptions.refiner);
|
|
373
|
-
if (typeof suite.configure === 'function') {
|
|
374
|
-
suite.configure(activeSuite);
|
|
375
|
-
}
|
|
376
|
-
runner.add(activeSuite);
|
|
377
|
-
await importFiles(files);
|
|
378
|
-
}
|
|
379
|
-
}
|
|
86
|
+
runner.add(executionPlanState.suite);
|
|
87
|
+
for (let fileURL of suite.filesURLs) {
|
|
88
|
+
executionPlanState.file = fileURLToPath(fileURL);
|
|
89
|
+
debug('importing test file %s', executionPlanState.file);
|
|
90
|
+
await config.importer(fileURL);
|
|
380
91
|
}
|
|
92
|
+
executionPlanState.suite = undefined;
|
|
381
93
|
}
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
*/
|
|
385
|
-
Object.keys(runnerOptions.filters).forEach((layer) => {
|
|
386
|
-
if (refinerFilteringLayers.includes(layer)) {
|
|
387
|
-
const values = runnerOptions.filters[layer];
|
|
388
|
-
if (values) {
|
|
389
|
-
runnerOptions.refiner.add(layer, values);
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
});
|
|
393
|
-
/**
|
|
394
|
-
* Step 7.1: Start the tests runner
|
|
395
|
-
*/
|
|
94
|
+
executionPlanState.phase = 'executing';
|
|
95
|
+
exceptionsManager.monitor();
|
|
396
96
|
await runner.start();
|
|
397
|
-
/**
|
|
398
|
-
* Step 7.2: Execute all the tests
|
|
399
|
-
*/
|
|
400
97
|
await runner.exec();
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
await setupRunner.cleanup(runner);
|
|
405
|
-
await teardownRunner.run(runner);
|
|
406
|
-
await teardownRunner.cleanup(runner);
|
|
407
|
-
/**
|
|
408
|
-
* Step 7.4: End or wait for process to exit
|
|
409
|
-
*/
|
|
410
|
-
await endTests(runner);
|
|
411
|
-
/**
|
|
412
|
-
* Step 8: Update the process exit code
|
|
413
|
-
*/
|
|
98
|
+
await globalHooks.teardown(null, runner);
|
|
99
|
+
await runner.end();
|
|
100
|
+
await exceptionsManager.flow();
|
|
414
101
|
const summary = runner.getSummary();
|
|
415
|
-
if (summary.hasError) {
|
|
102
|
+
if (summary.hasError || exceptionsManager.hasErrors) {
|
|
416
103
|
process.exitCode = 1;
|
|
417
104
|
}
|
|
418
|
-
|
|
105
|
+
if (config.forceExit) {
|
|
106
|
+
process.exit();
|
|
107
|
+
}
|
|
419
108
|
}
|
|
420
109
|
catch (error) {
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
}
|
|
424
|
-
if (teardownRunner && teardownRunner.isCleanupPending) {
|
|
425
|
-
await teardownRunner.cleanup(error, runner);
|
|
426
|
-
}
|
|
427
|
-
const printer = new errors_printer_1.ErrorsPrinter();
|
|
110
|
+
await globalHooks.teardown(error, runner);
|
|
111
|
+
const printer = new ErrorsPrinter();
|
|
428
112
|
await printer.printError(error);
|
|
113
|
+
await exceptionsManager.flow();
|
|
429
114
|
process.exitCode = 1;
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
}
|
|
433
|
-
exports.run = run;
|
|
434
|
-
/**
|
|
435
|
-
* Add a new test
|
|
436
|
-
*/
|
|
437
|
-
function test(title, callback) {
|
|
438
|
-
ensureIsConfigured('Cannot add test without configuring the test runner');
|
|
439
|
-
const testInstance = new main_1.Test(title, getContext, emitter, runnerOptions.refiner, activeGroup);
|
|
440
|
-
/**
|
|
441
|
-
* Set filename and suite
|
|
442
|
-
*/
|
|
443
|
-
testInstance.options.meta.suite = activeSuite;
|
|
444
|
-
testInstance.options.meta.fileName = recentlyImportedFile;
|
|
445
|
-
/**
|
|
446
|
-
* Define timeout on the test when exists globally
|
|
447
|
-
*/
|
|
448
|
-
if (globalTimeout !== undefined) {
|
|
449
|
-
testInstance.timeout(globalTimeout);
|
|
450
|
-
}
|
|
451
|
-
/**
|
|
452
|
-
* Define test executor function
|
|
453
|
-
*/
|
|
454
|
-
if (callback) {
|
|
455
|
-
testInstance.run(callback);
|
|
456
|
-
}
|
|
457
|
-
/**
|
|
458
|
-
* Add test to the group or suite
|
|
459
|
-
*/
|
|
460
|
-
if (activeGroup) {
|
|
461
|
-
activeGroup.add(testInstance);
|
|
462
|
-
}
|
|
463
|
-
else {
|
|
464
|
-
activeSuite.add(testInstance);
|
|
115
|
+
if (runnerConfig.forceExit) {
|
|
116
|
+
process.exit();
|
|
117
|
+
}
|
|
465
118
|
}
|
|
466
|
-
return testInstance;
|
|
467
119
|
}
|
|
468
|
-
exports.test = test;
|
|
469
|
-
/**
|
|
470
|
-
* Define test group
|
|
471
|
-
*/
|
|
472
|
-
test.group = function (title, callback) {
|
|
473
|
-
ensureIsConfigured('Cannot add test group without configuring the test runner');
|
|
474
|
-
/**
|
|
475
|
-
* Disallow nested groups
|
|
476
|
-
*/
|
|
477
|
-
if (activeGroup) {
|
|
478
|
-
throw new Error('Cannot create nested test groups');
|
|
479
|
-
}
|
|
480
|
-
activeGroup = new main_1.Group(title, emitter, runnerOptions.refiner);
|
|
481
|
-
/**
|
|
482
|
-
* Set filename and suite
|
|
483
|
-
*/
|
|
484
|
-
activeGroup.options.meta.suite = activeSuite;
|
|
485
|
-
activeGroup.options.meta.fileName = recentlyImportedFile;
|
|
486
|
-
/**
|
|
487
|
-
* Add group to the default suite
|
|
488
|
-
*/
|
|
489
|
-
activeSuite.add(activeGroup);
|
|
490
|
-
callback(activeGroup);
|
|
491
|
-
activeGroup = undefined;
|
|
492
|
-
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Emitter, Refiner, Test as BaseTest, Suite as BaseSuite, Group as BaseGroup, Runner as BaseRunner, TestContext as BaseTestContext } from '@japa/core';
|
|
2
|
+
import { BaseReporter } from './reporters/base.js';
|
|
3
|
+
import type { DataSetNode, TestHooksCleanupHandler } from './types.js';
|
|
4
|
+
declare module '@japa/core' {
|
|
5
|
+
interface Test<Context extends Record<any, any>, TestData extends DataSetNode = undefined> {
|
|
6
|
+
throws(message: string | RegExp, errorConstructor?: any): this;
|
|
7
|
+
}
|
|
8
|
+
interface TestContext {
|
|
9
|
+
cleanup: (cleanupCallback: TestHooksCleanupHandler<TestContext>) => void;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export { Emitter, Refiner, BaseReporter };
|
|
13
|
+
export declare class TestContext extends BaseTestContext {
|
|
14
|
+
test: Test;
|
|
15
|
+
cleanup: (cleanupCallback: TestHooksCleanupHandler<TestContext>) => void;
|
|
16
|
+
constructor(test: Test);
|
|
17
|
+
}
|
|
18
|
+
export declare class Test<TestData extends DataSetNode = undefined> extends BaseTest<TestContext, TestData> {
|
|
19
|
+
static executedCallbacks: never[];
|
|
20
|
+
static executingCallbacks: never[];
|
|
21
|
+
throws(message: string | RegExp, errorConstructor?: any): this;
|
|
22
|
+
}
|
|
23
|
+
export declare class Group extends BaseGroup<TestContext> {
|
|
24
|
+
}
|
|
25
|
+
export declare class Suite extends BaseSuite<TestContext> {
|
|
26
|
+
}
|
|
27
|
+
export declare class Runner extends BaseRunner<TestContext> {
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=main.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../modules/core/main.ts"],"names":[],"mappings":"AASA,OAAO,EACL,OAAO,EACP,OAAO,EACP,IAAI,IAAI,QAAQ,EAChB,KAAK,IAAI,SAAS,EAClB,KAAK,IAAI,SAAS,EAClB,MAAM,IAAI,UAAU,EACpB,WAAW,IAAI,eAAe,EAC/B,MAAM,YAAY,CAAA;AAGnB,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA;AAEtE,OAAO,QAAQ,YAAY,CAAC;IAC1B,UAAU,IAAI,CAAC,OAAO,SAAS,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,QAAQ,SAAS,WAAW,GAAG,SAAS;QACvF,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,gBAAgB,CAAC,EAAE,GAAG,GAAG,IAAI,CAAA;KAC/D;IACD,UAAU,WAAW;QACnB,OAAO,EAAE,CAAC,eAAe,EAAE,uBAAuB,CAAC,WAAW,CAAC,KAAK,IAAI,CAAA;KACzE;CACF;AAED,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,CAAA;AAKzC,qBAAa,WAAY,SAAQ,eAAe;IAO3B,IAAI,EAAE,IAAI;IAFrB,OAAO,EAAE,CAAC,eAAe,EAAE,uBAAuB,CAAC,WAAW,CAAC,KAAK,IAAI,CAAA;gBAE7D,IAAI,EAAE,IAAI;CAM9B;AAMD,qBAAa,IAAI,CAAC,QAAQ,SAAS,WAAW,GAAG,SAAS,CAAE,SAAQ,QAAQ,CAC1E,WAAW,EACX,QAAQ,CACT;IAIC,MAAM,CAAC,iBAAiB,UAAK;IAK7B,MAAM,CAAC,kBAAkB,UAAK;IAO9B,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,gBAAgB,CAAC,EAAE,GAAG;CAgExD;AAMD,qBAAa,KAAM,SAAQ,SAAS,CAAC,WAAW,CAAC;CAAG;AAOpD,qBAAa,KAAM,SAAQ,SAAS,CAAC,WAAW,CAAC;CAAG;AAKpD,qBAAa,MAAO,SAAQ,UAAU,CAAC,WAAW,CAAC;CAAG"}
|