- synthetic injected datasets only — never the network, never the committed file - F3 pins the 200 m haversine tolerance boundary; F6 the defensive pair skip - F7 the lazy-index source gate (LAW 1); L2 the esbuild inline marker
91 lines
3.6 KiB
JavaScript
91 lines
3.6 KiB
JavaScript
#!/usr/bin/env node
|
||
/*
|
||
* loader-env.test.mjs — the three-environment loader proof (L1–L3).
|
||
* -----------------------------------------------------------------
|
||
* THE phase's top mechanical risk, mirroring search/test/loader-env.test.mjs
|
||
* (Phase 4): the fixture dataset must be reachable identically from
|
||
* (1) the bare-Node corpus runner (plan 05-02), (2) the Vite bundle
|
||
* (plan 05-04), and (3) the wrangler/esbuild bundle family. Workers have no
|
||
* fs, so the dataset MUST be a static build-time import — never a runtime
|
||
* retrieval.
|
||
*
|
||
* L1 bare Node — the seed JSON static-imports with `with { type: "json" }`
|
||
* under Node 24 type-stripping and exposes `pairs`
|
||
* L2 esbuild — the bundler family of BOTH wrangler and Vite INLINES the
|
||
* seed: the bundle text carries the `router.project-osrm.org` marker
|
||
* (the `_source` header survives inlining)
|
||
* L3 the committed EMPTY seed serves null through the whole default path
|
||
* (static import -> lazy index -> route()) — the honest corpus state
|
||
* until plan 05-02 fills it
|
||
*
|
||
* Run: npm run routing:test (exit 0 = all green)
|
||
*/
|
||
import { strict as assert } from "node:assert";
|
||
import { spawnSync } from "node:child_process";
|
||
import { mkdirSync, readFileSync } from "node:fs";
|
||
import path from "node:path";
|
||
import { fileURLToPath } from "node:url";
|
||
import { test } from "./harness.mjs";
|
||
import fixturesSeed from "../src/data/route-fixtures.json" with { type: "json" };
|
||
|
||
const here = path.dirname(fileURLToPath(import.meta.url)); // routing/test
|
||
const routingDir = path.resolve(here, ".."); // routing/
|
||
const repoRoot = path.resolve(routingDir, ".."); // repo root
|
||
const esbuildBin = path.join(repoRoot, "node_modules", ".bin", "esbuild");
|
||
|
||
// Lazy index load — missing module => per-case ERR_MODULE_NOT_FOUND (the RED state).
|
||
let indexPromise = null;
|
||
function loadIndex() {
|
||
if (!indexPromise) {
|
||
indexPromise = import("../src/index.ts");
|
||
}
|
||
return indexPromise;
|
||
}
|
||
|
||
test("L1 bare-Node static JSON import — the seed parses under Node 24 type-stripping", () => {
|
||
assert.ok(Array.isArray(fixturesSeed.pairs), "the seed's pairs array is reachable");
|
||
assert.equal(fixturesSeed.version, 1);
|
||
assert.ok(
|
||
String(fixturesSeed._source).includes("router.project-osrm.org"),
|
||
"the bundle marker rides inside the committed seed",
|
||
);
|
||
});
|
||
|
||
test("L2 esbuild bundle marker — the wrangler/Vite bundler family inlines the seed", () => {
|
||
const outDir = "/tmp/opencode/araharah-routing-bundle";
|
||
mkdirSync(outDir, { recursive: true });
|
||
const outfile = path.join(outDir, "routing-bundle.mjs");
|
||
const bundle = spawnSync(
|
||
esbuildBin,
|
||
[
|
||
path.join(routingDir, "src", "index.ts"),
|
||
"--bundle",
|
||
"--format=esm",
|
||
`--outfile=${outfile}`,
|
||
"--log-level=error",
|
||
],
|
||
{ encoding: "utf8", timeout: 60000 },
|
||
);
|
||
assert.equal(bundle.status, 0, `esbuild bundle failed: ${bundle.stderr || bundle.stdout}`);
|
||
const bundled = readFileSync(outfile, "utf8");
|
||
assert.ok(
|
||
bundled.includes("router.project-osrm.org"),
|
||
"a static JSON import MUST be inlined at build time — a runtime retrieval would be a hard Worker failure",
|
||
);
|
||
});
|
||
|
||
test("L3 the empty committed seed serves null — the honest corpus state until 05-02", async () => {
|
||
const mod = await loadIndex();
|
||
const source = mod.createFixtureRoutingSource();
|
||
assert.equal(source.name, "fixture");
|
||
const result = await source.route({
|
||
origin: { lat: 3.1528, lng: 101.7038 },
|
||
destinationId: "kl-sentral",
|
||
});
|
||
assert.equal(
|
||
result,
|
||
null,
|
||
"the committed empty corpus must parse through the whole path and serve honest null",
|
||
);
|
||
});
|