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 <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-09-06 14:37:38 +00:00
co-authored by Claude Fable 5.1
parent 2649a3b6de
commit 287b976d9f
2 changed files with 14 additions and 5 deletions
+8 -3
View File
@@ -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<Record<SuccessKey, Done>> {
// 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 }); });
+6 -2
View File
@@ -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);
});