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:
10
packages/cli/src/__tests__/setup-test-isolation.ts
Normal file
10
packages/cli/src/__tests__/setup-test-isolation.ts
Normal 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;
|
||||
@@ -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 } },
|
||||
|
||||
29
packages/core/src/__tests__/setup-test-isolation.test.ts
Normal file
29
packages/core/src/__tests__/setup-test-isolation.test.ts
Normal 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$/);
|
||||
});
|
||||
});
|
||||
16
packages/core/src/__tests__/setup-test-isolation.ts
Normal file
16
packages/core/src/__tests__/setup-test-isolation.ts
Normal 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;
|
||||
@@ -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(
|
||||
|
||||
@@ -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 } },
|
||||
|
||||
Reference in New Issue
Block a user