factorio-test-cli 3.3.0 → 3.4.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/factorio-process.js +4 -1
- package/package.json +1 -1
- package/test-output.js +34 -5
- package/test-output.test.js +178 -3
- package/test-results.js +19 -0
- package/test-results.test.js +58 -1
package/factorio-process.js
CHANGED
|
@@ -118,7 +118,7 @@ function createOutputComponents(options) {
|
|
|
118
118
|
collector.handleEvent(event);
|
|
119
119
|
progress.handleEvent(event);
|
|
120
120
|
if (options.verbose) {
|
|
121
|
-
progress.withPermanentOutput(() =>
|
|
121
|
+
progress.withPermanentOutput(() => printer.printEvent(event));
|
|
122
122
|
}
|
|
123
123
|
});
|
|
124
124
|
handler.on("log", (line) => {
|
|
@@ -132,6 +132,9 @@ function createOutputComponents(options) {
|
|
|
132
132
|
progress.handleTestFinished(test);
|
|
133
133
|
progress.withPermanentOutput(() => printer.printTestResult(test));
|
|
134
134
|
});
|
|
135
|
+
collector.on("describeBlockFailed", (block) => {
|
|
136
|
+
progress.withPermanentOutput(() => printer.printTestResult(block));
|
|
137
|
+
});
|
|
135
138
|
handler.on("result", () => {
|
|
136
139
|
progress.finish();
|
|
137
140
|
printer.resetMessage();
|
package/package.json
CHANGED
package/test-output.js
CHANGED
|
@@ -87,16 +87,19 @@ export class OutputFormatter {
|
|
|
87
87
|
formatTestResult(test) {
|
|
88
88
|
if (this.options.quiet)
|
|
89
89
|
return;
|
|
90
|
-
const
|
|
90
|
+
const prefix = this.getPrefix(test.result);
|
|
91
|
+
const duration = test.durationMs !== undefined ? ` (${formatDuration(test.durationMs)})` : "";
|
|
92
|
+
console.log(`${prefix} ${test.path}${duration}`);
|
|
93
|
+
const showLogs = this.options.showLogs !== false &&
|
|
94
|
+
(test.result === "failed" || test.result === "error" || this.options.showPassedLogs);
|
|
91
95
|
if (showLogs && test.logs.length > 0) {
|
|
96
|
+
console.log("Log messages:");
|
|
92
97
|
for (const log of test.logs) {
|
|
93
98
|
console.log(" " + log);
|
|
94
99
|
}
|
|
95
100
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
console.log(`${prefix} ${test.path}${duration}`);
|
|
99
|
-
if (test.result === "failed") {
|
|
101
|
+
if ((test.result === "failed" || test.result === "error") && test.errors.length > 0) {
|
|
102
|
+
console.log("Errors:");
|
|
100
103
|
for (const error of test.errors) {
|
|
101
104
|
console.log(" " + error);
|
|
102
105
|
}
|
|
@@ -107,6 +110,7 @@ export class OutputFormatter {
|
|
|
107
110
|
return;
|
|
108
111
|
if (!this.options.quiet) {
|
|
109
112
|
this.printRecapSection(data.tests, "failed", "Failures:");
|
|
113
|
+
this.printRecapSection(data.tests, "error", "Describe block errors:");
|
|
110
114
|
this.printRecapSection(data.tests, "todo", "Todo:");
|
|
111
115
|
}
|
|
112
116
|
this.printCountsLine(data.summary);
|
|
@@ -126,6 +130,8 @@ export class OutputFormatter {
|
|
|
126
130
|
const segments = [];
|
|
127
131
|
if (summary.failed > 0)
|
|
128
132
|
segments.push(chalk.red(`${summary.failed} failed`));
|
|
133
|
+
if (summary.describeBlockErrors > 0)
|
|
134
|
+
segments.push(chalk.red(`${summary.describeBlockErrors} errors`));
|
|
129
135
|
if (summary.todo > 0)
|
|
130
136
|
segments.push(chalk.magenta(`${summary.todo} todo`));
|
|
131
137
|
if (summary.skipped > 0)
|
|
@@ -134,12 +140,28 @@ export class OutputFormatter {
|
|
|
134
140
|
const total = summary.passed + summary.failed + summary.skipped + summary.todo;
|
|
135
141
|
console.log(`Tests: ${segments.join(", ")} (${total} total)`);
|
|
136
142
|
}
|
|
143
|
+
formatEvent(event) {
|
|
144
|
+
switch (event.type) {
|
|
145
|
+
case "testRunStarted":
|
|
146
|
+
return chalk.dim(`Running ${event.total} tests...`);
|
|
147
|
+
case "testStarted":
|
|
148
|
+
return chalk.dim(`Starting: ${event.test.path}`);
|
|
149
|
+
case "loadError":
|
|
150
|
+
return chalk.red(`Load error: ${event.error}`);
|
|
151
|
+
case "testRunCancelled":
|
|
152
|
+
return chalk.yellow("Test run cancelled");
|
|
153
|
+
default:
|
|
154
|
+
return undefined;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
137
157
|
getPrefix(result) {
|
|
138
158
|
switch (result) {
|
|
139
159
|
case "passed":
|
|
140
160
|
return chalk.green("PASS");
|
|
141
161
|
case "failed":
|
|
142
162
|
return chalk.red("FAIL");
|
|
163
|
+
case "error":
|
|
164
|
+
return chalk.red("ERROR");
|
|
143
165
|
case "skipped":
|
|
144
166
|
return chalk.yellow("SKIP");
|
|
145
167
|
case "todo":
|
|
@@ -157,6 +179,7 @@ export class OutputPrinter {
|
|
|
157
179
|
verbose: options.verbose,
|
|
158
180
|
quiet: options.quiet,
|
|
159
181
|
showPassedLogs: options.verbose,
|
|
182
|
+
showLogs: !options.verbose,
|
|
160
183
|
});
|
|
161
184
|
}
|
|
162
185
|
printTestResult(test) {
|
|
@@ -180,6 +203,12 @@ export class OutputPrinter {
|
|
|
180
203
|
resetMessage() {
|
|
181
204
|
this.isMessageFirstLine = true;
|
|
182
205
|
}
|
|
206
|
+
printEvent(event) {
|
|
207
|
+
const formatted = this.formatter.formatEvent(event);
|
|
208
|
+
if (formatted !== undefined) {
|
|
209
|
+
console.log(formatted);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
183
212
|
printVerbose(line) {
|
|
184
213
|
if (this.options.verbose) {
|
|
185
214
|
console.log(line);
|
package/test-output.test.js
CHANGED
|
@@ -150,12 +150,19 @@ describe("OutputFormatter", () => {
|
|
|
150
150
|
expect(output.some((line) => line.includes("assertion failed"))).toBe(true);
|
|
151
151
|
expect(output.some((line) => line.includes("at test.ts:10"))).toBe(true);
|
|
152
152
|
});
|
|
153
|
-
it("shows logs
|
|
153
|
+
it("shows status line first, then logs and errors with headers", () => {
|
|
154
154
|
const formatter = new OutputFormatter({});
|
|
155
155
|
formatter.formatTestResult(failedTest);
|
|
156
|
-
const logIndex = output.findIndex((line) => line.includes("debug output"));
|
|
157
156
|
const failIndex = output.findIndex((line) => line.includes("FAIL"));
|
|
158
|
-
|
|
157
|
+
const logHeaderIndex = output.findIndex((line) => line.includes("Log messages:"));
|
|
158
|
+
const logIndex = output.findIndex((line) => line.includes("debug output"));
|
|
159
|
+
const errorHeaderIndex = output.findIndex((line) => line.includes("Errors:"));
|
|
160
|
+
const errorIndex = output.findIndex((line) => line.includes("assertion failed"));
|
|
161
|
+
expect(failIndex).toBe(0);
|
|
162
|
+
expect(logHeaderIndex).toBeGreaterThan(failIndex);
|
|
163
|
+
expect(logIndex).toBeGreaterThan(logHeaderIndex);
|
|
164
|
+
expect(errorHeaderIndex).toBeGreaterThan(logIndex);
|
|
165
|
+
expect(errorIndex).toBeGreaterThan(errorHeaderIndex);
|
|
159
166
|
});
|
|
160
167
|
it("hides logs for passed tests by default", () => {
|
|
161
168
|
const formatter = new OutputFormatter({});
|
|
@@ -199,6 +206,120 @@ describe("OutputFormatter", () => {
|
|
|
199
206
|
expect(output[0]).toContain("TODO");
|
|
200
207
|
expect(output[0]).toContain("todo test");
|
|
201
208
|
});
|
|
209
|
+
it("formats describe block error with ERROR prefix", () => {
|
|
210
|
+
const formatter = new OutputFormatter({});
|
|
211
|
+
const errorTest = {
|
|
212
|
+
path: "root > block",
|
|
213
|
+
result: "error",
|
|
214
|
+
errors: ["Error running afterAll: Oh no"],
|
|
215
|
+
logs: ["hook log"],
|
|
216
|
+
};
|
|
217
|
+
formatter.formatTestResult(errorTest);
|
|
218
|
+
expect(output[0]).toContain("ERROR");
|
|
219
|
+
expect(output[0]).toContain("root > block");
|
|
220
|
+
expect(output.some((line) => line.includes("Log messages:"))).toBe(true);
|
|
221
|
+
expect(output.some((line) => line.includes("hook log"))).toBe(true);
|
|
222
|
+
expect(output.some((line) => line.includes("Errors:"))).toBe(true);
|
|
223
|
+
expect(output.some((line) => line.includes("Oh no"))).toBe(true);
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
describe("OutputFormatter.formatEvent", () => {
|
|
227
|
+
it("formats testRunStarted", () => {
|
|
228
|
+
const formatter = new OutputFormatter({});
|
|
229
|
+
const result = formatter.formatEvent({ type: "testRunStarted", total: 42 });
|
|
230
|
+
expect(result).toContain("Running 42 tests...");
|
|
231
|
+
});
|
|
232
|
+
it("formats testStarted", () => {
|
|
233
|
+
const formatter = new OutputFormatter({});
|
|
234
|
+
const result = formatter.formatEvent({ type: "testStarted", test: { path: "root > my test" } });
|
|
235
|
+
expect(result).toContain("Starting: root > my test");
|
|
236
|
+
});
|
|
237
|
+
it("formats loadError", () => {
|
|
238
|
+
const formatter = new OutputFormatter({});
|
|
239
|
+
const result = formatter.formatEvent({ type: "loadError", error: "syntax error in foo.lua" });
|
|
240
|
+
expect(result).toContain("Load error: syntax error in foo.lua");
|
|
241
|
+
});
|
|
242
|
+
it("formats testRunCancelled", () => {
|
|
243
|
+
const formatter = new OutputFormatter({});
|
|
244
|
+
const result = formatter.formatEvent({ type: "testRunCancelled" });
|
|
245
|
+
expect(result).toContain("Test run cancelled");
|
|
246
|
+
});
|
|
247
|
+
it("returns undefined for testPassed", () => {
|
|
248
|
+
const formatter = new OutputFormatter({});
|
|
249
|
+
const result = formatter.formatEvent({ type: "testPassed", test: { path: "test" } });
|
|
250
|
+
expect(result).toBeUndefined();
|
|
251
|
+
});
|
|
252
|
+
it("returns undefined for testFailed", () => {
|
|
253
|
+
const formatter = new OutputFormatter({});
|
|
254
|
+
const result = formatter.formatEvent({ type: "testFailed", test: { path: "test" }, errors: ["err"] });
|
|
255
|
+
expect(result).toBeUndefined();
|
|
256
|
+
});
|
|
257
|
+
it("returns undefined for testRunFinished", () => {
|
|
258
|
+
const formatter = new OutputFormatter({});
|
|
259
|
+
const result = formatter.formatEvent({
|
|
260
|
+
type: "testRunFinished",
|
|
261
|
+
results: {
|
|
262
|
+
ran: 1,
|
|
263
|
+
passed: 1,
|
|
264
|
+
failed: 0,
|
|
265
|
+
skipped: 0,
|
|
266
|
+
todo: 0,
|
|
267
|
+
cancelled: 0,
|
|
268
|
+
describeBlockErrors: 0,
|
|
269
|
+
status: "passed",
|
|
270
|
+
},
|
|
271
|
+
});
|
|
272
|
+
expect(result).toBeUndefined();
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
describe("OutputFormatter showLogs option", () => {
|
|
276
|
+
let consoleSpy;
|
|
277
|
+
let output;
|
|
278
|
+
beforeEach(() => {
|
|
279
|
+
output = [];
|
|
280
|
+
consoleSpy = vi.spyOn(console, "log").mockImplementation((...args) => {
|
|
281
|
+
output.push(args.join(" "));
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
afterEach(() => {
|
|
285
|
+
consoleSpy.mockRestore();
|
|
286
|
+
});
|
|
287
|
+
it("showLogs: false suppresses logs for failed tests", () => {
|
|
288
|
+
const formatter = new OutputFormatter({ showLogs: false });
|
|
289
|
+
const test = {
|
|
290
|
+
path: "test",
|
|
291
|
+
result: "failed",
|
|
292
|
+
errors: ["assertion failed"],
|
|
293
|
+
logs: ["debug output"],
|
|
294
|
+
};
|
|
295
|
+
formatter.formatTestResult(test);
|
|
296
|
+
expect(output.some((l) => l.includes("Log messages:"))).toBe(false);
|
|
297
|
+
expect(output.some((l) => l.includes("debug output"))).toBe(false);
|
|
298
|
+
});
|
|
299
|
+
it("showLogs: false still shows errors", () => {
|
|
300
|
+
const formatter = new OutputFormatter({ showLogs: false });
|
|
301
|
+
const test = {
|
|
302
|
+
path: "test",
|
|
303
|
+
result: "failed",
|
|
304
|
+
errors: ["assertion failed"],
|
|
305
|
+
logs: ["debug output"],
|
|
306
|
+
};
|
|
307
|
+
formatter.formatTestResult(test);
|
|
308
|
+
expect(output.some((l) => l.includes("Errors:"))).toBe(true);
|
|
309
|
+
expect(output.some((l) => l.includes("assertion failed"))).toBe(true);
|
|
310
|
+
});
|
|
311
|
+
it("showLogs: false suppresses logs for error results", () => {
|
|
312
|
+
const formatter = new OutputFormatter({ showLogs: false });
|
|
313
|
+
const test = {
|
|
314
|
+
path: "block",
|
|
315
|
+
result: "error",
|
|
316
|
+
errors: ["hook error"],
|
|
317
|
+
logs: ["hook log"],
|
|
318
|
+
};
|
|
319
|
+
formatter.formatTestResult(test);
|
|
320
|
+
expect(output.some((l) => l.includes("hook log"))).toBe(false);
|
|
321
|
+
expect(output.some((l) => l.includes("hook error"))).toBe(true);
|
|
322
|
+
});
|
|
202
323
|
});
|
|
203
324
|
describe("OutputFormatter.formatSummary", () => {
|
|
204
325
|
let consoleSpy;
|
|
@@ -298,6 +419,37 @@ describe("OutputFormatter.formatSummary", () => {
|
|
|
298
419
|
expect(countsLine).toContain("1 passed");
|
|
299
420
|
expect(countsLine).toContain("(4 total)");
|
|
300
421
|
});
|
|
422
|
+
it("shows describe block errors in separate section from failures", () => {
|
|
423
|
+
const formatter = new OutputFormatter({});
|
|
424
|
+
const data = {
|
|
425
|
+
tests: [
|
|
426
|
+
{ path: "test", result: "failed", errors: ["test err"], logs: [] },
|
|
427
|
+
{ path: "block", result: "error", errors: ["block err"], logs: [] },
|
|
428
|
+
],
|
|
429
|
+
summary: makeSummary({ ran: 1, failed: 1, describeBlockErrors: 1, status: "failed" }),
|
|
430
|
+
};
|
|
431
|
+
formatter.formatSummary(data);
|
|
432
|
+
expect(output.some((l) => l.includes("Failures:"))).toBe(true);
|
|
433
|
+
expect(output.some((l) => l.includes("Describe block errors:"))).toBe(true);
|
|
434
|
+
const failuresIdx = output.findIndex((l) => l.includes("Failures:"));
|
|
435
|
+
const errorsIdx = output.findIndex((l) => l.includes("Describe block errors:"));
|
|
436
|
+
const failLine = output.findIndex((l) => l.includes("FAIL"));
|
|
437
|
+
const errorLine = output.findIndex((l) => l.includes("ERROR"));
|
|
438
|
+
expect(failLine).toBeGreaterThan(failuresIdx);
|
|
439
|
+
expect(failLine).toBeLessThan(errorsIdx);
|
|
440
|
+
expect(errorLine).toBeGreaterThan(errorsIdx);
|
|
441
|
+
});
|
|
442
|
+
it("includes describe block errors count in summary line", () => {
|
|
443
|
+
const formatter = new OutputFormatter({});
|
|
444
|
+
const data = {
|
|
445
|
+
tests: [{ path: "block", result: "error", errors: ["err"], logs: [] }],
|
|
446
|
+
summary: makeSummary({ passed: 1, describeBlockErrors: 2, status: "failed" }),
|
|
447
|
+
};
|
|
448
|
+
formatter.formatSummary(data);
|
|
449
|
+
const countsLine = output.find((l) => l.includes("Tests:"));
|
|
450
|
+
expect(countsLine).toContain("2 errors");
|
|
451
|
+
expect(countsLine).toContain("1 passed");
|
|
452
|
+
});
|
|
301
453
|
it("does nothing when summary is undefined", () => {
|
|
302
454
|
const formatter = new OutputFormatter({});
|
|
303
455
|
formatter.formatSummary({ tests: [] });
|
|
@@ -349,6 +501,29 @@ describe("OutputPrinter", () => {
|
|
|
349
501
|
expect(output.some((line) => line.includes("FAIL"))).toBe(true);
|
|
350
502
|
expect(output.some((line) => line.includes("TODO"))).toBe(true);
|
|
351
503
|
});
|
|
504
|
+
it("verbose mode: printEvent prints formatted events", () => {
|
|
505
|
+
const printer = new OutputPrinter({ verbose: true });
|
|
506
|
+
printer.printEvent({ type: "testStarted", test: { path: "root > test" } });
|
|
507
|
+
expect(output.some((l) => l.includes("Starting: root > test"))).toBe(true);
|
|
508
|
+
});
|
|
509
|
+
it("verbose mode: printEvent skips events that return undefined", () => {
|
|
510
|
+
const printer = new OutputPrinter({ verbose: true });
|
|
511
|
+
printer.printEvent({ type: "testPassed", test: { path: "test" } });
|
|
512
|
+
expect(output).toHaveLength(0);
|
|
513
|
+
});
|
|
514
|
+
it("verbose mode: printTestResult does not include logs", () => {
|
|
515
|
+
const printer = new OutputPrinter({ verbose: true });
|
|
516
|
+
const test = {
|
|
517
|
+
path: "test",
|
|
518
|
+
result: "failed",
|
|
519
|
+
errors: ["err"],
|
|
520
|
+
logs: ["debug log"],
|
|
521
|
+
};
|
|
522
|
+
printer.printTestResult(test);
|
|
523
|
+
expect(output.some((l) => l.includes("FAIL"))).toBe(true);
|
|
524
|
+
expect(output.some((l) => l.includes("debug log"))).toBe(false);
|
|
525
|
+
expect(output.some((l) => l.includes("err"))).toBe(true);
|
|
526
|
+
});
|
|
352
527
|
it("hides all tests in quiet mode", () => {
|
|
353
528
|
const printer = new OutputPrinter({ quiet: true });
|
|
354
529
|
printer.printTestResult(passedTest);
|
package/test-results.js
CHANGED
|
@@ -5,11 +5,13 @@ export class TestRunCollector extends EventEmitter {
|
|
|
5
5
|
data = { tests: [] };
|
|
6
6
|
currentTest;
|
|
7
7
|
currentLogs = [];
|
|
8
|
+
pendingLogs = [];
|
|
8
9
|
testStartTime;
|
|
9
10
|
handleEvent(event) {
|
|
10
11
|
switch (event.type) {
|
|
11
12
|
case "testStarted":
|
|
12
13
|
this.flushCurrentTest();
|
|
14
|
+
this.pendingLogs = [];
|
|
13
15
|
this.testStartTime = performance.now();
|
|
14
16
|
this.currentTest = {
|
|
15
17
|
path: event.test.path,
|
|
@@ -61,6 +63,20 @@ export class TestRunCollector extends EventEmitter {
|
|
|
61
63
|
logs: [],
|
|
62
64
|
});
|
|
63
65
|
break;
|
|
66
|
+
case "describeBlockFailed": {
|
|
67
|
+
this.flushCurrentTest();
|
|
68
|
+
const captured = {
|
|
69
|
+
path: event.block.path,
|
|
70
|
+
source: event.block.source,
|
|
71
|
+
result: "error",
|
|
72
|
+
errors: event.errors,
|
|
73
|
+
logs: [...this.pendingLogs],
|
|
74
|
+
};
|
|
75
|
+
this.data.tests.push(captured);
|
|
76
|
+
this.emit("describeBlockFailed", captured);
|
|
77
|
+
this.pendingLogs = [];
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
64
80
|
case "testRunFinished":
|
|
65
81
|
this.flushCurrentTest();
|
|
66
82
|
this.data.summary = event.results;
|
|
@@ -75,6 +91,9 @@ export class TestRunCollector extends EventEmitter {
|
|
|
75
91
|
if (this.currentTest) {
|
|
76
92
|
this.currentLogs.push(line);
|
|
77
93
|
}
|
|
94
|
+
else {
|
|
95
|
+
this.pendingLogs.push(line);
|
|
96
|
+
}
|
|
78
97
|
}
|
|
79
98
|
getData() {
|
|
80
99
|
return this.data;
|
package/test-results.test.js
CHANGED
|
@@ -38,12 +38,69 @@ describe("TestRunCollector", () => {
|
|
|
38
38
|
const data = collector.getData();
|
|
39
39
|
expect(data.tests[0].logs).toEqual(["log line 1", "log line 2"]);
|
|
40
40
|
});
|
|
41
|
-
it("does not
|
|
41
|
+
it("does not attach pending logs to skipped tests", () => {
|
|
42
42
|
collector.captureLog("orphan log");
|
|
43
43
|
collector.handleEvent({ type: "testSkipped", test: { path: "test" } });
|
|
44
44
|
const data = collector.getData();
|
|
45
45
|
expect(data.tests[0].logs).toEqual([]);
|
|
46
46
|
});
|
|
47
|
+
it("handles describeBlockFailed with errors and pending logs", () => {
|
|
48
|
+
collector.captureLog("hook output");
|
|
49
|
+
collector.handleEvent({
|
|
50
|
+
type: "describeBlockFailed",
|
|
51
|
+
block: { path: "root > block", source: { file: "test.ts", line: 5 } },
|
|
52
|
+
errors: ["Error running afterAll: Oh no"],
|
|
53
|
+
});
|
|
54
|
+
const data = collector.getData();
|
|
55
|
+
expect(data.tests).toHaveLength(1);
|
|
56
|
+
expect(data.tests[0]).toMatchObject({
|
|
57
|
+
path: "root > block",
|
|
58
|
+
result: "error",
|
|
59
|
+
errors: ["Error running afterAll: Oh no"],
|
|
60
|
+
logs: ["hook output"],
|
|
61
|
+
source: { file: "test.ts", line: 5 },
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
it("emits describeBlockFailed event", () => {
|
|
65
|
+
const handler = vi.fn();
|
|
66
|
+
collector.on("describeBlockFailed", handler);
|
|
67
|
+
collector.handleEvent({
|
|
68
|
+
type: "describeBlockFailed",
|
|
69
|
+
block: { path: "block" },
|
|
70
|
+
errors: ["err"],
|
|
71
|
+
});
|
|
72
|
+
expect(handler).toHaveBeenCalledOnce();
|
|
73
|
+
expect(handler.mock.calls[0][0].path).toBe("block");
|
|
74
|
+
});
|
|
75
|
+
it("clears pending logs when a new test starts", () => {
|
|
76
|
+
collector.captureLog("before test");
|
|
77
|
+
collector.handleEvent({ type: "testStarted", test: { path: "test" } });
|
|
78
|
+
collector.handleEvent({ type: "testPassed", test: { path: "test" } });
|
|
79
|
+
collector.handleEvent({
|
|
80
|
+
type: "describeBlockFailed",
|
|
81
|
+
block: { path: "block" },
|
|
82
|
+
errors: ["err"],
|
|
83
|
+
});
|
|
84
|
+
const data = collector.getData();
|
|
85
|
+
const block = data.tests.find((t) => t.path === "block");
|
|
86
|
+
expect(block.logs).toEqual([]);
|
|
87
|
+
});
|
|
88
|
+
it("captures logs after test finishes for describe block failure", () => {
|
|
89
|
+
collector.handleEvent({ type: "testStarted", test: { path: "test" } });
|
|
90
|
+
collector.captureLog("test log");
|
|
91
|
+
collector.handleEvent({ type: "testPassed", test: { path: "test" } });
|
|
92
|
+
collector.captureLog("after_all log");
|
|
93
|
+
collector.handleEvent({
|
|
94
|
+
type: "describeBlockFailed",
|
|
95
|
+
block: { path: "block" },
|
|
96
|
+
errors: ["hook error"],
|
|
97
|
+
});
|
|
98
|
+
const data = collector.getData();
|
|
99
|
+
expect(data.tests[0].logs).toEqual(["test log"]);
|
|
100
|
+
const block = data.tests[1];
|
|
101
|
+
expect(block.logs).toEqual(["after_all log"]);
|
|
102
|
+
expect(block.errors).toEqual(["hook error"]);
|
|
103
|
+
});
|
|
47
104
|
it("handles testSkipped without prior testStarted", () => {
|
|
48
105
|
collector.handleEvent({ type: "testSkipped", test: { path: "skipped test" } });
|
|
49
106
|
const data = collector.getData();
|