From 97ac04b96896e362f98bfb8bc836e5aa785be972 Mon Sep 17 00:00:00 2001 From: Brad Groux <3053586+BradGroux@users.noreply.github.com> Date: Sun, 23 Aug 2026 20:29:14 -0500 Subject: [PATCH] test: isolate tracked ignore guard (#1212) --- scripts/check-tracked-ignore.mjs | 7 +- scripts/check-tracked-ignore.test.mjs | 118 ++++++++++++-------------- 2 files changed, 59 insertions(+), 66 deletions(-) diff --git a/scripts/check-tracked-ignore.mjs b/scripts/check-tracked-ignore.mjs index 34dc1106..d9b19e26 100644 --- a/scripts/check-tracked-ignore.mjs +++ b/scripts/check-tracked-ignore.mjs @@ -14,15 +14,14 @@ function runGit(args, options = {}) { return result; } -export function findIgnoredTrackedFiles(cwd = process.cwd(), env = process.env) { - const tracked = runGit(['ls-files', '-z'], { cwd, env }); +export function findIgnoredTrackedFiles(cwd = process.cwd(), gitRunner = runGit) { + const tracked = gitRunner(['ls-files', '-z'], { cwd }); if (tracked.status !== 0) { throw new Error(`git ls-files failed: ${tracked.stderr.toString('utf8').trim()}`); } - const ignored = runGit(['check-ignore', '--no-index', '-z', '--stdin'], { + const ignored = gitRunner(['check-ignore', '--no-index', '-z', '--stdin'], { cwd, - env, input: tracked.stdout, }); if (ignored.status === 1) return []; diff --git a/scripts/check-tracked-ignore.test.mjs b/scripts/check-tracked-ignore.test.mjs index 53de9124..3a27299c 100644 --- a/scripts/check-tracked-ignore.test.mjs +++ b/scripts/check-tracked-ignore.test.mjs @@ -1,77 +1,71 @@ import assert from 'node:assert/strict'; -import { execFileSync } from 'node:child_process'; -import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises'; -import os from 'node:os'; -import path from 'node:path'; import test from 'node:test'; import { findIgnoredTrackedFiles } from './check-tracked-ignore.mjs'; -const isolatedGitEnvironment = Object.fromEntries( - Object.entries(process.env).filter(([key]) => !key.startsWith('GIT_')) -); - -async function createRepository() { - const root = await mkdtemp(path.join(os.tmpdir(), 'veritas-tracked-ignore-')); - execFileSync('git', ['init', '--quiet'], { cwd: root, env: isolatedGitEnvironment }); - return root; +function result(status, stdout = '', stderr = '') { + return { + status, + stdout: Buffer.from(stdout), + stderr: Buffer.from(stderr), + error: undefined, + }; } -async function write(root, relativePath, content = '') { - const destination = path.join(root, relativePath); - await mkdir(path.dirname(destination), { recursive: true }); - await writeFile(destination, content, 'utf8'); +function gitRunner(responses, calls) { + return (args, options) => { + calls.push({ args, options }); + const response = responses.shift(); + assert.ok(response, 'unexpected Git invocation'); + return response; + }; } -test('reports a tracked file covered by a later ignore rule', async (t) => { - const root = await createRepository(); - t.after(() => rm(root, { recursive: true, force: true })); +test('reports sorted tracked paths returned by check-ignore', () => { + const calls = []; + const tracked = 'server/src/storage/repository.ts\0server/src/__tests__/storage/example.test.ts\0'; + const ignored = + 'server/src/storage/repository.ts\0server/src/__tests__/storage/example.test.ts\0'; - await write(root, 'server/src/__tests__/storage/example.test.ts', 'export {};\n'); - execFileSync('git', ['add', 'server/src/__tests__/storage/example.test.ts'], { - cwd: root, - env: isolatedGitEnvironment, + assert.deepEqual( + findIgnoredTrackedFiles( + '/repo', + gitRunner([result(0, tracked), result(0, ignored)], calls) + ), + ['server/src/__tests__/storage/example.test.ts', 'server/src/storage/repository.ts'] + ); + assert.deepEqual(calls[0], { + args: ['ls-files', '-z'], + options: { cwd: '/repo' }, + }); + assert.deepEqual(calls[1], { + args: ['check-ignore', '--no-index', '-z', '--stdin'], + options: { cwd: '/repo', input: Buffer.from(tracked) }, }); - await write(root, '.gitignore', 'storage/\n'); - - assert.deepEqual(findIgnoredTrackedFiles(root, isolatedGitEnvironment), [ - 'server/src/__tests__/storage/example.test.ts', - ]); }); -test('allows tracked storage source while anchored runtime roots stay ignored', async (t) => { - const root = await createRepository(); - t.after(() => rm(root, { recursive: true, force: true })); - - await write(root, '.gitignore', '/storage/\n/server/storage/\n'); - await write(root, 'server/src/storage/repository.ts', 'export {};\n'); - await write(root, 'server/src/__tests__/storage/repository.test.ts', 'export {};\n'); - execFileSync( - 'git', - [ - 'add', - '.gitignore', - 'server/src/storage/repository.ts', - 'server/src/__tests__/storage/repository.test.ts', - ], - { cwd: root, env: isolatedGitEnvironment } - ); - - assert.deepEqual(findIgnoredTrackedFiles(root, isolatedGitEnvironment), []); - assert.equal( - execFileSync('git', ['check-ignore', 'storage/runtime.json'], { - cwd: root, - env: isolatedGitEnvironment, - encoding: 'utf8', - }), - 'storage/runtime.json\n' - ); - assert.equal( - execFileSync('git', ['check-ignore', 'server/storage/runtime.json'], { - cwd: root, - env: isolatedGitEnvironment, - encoding: 'utf8', - }), - 'server/storage/runtime.json\n' +test('accepts the normal check-ignore no-match exit status', () => { + const calls = []; + assert.deepEqual( + findIgnoredTrackedFiles( + '/repo', + gitRunner([result(0, 'server/src/storage/repository.ts\0'), result(1)], calls) + ), + [] + ); +}); + +test('surfaces Git command failures', () => { + assert.throws( + () => findIgnoredTrackedFiles('/repo', gitRunner([result(2, '', 'bad index')], [])), + /git ls-files failed: bad index/ + ); + assert.throws( + () => + findIgnoredTrackedFiles( + '/repo', + gitRunner([result(0, 'tracked\0'), result(128, '', 'bad ignore rules')], []) + ), + /git check-ignore failed: bad ignore rules/ ); });