diff --git a/packages/domain/src/__tests__/gates.test.ts b/packages/domain/src/__tests__/gates.test.ts new file mode 100644 index 0000000..14255ee --- /dev/null +++ b/packages/domain/src/__tests__/gates.test.ts @@ -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); + }); +}); diff --git a/packages/domain/src/__tests__/lint-gate.test.ts b/packages/domain/src/__tests__/lint-gate.test.ts deleted file mode 100644 index 17d8297..0000000 --- a/packages/domain/src/__tests__/lint-gate.test.ts +++ /dev/null @@ -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); - }); -}); diff --git a/scripts/check-lint-gate.mjs b/scripts/check-gates.mjs similarity index 84% rename from scripts/check-lint-gate.mjs rename to scripts/check-gates.mjs index 8182e84..cc941f8 100644 --- a/scripts/check-lint-gate.mjs +++ b/scripts/check-gates.mjs @@ -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} */ 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")) { diff --git a/vitest.config.ts b/vitest.config.ts index 4fd79c8..fdfe999 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -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,