@reporters/mocha 1.2.0 → 1.3.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/index.js +148 -58
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -39,6 +39,8 @@ class Test {
|
|
|
39
39
|
this.parent = parent;
|
|
40
40
|
this.root = !parent;
|
|
41
41
|
this.children = [];
|
|
42
|
+
this.kind = 'test';
|
|
43
|
+
this.started = false;
|
|
42
44
|
this.#mochaOptions = mochaOptions;
|
|
43
45
|
|
|
44
46
|
this.body = '';
|
|
@@ -48,15 +50,19 @@ class Test {
|
|
|
48
50
|
this._afterEach = [];
|
|
49
51
|
}
|
|
50
52
|
|
|
51
|
-
|
|
53
|
+
applyStartEvent(event) {
|
|
52
54
|
this.title = event.data.name;
|
|
53
55
|
this.file = event.data.file;
|
|
56
|
+
this.nesting = event.data.nesting;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
applyTestEvent(event, passed) {
|
|
60
|
+
this.applyStartEvent(event);
|
|
54
61
|
this.pending = Boolean(event.data.skip || event.data.todo);
|
|
55
62
|
this.duration = event.data.details?.duration_ms;
|
|
56
63
|
const error = event.data.details?.error;
|
|
57
64
|
this.err = error?.cause instanceof Error ? error.cause : error;
|
|
58
65
|
this.passed = passed;
|
|
59
|
-
this.nesting = event.data.nesting;
|
|
60
66
|
}
|
|
61
67
|
|
|
62
68
|
get state() {
|
|
@@ -90,17 +96,25 @@ class Test {
|
|
|
90
96
|
return this.titlePath().join(' ');
|
|
91
97
|
}
|
|
92
98
|
|
|
93
|
-
|
|
94
|
-
this.
|
|
95
|
-
this.tests = this._tests;
|
|
99
|
+
markSuite() {
|
|
100
|
+
this.kind = 'suite';
|
|
96
101
|
}
|
|
97
102
|
|
|
98
|
-
|
|
99
|
-
|
|
103
|
+
beginSuite() {
|
|
104
|
+
this.markSuite();
|
|
105
|
+
this.started = true;
|
|
100
106
|
}
|
|
101
107
|
|
|
102
|
-
get
|
|
103
|
-
return this.
|
|
108
|
+
get isSuite() {
|
|
109
|
+
return this.kind === 'suite';
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
get suites() {
|
|
113
|
+
return this.children.filter((child) => child.isSuite);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
get tests() {
|
|
117
|
+
return this.children.filter((child) => !child.isSuite);
|
|
104
118
|
}
|
|
105
119
|
}
|
|
106
120
|
|
|
@@ -118,11 +132,16 @@ class Runner extends EventEmitter {
|
|
|
118
132
|
|
|
119
133
|
#reporter;
|
|
120
134
|
|
|
121
|
-
#
|
|
135
|
+
#mochaOptions = loadOptions([]);
|
|
122
136
|
|
|
123
|
-
#
|
|
137
|
+
#root = new Test(null, this.#mochaOptions);
|
|
124
138
|
|
|
125
|
-
#
|
|
139
|
+
#activeNodes = [];
|
|
140
|
+
|
|
141
|
+
constructor() {
|
|
142
|
+
super();
|
|
143
|
+
this.#root.markSuite();
|
|
144
|
+
}
|
|
126
145
|
|
|
127
146
|
async init() {
|
|
128
147
|
const reporterName = this.#mochaOptions.reporter ?? 'spec';
|
|
@@ -135,10 +154,12 @@ class Runner extends EventEmitter {
|
|
|
135
154
|
try {
|
|
136
155
|
Reporter = await import(reporterName).then((m) => m.default || m);
|
|
137
156
|
} catch (err) {
|
|
157
|
+
// eslint-disable-next-line no-console
|
|
138
158
|
console.error(err);
|
|
139
159
|
}
|
|
140
160
|
}
|
|
141
161
|
if (!Reporter) {
|
|
162
|
+
// eslint-disable-next-line no-console
|
|
142
163
|
console.error(new Error(`invalid reporter "${reporterName}"`));
|
|
143
164
|
return;
|
|
144
165
|
}
|
|
@@ -147,72 +168,144 @@ class Runner extends EventEmitter {
|
|
|
147
168
|
}
|
|
148
169
|
|
|
149
170
|
get suite() {
|
|
150
|
-
return this.#
|
|
171
|
+
return this.#root;
|
|
151
172
|
}
|
|
152
173
|
|
|
153
174
|
end() {
|
|
154
175
|
if (!this.#reporter) {
|
|
155
176
|
return;
|
|
156
177
|
}
|
|
178
|
+
this.#closeActiveSuites();
|
|
157
179
|
this.stats.end = new Date();
|
|
158
180
|
this.stats.duration = this.stats.end - this.stats.start;
|
|
159
|
-
this.#
|
|
181
|
+
this.#startRootSuite();
|
|
182
|
+
this.emit(EVENT_SUITE_END, this.#root);
|
|
160
183
|
this.emit(EVENT_RUN_END);
|
|
161
184
|
if (typeof this.#reporter.done === 'function') {
|
|
162
185
|
this.#reporter.done(this.stats.failures, () => {});
|
|
163
186
|
}
|
|
164
187
|
}
|
|
165
188
|
|
|
166
|
-
#
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
189
|
+
#startRootSuite() {
|
|
190
|
+
if (this.#root.started) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
this.#root.beginSuite();
|
|
194
|
+
this.emit(EVENT_SUITE_BEGIN, this.#root);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
#findParent(nesting) {
|
|
198
|
+
if (nesting === 0) {
|
|
199
|
+
return this.#root;
|
|
200
|
+
}
|
|
201
|
+
return this.#activeNodes[nesting - 1] ?? this.#root;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
#matchesNode(node, event) {
|
|
205
|
+
return node
|
|
206
|
+
&& node.nesting === event.data.nesting
|
|
207
|
+
&& node.title === event.data.name;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
#ensureNode(event) {
|
|
211
|
+
const { nesting } = event.data;
|
|
212
|
+
const existingNode = this.#activeNodes[nesting];
|
|
213
|
+
if (this.#matchesNode(existingNode, event)) {
|
|
214
|
+
return existingNode;
|
|
173
215
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
216
|
+
|
|
217
|
+
const parent = this.#findParent(nesting);
|
|
218
|
+
const node = new Test(parent, this.#mochaOptions);
|
|
219
|
+
node.applyStartEvent(event);
|
|
220
|
+
parent.children.push(node);
|
|
221
|
+
this.#activeNodes[nesting] = node;
|
|
222
|
+
this.#activeNodes.length = nesting + 1;
|
|
223
|
+
return node;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
#openSuite(node) {
|
|
227
|
+
if (node.started) {
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
node.beginSuite();
|
|
231
|
+
this.emit(EVENT_SUITE_BEGIN, node);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
#ensureOpenAncestors(nesting) {
|
|
235
|
+
for (let i = 0; i < nesting; i += 1) {
|
|
236
|
+
const node = this.#activeNodes[i];
|
|
237
|
+
if (node) {
|
|
238
|
+
this.#openSuite(node);
|
|
182
239
|
}
|
|
183
|
-
this.emit(EVENT_TEST_END, test);
|
|
184
240
|
}
|
|
185
|
-
this.emit(EVENT_SUITE_END, suite);
|
|
186
241
|
}
|
|
187
242
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
243
|
+
#trimActiveNodes() {
|
|
244
|
+
while (
|
|
245
|
+
this.#activeNodes.length > 0
|
|
246
|
+
&& this.#activeNodes[this.#activeNodes.length - 1] === undefined
|
|
247
|
+
) {
|
|
248
|
+
this.#activeNodes.pop();
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
#reportTest(node) {
|
|
253
|
+
this.stats.tests += 1;
|
|
254
|
+
this.emit(EVENT_TEST_BEGIN, node);
|
|
255
|
+
if (node.pending) {
|
|
256
|
+
this.stats.pending += 1;
|
|
257
|
+
this.emit(EVENT_TEST_PENDING, node);
|
|
258
|
+
} else if (!node.passed) {
|
|
259
|
+
this.stats.failures += 1;
|
|
260
|
+
this.emit(EVENT_TEST_FAIL, node, node.err);
|
|
261
|
+
} else {
|
|
262
|
+
this.stats.passes += 1;
|
|
263
|
+
this.emit(EVENT_TEST_PASS, node);
|
|
264
|
+
}
|
|
265
|
+
this.emit(EVENT_TEST_END, node);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
#closeSuite(node) {
|
|
269
|
+
this.stats.suites += 1;
|
|
270
|
+
this.#openSuite(node);
|
|
271
|
+
this.emit(EVENT_SUITE_END, node);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
#completeNode(event, passed) {
|
|
275
|
+
const node = this.#ensureNode(event);
|
|
276
|
+
this.#ensureOpenAncestors(event.data.nesting);
|
|
277
|
+
node.applyTestEvent(event, passed);
|
|
278
|
+
|
|
279
|
+
if (event.data.details?.type === 'suite' || node.children.length > 0) {
|
|
280
|
+
this.#closeSuite(node);
|
|
281
|
+
} else {
|
|
282
|
+
this.#reportTest(node);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
this.#activeNodes[event.data.nesting] = undefined;
|
|
286
|
+
this.#trimActiveNodes();
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
onTestStart(event) {
|
|
290
|
+
this.#startRootSuite();
|
|
291
|
+
this.#ensureOpenAncestors(event.data.nesting);
|
|
292
|
+
this.#ensureNode(event);
|
|
193
293
|
}
|
|
194
294
|
|
|
195
|
-
|
|
196
|
-
|
|
295
|
+
onTestComplete(event, passed) {
|
|
296
|
+
this.#startRootSuite();
|
|
297
|
+
this.#completeNode(event, passed);
|
|
197
298
|
}
|
|
198
299
|
|
|
199
|
-
|
|
200
|
-
this.#
|
|
201
|
-
|
|
202
|
-
if (
|
|
203
|
-
this
|
|
204
|
-
|
|
205
|
-
this.stats.tests += 1;
|
|
206
|
-
this.stats.pending += 1;
|
|
207
|
-
} else if (!this.#current.passed) {
|
|
208
|
-
this.stats.tests += 1;
|
|
209
|
-
this.stats.failures += 1;
|
|
210
|
-
} else {
|
|
211
|
-
this.stats.tests += 1;
|
|
212
|
-
this.stats.passes += 1;
|
|
300
|
+
#closeActiveSuites() {
|
|
301
|
+
for (let i = this.#activeNodes.length - 1; i >= 0; i -= 1) {
|
|
302
|
+
const node = this.#activeNodes[i];
|
|
303
|
+
if (node && node.isSuite) {
|
|
304
|
+
this.#closeSuite(node);
|
|
305
|
+
this.#activeNodes[i] = undefined;
|
|
213
306
|
}
|
|
214
|
-
this.#current = this.#current.parent;
|
|
215
307
|
}
|
|
308
|
+
this.#trimActiveNodes();
|
|
216
309
|
}
|
|
217
310
|
}
|
|
218
311
|
|
|
@@ -223,14 +316,11 @@ module.exports = async function mochaReporter(source) {
|
|
|
223
316
|
for await (const event of source) {
|
|
224
317
|
switch (event.type) {
|
|
225
318
|
case 'test:start':
|
|
226
|
-
runner.
|
|
319
|
+
runner.onTestStart(event);
|
|
227
320
|
break;
|
|
228
321
|
case 'test:pass':
|
|
229
322
|
case 'test:fail': {
|
|
230
|
-
|
|
231
|
-
runner.addChild(event, event.type === 'test:pass');
|
|
232
|
-
}
|
|
233
|
-
runner.childCompleted(event, event.type === 'test:pass');
|
|
323
|
+
runner.onTestComplete(event, event.type === 'test:pass');
|
|
234
324
|
break;
|
|
235
325
|
}
|
|
236
326
|
default:
|