Files
arah2/routing/test/polyline.test.mjs
araharah-executor 9b66f90a4b test(05-01): add failing polyline6 codec vectors (P1-P8)
- hand-derived vectors from the plan's <polyline_vectors> block
- external live-OSRM demo geometry (RESEARCH Finding 1) as ground truth
- P7 pins the truncated-varint refusal law (T-05-02)
2026-10-24 05:00:32 +08:00

134 lines
5.5 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env node
/*
* polyline.test.mjs — polyline6 codec vectors (P1–P8).
* -----------------------------------------------------
* RED first (plan 05-01 task 2): every case fails while
* routing/src/polyline.ts does not exist — the lazy-import pattern
* keeps each case reporting its own failure.
*
* Vectors are computed ground truth (the plan's <polyline_vectors> block,
* derived with the reference algorithm in the planning session), NOT
* guesses:
* P1 zero vector — decode("??") -> [{lat:0,lng:0}]; encode inverts
* P2 KL point vector — encode([{3.1578,101.7117}]) === "oqv_Egt~~`E"
* (note: the string contains a BACKTICK)
* P3 delta accumulation — the 3-point KL vector (deltas 100/100/100/200)
* P4 negative zigzag — the V4 vector (the ~ inversion branch)
* P5 external OSRM vector — live demo-server geometry (KLCC -> KL Sentral,
* probed 2026-10-24; RESEARCH Finding 1): first
* point decodes to {3.157846, 101.711716} (OSRM
* snapped the origin onto the road graph) and
* encode(decode(s)) === s byte-identically
* P6 empty input — decode("") -> []; encode([]) === ""
* P7 malformed refusal — decode("A") / decode("g") THROW (truncated
* varint — never a partial/NaN point, T-05-02)
* P8 round-trip law — encode(decode(s)) === s for EVERY vector here
*
* Run: npm run routing:test (exit 0 = all green)
*/
import { strict as assert } from "node:assert";
import { test } from "./harness.mjs";
// Lazy codec load — missing module => per-case ERR_MODULE_NOT_FOUND (the RED state).
let codecPromise = null;
function loadCodec() {
if (!codecPromise) {
codecPromise = import("../src/polyline.ts");
}
return codecPromise;
}
/* ————— the pinned vectors ————— */
const V_ZERO = "??";
const V_KL_POINT = "oqv_Egt~~`E";
const V_KL_THREE = "oqv_Egt~~`EgEgEgEoK";
const V_NEGATIVE = "~tpzA_pihC_pihCnt}oC";
const V_EXTERNAL =
"ktv_Egu~~`EsAlFaDnGeF`EmGvEmWbSySjOiTfUiOb`@{n@xZ}FhBsGx@cJ?";
const KL_POINT = { lat: 3.1578, lng: 101.7117 };
const KL_THREE_POINTS = [
{ lat: 3.1578, lng: 101.7117 },
{ lat: 3.1579, lng: 101.7118 },
{ lat: 3.158, lng: 101.712 },
];
const NEGATIVE_POINTS = [
{ lat: -1.5, lng: 2.25 },
{ lat: 0.75, lng: -0.125 },
];
/* ————— P1–P8 ————— */
test("P1 zero vector — decode('??') -> [{lat:0,lng:0}]; encode inverts exactly", async () => {
const { decodePolyline6, encodePolyline6 } = await loadCodec();
assert.deepEqual(decodePolyline6(V_ZERO), [{ lat: 0, lng: 0 }]);
assert.equal(encodePolyline6([{ lat: 0, lng: 0 }]), V_ZERO);
});
test("P2 KL point vector — encode([{3.1578,101.7117}]) === 'oqv_Egt~~`E' and decode inverts", async () => {
const { decodePolyline6, encodePolyline6 } = await loadCodec();
assert.equal(encodePolyline6([KL_POINT]), V_KL_POINT);
assert.deepEqual(decodePolyline6(V_KL_POINT), [KL_POINT]);
});
test("P3 delta accumulation — the 3-point KL vector encodes/decodes exactly", async () => {
const { decodePolyline6, encodePolyline6 } = await loadCodec();
assert.equal(encodePolyline6(KL_THREE_POINTS), V_KL_THREE);
assert.deepEqual(decodePolyline6(V_KL_THREE), KL_THREE_POINTS);
});
test("P4 negative zigzag — the V4 vector exercises the ~ inversion branch", async () => {
const { decodePolyline6, encodePolyline6 } = await loadCodec();
assert.equal(encodePolyline6(NEGATIVE_POINTS), V_NEGATIVE);
assert.deepEqual(decodePolyline6(V_NEGATIVE), NEGATIVE_POINTS);
});
test("P5 external OSRM vector — live demo geometry decodes and re-encodes byte-identically", async () => {
const { decodePolyline6, encodePolyline6 } = await loadCodec();
const first = decodePolyline6(V_EXTERNAL)[0];
assert.deepEqual(
first,
{ lat: 3.157846, lng: 101.711716 },
"OSRM snapped the origin onto the road graph — the small offset from 3.1578/101.7117 is expected",
);
assert.equal(
encodePolyline6(decodePolyline6(V_EXTERNAL)),
V_EXTERNAL,
"the external ground truth must round-trip byte-identically (RESEARCH Finding 1)",
);
});
test("P6 empty input — decode('') -> []; encode([]) === ''", async () => {
const { decodePolyline6, encodePolyline6 } = await loadCodec();
assert.deepEqual(decodePolyline6(""), []);
assert.equal(encodePolyline6([]), "");
});
test("P7 malformed refusal — truncated varints THROW, never return partial/NaN points (T-05-02)", async () => {
const { decodePolyline6 } = await loadCodec();
assert.throws(() => decodePolyline6("A"), "a lone 'A' is a truncated coordinate — must throw");
assert.throws(() => decodePolyline6("g"), "a dangling continuation chunk — must throw");
for (const bad of ["A", "g", "oqv_E"]) {
let points = null;
try {
points = decodePolyline6(bad);
} catch {
continue; // throwing is the contract
}
assert.fail(`decode(${JSON.stringify(bad)}) returned ${JSON.stringify(points)} instead of throwing`);
}
});
test("P8 round-trip law — encode(decode(s)) === s for EVERY vector string in this suite", async () => {
const { decodePolyline6, encodePolyline6 } = await loadCodec();
const all = [V_ZERO, V_KL_POINT, V_KL_THREE, V_NEGATIVE, V_EXTERNAL];
for (const s of all) {
assert.equal(
encodePolyline6(decodePolyline6(s)),
s,
`round-trip law violated for ${s.slice(0, 12)}… — the corpus gate (plan 05-02) leans on this`,
);
}
});