factorio-test-cli 3.3.1 → 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.
@@ -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(() => console.log(JSON.stringify(event)));
121
+ progress.withPermanentOutput(() => printer.printEvent(event));
122
122
  }
123
123
  });
124
124
  handler.on("log", (line) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "factorio-test-cli",
3
- "version": "3.3.1",
3
+ "version": "3.4.0",
4
4
  "description": "A CLI to run FactorioTest.",
5
5
  "license": "MIT",
6
6
  "repository": {
package/test-output.js CHANGED
@@ -90,7 +90,8 @@ export class OutputFormatter {
90
90
  const prefix = this.getPrefix(test.result);
91
91
  const duration = test.durationMs !== undefined ? ` (${formatDuration(test.durationMs)})` : "";
92
92
  console.log(`${prefix} ${test.path}${duration}`);
93
- const showLogs = test.result === "failed" || test.result === "error" || this.options.showPassedLogs;
93
+ const showLogs = this.options.showLogs !== false &&
94
+ (test.result === "failed" || test.result === "error" || this.options.showPassedLogs);
94
95
  if (showLogs && test.logs.length > 0) {
95
96
  console.log("Log messages:");
96
97
  for (const log of test.logs) {
@@ -139,6 +140,20 @@ export class OutputFormatter {
139
140
  const total = summary.passed + summary.failed + summary.skipped + summary.todo;
140
141
  console.log(`Tests: ${segments.join(", ")} (${total} total)`);
141
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
+ }
142
157
  getPrefix(result) {
143
158
  switch (result) {
144
159
  case "passed":
@@ -164,6 +179,7 @@ export class OutputPrinter {
164
179
  verbose: options.verbose,
165
180
  quiet: options.quiet,
166
181
  showPassedLogs: options.verbose,
182
+ showLogs: !options.verbose,
167
183
  });
168
184
  }
169
185
  printTestResult(test) {
@@ -187,6 +203,12 @@ export class OutputPrinter {
187
203
  resetMessage() {
188
204
  this.isMessageFirstLine = true;
189
205
  }
206
+ printEvent(event) {
207
+ const formatted = this.formatter.formatEvent(event);
208
+ if (formatted !== undefined) {
209
+ console.log(formatted);
210
+ }
211
+ }
190
212
  printVerbose(line) {
191
213
  if (this.options.verbose) {
192
214
  console.log(line);
@@ -223,6 +223,104 @@ describe("OutputFormatter", () => {
223
223
  expect(output.some((line) => line.includes("Oh no"))).toBe(true);
224
224
  });
225
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
+ });
323
+ });
226
324
  describe("OutputFormatter.formatSummary", () => {
227
325
  let consoleSpy;
228
326
  let output;
@@ -403,6 +501,29 @@ describe("OutputPrinter", () => {
403
501
  expect(output.some((line) => line.includes("FAIL"))).toBe(true);
404
502
  expect(output.some((line) => line.includes("TODO"))).toBe(true);
405
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
+ });
406
527
  it("hides all tests in quiet mode", () => {
407
528
  const printer = new OutputPrinter({ quiet: true });
408
529
  printer.printTestResult(passedTest);