Files
dc/sas/mocks/test/parity/check.js
T
dc dd2a777438
Build / Build-and-ng-test (pull_request) Successful in 3m54s
Lighthouse Checks / lighthouse (pull_request) Successful in 9m1s
Build / Build-and-test-development (pull_request) Failing after 34m59s
fix(mocks): restore the MPE_X_TEST fixtures and pin the replay's timezone
The parity gate's Cypress job went red after the seed work landed, and the two
causes are the same change seen from the fixture side:

- makedata now carries SAS's demo validation rules for MPE_X_TEST, including the
  HARDREGEX on SOME_CHAR that blocks any text but 'the'/'data'. The excel
  fixtures upload arbitrary values into that table and expect the submission to
  reach the approval screen, so ten excel specs timed out with no Approve
  button. createdemodata drops MPE_X_TEST's rules, which is what editor.cy.ts
  already documents ("MPE_X_TEST stays clean to match the excel fixtures").
- the LABELs the viewer-labels spec asserts went with the hand-written schema.
  createdemodata restores them, because a SAS estate has none and the control
  library should not claim otherwise.

Both are declared as fixture divergences in the parity README and asserted in
createdemodata.test.js, so the next change to either side fails a test instead
of a Cypress run.

Review findings:

- the SYSTIMEZONEOFFSET acceptance depended on the host's zone; both entry
  points pin TZ=UTC before the harness loads, so the accepted list is the same
  everywhere.
- the sas9 mock still published '+0100'; it now answers seconds east of UTC
  like the standard estate.
- the README promised an eight-digit id scan that IDENTIFIER_CLASSES no longer
  had. A DC-prefixed eight-digit class is back (a plain digit class would fire
  on a yyyymmdd date), with a case proving a date is not refused.
2026-11-06 18:41:13 +00:00

80 lines
2.8 KiB
JavaScript

#!/usr/bin/env node
/**
* Replays every recorded golden against a mock estate and prints the
* differences.
*
* node sas/mocks/test/parity/check.js
* node sas/mocks/test/parity/check.js --scenario public/startupservice
* node sas/mocks/test/parity/check.js --advisory # report, exit 0
*
* This is the human-facing half of the same comparison `test/parity-check.test.js`
* runs as a gate; both go through `parity/replay.js`, so neither can drift from
* the other.
*
* Both sides are projections, so the values printed here are the placeholders
* the golden already carries - <LIBREF>, <PATH>, <STAGING_ID> - and a log of a
* failure is as safe to paste as the golden itself.
*/
// The mock derives SYSTIMEZONEOFFSET from the host, and the golden carries the
// estate's own offset: pin the zone so the accepted difference is the same on
// every machine, not only on the UTC container the suite usually runs in.
process.env.TZ = 'UTC'
const fs = require('fs')
const path = require('path')
const { seededEstate, runService } = require('../harness')
const { replay } = require('./replay')
function arg(name, fallback) {
const index = process.argv.indexOf('--' + name)
if (index < 0) return fallback
const next = process.argv[index + 1]
return next && next.indexOf('--') !== 0 ? next : true
}
try {
const only = arg('scenario', null)
const advisory = arg('advisory', false) === true
const scenarios = JSON.parse(
fs.readFileSync(path.join(__dirname, 'scenarios.json'), 'utf8')
).scenarios.filter(function (scenario) {
return !only || scenario.id === only || scenario.service === only
})
if (!scenarios.length) throw new Error('no scenario matched ' + only)
// the golden is recorded against a stock estate (makedata only), so the mock
// side is built the same way - fixtures would add datasets the golden never saw
const estate = seededEstate({ demo: false })
let failed = 0
for (const result of replay(estate, runService, scenarios)) {
const id = result.scenario.service + '/' + result.scenario.id
if (!result.golden) {
console.log('SKIP ' + id + ' - no golden')
continue
}
if (result.unexpected.length || result.stale.length) {
console.log(
'DIFF ' + id + ' - ' + result.unexpected.length +
' unaccepted, ' + result.stale.length + ' stale acceptance(s)'
)
for (const difference of result.unexpected.slice(0, 40)) {
console.log(' ' + difference)
}
for (const stale of result.stale) {
console.log(' ' + stale + ': accepted, but no longer differs')
}
failed++
continue
}
console.log(
'ok ' + id + ' (' + result.accepted.length + ' accepted difference(s))'
)
}
if (failed && !advisory) process.exitCode = 1
} catch (err) {
console.error(err.message)
process.exitCode = 1
}