#!/usr/bin/env node // // Write the expected-output fixtures for a roster added to // src/transforms/__fixtures__/. // // node scripts/update-fixtures.mjs # only writes what is missing // node scripts/update-fixtures.mjs --force # re-baselines everything // // Drop a new `.ros` in that directory and run this to generate the four // `.{merge,strip,convert,all}.ros` files the test suite compares against. // Read the diff before committing: this records whatever the transforms do // today, so it cannot tell a fix from a regression. // // Existing fixtures are left alone unless --force is given, and that guard is // the point rather than a convenience. The fixtures that came with this repo // were produced by a separate Python implementation and verified by printing // the cards; the test suite is worth something because it checks the transforms // against that independent output. Re-baselining a fixture from the JS replaces // it with the very thing under test, and the comparison becomes a tautology // that passes no matter what the code does. import { readFileSync, readdirSync, existsSync, writeFileSync } from "node:fs"; import { dirname, join } from "node:path"; import { fileURLToPath } from "node:url"; import { JSDOM } from "jsdom"; import { convertChoiceAbilities, defaultConfig, mergeDuplicateUnits, removeLeaderAbilities, } from "../src/transforms/index.js"; const FIXTURES = join( dirname(fileURLToPath(import.meta.url)), "..", "src", "transforms", "__fixtures__", ); const STEPS = { merge: (doc) => mergeDuplicateUnits(doc, defaultConfig), strip: (doc) => removeLeaderAbilities(doc, defaultConfig), convert: (doc) => convertChoiceAbilities(doc, defaultConfig), }; // Chained, in the order the app runs them; see src/transforms/index.js. const PIPELINE = ["merge", "strip", "convert"]; const force = process.argv.includes("--force"); const { window } = new JSDOM(); const inputs = readdirSync(FIXTURES) .filter((name) => name.endsWith(".ros") && name.split(".").length === 2) .map((name) => name.replace(/\.ros$/, "")); let written = 0; let kept = 0; for (const input of inputs) { const xml = readFileSync(join(FIXTURES, `${input}.ros`), "utf8"); const outputs = { ...STEPS, all: null }; for (const label of Object.keys(outputs)) { const path = join(FIXTURES, `${input}.${label}.ros`); if (existsSync(path) && !force) { kept++; continue; } const doc = new window.DOMParser().parseFromString(xml, "text/xml"); if (label === "all") { for (const step of PIPELINE) STEPS[step](doc); } else { STEPS[label](doc); } writeFileSync(path, new window.XMLSerializer().serializeToString(doc), "utf8"); console.log(`wrote ${input}.${label}.ros`); written++; } } console.log(`\n${written} written, ${kept} left alone.`); if (kept > 0 && !force) { console.log("Pass --force to re-baseline the rest, but read the header first."); }