|
8 | 8 | import { describe, it, expect } from 'vitest'; |
9 | 9 | import { tmpdir } from 'node:os'; |
10 | 10 | import { join } from 'node:path'; |
| 11 | +import { mkdtemp } from 'node:fs/promises'; |
11 | 12 | import { |
12 | 13 | BaseInterfaceContract, |
13 | 14 | ValidationHelpers, |
@@ -55,10 +56,12 @@ const mockStateMachine = { |
55 | 56 | }, |
56 | 57 | }; |
57 | 58 |
|
58 | | -// Create test paths using temp directory |
59 | | -const testDir = join(tmpdir(), 'plan-manager-contract-tests'); |
60 | | -const testPlanPath = join(testDir, 'plan.md'); |
61 | | -const testProjectPath = join(testDir, 'project'); |
| 59 | +// Paths are resolved lazily in setup() so each test run gets a unique directory. |
| 60 | +// Using a static path caused flakiness when cleanup in one test deleted the |
| 61 | +// directory while another concurrent test was still writing to it. |
| 62 | +let testDir = join(tmpdir(), 'plan-manager-contract-tests'); |
| 63 | +let testPlanPath = join(testDir, 'plan.md'); |
| 64 | +let testProjectPath = join(testDir, 'project'); |
62 | 65 |
|
63 | 66 | /** |
64 | 67 | * Plan Manager Contract Test Suite |
@@ -315,9 +318,10 @@ describe('IPlanManager Interface Contract', () => { |
315 | 318 | return new PlanManager(); |
316 | 319 | }, |
317 | 320 | setup: async (instance: IPlanManager) => { |
318 | | - // Ensure test directory exists |
319 | | - const { mkdir } = await import('node:fs/promises'); |
320 | | - await mkdir(testDir, { recursive: true }); |
| 321 | + // Create a unique temp directory per test run to avoid concurrent-cleanup races |
| 322 | + testDir = await mkdtemp(join(tmpdir(), 'plan-manager-contract-')); |
| 323 | + testPlanPath = join(testDir, 'plan.md'); |
| 324 | + testProjectPath = join(testDir, 'project'); |
321 | 325 |
|
322 | 326 | // Set up state machine for PlanManager |
323 | 327 | ( |
|
0 commit comments