@japa/runner 3.0.4 → 3.0.5
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-CXTCA2MO.js +503 -0
- package/build/chunk-CXTCA2MO.js.map +1 -0
- package/build/chunk-MWYEWO7K.js +18 -0
- package/build/chunk-MWYEWO7K.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/reporters/main.js +12 -37
- package/build/src/reporters/main.js.map +1 -0
- package/build/src/types.js +15 -9
- package/build/src/types.js.map +1 -0
- package/package.json +32 -16
- 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
|
@@ -1,86 +0,0 @@
|
|
|
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 { relative } from 'node:path';
|
|
10
|
-
import { serializeError } from 'serialize-error';
|
|
11
|
-
import { BaseReporter } from '../../modules/core/main.js';
|
|
12
|
-
/**
|
|
13
|
-
* Prints tests progress as JSON. Each event is emitted
|
|
14
|
-
* independently
|
|
15
|
-
*/
|
|
16
|
-
export class NdJSONReporter extends BaseReporter {
|
|
17
|
-
/**
|
|
18
|
-
* Returns the filename relative from the current working dir
|
|
19
|
-
*/
|
|
20
|
-
#getRelativeFilename(fileName) {
|
|
21
|
-
return relative(process.cwd(), fileName);
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Serialize errors to JSON
|
|
25
|
-
*/
|
|
26
|
-
#serializeErrors(errors) {
|
|
27
|
-
return errors.map((error) => ({
|
|
28
|
-
phase: error.phase,
|
|
29
|
-
error: serializeError(error.error),
|
|
30
|
-
}));
|
|
31
|
-
}
|
|
32
|
-
onTestEnd(payload) {
|
|
33
|
-
console.log(JSON.stringify({
|
|
34
|
-
event: 'test:end',
|
|
35
|
-
filePath: this.currentFileName,
|
|
36
|
-
relativePath: this.currentFileName
|
|
37
|
-
? this.#getRelativeFilename(this.currentFileName)
|
|
38
|
-
: undefined,
|
|
39
|
-
title: payload.title,
|
|
40
|
-
duration: payload.duration,
|
|
41
|
-
failReason: payload.failReason,
|
|
42
|
-
isFailing: payload.isFailing,
|
|
43
|
-
skipReason: payload.skipReason,
|
|
44
|
-
isSkipped: payload.isSkipped,
|
|
45
|
-
isTodo: payload.isTodo,
|
|
46
|
-
isPinned: payload.isPinned,
|
|
47
|
-
retryAttempt: payload.retryAttempt,
|
|
48
|
-
retries: payload.retries,
|
|
49
|
-
errors: this.#serializeErrors(payload.errors),
|
|
50
|
-
}));
|
|
51
|
-
}
|
|
52
|
-
onGroupStart(payload) {
|
|
53
|
-
console.log(JSON.stringify({
|
|
54
|
-
event: 'group:start',
|
|
55
|
-
title: payload.title,
|
|
56
|
-
}));
|
|
57
|
-
}
|
|
58
|
-
onGroupEnd(payload) {
|
|
59
|
-
JSON.stringify({
|
|
60
|
-
event: 'group:end',
|
|
61
|
-
title: payload.title,
|
|
62
|
-
errors: this.#serializeErrors(payload.errors),
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
onSuiteStart(payload) {
|
|
66
|
-
console.log(JSON.stringify({
|
|
67
|
-
event: 'suite:start',
|
|
68
|
-
...payload,
|
|
69
|
-
}));
|
|
70
|
-
}
|
|
71
|
-
onSuiteEnd(payload) {
|
|
72
|
-
console.log(JSON.stringify({
|
|
73
|
-
event: 'suite:end',
|
|
74
|
-
...payload,
|
|
75
|
-
}));
|
|
76
|
-
}
|
|
77
|
-
async end() {
|
|
78
|
-
const summary = this.runner.getSummary();
|
|
79
|
-
console.log(JSON.stringify({
|
|
80
|
-
aggregates: summary.aggregates,
|
|
81
|
-
duration: summary.duration,
|
|
82
|
-
failedTestsTitles: summary.failedTestsTitles,
|
|
83
|
-
hasError: summary.hasError,
|
|
84
|
-
}));
|
|
85
|
-
}
|
|
86
|
-
}
|
|
@@ -1,152 +0,0 @@
|
|
|
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 ms from 'ms';
|
|
10
|
-
import { relative } from 'node:path';
|
|
11
|
-
import { colors, icons } from '../helpers.js';
|
|
12
|
-
import { BaseReporter } from '../../modules/core/main.js';
|
|
13
|
-
/**
|
|
14
|
-
* Pretty prints the tests on the console
|
|
15
|
-
*/
|
|
16
|
-
export class SpecReporter extends BaseReporter {
|
|
17
|
-
/**
|
|
18
|
-
* Tracking if the first event we get is for a test without any parent group
|
|
19
|
-
* We need this to decide the display style for tests without groups.
|
|
20
|
-
*/
|
|
21
|
-
#isFirstLoneTest = true;
|
|
22
|
-
/**
|
|
23
|
-
* Returns the icon for the test
|
|
24
|
-
*/
|
|
25
|
-
#getTestIcon(payload) {
|
|
26
|
-
if (payload.isTodo) {
|
|
27
|
-
return colors.cyan(icons.info);
|
|
28
|
-
}
|
|
29
|
-
if (payload.isFailing) {
|
|
30
|
-
return payload.hasError ? colors.magenta(icons.squareSmallFilled) : colors.red(icons.cross);
|
|
31
|
-
}
|
|
32
|
-
if (payload.hasError) {
|
|
33
|
-
return colors.red(icons.cross);
|
|
34
|
-
}
|
|
35
|
-
if (payload.isSkipped) {
|
|
36
|
-
return colors.yellow(icons.bullet);
|
|
37
|
-
}
|
|
38
|
-
return colors.green(icons.tick);
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Returns the test message
|
|
42
|
-
*/
|
|
43
|
-
#getTestMessage(payload) {
|
|
44
|
-
const message = typeof payload.title === 'string' ? payload.title : payload.title.expanded;
|
|
45
|
-
if (payload.isTodo) {
|
|
46
|
-
return colors.blue(message);
|
|
47
|
-
}
|
|
48
|
-
if (payload.isFailing) {
|
|
49
|
-
return payload.hasError ? colors.magenta(message) : colors.red(message);
|
|
50
|
-
}
|
|
51
|
-
if (payload.hasError) {
|
|
52
|
-
return colors.red(message);
|
|
53
|
-
}
|
|
54
|
-
if (payload.isSkipped) {
|
|
55
|
-
return colors.yellow(message);
|
|
56
|
-
}
|
|
57
|
-
return colors.grey(message);
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Returns the subtext message for the test
|
|
61
|
-
*/
|
|
62
|
-
#getSubText(payload) {
|
|
63
|
-
if (payload.isSkipped && payload.skipReason) {
|
|
64
|
-
return colors.yellow(payload.skipReason);
|
|
65
|
-
}
|
|
66
|
-
if (!payload.isFailing) {
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
if (!payload.hasError) {
|
|
70
|
-
return colors.magenta(`Test marked with ".fails()" must finish with an error`);
|
|
71
|
-
}
|
|
72
|
-
if (payload.failReason) {
|
|
73
|
-
return colors.magenta(payload.failReason);
|
|
74
|
-
}
|
|
75
|
-
const testErrorMessage = payload.errors.find((error) => error.phase === 'test');
|
|
76
|
-
if (testErrorMessage && testErrorMessage.error) {
|
|
77
|
-
return colors.magenta(testErrorMessage.error.message);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Returns the filename relative from the current working dir
|
|
82
|
-
*/
|
|
83
|
-
#getRelativeFilename(fileName) {
|
|
84
|
-
return relative(process.cwd(), fileName);
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Prints the test details
|
|
88
|
-
*/
|
|
89
|
-
#printTest(payload) {
|
|
90
|
-
const icon = this.#getTestIcon(payload);
|
|
91
|
-
const message = this.#getTestMessage(payload);
|
|
92
|
-
const prefix = payload.isPinned ? colors.yellow('[PINNED] ') : '';
|
|
93
|
-
const indentation = this.currentFileName || this.currentGroupName ? ' ' : '';
|
|
94
|
-
const duration = colors.dim(`(${ms(Number(payload.duration.toFixed(2)))})`);
|
|
95
|
-
const retries = payload.retryAttempt && payload.retryAttempt > 1
|
|
96
|
-
? colors.dim(`(x${payload.retryAttempt}) `)
|
|
97
|
-
: '';
|
|
98
|
-
let subText = this.#getSubText(payload);
|
|
99
|
-
subText = subText ? `\n${indentation} ${subText}` : '';
|
|
100
|
-
console.log(`${indentation}${icon} ${prefix}${retries}${message} ${duration}${subText}`);
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* Prints the group name
|
|
104
|
-
*/
|
|
105
|
-
#printGroup(payload) {
|
|
106
|
-
const title = this.currentSuiteName !== 'default'
|
|
107
|
-
? `${this.currentSuiteName} / ${payload.title}`
|
|
108
|
-
: payload.title;
|
|
109
|
-
const suffix = this.currentFileName
|
|
110
|
-
? colors.dim(` (${this.#getRelativeFilename(this.currentFileName)})`)
|
|
111
|
-
: '';
|
|
112
|
-
console.log(`\n${title}${suffix}`);
|
|
113
|
-
}
|
|
114
|
-
onTestStart() {
|
|
115
|
-
/**
|
|
116
|
-
* Display the filename when
|
|
117
|
-
*
|
|
118
|
-
* - The filename exists
|
|
119
|
-
* - The test is not under a group
|
|
120
|
-
* - Test is first in a sequence
|
|
121
|
-
*/
|
|
122
|
-
if (this.currentFileName && this.#isFirstLoneTest) {
|
|
123
|
-
console.log(`\n${colors.dim(this.#getRelativeFilename(this.currentFileName))}`);
|
|
124
|
-
}
|
|
125
|
-
this.#isFirstLoneTest = false;
|
|
126
|
-
}
|
|
127
|
-
onTestEnd(payload) {
|
|
128
|
-
this.#printTest(payload);
|
|
129
|
-
}
|
|
130
|
-
onGroupStart(payload) {
|
|
131
|
-
/**
|
|
132
|
-
* When a group starts, we mark the upcoming test as NOT a
|
|
133
|
-
* lone test
|
|
134
|
-
*/
|
|
135
|
-
this.#isFirstLoneTest = false;
|
|
136
|
-
this.#printGroup(payload);
|
|
137
|
-
}
|
|
138
|
-
onGroupEnd() {
|
|
139
|
-
/**
|
|
140
|
-
* When the group ends we assume that the next test can
|
|
141
|
-
* be out of the group, hence a lone test.
|
|
142
|
-
*
|
|
143
|
-
* If this assumption is false, then the `onGroupStart` method
|
|
144
|
-
* will toggle the boolean
|
|
145
|
-
*/
|
|
146
|
-
this.#isFirstLoneTest = true;
|
|
147
|
-
}
|
|
148
|
-
async end() {
|
|
149
|
-
const summary = this.runner.getSummary();
|
|
150
|
-
await this.printSummary(summary);
|
|
151
|
-
}
|
|
152
|
-
}
|
package/build/src/validator.js
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
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
|
-
/**
|
|
10
|
-
* Validator encapsulates the validations to perform before running
|
|
11
|
-
* the tests
|
|
12
|
-
*/
|
|
13
|
-
class Validator {
|
|
14
|
-
/**
|
|
15
|
-
* Ensures the japa is configured. Otherwise raises an exception
|
|
16
|
-
*/
|
|
17
|
-
ensureIsConfigured(config) {
|
|
18
|
-
if (!config) {
|
|
19
|
-
throw new Error(`Cannot run tests. Make sure to call "configure" method before the "run" method`);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Ensures the japa is in planning phase
|
|
24
|
-
*/
|
|
25
|
-
ensureIsInPlanningPhase(phase) {
|
|
26
|
-
if (phase !== 'planning') {
|
|
27
|
-
throw new Error(`Cannot import japa test file directly. It must be imported by calling the "japa.run" method`);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Ensures the suites filter uses a subset of the user configured suites.
|
|
32
|
-
*/
|
|
33
|
-
validateSuitesFilter(config) {
|
|
34
|
-
/**
|
|
35
|
-
* Do not perform any validation if no filters are applied
|
|
36
|
-
* in the first place
|
|
37
|
-
*/
|
|
38
|
-
if (!config.filters.suites || !config.filters.suites.length) {
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Notify user they have applied the suites filter but forgot to define
|
|
43
|
-
* suites
|
|
44
|
-
*/
|
|
45
|
-
if (!('suites' in config) || !config.suites.length) {
|
|
46
|
-
throw new Error(`Cannot apply suites filter. You have not configured any test suites`);
|
|
47
|
-
}
|
|
48
|
-
const suites = config.suites.map(({ name }) => name);
|
|
49
|
-
/**
|
|
50
|
-
* Find unknown suites and report the error
|
|
51
|
-
*/
|
|
52
|
-
const unknownSuites = config.filters.suites.filter((suite) => !suites.includes(suite));
|
|
53
|
-
if (unknownSuites.length) {
|
|
54
|
-
throw new Error(`Cannot apply suites filter. "${unknownSuites[0]}" suite is not configured`);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Ensure there are unique suites
|
|
59
|
-
*/
|
|
60
|
-
validateSuitesForUniqueness(config) {
|
|
61
|
-
if (!('suites' in config)) {
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
const suites = new Set();
|
|
65
|
-
config.suites.forEach(({ name }) => {
|
|
66
|
-
if (suites.has(name)) {
|
|
67
|
-
throw new Error(`Duplicate suite "${name}"`);
|
|
68
|
-
}
|
|
69
|
-
suites.add(name);
|
|
70
|
-
});
|
|
71
|
-
suites.clear();
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Ensure the activated reporters are in the list of defined
|
|
75
|
-
* reporters
|
|
76
|
-
*/
|
|
77
|
-
validateActivatedReporters(config) {
|
|
78
|
-
const reportersList = config.reporters.list.map(({ name }) => name);
|
|
79
|
-
const unknownReporters = config.reporters.activated.filter((name) => !reportersList.includes(name));
|
|
80
|
-
if (unknownReporters.length) {
|
|
81
|
-
throw new Error(`Invalid reporter "${unknownReporters[0]}". Make sure to register it first inside the "reporters.list" array`);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
export default new Validator();
|