40 lines
1.5 KiB
TypeScript
40 lines
1.5 KiB
TypeScript
import { routes, type RouteName } from "@deadhead/schema";
|
|
import { describe, expect, it } from "vitest";
|
|
import { SERVER_ONLY_ROUTES } from "../src/index";
|
|
|
|
declare global {
|
|
interface ImportMeta {
|
|
glob(
|
|
pattern: string,
|
|
options: { query: "?raw"; import: "default"; eager: true },
|
|
): Record<string, string>;
|
|
}
|
|
}
|
|
|
|
/** Every engine test file's source (Vite's glob, read at test time). */
|
|
const sources = Object.entries(
|
|
import.meta.glob("./**/*.test.ts", { query: "?raw", import: "default", eager: true }),
|
|
).filter(([path]) => !path.endsWith("catalog.test.ts"));
|
|
|
|
/** A test uses a command if it names it, or calls its old endpoint path. */
|
|
function usedBy(name: RouteName, source: string): boolean {
|
|
if (new RegExp(`["'\`]${name}["'\`]`).test(source)) return true;
|
|
const pieces = routes[name].path.split(/:\w+/).filter((p) => p.length > 1);
|
|
return pieces.every((piece) => source.includes(piece)) && source.includes(routes[name].method);
|
|
}
|
|
|
|
describe("command catalog coverage (Step 14.5)", () => {
|
|
const commands = (Object.keys(routes) as RouteName[]).filter(
|
|
(name) => !(SERVER_ONLY_ROUTES as readonly string[]).includes(name),
|
|
);
|
|
|
|
it("finds the engine test files", () => {
|
|
expect(sources.length).toBeGreaterThan(20);
|
|
});
|
|
|
|
it.each(commands)("%s has at least one engine test", (name) => {
|
|
const files = sources.filter(([, source]) => usedBy(name, source)).map(([path]) => path);
|
|
expect(files, `no engine test uses ${name}`).not.toEqual([]);
|
|
});
|
|
});
|