1import { assert, describe } from "@effect/vitest";
2
3import { createOxlintRuleHarness } from "../test/utils.ts";
4
5const rule = createOxlintRuleHarness("t3code/no-wall-clock-in-tests", {
6 filename: "fixture.test.ts",
7});
8
9describe("t3code/no-wall-clock-in-tests", () => {
10 rule.valid(
11 "ignores a computed member with a variable key",
12 `
13 import { it } from "vitest";
14 it("parses", () => {
15 const now = "parse";
16 const parsed = Date[now]("2026-01-01");
17 const literal = Date["parse"]("2026-01-01");
18 });
19 `,
20 );
21
22 rule.valid(
23 "allows fixed dates and readings that seed mocks",
24 `
25 import { vi } from "vitest";
26
27 const epoch = new Date("2026-01-01T00:00:00.000Z");
28 export const later = new Date(epoch.getTime() + 1_000);
29 vi.setSystemTime(new Date());
30 vi.spyOn(Date, "now").mockReturnValue(Date.now() + 5_000);
31 const clock = vi.fn(() => performance.now());
32 clock.mockImplementation(() => Number(process.hrtime.bigint()));
33 vi.mock("./clock", () => ({ now: () => Date.now() }));
34 `,
35 );
36
37 rule.invalid(
38 "reports elapsed-time measurement",
39 `
40 const startedAt = performance.now();
41 const elapsed = performance.now() - startedAt;
42 if (elapsed > 10_000) throw new Error("slow");
43 `,
44 (output) => {
45 assert.match(output, /Wall-clock reading in a test/);
46 assert.equal(output.match(/no-wall-clock-in-tests/g)?.length, 2);
47 },
48 );
49
50 rule.invalid(
51 "reports Date.now fixtures",
52 `
53 export const session = { expiresAt: Date.now() + 60_000 };
54 `,
55 );
56
57 rule.invalid(
58 "reports new Date() with no arguments",
59 `
60 export const createdAt = new Date().toISOString();
61 `,
62 );
63
64 rule.invalid(
65 "reports process.hrtime and process.hrtime.bigint",
66 `
67 export const a = process.hrtime();
68 export const b = process.hrtime.bigint();
69 `,
70 (output) => {
71 assert.equal(output.match(/no-wall-clock-in-tests/g)?.length, 2);
72 },
73 );
74
75 rule.invalid(
76 "reports a reading outside the mock's arguments",
77 `
78 import { vi } from "vitest";
79
80 const mock = vi.fn();
81 mock.mockReturnValue(1);
82 export const now = Date.now();
83 `,
84 );
85});
86
87const productionRule = createOxlintRuleHarness("t3code/no-wall-clock-in-tests");
88
89productionRule.valid(
90 "ignores non-test files",
91 `
92 export const now = Date.now();
93 `,
94);