Skip to content

chore(tests): add chokepoint-baselines fixture + parity guard (§L #8)#3379

Merged
koala73 merged 2 commits into
mainfrom
chore/chokepoint-baselines-fixture
Apr 24, 2026
Merged

chore(tests): add chokepoint-baselines fixture + parity guard (§L #8)#3379
koala73 merged 2 commits into
mainfrom
chore/chokepoint-baselines-fixture

Conversation

@koala73

@koala73 koala73 commented Apr 24, 2026

Copy link
Copy Markdown
Owner

Summary

Closes gap #8 from `docs/internal/energy-atlas-registry-expansion.md` §L — the last missing V5-7 golden fixture. Brings parity with the other seed fixtures already under `tests/fixtures/` (`ember-monthly-sample.csv`, `portwatch-arcgis-sample.json`, …).

Changes

  • New: `tests/fixtures/chokepoint-baselines-sample.json` — snapshot of the expected `buildPayload()` output shape: 7 EIA chokepoints, top-level `source` / `referenceYear` / `chokepoints` array.
  • Extend: `tests/chokepoint-baselines-seed.test.mjs` — add a 3-test fixture-parity `describe` block:
    • Top-level key set matches buildPayload (source, referenceYear, chokepoints array length)
    • Position-by-position entries match (id, relayId, mbd)
    • `updatedAt` ISO-parseability (format only — value is volatile, not byte-matched)

The existing 14 tests on main are untouched.

Why schema-stable fields only (no byte-match on updatedAt)

`updatedAt` is a per-run timestamp. Asserting an exact value would break every run. Parity is scoped to the downstream-consumer contract instead: `CountryDeepDivePanel` transit-chokepoint scoring, the shock RPC `CHOKEPOINT_EXPOSURE` lookup, and chokepoint-flows calibration all depend on the stable fields (id / relayId / mbd / lat / lon) — those are the regression surface this guard protects.

If a future change adds/removes an entry or renames a field, the suite now fails until the fixture is updated alongside.

Test plan

  • `npx tsx --test tests/chokepoint-baselines-seed.test.mjs` — 17/17 pass (14 pre-existing + 3 new)
  • `npm run typecheck` — clean
  • `npm run test:data` — 6697/6697 pass

Context

This was the only remaining item in the plan's §L gap list. With this merged, the plan doc's §N announcement gate is substantively complete except for product decisions that were already resolved (§S=A subdomain-deferred path keeps #9/10/11/12 out of scope).

Closes gap #8 from docs/internal/energy-atlas-registry-expansion.md §L —
the last missing V5-7 golden fixture.

Adds `tests/fixtures/chokepoint-baselines-sample.json` as a snapshot of
the expected buildPayload output shape (7 EIA chokepoints, top-level
source/referenceYear/chokepoints). Extends the existing
`tests/chokepoint-baselines-seed.test.mjs` with a 3-test fixture-parity
describe block that catches any silent drift in:

- Top-level key set (source, referenceYear, chokepoints array length)
- Position-by-position chokepoint entries (id, relayId, mbd)
- updatedAt ISO-parseability (format only — value is volatile)

Doesn't snapshot updatedAt byte-for-byte because it's a per-run
timestamp; parity is scoped to the schema-stable fields downstream
consumers depend on (CountryDeepDivePanel transit-chokepoint scoring,
shock RPC CHOKEPOINT_EXPOSURE lookup, chokepoint-flows calibration).

If a future change adds/removes an entry or renames a field, this
suite fails until the fixture is updated alongside — making schema
drift a deliberate reviewed action rather than a silent shift.

Test plan:
- [x] `npx tsx --test tests/chokepoint-baselines-seed.test.mjs` — 17/17 pass
- [x] `npm run typecheck` — clean
- [x] `npm run test:data` — 6697/6697 pass (+3 new fixture-parity cases)
@vercel

vercel Bot commented Apr 24, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
worldmonitor Ready Ready Preview, Comment Apr 24, 2026 1:21pm

Request Review

@greptile-apps

greptile-apps Bot commented Apr 24, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a golden fixture (tests/fixtures/chokepoint-baselines-sample.json) snapshotting buildPayload() output for the 7 EIA chokepoints and wires a 3-test fixture-parity describe block into the existing seed test file. The new tests verify top-level shape, position-by-position entry identity, and updatedAt ISO-parseability.

  • The position-by-position test checks only id, relayId, and mbd, but the PR description explicitly calls out lat and lon as part of the stable regression surface ("chokepoint-flows calibration all depend on the stable fields (id / relayId / mbd / lat / lon)"). Those two fields are present in the fixture but unguarded by the test — a coordinate drift would pass silently.

Confidence Score: 4/5

Safe to merge after adding lat/lon assertions to the parity test.

One P1 gap: lat/lon are stated as part of the guarded regression surface in the PR description but are absent from the position-by-position test. The fixture carries correct values so the fix is a one-line addition, but the guard as written doesn't fulfill its stated purpose.

tests/chokepoint-baselines-seed.test.mjs — position-by-position test needs lat/lon assertions.

Important Files Changed

Filename Overview
tests/chokepoint-baselines-seed.test.mjs Adds a 3-test fixture-parity describe block; the position-by-position test omits lat/lon assertions despite those fields being named as part of the stable regression surface in the PR description.
tests/fixtures/chokepoint-baselines-sample.json New golden fixture snapshotting buildPayload() output; data values match seed-chokepoint-baselines.mjs exactly, updatedAt placeholder is ISO-8601 formatted.

Sequence Diagram

sequenceDiagram
    participant T as Test Runner
    participant S as seed-chokepoint-baselines.mjs
    participant F as fixtures/chokepoint-baselines-sample.json

    T->>S: import CHOKEPOINTS, buildPayload()
    T->>F: readFileSync (fixture)
    T->>S: buildPayload() → payload
    T->>T: assert fixture.source == payload.source
    T->>T: assert fixture.referenceYear == payload.referenceYear
    T->>T: assert fixture.chokepoints.length == payload.chokepoints.length
    loop for each CHOKEPOINT[i]
        T->>T: assert fix.id == seed.id
        T->>T: assert fix.relayId == seed.relayId
        T->>T: assert fix.mbd == seed.mbd
        note over T: ⚠ lat / lon NOT asserted
    end
    T->>T: assert Date.parse(fixture.updatedAt) is finite
Loading

Reviews (1): Last reviewed commit: "chore(tests): add chokepoint-baselines f..." | Re-trigger Greptile

Comment on lines +122 to +130
assert.ok(Array.isArray(fixture.chokepoints));
assert.equal(fixture.chokepoints.length, payload.chokepoints.length);
});

it('fixture chokepoints match seeded CHOKEPOINTS position-by-position (id, relayId, mbd)', () => {
for (let i = 0; i < CHOKEPOINTS.length; i++) {
const seed = CHOKEPOINTS[i];
const fix = fixture.chokepoints[i];
assert.equal(fix.id, seed.id, `position ${i}: id drift (seed=${seed.id} fixture=${fix.id})`);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 lat/lon omitted from parity guard despite stated regression surface

The PR description explicitly lists lat and lon among the stable fields the guard is meant to protect ("chokepoint-flows calibration all depend on the stable fields (id / relayId / mbd / lat / lon)"), but the position-by-position test only asserts id, relayId, and mbd. A silent drift in either coordinate would go undetected by this suite, even though the fixture already carries the correct values.

Suggested change
assert.ok(Array.isArray(fixture.chokepoints));
assert.equal(fixture.chokepoints.length, payload.chokepoints.length);
});
it('fixture chokepoints match seeded CHOKEPOINTS position-by-position (id, relayId, mbd)', () => {
for (let i = 0; i < CHOKEPOINTS.length; i++) {
const seed = CHOKEPOINTS[i];
const fix = fixture.chokepoints[i];
assert.equal(fix.id, seed.id, `position ${i}: id drift (seed=${seed.id} fixture=${fix.id})`);
it('fixture chokepoints match seeded CHOKEPOINTS position-by-position (id, relayId, mbd, lat, lon)', () => {
for (let i = 0; i < CHOKEPOINTS.length; i++) {
const seed = CHOKEPOINTS[i];
const fix = fixture.chokepoints[i];
assert.equal(fix.id, seed.id, `position ${i}: id drift (seed=${seed.id} fixture=${fix.id})`);
assert.equal(fix.relayId, seed.relayId, `${seed.id}: relayId drift`);
assert.equal(fix.mbd, seed.mbd, `${seed.id}: mbd drift (seed=${seed.mbd} fixture=${fix.mbd})`);
assert.equal(fix.lat, seed.lat, `${seed.id}: lat drift (seed=${seed.lat} fixture=${fix.lat})`);
assert.equal(fix.lon, seed.lon, `${seed.id}: lon drift (seed=${seed.lon} fixture=${fix.lon})`);
}
});

… (review P2)

Codex P2: the parity check validated entries against the CHOKEPOINTS
constant, not buildPayload().chokepoints — so it guarded the source
array rather than the seeded wire contract the fixture claims to
snapshot. If buildPayload ever transforms entries (coerce, reorder,
normalize), the check would miss it.

Also P2: the fixture contained richer fields (name, lat, lon) but the
old assert only checked id/relayId/mbd — most of the fixture realism
was unused and produced false confidence.

Fix:
- Parity loop now iterates payload.chokepoints (seeded output, not
  the raw source array) and asserts id, relayId, name, mbd, lat, lon
  per entry.
- Added an entry-key-set assertion that catches added/removed fields
  between seed and fixture — forces deliberate evolution rather than
  silent drift.

18 tests pass (was 17), typecheck clean.
@koala73
koala73 merged commit 20ad5f5 into main Apr 24, 2026
10 checks passed
@koala73
koala73 deleted the chore/chokepoint-baselines-fixture branch April 24, 2026 15:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant