40 lines
2.7 KiB
JavaScript
40 lines
2.7 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* check-facet-shape — the facet gate's in-page source reader, tested headlessly on both engines' shapes.
|
|
* Imports the SAME WALK string check:facet-changes-map injects (internal/lib/facet-walk.mjs), so a copy cannot
|
|
* drift from what ships. No browser. Negative-tested by upg100: without the { geojson } unwrap it is 4/5.
|
|
* EXIT 0 pass · 1 fail
|
|
*/
|
|
import { WALK } from './lib/facet-walk.mjs'
|
|
|
|
// ── SHAPE TEST (headless, no browser) ────────────────────────────────────────────────────────────
|
|
// ★ NEGATIVE-TESTS __srcFeatures AGAINST BOTH ENGINE SHAPES, in sr's check-pin-selection style.
|
|
// ⚠ NOT `--self-test`: that already means "run the browser gate with the bug put back, it MUST
|
|
// fail". This one never opens a browser, so it can run anywhere and in gates:pre.
|
|
// It evaluates the helper OUT OF THE WALK STRING ITSELF, so the thing tested is the thing injected
|
|
// into the page — a copy pasted here would pass while the shipped helper rotted.
|
|
const FC = { type: 'FeatureCollection', features: [{ type: 'Feature', properties: { slug: 'a' } },
|
|
{ type: 'Feature', properties: { slug: 'b' } }] }
|
|
const srcFeatures = new Function(`${WALK}\nreturn __srcFeatures`)()
|
|
const mapWith = (src) => ({ getSource: (id) => (id === 'rd-bubbles' ? src : null) })
|
|
const cases = [
|
|
['mapbox shape (_data = FeatureCollection)', () => srcFeatures(mapWith({ _data: FC }), 'rd-bubbles'), 2],
|
|
['maplibre shape (_data = { geojson })', () => srcFeatures(mapWith({ _data: { geojson: FC } }), 'rd-bubbles'), 2],
|
|
['public fallback (no _data, serialize())', () => srcFeatures(mapWith({ serialize: () => ({ data: FC }) }), 'rd-bubbles'), 2],
|
|
// A REMOTE SOURCE MUST NOT READ AS EMPTY. null means "could not measure"; 0 would mean "the map
|
|
// drew nothing", which is the finding this gate exists to report.
|
|
['remote (_data = { url }) -> null, not 0', () => srcFeatures(mapWith({ _data: { url: 'https://x.invalid/a.json' } }), 'rd-bubbles'), null],
|
|
['absent source -> null', () => srcFeatures(mapWith(null), 'rd-bubbles'), null],
|
|
]
|
|
let ok = 0
|
|
for (const [name, run, want] of cases) {
|
|
const got = run()
|
|
const n = got === null || got === undefined ? null : got.length
|
|
const pass = n === want
|
|
console.log(` ${pass ? '✓' : '✗'} ${name} -> ${n === null ? 'null' : n + ' feature(s)'}`)
|
|
if (pass) ok++
|
|
}
|
|
console.log(ok === cases.length
|
|
? `FACET-SHAPE-TEST: PASS — ${ok}/${cases.length}, both engine shapes measured`
|
|
: `FACET-SHAPE-TEST: FAIL — ${ok}/${cases.length}`)
|
|
process.exit(ok === cases.length ? 0 : 1)
|