Skip to content

Commit e177694

Browse files
dmealingclaude
andcommitted
test(runtime-web): restore loadMetaModel browser-bundle coverage
Task 6 (#287 follow-up) had lost this assertion when a prior attempt deleted its own test to silence a Bun.build() race across concurrently-run test files. Restore a dedicated "loadMetaModel is reachable in a browser bundle" test that goes through the shared browserBundle() helper, and memoize the helper by entry path so multiple tests bundling the SAME entry share one real Bun.build() call instead of each triggering a fresh one — that repeated independent build is what raced and broke the full suite. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015NrWUxA6euwvnFcwKxcK6A
1 parent d48211a commit e177694

1 file changed

Lines changed: 43 additions & 14 deletions

File tree

‎client/web/packages/runtime-web/test/browser-bundleable.test.ts‎

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,22 +38,40 @@ const METADATA_CONSTANTS = join(
3838
PKG_ROOT, "..", "..", "..", "..", "server", "typescript", "packages", "metadata", "dist", "constants.js",
3939
);
4040

41+
type BundleResult = { ok: boolean; message: string; code: string };
42+
43+
// Bun's bundler races (a spurious "Unexpected reading file" against an unrelated
44+
// node_modules package) when this file issues more than a handful of independent
45+
// `Bun.build()` calls while the full package suite runs concurrently with other test
46+
// files — this is what broke the suite the first time a 4th build was added here (#287
47+
// follow-up). Memoize by entry path so multiple tests asserting on the SAME entry share
48+
// one real build instead of each triggering a fresh one.
49+
const bundleCache = new Map<string, Promise<BundleResult>>();
50+
4151
/** Bundle `entry` for the browser via Bun's bundler; resolve the failure text and code output. */
42-
async function browserBundle(entry: string): Promise<{ ok: boolean; message: string; code: string }> {
43-
const built = await Bun.build({ entrypoints: [entry], target: "browser", throw: false });
44-
let code = "";
45-
if (built.success && built.outputs.length > 0) {
46-
try {
47-
code = await built.outputs[0]!.text();
48-
} catch {
49-
// Failed to read output; code stays empty
52+
function browserBundle(entry: string): Promise<BundleResult> {
53+
const cached = bundleCache.get(entry);
54+
if (cached) return cached;
55+
56+
const promise = (async (): Promise<BundleResult> => {
57+
const built = await Bun.build({ entrypoints: [entry], target: "browser", throw: false });
58+
let code = "";
59+
if (built.success && built.outputs.length > 0) {
60+
try {
61+
code = await built.outputs[0]!.text();
62+
} catch {
63+
// Failed to read output; code stays empty
64+
}
5065
}
51-
}
52-
return {
53-
ok: built.success,
54-
message: built.logs.map((l) => String(l)).join("\n"),
55-
code,
56-
};
66+
return {
67+
ok: built.success,
68+
message: built.logs.map((l) => String(l)).join("\n"),
69+
code,
70+
};
71+
})();
72+
73+
bundleCache.set(entry, promise);
74+
return promise;
5775
}
5876

5977
describe("#287 — browser bundleability", () => {
@@ -101,4 +119,15 @@ describe("#287 — browser bundleability", () => {
101119
const { ok } = await browserBundle(root);
102120
expect(ok).toBe(false);
103121
});
122+
123+
test("loadMetaModel is reachable in a browser bundle", async () => {
124+
// load-meta-model.ts imports its metamodel constants from
125+
// `@metaobjectsdev/metadata/constants`, not the package root. If that import were ever
126+
// repointed at the root, the root barrel would pull in `MetaDataLoader` ->
127+
// `library-sources.ts` -> `node:url`, and this bundle would fail exactly like #287 did.
128+
const { ok, code } = await browserBundle(DIST_ENTRY);
129+
expect(ok).toBe(true);
130+
expect(code).toContain("loadMetaModel");
131+
expect(code).not.toContain("fileURLToPath");
132+
});
104133
});

0 commit comments

Comments
 (0)