1import { assert, describe } from "@effect/vitest";
2
3import { createOxlintRuleHarness } from "../test/utils.ts";
4
5const rule = createOxlintRuleHarness("t3code/no-manual-effect-runtime-in-tests", {
6 filename: "fixture.test.ts",
7});
8
9describe("t3code/no-manual-effect-runtime-in-tests", () => {
10 rule.valid(
11 "allows @effect/vitest effect tests",
12 `
13 import { it } from "@effect/vitest";
14 import * as Effect from "effect/Effect";
15
16 it.effect("runs an Effect", () => Effect.succeed("ok"));
17 `,
18 );
19
20 const runtimeMethods = [
21 "runCallback",
22 "runCallbackWith",
23 "runFork",
24 "runForkWith",
25 "runPromise",
26 "runPromiseExit",
27 "runPromiseExitWith",
28 "runPromiseWith",
29 "runSync",
30 "runSyncExit",
31 "runSyncExitWith",
32 "runSyncWith",
33 ] as const;
34
35 for (const method of runtimeMethods) {
36 rule.invalid(
37 `reports Effect.${method}`,
38 `
39 import * as Effect from "effect/Effect";
40
41 test("runs an Effect", () => {
42 Effect.${method}(Effect.succeed("ok"));
43 });
44 `,
45 (output) => {
46 assert.match(output, /Use @effect\/vitest with it\.effect/);
47 },
48 );
49 }
50
51 rule.invalid(
52 "reports ManagedRuntime.make",
53 `
54 import * as Layer from "effect/Layer";
55 import * as ManagedRuntime from "effect/ManagedRuntime";
56
57 test("makes a runtime", () => {
58 ManagedRuntime.make(Layer.empty);
59 });
60 `,
61 );
62});
63
64const productionRule = createOxlintRuleHarness("t3code/no-manual-effect-runtime-in-tests");
65
66productionRule.valid(
67 "allows production runtime boundaries",
68 `
69 import * as Effect from "effect/Effect";
70
71 export const main = () => Effect.runPromise(Effect.void);
72 `,
73);
74
75const legacyRule = createOxlintRuleHarness("t3code/no-manual-effect-runtime-in-tests", {
76 filename: "legacy.test.ts",
77 ruleOptions: [{ maxOccurrences: 2 }],
78});
79
80describe("t3code/no-manual-effect-runtime-in-tests with maxOccurrences", () => {
81 legacyRule.valid(
82 "allows occurrences up to the ceiling",
83 `
84 import * as Effect from "effect/Effect";
85
86 test("first", () => Effect.runSync(Effect.void));
87 test("second", () => Effect.runSync(Effect.void));
88 `,
89 );
90
91 legacyRule.invalid(
92 "reports occurrences beyond the ceiling",
93 `
94 import * as Effect from "effect/Effect";
95
96 test("first", () => Effect.runSync(Effect.void));
97 test("second", () => Effect.runSync(Effect.void));
98 test("third", () => Effect.runSync(Effect.void));
99 `,
100 (output) => {
101 assert.equal(output.match(/no-manual-effect-runtime-in-tests/g)?.length, 1);
102 },
103 );
104});