Files
kandev/apps/web/scripts/lib/changed-files.test.ts
2026-08-13 22:50:13 +01:00

79 lines
2.9 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { isCandidate, isE2eCandidate } from "./changed-files.mjs";
/**
* `isCandidate` decides which files the **live i18n ratchet** judges, and had no
* test until the sleep ratchet needed the same git plumbing with a different
* predicate. These cases pin the existing behaviour so that extraction is
* provably behaviour-preserving, and pin the new predicate as its exact
* complement over the `e2e/` tree.
*/
describe("isCandidate (i18n ratchet file selection)", () => {
it.each([
"apps/web/components/task/card.tsx",
"apps/web/app/settings/page.tsx",
"apps/web/hooks/domains/kanban/use-board.ts",
"apps/web/lib/state/store.ts",
"apps/web/src/settings-routes.tsx",
])("includes UI source %s", (path) => {
expect(isCandidate(path)).toBe(true);
});
it.each([
// Tests build fixtures out of literals on purpose.
["apps/web/components/task/card.test.tsx", "unit test"],
["apps/web/lib/util.spec.ts", "spec file"],
// Not UI source.
["apps/web/e2e/tests/task/chat.spec.ts", "e2e tree"],
["apps/web/scripts/check-i18n-keys.mjs", "build script"],
["apps/web/eslint.config.mjs", "config, not .ts"],
["apps/web/components/task/styles.css", "not TypeScript"],
["apps/backend/internal/office/router.go", "outside apps/web"],
["apps/packages/ui/src/button.tsx", "outside apps/web"],
])("excludes %s (%s)", (path) => {
expect(isCandidate(path)).toBe(false);
});
});
describe("isE2eCandidate (sleep ratchet file selection)", () => {
it.each([
"apps/web/e2e/tests/task/chat.spec.ts",
"apps/web/e2e/helpers/api-client.ts",
"apps/web/e2e/fixtures/backend.ts",
"apps/web/e2e/pages/task-page.ts",
// Exemption is the eslint config's job, not the selector's — this path is
// deliberately still selected here.
"apps/web/e2e/helpers/causal-waits.ts",
])("includes %s", (path) => {
expect(isE2eCandidate(path)).toBe(true);
});
it.each([
["apps/web/components/task/card.tsx", "UI source, not e2e"],
["apps/web/scripts/check-new-e2e-sleeps.mjs", "build script"],
["apps/web/e2e/README.md", "not TypeScript"],
["apps/web/e2e/scripts/seed.js", "plain JS is not parsed by the rule config"],
["apps/backend/internal/office/router.go", "outside apps/web"],
])("excludes %s (%s)", (path) => {
expect(isE2eCandidate(path)).toBe(false);
});
/**
* The two predicates must not both claim a file: the i18n guard would demand
* catalog keys for test fixture strings, which is why `e2e/` was excluded from
* it in the first place.
*/
it("never overlaps with the i18n predicate", () => {
const paths = [
"apps/web/e2e/tests/task/chat.spec.ts",
"apps/web/e2e/helpers/api-client.ts",
"apps/web/components/task/card.tsx",
"apps/web/lib/state/store.ts",
];
for (const path of paths) {
expect(isCandidate(path) && isE2eCandidate(path)).toBe(false);
}
});
});