Description
Running bun run test:isolated produces 4 test failures in test/isolated/dsn/errors.test.ts because mock.module() in test/isolated/resolve-target.test.ts pollutes the module cache for subsequent test files.
Steps to Reproduce
# Fails — 4 tests break
bun run test:isolated
# 53 pass, 4 fail
# Passes — same file in isolation works fine
bun test test/isolated/dsn/errors.test.ts
# 17 pass, 0 fail
Failing tests (all in formatMultipleProjectsFooter describe block):
formats footer with two projects
formats footer with projects without detectedFrom
formats footer with mixed detectedFrom presence
handles many projects
Error pattern:
Expected to contain: "Found 2 Sentry projects:"
Received: "Found 2 projects"
Root Cause
Bun runs test files sequentially in one thread. The execution order is:
-
test/isolated/resolve-target.test.ts runs first and calls:
// Line 56-65
mock.module("../../src/lib/dsn/index.js", () => ({
// ...
formatMultipleProjectsFooter: (projects: unknown[]) =>
projects.length > 1
? `Found ${projects.length} projects` // ← simplified mock, missing "Sentry"
: "",
}));
-
test/isolated/dsn/errors.test.ts runs afterward and imports:
// Line 4
import { formatMultipleProjectsFooter } from "../../../src/lib/dsn/errors.js";
-
Even though errors.test.ts imports from the direct source (dsn/errors.js) rather than the re-export (dsn/index.js), Bun's module cache has been poisoned by the mock.module() call. The mock's simplified formatMultipleProjectsFooter (returns "Found N projects") overrides the real implementation (returns "Found N Sentry projects:").
Proposed Fix
Several options:
Option 1: Clean up mocks in resolve-target.test.ts
Add afterAll cleanup to restore the original module:
import { afterAll } from "bun:test";
afterAll(() => {
mock.restore();
});
Option 2: Move non-isolated tests out of test/isolated/
The formatMultipleProjectsFooter tests in errors.test.ts don't use mock.module() themselves — they test the real function directly. They could be moved to test/lib/dsn/errors.test.ts to avoid the polluted environment entirely.
Option 3: Re-import in each test
Use dynamic import() inside each test to get a fresh module reference, bypassing the cached mock.
Files
test/isolated/resolve-target.test.ts:56-65 — the mock.module() call that pollutes the cache
test/isolated/dsn/errors.test.ts:297-368 — the 4 failing test assertions
src/lib/dsn/errors.ts:153-168 — the real formatMultipleProjectsFooter implementation
src/lib/dsn/index.ts:42 — re-export of formatMultipleProjectsFooter
Description
Running
bun run test:isolatedproduces 4 test failures intest/isolated/dsn/errors.test.tsbecausemock.module()intest/isolated/resolve-target.test.tspollutes the module cache for subsequent test files.Steps to Reproduce
Failing tests (all in
formatMultipleProjectsFooterdescribe block):formats footer with two projectsformats footer with projects without detectedFromformats footer with mixed detectedFrom presencehandles many projectsError pattern:
Root Cause
Bun runs test files sequentially in one thread. The execution order is:
test/isolated/resolve-target.test.tsruns first and calls:test/isolated/dsn/errors.test.tsruns afterward and imports:Even though
errors.test.tsimports from the direct source (dsn/errors.js) rather than the re-export (dsn/index.js), Bun's module cache has been poisoned by themock.module()call. The mock's simplifiedformatMultipleProjectsFooter(returns"Found N projects") overrides the real implementation (returns"Found N Sentry projects:").Proposed Fix
Several options:
Option 1: Clean up mocks in
resolve-target.test.tsAdd
afterAllcleanup to restore the original module:Option 2: Move non-isolated tests out of
test/isolated/The
formatMultipleProjectsFootertests inerrors.test.tsdon't usemock.module()themselves — they test the real function directly. They could be moved totest/lib/dsn/errors.test.tsto avoid the polluted environment entirely.Option 3: Re-import in each test
Use dynamic
import()inside each test to get a fresh module reference, bypassing the cached mock.Files
test/isolated/resolve-target.test.ts:56-65— themock.module()call that pollutes the cachetest/isolated/dsn/errors.test.ts:297-368— the 4 failing test assertionssrc/lib/dsn/errors.ts:153-168— the realformatMultipleProjectsFooterimplementationsrc/lib/dsn/index.ts:42— re-export offormatMultipleProjectsFooter