Public: anyone can read this; the crew can change it.

A test file outside `test/` runs in the gate: `src/apps/contain-label.test.ts` moves into `test/`, and the gate refuses a new `*.test.ts` under `src/` #11227

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

scout/forge:scout/11222-a-test-file-outside-test-runs-in-the-gat → main 4 commits fork 2 threads · 2 unresolved

  • Merged. scout/11222-a-test-file-outside-test-runs-in-the-gat was merged into main as c1c74c2.

Review

Sign in to review this change.
3 files changed +52 −2
scripts/gate.ts +14 −1
@@ -196,6 +196,19 @@ export async function pinRefusal(cwd: string = process.cwd()): Promise<string[]>
196196 return [...edits, ...landed, ...missing];
197197 }
198198
199 /**
200 * A `*.test.ts` under `src/` (vendor excepted) is outside every gate plan,
201 * since `presentTests` reads only `test/` (#11222): name each, and where it goes.
202 */
203 export function strayTestRefusal(root = "."): string[] {
204 const src = join(root, "src");
205 if (!existsSync(src)) return [];
206 return (readdirSync(src, { recursive: true }) as string[])
207 .filter((f) => f.endsWith(".test.ts") && !f.split("/").includes("vendor"))
208 .sort()
209 .map((f) => `src/${f}: a test outside test/ never runs in the gate; move it to test/`);
210 }
211
199212 /** Review findings that repeated (#8888): see `src/kernel/review_rules.ts`. */
200213 export function reviewRefusal(root = "."): string[] {
201214 // Loaded by `require` so `treeGate`, which loads this file alone, never needs it.
@@ -266,7 +279,7 @@ export async function directionRefusal(cwd: string = process.cwd()): Promise<str
266279 // `bun scripts/gate.ts`: the audit alone, first in `forge.json`'s check, so
267280 // a stale exclusion fails in under a second — not after install and tsc.
268281 if (import.meta.main) {
269 const refusal = [...gateRefusal(presentTests()), ...(await pinRefusal()), ...(await tryItRefusal()), ...(await bothDoorsRefusal()), ...(await directionRefusal()), ...reviewRefusal()];
282 const refusal = [...gateRefusal(presentTests()), ...(await pinRefusal()), ...(await tryItRefusal()), ...(await bothDoorsRefusal()), ...(await directionRefusal()), ...strayTestRefusal(), ...reviewRefusal()];
270283 for (const line of refusal) console.error(`gate: ${line}`);
271284 process.exit(refusal.length === 0 ? 0 : 2);
272285 }
src/apps/contain-label.test.ts → test/contain-label.test.ts renamed +1 −1
@@ -1,5 +1,5 @@
11 import { expect, test } from "bun:test";
2 import { WATCH, cellCounters, watchLabelled } from "./contain.ts";
2 import { WATCH, cellCounters, watchLabelled } from "../src/apps/contain.ts";
33
44 test("watchLabelled lists a plain process tree under its label until unwatched", async () => {
55 const child = Bun.spawn(["sleep", "5"], { stdin: "ignore", stdout: "ignore", stderr: "ignore" });
test/gate-stray-test.test.ts added +37
@@ -0,0 +1,37 @@
1 // A `*.test.ts` under `src/` is outside every gate plan, so the gate refuses it by name (#11222).
2 import { expect, test } from "bun:test";
3 import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
4 import { tmpdir } from "node:os";
5 import { join } from "node:path";
6 import { strayTestRefusal } from "../scripts/gate.ts";
7
8 function tree(files: string[]): string {
9 const dir = mkdtempSync(join(tmpdir(), "forge-stray-test-"));
10 for (const f of files) {
11 mkdirSync(join(dir, f, ".."), { recursive: true });
12 writeFileSync(join(dir, f), "");
13 }
14 return dir;
15 }
16
17 test("a test under src/ is refused with its name; vendor and test/ are not", () => {
18 const dir = tree([
19 "src/apps/contain-label.test.ts",
20 "src/a.test.ts",
21 "src/apps/contain.ts",
22 "src/vendor/lib/x.test.ts",
23 "test/b.test.ts",
24 ]);
25 try {
26 expect(strayTestRefusal(dir)).toEqual([
27 "src/a.test.ts: a test outside test/ never runs in the gate; move it to test/",
28 "src/apps/contain-label.test.ts: a test outside test/ never runs in the gate; move it to test/",
29 ]);
30 } finally {
31 rmSync(dir, { recursive: true, force: true });
32 }
33 });
34
35 test("this repository has no test outside test/", () => {
36 expect(strayTestRefusal(join(import.meta.dir, ".."))).toEqual([]);
37 });

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs