Files
Ignacy Łątka fd978f302d test(tool-server): stop a failed beforeEach from throwing again in teardown (#1091)
Fixes #1076

**Cause** - suites that redirect `os.tmpdir()` for a whole file hoist
the restorer, and the scratch directory it points at, into uninitialized
`let`s that `beforeEach` assigns partway through. Vitest still runs
`afterEach` when `beforeEach` throws, so teardown calls `undefined()`
and hands `undefined` to `fs.rm` - bogus `TypeError`s reported beside
the real failure, and a reader chases the wrong one.

**Fix** - initialize what the teardown reads (`= () => {}` / `= ""`;
`fs.rm("", { force: true })` is a no-op), plus a guard in
`tmpdir-env.test.ts` that scans the suite for the shape so a new
`redirectTmpdir` caller cannot reintroduce it.

**Verified** - injected a throw ahead of the assignment in each affected
`beforeEach`: before, the teardown `TypeError` rode alongside the
injected error; after, only the injected error is reported. The guard
lists all 9 declarations against `origin/main` and passes with the fix.
`npx tsc --build`, `typecheck:tests -w @argent/tool-server`, and the
full package suite (433 files, 6164 tests) are green.

Docs: none - test-only change, no tool, CLI, config key, flow file or
user-facing capability touched.

<details>
<summary>Repro, before and after</summary>

`packages/tool-server/test/react-profiler/dump.test.ts`, throw injected
as the first statement of `beforeEach`:

Before:
```
⎯⎯⎯⎯⎯⎯ Failed Tests 17 ⎯⎯⎯⎯⎯⎯⎯
Error: SIMULATED mkdtemp failure before assignment
TypeError: restoreTmpdir is not a function
```

With only the restorer initialized - the second half of the same hook
still throws:
```
Error: SIMULATED mkdtemp failure before assignment
TypeError: The "path" argument must be of type string or an instance of Buffer or URL. Received undefined
```

After (same for `screen-recording`, `profiler-load-list-e2e`,
`native-profiler-freshness-e2e`, `flow-visual`):
```
Error: SIMULATED failure before assignment
```
</details>

<details>
<summary>Guard against origin/main</summary>

```
- []
+ [
+   "android-perfetto/native-profiler-freshness-e2e.test.ts: let tempDir: string;",
+   "android-perfetto/native-profiler-freshness-e2e.test.ts: let restoreTmpdir: () => void;",
+   "android-perfetto/profiler-load-list-e2e.test.ts: let scratch: string;",
+   "android-perfetto/profiler-load-list-e2e.test.ts: let restoreTmpdir: () => void;",
+   "flows/flow-visual.test.ts: let tmpDir: string;",
+   "react-profiler/dump.test.ts: let restoreTmpdir: () => void;",
+   "react-profiler/dump.test.ts: let scratch: string;",
+   "screen-recording.test.ts: let restoreTmpdir: () => void;",
+   "screen-recording.test.ts: let scratch: string;",
+ ]
```
</details>

<details>
<summary>Class check - what was left alone</summary>

- `packages/telemetry/test/index.test.ts:89` `let restoreOptOut: () =>
void;` - same shape, no window: the assignment is the first statement of
the file's first `beforeEach`, so nothing can throw ahead of it.
- Roughly 90 other hoisted `let`s across tool-server tests are read in
`afterEach` without an initializer (`tmpDir`, `handle`, `exitSpy`, ...)
in suites that never redirect the tmpdir. That is a repo-wide pattern
for a lint rule, not for this fix; the guard is scoped to the
`redirectTmpdir` suites the issue reports.
- Local `npx eslint` on the changed files could not run:
`packages/docs/tsconfig.json` fails to resolve `@docusaurus/tsconfig`
because the root install skips that workspace. Pre-existing and
unrelated; CI's ESLint job is green on this branch.
</details>

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-09-09 20:17:23 +02:00
..