Files
suaveplan/packages/testkit/testing/testing-dom/tests/exports-map.spec-conformance.test.ts
2026-05-27 23:47:53 +01:00

117 lines
3.8 KiB
TypeScript

/**
* Spec-conformance: pins the dual-runner conditional-exports shape
* declared in `package.json`. A regression that flips the `bun`
* condition to a vitest-only barrel (or vice versa) would silently
* break consumers running under `bun test`; this test catches it at
* the JSON-shape level rather than at integration time.
*/
import { readFile } from "node:fs/promises";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import { describe, expect, it } from "../src/runner/index.js";
const here = dirname(fileURLToPath(import.meta.url));
const pkgPath = resolve(here, "..", "package.json");
interface ExportTarget {
readonly types?: string;
readonly default?: string;
}
interface ExportsMap {
readonly "."?: {
readonly vitest?: ExportTarget;
readonly bun?: ExportTarget;
readonly default?: ExportTarget;
};
readonly "./polyfills"?: string | ExportTarget;
readonly "./matchers"?: string | ExportTarget;
readonly "./config"?: string | ExportTarget;
readonly "./errors"?: string | ExportTarget;
readonly "./render"?: string | ExportTarget;
readonly "./queries"?: string | ExportTarget;
readonly "./user"?: string | ExportTarget;
readonly "./package.json"?: string;
}
interface MinimalPkg {
exports?: ExportsMap;
}
async function loadPkg(): Promise<MinimalPkg> {
return JSON.parse(await readFile(pkgPath, "utf8")) as MinimalPkg;
}
describe("dual-runner conditional exports", () => {
it("routes vitest + default to the index barrel", {
timeout: 5000,
}, async () => {
const pkg = await loadPkg();
const root = pkg.exports?.["."];
expect(root, "exports['.'] missing").toBeDefined();
expect(root?.vitest?.default).toBe("./dist/index.js");
expect(root?.default?.default).toBe("./dist/index.js");
});
it("routes the bun condition to the bun-test barrel", {
timeout: 5000,
}, async () => {
const pkg = await loadPkg();
const root = pkg.exports?.["."];
expect(root?.bun?.default).toBe("./dist/runner/bun-test.js");
});
it("vitest and default conditions share the same types entry", {
timeout: 5000,
}, async () => {
const pkg = await loadPkg();
const root = pkg.exports?.["."];
expect(root?.vitest?.types).toBe("./dist/index.d.ts");
expect(root?.default?.types).toBe("./dist/index.d.ts");
});
it("bun condition has its own types entry", { timeout: 5000 }, async () => {
const pkg = await loadPkg();
const root = pkg.exports?.["."];
expect(root?.bun?.types).toBe("./dist/runner/bun-test.d.ts");
});
});
describe("subpath exports presence", () => {
const REQUIRED_SUBPATHS = [
"./polyfills",
"./matchers",
"./config",
"./errors",
"./render",
"./queries",
"./user",
] as const;
it("declares every required subpath", { timeout: 5000 }, async () => {
const pkg = await loadPkg();
const exportsMap = pkg.exports ?? {};
for (const sub of REQUIRED_SUBPATHS) {
expect(
Object.hasOwn(exportsMap, sub),
`package.json#exports is missing "${sub}"`
).toBe(true);
}
});
it("polyfills + matchers resolve to side-effecting dist files", {
timeout: 5000,
}, async () => {
const pkg = await loadPkg();
const exportsMap = pkg.exports ?? {};
const polyfills = exportsMap["./polyfills"];
const matchers = exportsMap["./matchers"];
expect(
typeof polyfills === "string" ? polyfills : polyfills?.default
).toBe("./dist/setup/polyfills.js");
expect(
typeof matchers === "string" ? matchers : matchers?.default
).toBe("./dist/matchers/matchers.js");
});
});