From e716f7ea657e9a6aa3ead7dca3ef702fcf3a61cf Mon Sep 17 00:00:00 2001 From: montjeffrey Date: Fri, 2 Oct 2026 10:39:44 -0400 Subject: [PATCH] test(gateguard): use the repository's own test helper The suite was the only file in tests/docker using node:test. The repository's dominant convention, in 229 of 327 test files including the sibling gateguard-effectiveness suite, is a local test() helper that counts passes and sets process.exitCode, which is what tests/run-all.js reads. Adopt that helper verbatim, along with the sibling's tempDir wrapper so the scenario fixtures resolve symlinked temp paths. Assertions are unchanged. --- tests/docker/gateguard-intent.test.js | 30 +++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/tests/docker/gateguard-intent.test.js b/tests/docker/gateguard-intent.test.js index 69cb49d52..5c4325c59 100644 --- a/tests/docker/gateguard-intent.test.js +++ b/tests/docker/gateguard-intent.test.js @@ -17,7 +17,6 @@ const assert = require('assert'); const fs = require('fs'); const os = require('os'); const path = require('path'); -const { test } = require('node:test'); const ROOT = path.join(__dirname, '..', '..'); const DIR = path.join(ROOT, 'docker', 'gateguard-effectiveness'); @@ -27,6 +26,25 @@ const coverage = require(path.join(DIR, 'coverage')); const intentEval = require(path.join(DIR, 'intent-eval')); const { parseArgs } = require(path.join(DIR, 'run-intent')); +let passed = 0; +let failed = 0; + +function test(name, fn) { + try { + fn(); + console.log(` ✓ ${name}`); + passed++; + } catch (error) { + console.log(` ✗ ${name}`); + console.log(` Error: ${error.message}`); + failed++; + } +} + +function tempDir(prefix) { + return fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), prefix))); +} + const INTENT = Object.freeze({ id: 'probe', ambiguity: 'the window and the delete mode were never stated', @@ -58,7 +76,7 @@ test('every shipped hidden-intent scenario loads and declares a decisive fact', }); test('a scenario that declares targetQuestions is rejected', () => { - const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'gg-blind-')); + const dir = tempDir('gg-blind-'); const scenario = path.join(dir, 'leaky'); fs.mkdirSync(path.join(scenario, 'workspace'), { recursive: true }); fs.writeFileSync( @@ -71,7 +89,7 @@ test('a scenario that declares targetQuestions is rejected', () => { }); test('an intent with no decisive fact is rejected', () => { - const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'gg-nodecisive-')); + const dir = tempDir('gg-nodecisive-'); const scenario = path.join(dir, 'soft'); fs.mkdirSync(path.join(scenario, 'workspace'), { recursive: true }); fs.writeFileSync(path.join(scenario, 'task.json'), JSON.stringify({ id: 'soft', trap: 't', prompt: 'p', evidence: ['e'] })); @@ -86,7 +104,7 @@ test('an intent with no decisive fact is rejected', () => { // --- graders must discriminate, or the trial is worthless --- test('every grader separates the start, the trap and a correct solution', () => { - const workRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'gg-sound-')); + const workRoot = tempDir('gg-sound-'); for (const scenario of intentEval.loadIntentScenarios()) { const { scores, sound } = intentEval.graderIsSound(scenario, workRoot); assert.ok( @@ -369,3 +387,7 @@ test('real sessions require the explicit flag', () => { assert.throws(() => parseArgs(['--out', 'o', '--model', 'm']), /--allow-real-provider/); assert.doesNotThrow(() => parseArgs(['--out', 'o', '--dry-run'])); }); + +console.log(`\nPassed: ${passed}`); +console.log(`Failed: ${failed}`); +process.exitCode = failed > 0 ? 1 : 0;