From 287b976d9f04c777b11475d0bbb3b3fddbd3e7e1 Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Sun, 6 Sep 2026 14:37:38 +0000 Subject: [PATCH] fix(test): gate POSIX-only fixtures off Windows windows-free-tests: the gstack-render CLI tests drive a shebang fake browse that CreateProcess cannot exec, and two NEEDS_BUILD cases assert an execute bit and a bare-name miss that MSYS bash does not have (test -x ignores mode bits and resolves design -> design.exe). Those describes and cases now self-skip on win32; argument guards, --help, the no-browser case, and every other rebuild-check case still run there. Co-Authored-By: Claude Fable 5.1 --- test/gstack-render-cli.test.ts | 11 ++++++++--- test/setup-needs-build.test.ts | 8 ++++++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/test/gstack-render-cli.test.ts b/test/gstack-render-cli.test.ts index 8f518b574..739d4f1ad 100644 --- a/test/gstack-render-cli.test.ts +++ b/test/gstack-render-cli.test.ts @@ -38,6 +38,11 @@ import * as path from 'node:path'; import { resolveBrowseBin } from '../lib/aside-render'; const ROOT = path.resolve(import.meta.dir, '..'); +// The fake `browse` is a shebang shell script: Windows' CreateProcess cannot +// exec it (spawn reports "Executable not found"), so every describe that drives +// the CLI through the fake self-skips on win32. The argument guards, --help, +// and the no-browser case need no fake and run everywhere. +const isWin = process.platform === 'win32'; const CLI = path.join(ROOT, 'bin/gstack-render.ts'); // The same bun that runs this test file, by absolute path: a scrubbed PATH in a // child env must never decide whether the CLI itself can start. @@ -334,7 +339,7 @@ function successRuns(): Promise> { // File-level: the batch is shared by two describes (--serve-root reads its fixture too). afterAll(() => { for (const f of successFixtures) fs.rmSync(f.dir, { recursive: true, force: true }); }); -describe('gstack-render CLI: output contract through the browse fallback', () => { +describe.skipIf(isWin)('gstack-render CLI: output contract through the browse fallback', () => { test('pdf + screenshot + eval --out: ENGINE=browse first, one OK per artifact, files exist, no fence without inline evals', async () => { const { f, r } = (await successRuns()).artifacts; const pdf = path.join(f.dir, 'out', 'doc.pdf'); @@ -430,7 +435,7 @@ describe('gstack-render CLI: output contract through the browse fallback', () => // ─── Failure path ──────────────────────────────────────────────────────────── -describe('gstack-render CLI: failure path', () => { +describe.skipIf(isWin)('gstack-render CLI: failure path', () => { let f: Fixture; beforeAll(() => { f = makeFixture(); }); afterAll(() => { fs.rmSync(f.dir, { recursive: true, force: true }); }); @@ -469,7 +474,7 @@ describe('gstack-render CLI: failure path', () => { // ─── --serve-root ──────────────────────────────────────────────────────────── -describe('gstack-render CLI: --serve-root', () => { +describe.skipIf(isWin)('gstack-render CLI: --serve-root', () => { let f: Fixture; beforeAll(() => { f = makeFixture(); }); afterAll(() => { fs.rmSync(f.dir, { recursive: true, force: true }); }); diff --git a/test/setup-needs-build.test.ts b/test/setup-needs-build.test.ts index 86957348c..f24bd122d 100644 --- a/test/setup-needs-build.test.ts +++ b/test/setup-needs-build.test.ts @@ -155,7 +155,9 @@ describe('setup: NEEDS_BUILD decision executes', () => { expect(decide(dir)).toBe(1); }); - test('a binary that exists but is not executable counts as missing → 1', () => { + // MSYS bash has no execute bit: `[ -x file ]` is true for any regular file, so + // this case is POSIX-only. + test.skipIf(process.platform === 'win32')('a binary that exists but is not executable counts as missing → 1', () => { const dir = makeTree(); fs.chmodSync(path.join(dir, 'design/dist/design'), 0o644); expect(decide(dir)).toBe(1); @@ -221,7 +223,9 @@ describe('setup: NEEDS_BUILD decision executes', () => { expect(decide(dir, { isWindows: '1' })).toBe(1); }); - test('IS_WINDOWS=0: only the .exe names present → 1 (no suffix on Unix)', () => { + // MSYS bash resolves `[ -x design ]` to design.exe on its own, so the "no + // suffix on Unix" contrast can only be asserted on a POSIX host. + test.skipIf(process.platform === 'win32')('IS_WINDOWS=0: only the .exe names present → 1 (no suffix on Unix)', () => { const dir = makeTree({ exe: '.exe' }); expect(decide(dir, { isWindows: '0' })).toBe(1); });