diff --git a/bunfig.toml b/bunfig.toml new file mode 100644 index 00000000..dbf0d8f5 --- /dev/null +++ b/bunfig.toml @@ -0,0 +1,7 @@ +[test] +# Force each test file into its own worker process. +# Prevents mock.module() calls (which are permanent within a worker) +# from leaking across test files in parallel runs. +# Note: smol=true increases test startup time by spawning one Bun process per file. +# See: https://github.com/thedotmack/claude-mem/issues/1299 +smol = true diff --git a/tests/hooks/context-reinjection-guard.test.ts b/tests/hooks/context-reinjection-guard.test.ts index 6d84e278..0db5f2fd 100644 --- a/tests/hooks/context-reinjection-guard.test.ts +++ b/tests/hooks/context-reinjection-guard.test.ts @@ -38,10 +38,6 @@ mock.module('../../src/shared/worker-utils.js', () => ({ }, })); -mock.module('../../src/utils/project-name.js', () => ({ - getProjectName: () => 'test-project', -})); - mock.module('../../src/utils/project-filter.js', () => ({ isProjectExcluded: () => false, })); diff --git a/tests/utils/project-name-isolation.test.ts b/tests/utils/project-name-isolation.test.ts new file mode 100644 index 00000000..7c08e04c --- /dev/null +++ b/tests/utils/project-name-isolation.test.ts @@ -0,0 +1,28 @@ +/** + * Regression test for mock.module() worker pollution (#1299) + * + * context-reinjection-guard.test.ts used to call mock.module('../../src/utils/project-name.js', ...) + * at the top level, which permanently stubbed getProjectName to return 'test-project' + * for every subsequent import in the same Bun worker process. + * + * Without bunfig.toml [test] smol=true, this test would fail when Bun scheduled + * it in the same worker as context-reinjection-guard.test.ts, because the module + * was mocked before these tests ran and getProjectName() returned 'test-project' + * instead of the real extracted basename. + */ +import { describe, it, expect } from 'bun:test'; +import { getProjectName } from '../../src/utils/project-name.js'; + +describe('getProjectName mock isolation (#1299)', () => { + it('returns real basename, not the leaked test-project mock', () => { + expect(getProjectName('/real/path/to/my-project')).toBe('my-project'); + }); + + it('returns unknown-project for empty string (real implementation)', () => { + expect(getProjectName('')).toBe('unknown-project'); + }); + + it('returns real basename from nested path', () => { + expect(getProjectName('/home/user/code/awesome-app')).toBe('awesome-app'); + }); +});