From 34b39f0a37aa71ac09934c6f6c5ea5e6ba756bb0 Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Fri, 24 Apr 2026 20:22:17 -0400 Subject: [PATCH] test(#2659): regression guard against bare output() in audit-open handler (#2680) * fix(#2659): qualify bare output() calls in audit-open handler The audit-open dispatch case in bin/gsd-tools.cjs previously called bare output() on both --json and text branches, which crashed with ReferenceError: output is not defined. The core module is imported as `const core`, so every other case uses core.output(). HEAD already qualifies the calls correctly; this commit adds a regression test that invokes `audit-open` and `audit-open --json` through runGsdTools and asserts a clean exit plus non-empty stdout (and an explicit check that the failure mode is not ReferenceError). The test fails on any revision where either call reverts to bare output(). Closes #2659 * test(#2659): assert valid JSON output in --json mode CodeRabbit nit: tighten --json regression coverage by parsing stdout and asserting the result is a JSON object/array, not just non-empty. --- tests/bug-2659-audit-open-crash.test.cjs | 73 ++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 tests/bug-2659-audit-open-crash.test.cjs diff --git a/tests/bug-2659-audit-open-crash.test.cjs b/tests/bug-2659-audit-open-crash.test.cjs new file mode 100644 index 000000000..9f90ebda8 --- /dev/null +++ b/tests/bug-2659-audit-open-crash.test.cjs @@ -0,0 +1,73 @@ +'use strict'; + +/** + * Regression test for #2659. + * + * The `audit-open` dispatch case in bin/gsd-tools.cjs previously called bare + * `output(...)` on both the --json and text branches. `output` is never in + * local scope — the entire core module is imported as `const core`, so every + * other case uses `core.output(...)`. The bare calls therefore crashed with + * `ReferenceError: output is not defined` the moment `audit-open` ran. + * + * This test runs both invocations against a minimal temp project and asserts + * they exit successfully with non-empty stdout. It fails with the + * ReferenceError on any revision that still has the bare `output(...)` calls. + */ + +const { test, describe, beforeEach, afterEach } = require('node:test'); +const assert = require('node:assert/strict'); + +const { runGsdTools, createTempProject, cleanup } = require('./helpers.cjs'); + +describe('audit-open — does not crash with ReferenceError (#2659)', () => { + let tmpDir; + + beforeEach(() => { + tmpDir = createTempProject('gsd-bug-2659-'); + }); + + afterEach(() => { + cleanup(tmpDir); + }); + + test('audit-open (text output) succeeds and produces stdout', () => { + const result = runGsdTools('audit-open', tmpDir); + assert.ok( + result.success, + `audit-open must not crash. stderr: ${result.error}` + ); + assert.ok( + !/ReferenceError.*output is not defined/.test(result.error || ''), + `audit-open must not throw ReferenceError. stderr: ${result.error}` + ); + assert.ok( + result.output && result.output.length > 0, + 'audit-open must write a non-empty report to stdout' + ); + }); + + test('audit-open --json succeeds and produces stdout', () => { + const result = runGsdTools(['audit-open', '--json'], tmpDir); + assert.ok( + result.success, + `audit-open --json must not crash. stderr: ${result.error}` + ); + assert.ok( + !/ReferenceError.*output is not defined/.test(result.error || ''), + `audit-open --json must not throw ReferenceError. stderr: ${result.error}` + ); + assert.ok( + result.output && result.output.length > 0, + 'audit-open --json must write output to stdout' + ); + let parsed; + assert.doesNotThrow( + () => { parsed = JSON.parse(result.output); }, + 'audit-open --json must emit valid JSON' + ); + assert.ok( + parsed !== null && typeof parsed === 'object', + 'audit-open --json must emit a JSON object or array' + ); + }); +});