fix(test): give each unit test file its own HOME (#927)

Commands resolve ~/.teamai from HOME, so a unit test that reached the real
home shared the sync lock with every teamai session on the machine.
push-env.test.ts failed while another session held ~/.teamai/.sync-lock
(#924). A setup file, listed first so module-level home paths see it too,
now points HOME/USERPROFILE at an empty temp dir per test file. The e2e
config keeps the real home, which CI prepares.
This commit is contained in:
Saul Moro
2026-10-01 14:48:05 +08:00
committed by GitHub
parent fe5c3c5a2b
commit 3030ffd8a8
3 changed files with 42 additions and 1 deletions
+19
View File
@@ -0,0 +1,19 @@
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { afterAll } from 'vitest';
// Commands resolve ~/.teamai (config, state, the sync lock) from HOME at call
// time. A test that reaches the real home shares that state with every teamai
// session on the machine, so a live session's lock made push() tests fail
// (#924). Give each test file, and the CLIs it spawns, its own empty home.
// A test that stubs HOME itself still wins, and unstubbing restores this one.
// Long path, like other temp roots (#870): Windows can hand out a short
// 8.3 tmpdir that paths resolved later would not match.
const home = fs.realpathSync.native(fs.mkdtempSync(path.join(os.tmpdir(), 'teamai-test-home-')));
process.env.HOME = home;
process.env.USERPROFILE = home;
afterAll(() => {
fs.rmSync(home, { recursive: true, force: true });
});
+17
View File
@@ -0,0 +1,17 @@
import { describe, it, expect } from 'vitest';
import os from 'node:os';
import path from 'node:path';
import { TEAMAI_SOURCES_DIR } from '../types.js';
import { getUserHome } from '../utils/home.js';
// Guards helpers/isolate-home.ts (#924): a unit test that reaches the real home
// shares ~/.teamai, and its sync lock, with every teamai session on the machine.
describe('unit test home isolation', () => {
it('runs each test file with a temp home, not the real one', () => {
expect(getUserHome()).not.toBe(os.userInfo().homedir);
});
it('isolates the home before any module builds a path from it', () => {
expect(TEAMAI_SOURCES_DIR).toBe(path.join(getUserHome(), '.teamai', 'sources'));
});
});
+6 -1
View File
@@ -4,7 +4,12 @@ export default defineConfig({
test: {
include: ['src/__tests__/**/*.test.ts'],
exclude: ['src/__tests__/e2e/**', 'src/__tests__/*-e2e.test.ts'],
setupFiles: ['src/__tests__/helpers/clear-agent-session-env.ts'],
// isolate-home first: the other setup file imports modules that build
// home paths at load time.
setupFiles: [
'src/__tests__/helpers/isolate-home.ts',
'src/__tests__/helpers/clear-agent-session-env.ts',
],
// CI workers can be resource-constrained under parallel load, which made
// otherwise-fast tests sporadically exceed vitest's 5s default timeout.
testTimeout: 15000,