From 44df54774845458019a23f45e1acfc6c90c8292d Mon Sep 17 00:00:00 2001 From: ozymandiashh <234437643+ozymandiashh@users.noreply.github.com> Date: Mon, 20 Jul 2026 15:23:28 +0300 Subject: [PATCH] test(electron): make dev-resolution tests self-sufficient on fresh clones (#689) * test(electron): isolate dev-resolution fixtures via CODEBURN_DEV_REPO_ROOT Rework of the #681 fix per review: instead of stubbing the real repo dist/cli.js with snapshot-restore, the Vite-dev resolution branch gains a CODEBURN_DEV_REPO_ROOT override (matching the CODEBURN_PATH_DIRS precedent) so the whole fixture lives in a per-test tmpdir. With the env unset the resolution order is byte-identical to before. - covers all three fresh-clone failures on current main, including the resolveTarget dev-repo-beats-bundled case - deletes the snapshot-restore machinery, the parent-path precondition and the beforeAll repo-scanning guard - tests assert both override-set (tmpdir wins) and override-unset behavior Closes #681 * test(electron): drop environment-coupled null assertion for unset dev-root override The override-unset case resolved /dist/cli.js whenever a build had run, so the toBeNull() assertion depended on the absence of a gitignored artifact. The override-set tests already prove the new branch and the non-Vite test covers the null path. --- app/electron/cli.test.ts | 24 ++++++++++++++++++++---- app/electron/cli.ts | 19 +++++++++++++------ 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/app/electron/cli.test.ts b/app/electron/cli.test.ts index 72fe234..e95bc93 100644 --- a/app/electron/cli.test.ts +++ b/app/electron/cli.test.ts @@ -12,6 +12,7 @@ const originalPathDirs = process.env.CODEBURN_PATH_DIRS const originalPathFile = process.env.CODEBURN_CLI_PATH_FILE const originalViteUrl = process.env.VITE_DEV_SERVER_URL const originalBundled = process.env.CODEBURN_BUNDLED_CLI +const originalDevRepoRoot = process.env.CODEBURN_DEV_REPO_ROOT /** Writes an executable node script and points CODEBURN_BIN at it. */ function fakeBin(name: string, body: string): string { @@ -22,6 +23,17 @@ function fakeBin(name: string, body: string): string { return p } +/** Writes the repo CLI under this test's isolated dev-root override. */ +function fakeDevRepoCli(): string { + const repoRoot = join(dir, 'dev-repo') + const p = join(repoRoot, 'dist', 'cli.js') + mkdirSync(dirname(p), { recursive: true }) + writeFileSync(p, '#!/usr/bin/env node\n', { mode: 0o755 }) + chmodSync(p, 0o755) + process.env.CODEBURN_DEV_REPO_ROOT = repoRoot + return p +} + beforeEach(() => { dir = mkdtempSync(join(tmpdir(), 'codeburn-cli-')) }) @@ -37,6 +49,8 @@ afterEach(() => { else process.env.VITE_DEV_SERVER_URL = originalViteUrl if (originalBundled === undefined) delete process.env.CODEBURN_BUNDLED_CLI else process.env.CODEBURN_BUNDLED_CLI = originalBundled + if (originalDevRepoRoot === undefined) delete process.env.CODEBURN_DEV_REPO_ROOT + else process.env.CODEBURN_DEV_REPO_ROOT = originalDevRepoRoot rmSync(dir, { recursive: true, force: true }) }) @@ -46,8 +60,9 @@ describe('resolveCodeburnPath (Vite development)', () => { process.env.CODEBURN_PATH_DIRS = '' process.env.CODEBURN_CLI_PATH_FILE = join(dir, 'no-persisted-path') process.env.VITE_DEV_SERVER_URL = 'http://localhost:5173' + const devBin = fakeDevRepoCli() - expect(resolveCodeburnPath()).toMatch(/dist\/cli\.js$/) + expect(resolveCodeburnPath()).toBe(devBin) }) it('prefers the repo dev CLI over a persisted-path file (stale global) in dev', () => { @@ -63,9 +78,10 @@ describe('resolveCodeburnPath (Vite development)', () => { writeFileSync(persistedFile, persistedTarget) process.env.CODEBURN_CLI_PATH_FILE = persistedFile process.env.VITE_DEV_SERVER_URL = 'http://localhost:5173' + const devBin = fakeDevRepoCli() const resolved = resolveCodeburnPath() - expect(resolved).toMatch(/dist\/cli\.js$/) + expect(resolved).toBe(devBin) expect(resolved).not.toBe(persistedTarget) }) @@ -120,10 +136,10 @@ describe('resolveTarget (bundled CLI in the packaged app)', () => { process.env.CODEBURN_CLI_PATH_FILE = join(dir, 'no-persisted-path') process.env.CODEBURN_BUNDLED_CLI = bundledEntry('bundled.js') process.env.VITE_DEV_SERVER_URL = 'http://localhost:5173' + const devBin = fakeDevRepoCli() const target = resolveTarget() - expect(target?.kind).toBe('external') - expect(target && target.kind === 'external' ? target.bin : '').toMatch(/dist\/cli\.js$/) + expect(target).toEqual({ kind: 'external', bin: devBin }) }) it('falls through when CODEBURN_BUNDLED_CLI points at a missing file', () => { diff --git a/app/electron/cli.ts b/app/electron/cli.ts index e7e1cac..30efddc 100644 --- a/app/electron/cli.ts +++ b/app/electron/cli.ts @@ -255,12 +255,19 @@ export function resolveTarget(): CliTarget | null { // freshly-built CLI over a stale globally-installed/persisted one, so // newly-added commands (sessions/compare/act JSON) work without CODEBURN_BIN. if (process.env.VITE_DEV_SERVER_URL) { - const devBin = join(__dirname, '..', '..', '..', 'dist', 'cli.js') - if (isExecutableFile(devBin)) return { kind: 'external', bin: devBin } - // Vitest loads this source module from app/electron rather than the emitted - // app/dist/electron directory; keep the same repo CLI discoverable there. - const sourceDevBin = join(__dirname, '..', '..', 'dist', 'cli.js') - if (isExecutableFile(sourceDevBin)) return { kind: 'external', bin: sourceDevBin } + const devRepoRoot = process.env.CODEBURN_DEV_REPO_ROOT + if (devRepoRoot) { + // Test/advanced override, matching CODEBURN_PATH_DIRS: keep dev lookup in an isolated repo root. + const devBin = join(devRepoRoot, 'dist', 'cli.js') + if (isExecutableFile(devBin)) return { kind: 'external', bin: devBin } + } else { + const devBin = join(__dirname, '..', '..', '..', 'dist', 'cli.js') + if (isExecutableFile(devBin)) return { kind: 'external', bin: devBin } + // Vitest loads this source module from app/electron rather than the emitted + // app/dist/electron directory; keep the same repo CLI discoverable there. + const sourceDevBin = join(__dirname, '..', '..', 'dist', 'cli.js') + if (isExecutableFile(sourceDevBin)) return { kind: 'external', bin: sourceDevBin } + } } // Packaged app: main.ts sets CODEBURN_BUNDLED_CLI to resources/cli/dist/cli.js.