111 lines
4.0 KiB
TypeScript
111 lines
4.0 KiB
TypeScript
/**
|
|
* Spec-conformance tests for `@suaveplan/macos-contacts`. Pins barrel
|
|
* shape, subpath exports, error-code wiring, and the §7 ban on direct
|
|
* `vitest` / `bun:test` imports. Failure of any test here means an OpenSpec
|
|
* requirement has drifted from the implementation.
|
|
*/
|
|
|
|
import { readdirSync, readFileSync, statSync } from "node:fs";
|
|
import { join, relative, resolve } from "node:path";
|
|
import { describe, expect, it } from "@suaveplan/testing/runner";
|
|
import { MACOS_CONTACTS_CODES } from "./error-codes/error-codes.js";
|
|
|
|
const PKG_ROOT = resolve(__dirname, "..");
|
|
const SRC_ROOT = join(PKG_ROOT, "src");
|
|
|
|
function walk(dir: string, out: string[] = []): string[] {
|
|
for (const entry of readdirSync(dir)) {
|
|
const p = join(dir, entry);
|
|
const stat = statSync(p);
|
|
if (stat.isDirectory()) walk(p, out);
|
|
else out.push(p);
|
|
}
|
|
return out;
|
|
}
|
|
|
|
describe("macos-contacts conformance", () => {
|
|
it("every feature index.ts uses explicit named exports", {
|
|
timeout: 5000,
|
|
}, () => {
|
|
const offenders: string[] = [];
|
|
const files = walk(SRC_ROOT).filter(
|
|
(f) =>
|
|
f.endsWith("/index.ts") && relative(SRC_ROOT, f) !== "index.ts"
|
|
);
|
|
expect(files.length).toBeGreaterThan(0);
|
|
for (const file of files) {
|
|
const text = readFileSync(file, "utf-8");
|
|
if (/^\s*export\s+(type\s+)?\*\s+from/m.test(text)) {
|
|
offenders.push(relative(SRC_ROOT, file));
|
|
}
|
|
}
|
|
expect(offenders).toEqual([]);
|
|
});
|
|
|
|
it("every declared subpath export resolves to a real source file", {
|
|
timeout: 5000,
|
|
}, () => {
|
|
const pkg = JSON.parse(
|
|
readFileSync(join(PKG_ROOT, "package.json"), "utf-8")
|
|
) as { exports: Record<string, unknown> };
|
|
const subpaths = Object.keys(pkg.exports).filter(
|
|
(k) => k.startsWith("./") && k !== "./package.json"
|
|
);
|
|
expect(subpaths.length).toBeGreaterThanOrEqual(7);
|
|
for (const subpath of subpaths) {
|
|
if (subpath === ".") continue;
|
|
const featurePath = subpath.replace(/^\.\//, "");
|
|
const srcFile = join(SRC_ROOT, `${featurePath}.ts`);
|
|
expect(() => statSync(srcFile), srcFile).not.toThrow();
|
|
}
|
|
});
|
|
|
|
it("every MACOS_CONTACTS_CODES code is referenced in non-test src", {
|
|
timeout: 5000,
|
|
}, () => {
|
|
const codeNames = Object.keys(MACOS_CONTACTS_CODES);
|
|
const files = walk(SRC_ROOT).filter(
|
|
(f) =>
|
|
f.endsWith(".ts") &&
|
|
!f.endsWith(".test.ts") &&
|
|
!f.endsWith(".spec-conformance.test.ts") &&
|
|
!f.endsWith("error-codes.ts")
|
|
);
|
|
const blob = files.map((f) => readFileSync(f, "utf-8")).join("\n");
|
|
const missing: string[] = [];
|
|
for (const name of codeNames) {
|
|
if (!new RegExp(`\\b${name}\\b`).test(blob)) missing.push(name);
|
|
}
|
|
expect(missing).toEqual([]);
|
|
});
|
|
|
|
it("OTel instrument bundle exposes the eight declared instruments", {
|
|
timeout: 5000,
|
|
}, async () => {
|
|
const mod = await import("./otel/instruments.js");
|
|
mod.resetMacOSContactsInstruments();
|
|
const bundle = mod.getMacOSContactsInstruments();
|
|
const keys = Object.keys(bundle);
|
|
expect(keys.length).toBe(8);
|
|
});
|
|
|
|
it("no test file imports from vitest or bun:test directly", {
|
|
timeout: 5000,
|
|
}, () => {
|
|
const offenders: string[] = [];
|
|
const files = walk(SRC_ROOT).filter((f) => f.endsWith(".test.ts"));
|
|
for (const file of files) {
|
|
const text = readFileSync(file, "utf-8");
|
|
if (/from\s+['"](vitest|bun:test)['"]/.test(text)) {
|
|
offenders.push(relative(SRC_ROOT, file));
|
|
}
|
|
}
|
|
expect(offenders).toEqual([]);
|
|
});
|
|
|
|
it("root barrel exports MACOS_CONTACTS_CODES", { timeout: 5000 }, () => {
|
|
const index = readFileSync(join(SRC_ROOT, "index.ts"), "utf-8");
|
|
expect(index).toMatch(/MACOS_CONTACTS_CODES/);
|
|
});
|
|
});
|