| 32 | } |
| 33 | |
| 34 | const runCoverage = (): { |
| 35 | combined: string; |
| 36 | exitCode: number; |
| 37 | spawnError?: Error; |
| 38 | } => { |
| 39 | /* |
| 40 | * Bun emits the coverage table on stderr; the test result on stdout. |
| 41 | * Capture both into the same buffer so the gate's row-parser sees the |
| 42 | * table, and stream the buffer to the user verbatim at the end. |
| 43 | */ |
| 44 | /* |
| 45 | * Scoped to `tests` on purpose. Without a path Bun discovers every |
| 46 | * `*.test.ts` in the project, which now includes `security-spec/`: an |
| 47 | * intentionally-red suite that asserts the behaviour of unfixed security |
| 48 | * findings. Those belong to their own lane (`bun run test:security`); |
| 49 | * letting them into the coverage gate turns the ordinary merge gate red |
| 50 | * for reasons unrelated to the change under review. |
| 51 | */ |
| 52 | const result = spawnSync("bun", ["test", "tests", "--coverage"], { |
| 53 | encoding: "utf8", |
| 54 | maxBuffer: MAX_TEST_OUTPUT_BUFFER_BYTES, |
| 55 | env: { |
| 56 | ...process.env, |
| 57 | NODE_ENV: "test", |
| 58 | LOG_LEVEL: "error", |
| 59 | NODE_NO_WARNINGS: "1", |
| 60 | }, |
| 61 | }); |
| 62 | |
| 63 | return { |