#!/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 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`, ); } });