|
4 | 4 | // here matter as much as the positive one. Reading the clock live is CORRECT wherever the passage of time is |
5 | 5 | // itself under test; the distinguishing property is whether the helper projects a fixture timestamp from an |
6 | 6 | // offset its caller varies. |
| 7 | +import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs"; |
| 8 | +import { tmpdir } from "node:os"; |
| 9 | +import { join } from "node:path"; |
| 10 | + |
7 | 11 | import { describe, expect, it } from "vitest"; |
8 | 12 |
|
9 | | -import { findFixtureClockRaces } from "../../scripts/check-fixture-clock-races"; |
| 13 | +import { FIXTURE_TEST_ROOTS, findFixtureClockRaces, walk } from "../../scripts/check-fixture-clock-races"; |
10 | 14 |
|
11 | 15 | describe("findFixtureClockRaces (#9955)", () => { |
12 | 16 | it("REGRESSION: catches the exact queue-trends shape that reached CI", () => { |
@@ -105,4 +109,52 @@ seed(dayAgo(3)); |
105 | 109 | `; |
106 | 110 | expect(findFixtureClockRaces("f.test.ts", source)).toHaveLength(1); |
107 | 111 | }); |
| 112 | + |
| 113 | + it("REGRESSION (#10043): reports the daysAgoIso shape that lived in packages/loopover-engine/test unscanned", () => { |
| 114 | + // Verbatim the pre-fix helper from packages/loopover-engine/test/issue-quality-report.test.ts, plus its |
| 115 | + // two call sites -- the exact shape the checker never saw because main() only walked test/. |
| 116 | + const source = ` |
| 117 | +function daysAgoIso(days: number): string { |
| 118 | + return new Date(Date.now() - days * 86_400_000).toISOString(); |
| 119 | +} |
| 120 | +const stale = build(daysAgoIso(60)); |
| 121 | +const ancient = build(daysAgoIso(100)); |
| 122 | +`; |
| 123 | + expect(findFixtureClockRaces("packages/loopover-engine/test/x.test.ts", source)).toEqual([ |
| 124 | + { file: "packages/loopover-engine/test/x.test.ts", helper: "daysAgoIso", calls: 2 }, |
| 125 | + ]); |
| 126 | + }); |
| 127 | +}); |
| 128 | + |
| 129 | +describe("FIXTURE_TEST_ROOTS and walk (#10043)", () => { |
| 130 | + it("scans both the root suite and the engine suite", () => { |
| 131 | + expect(FIXTURE_TEST_ROOTS).toContain("test"); |
| 132 | + expect(FIXTURE_TEST_ROOTS).toContain("packages/loopover-engine/test"); |
| 133 | + }); |
| 134 | + |
| 135 | + it("walk tolerates a missing directory instead of throwing", () => { |
| 136 | + const out: string[] = []; |
| 137 | + expect(() => walk(join(tmpdir(), "check-fixture-clock-races-missing-dir-fixture"), out)).not.toThrow(); |
| 138 | + expect(out).toEqual([]); |
| 139 | + }); |
| 140 | + |
| 141 | + it("walk reaches a fixture under EITHER root the same way, mirroring main()'s per-root loop", () => { |
| 142 | + const workspace = mkdtempSync(join(tmpdir(), "fixture-clock-races-")); |
| 143 | + try { |
| 144 | + const rootTestDir = join(workspace, "test", "unit"); |
| 145 | + const engineTestDir = join(workspace, "packages", "loopover-engine", "test"); |
| 146 | + mkdirSync(rootTestDir, { recursive: true }); |
| 147 | + mkdirSync(engineTestDir, { recursive: true }); |
| 148 | + writeFileSync(join(rootTestDir, "root-fixture.test.ts"), "export const rootFixture = 1;\n"); |
| 149 | + writeFileSync(join(engineTestDir, "engine-fixture.test.ts"), "export const engineFixture = 1;\n"); |
| 150 | + |
| 151 | + const found: string[] = []; |
| 152 | + for (const testRoot of FIXTURE_TEST_ROOTS) walk(join(workspace, testRoot), found); |
| 153 | + |
| 154 | + expect(found).toContain(join(rootTestDir, "root-fixture.test.ts")); |
| 155 | + expect(found).toContain(join(engineTestDir, "engine-fixture.test.ts")); |
| 156 | + } finally { |
| 157 | + rmSync(workspace, { recursive: true, force: true }); |
| 158 | + } |
| 159 | + }); |
108 | 160 | }); |
0 commit comments