test(FN-2122): isolate HOME for core and CLI vitest runs

- Add test setup files in core and CLI that override HOME to a per-worker temp directory
- Wire the new isolation setup into core and CLI vitest setupFiles before existing test bootstrap
- Add a core canary test to verify HOME, homedir(), and defaultGlobalDir() resolve under isolated temp paths
- Document how global HOME isolation complements per-fixture isolation in test-project utilities
This commit is contained in:
Fusion
2026-04-19 03:43:48 -07:00
committed by gsxdsm
parent 8e00867012
commit 9a532316cf
6 changed files with 67 additions and 2 deletions

View File

@@ -0,0 +1,10 @@
/**
* Global test isolation for CLI package.
* @see packages/core/src/__tests__/setup-test-isolation.ts
*/
import { mkdtempSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
const tempHome = mkdtempSync(join(tmpdir(), "fn-test-home-"));
process.env.HOME = tempHome;

View File

@@ -14,7 +14,10 @@ export default defineConfig({
},
test: {
include: ["src/**/*.test.ts"],
setupFiles: [resolve(__dirname, "../core/src/__test-utils__/vitest-setup.ts")],
setupFiles: [
"./src/__tests__/setup-test-isolation.ts",
resolve(__dirname, "../core/src/__test-utils__/vitest-setup.ts"),
],
globalSetup: [resolve(__dirname, "../core/src/__test-utils__/vitest-teardown.ts")],
maxWorkers,
poolOptions: { threads: { minThreads: 1, maxThreads: maxWorkers }, forks: { minForks: 1, maxForks: maxWorkers } },

View File

@@ -0,0 +1,29 @@
import { describe, expect, it } from "vitest";
import { homedir, tmpdir } from "node:os";
const TEMP_HOME_PREFIX = "fn-test-home-";
describe("test isolation setup", () => {
it("process.env.HOME is overridden to a temp directory", () => {
const home = process.env.HOME;
expect(home).toBeDefined();
expect(home).toContain(tmpdir());
expect(home).toContain(TEMP_HOME_PREFIX);
});
it("homedir() resolves to the temp HOME", () => {
const home = homedir();
expect(home).toContain(tmpdir());
expect(home).toContain(TEMP_HOME_PREFIX);
});
it("defaultGlobalDir() resolves under the temp HOME", async () => {
const { defaultGlobalDir } = await import("../global-settings.js");
const dir = defaultGlobalDir();
expect(dir).toContain(tmpdir());
expect(dir).toMatch(/fn-test-home-.*[\\/]\.fusion$/);
});
});

View File

@@ -0,0 +1,16 @@
/**
* Global test isolation: prevents tests from writing to the real ~/.fusion/ directory.
*
* Vitest runs setupFiles in each worker thread. By overriding process.env.HOME
* to a temp directory, all calls to homedir() (and derived paths like ~/.fusion)
* resolve to isolated temp locations instead of the user's real home directory.
*
* This protects against tests accidentally creating projects, databases, or
* settings files in the production ~/.fusion/ directory.
*/
import { mkdtempSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
const tempHome = mkdtempSync(join(tmpdir(), "fn-test-home-"));
process.env.HOME = tempHome;

View File

@@ -55,6 +55,10 @@ function splitSettings(settings?: Partial<Settings>): {
}
/**
* NOTE: Global test isolation overrides HOME in vitest setupFiles,
* so homedir()/resolveGlobalDir() always resolve to temp directories.
* This file provides per-fixture isolation on top of that safety net.
*
* Create an isolated temporary test project with a real TaskStore + SQLite DB.
*/
export async function createTestProject(

View File

@@ -14,7 +14,10 @@ export default defineConfig({
},
test: {
include: ["src/**/*.test.ts"],
setupFiles: ["./src/__test-utils__/vitest-setup.ts"],
setupFiles: [
"./src/__tests__/setup-test-isolation.ts",
"./src/__test-utils__/vitest-setup.ts",
],
globalSetup: ["./src/__test-utils__/vitest-teardown.ts"],
maxWorkers,
poolOptions: { threads: { minThreads: 1, maxThreads: maxWorkers }, forks: { minForks: 1, maxForks: maxWorkers } },