manifest.test.js
2.9 kB · javascript · 76 lines
1import { expect, test } from "bun:test";23const manifest = await Bun.file(new URL("../../bridge/manifest.json", import.meta.url)).json();4const units = (await Bun.file(new URL("../../bridge/units.txt", import.meta.url)).text())5 .split("\n")6 .map((line) => line.trim())7 .filter(Boolean);8const pkg = await Bun.file(new URL("./package.json", import.meta.url)).json();9const kinds = new Map(manifest.types.map((t) => [t.path, t.cross.kind]));1011function parent(path) {12 const at = path.lastIndexOf("::");13 return at < 0 ? "" : path.slice(0, at);14}1516function relative(unit, path) {17 return unit === "all" ? path : path.slice(unit.length + 2);18}1920function walk(mod, path) {21 let node = mod;22 for (const seg of path.split("::").filter(Boolean)) {23 if (node === undefined || node === null) return undefined;24 node = node[seg];25 }26 return node;27}2829function holds(unit, path) {30 return unit === "all" || path.split("::")[0] === unit;31}3233function check(mod, unit, f) {34 const kind = f.owner ? kinds.get(f.owner) : undefined;35 if (kind === "class") {36 const cls = walk(mod, relative(unit, f.owner));37 if (typeof cls !== "function") return false;38 if (f.self_kind === null && f.name === "new") return true;39 if (f.self_kind === null) return typeof cls[f.name] === "function";40 return typeof cls.prototype[f.name] === "function";41 }42 if (kind === "plain" || kind === "enum") {43 const holder = walk(mod, relative(unit, f.owner));44 return typeof holder === "function" && typeof holder[f.name] === "function";45 }46 return typeof walk(mod, relative(unit, f.path)) === "function";47}4849for (const unit of units) {50 test(`${unit} exports every ok name`, async () => {51 expect(pkg.exports[unit === "all" ? "." : `./${unit}`]).toBeDefined();52 const mod = await import(`./${unit}.js`);53 const bytes = await Bun.file(new URL(`./pkg/${unit}/mrlyjs_${unit}_bg.wasm`, import.meta.url)).arrayBuffer();54 mod.initSync({ module: bytes });55 expect(typeof mod.Rng).toBe("function");56 const missing = [];57 const names = new Set();58 for (const f of manifest.functions) {59 if (f.cross.status !== "ok" || !holds(unit, f.module)) continue;60 names.add(f.path);61 if (!check(mod, unit, f)) missing.push(f.path);62 }63 for (const c of manifest.consts) {64 if (c.cross.status !== "ok" || !holds(unit, c.path)) continue;65 names.add(c.path);66 if (typeof walk(mod, relative(unit, c.path)) !== "function") missing.push(c.path);67 }68 for (const t of manifest.types) {69 if (t.cross.kind !== "class" || !holds(unit, t.path)) continue;70 names.add(t.path);71 if (typeof walk(mod, relative(unit, t.path)) !== "function") missing.push(t.path);72 }73 expect(missing).toEqual([]);74 console.log(`${unit}: ${names.size} names`);75 });76}