Make the test gate fail when no tests match

vitest.config.ts set passWithNoTests: true, added in the 7dd4abb
scaffolding commit when the repo genuinely had no tests yet. Once tests
existed it became the same hazard as the oxlint bugs fixed in 91f46ff:
if the include globs ever stopped matching, the suite would exit 0
having run nothing.

Vitest already defaults to failing in that case, so removing the line is
the whole fix — a broken glob now reports "No test files found, exiting
with code 1". Verified by pointing the globs at a nonexistent directory.

Extends the gate check to flag the option coming back, and renames it
from check-lint-gate to check-gates now that it covers more than oxlint.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Lukas
2026-08-05 14:16:04 +02:00
co-authored by Claude Opus 5
parent 8204122bd0
commit 67c398d3a2
4 changed files with 22 additions and 17 deletions
@@ -0,0 +1,14 @@
import { describe, expect, it } from "vitest";
import { checkGates } from "../../../../scripts/check-gates.mjs";
describe("quality gates", () => {
it("fail on violations instead of silently passing", () => {
const violations = checkGates();
if (violations.length > 0) {
throw new Error(
`Gate integrity violations:\n ${violations.join("\n ")}`,
);
}
expect(violations).toHaveLength(0);
});
});
@@ -1,14 +0,0 @@
import { describe, expect, it } from "vitest";
import { checkLintGate } from "../../../../scripts/check-lint-gate.mjs";
describe("lint gate", () => {
it("fails on warnings instead of silently passing", () => {
const violations = checkLintGate();
if (violations.length > 0) {
throw new Error(
`Lint gate integrity violations:\n ${violations.join("\n ")}`,
);
}
expect(violations).toHaveLength(0);
});
});
@@ -48,15 +48,21 @@ function failsOnWarnings(oxlintScript) {
}
/**
* Reports ways the oxlint gate could pass without checking anything, which is
* Reports ways a quality gate could pass without checking anything, which is
* indistinguishable from a clean run.
* @returns {string[]}
*/
export function checkLintGate() {
export function checkGates() {
/** @type {Record<string, string>} */
const scripts = JSON.parse(read("package.json")).scripts;
const violations = findGatesWithOwnFlags(scripts);
// Vitest defaults to failing when no test file matches. Setting this puts
// the test gate back to exiting 0 if the include globs ever stop matching.
if (read("vitest.config.ts").includes("passWithNoTests")) {
violations.push("vitest.config.ts sets passWithNoTests");
}
// The canary rule below is not type-aware, so the probe alone cannot
// detect type-aware rules being switched off.
if (!scripts.oxlint.includes("--type-aware")) {
-1
View File
@@ -3,7 +3,6 @@ import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
include: ["packages/*/src/**/*.test.ts", "apps/*/src/**/*.test.{ts,tsx}"],
passWithNoTests: true,
coverage: {
provider: "v8",
enabled: true,