fix(#224): return byte counts for --pick stdout capture (#226)

This commit is contained in:
Tom Boucher
2026-05-24 16:34:02 -04:00
committed by GitHub
parent 5f3eb42864
commit cf7e65e18c
3 changed files with 101 additions and 58 deletions

View File

@@ -48,17 +48,14 @@ describe('bug #1891: @file: resolution in gsd-tools.cjs', () => {
});
test('stdout interception wraps runCommand in the non-pick path', () => {
// The main function should intercept fs.writeSync for fd=1
// in BOTH the pick path AND the normal path
// The main function should resolve @file: output in BOTH --pick and
// non-pick paths. This can be either two inline checks or a shared helper.
const mainFunc = src.slice(src.indexOf('async function main()'));
const pickInterception = mainFunc.indexOf('// When --pick is active');
const fileResolution = mainFunc.indexOf('@file:');
// There should be at least two @file: resolution points:
// one in the --pick path and one in the normal path
const firstAt = mainFunc.indexOf("'@file:'");
const secondAt = mainFunc.indexOf("'@file:'", firstAt + 1);
assert.ok(secondAt > firstAt,
'Both --pick and normal paths should resolve @file: references');
const resolveCalls = (mainFunc.match(/resolveAtFileOutput\(/g) || []).length;
const inlineAtFileChecks = (mainFunc.match(/@file:/g) || []).length;
assert.ok(
resolveCalls >= 2 || inlineAtFileChecks >= 2,
'Both --pick and normal paths should resolve @file: references'
);
});
});

View File

@@ -0,0 +1,40 @@
// allow-test-rule: structural-implementation-guard
// Bug #224 is a platform-specific (Node 24 + Windows) flake in `--pick` where
// stdout interception can produce non-deterministic failures. We lock the seam
// contract structurally until we have a deterministic Windows reproduction
// harness in CI.
'use strict';
const { describe, test, before } = require('node:test');
const assert = require('node:assert/strict');
const fs = require('fs');
const path = require('path');
const { runGsdTools } = require('./helpers.cjs');
const GSD_TOOLS_SRC = path.join(__dirname, '..', 'get-shit-done', 'bin', 'gsd-tools.cjs');
describe('bug #224: --pick stdout capture contract', () => {
let src;
before(() => {
src = fs.readFileSync(GSD_TOOLS_SRC, 'utf-8');
});
test('--pick output still succeeds for current-timestamp command', () => {
const result = runGsdTools(['current-timestamp', '--pick', 'timestamp']);
assert.strictEqual(result.success, true, result.error || 'expected command to succeed');
assert.match(result.output, /^\d{4}-\d{2}-\d{2}T/, 'expected ISO timestamp output');
});
test('stdout interception for fd=1 returns a byte count (never undefined)', () => {
const mainStart = src.indexOf('async function main()');
assert.ok(mainStart !== -1, 'main() must exist');
const mainSrc = src.slice(mainStart);
assert.ok(
mainSrc.includes('Buffer.byteLength(') || mainSrc.includes('return data.length'),
'stdout interception must return written-byte counts for fd=1 captures'
);
});
});