#!/usr/bin/env node 'use strict'; // SHADES — Lane C — headless runner for the weather suite. // // node web/world/js/tests/run-node.mjs // // The same suite Lane A's selftest.html runs, but with no browser and no server, // so tuning a storm curve is a one-second loop. Exits non-zero on failure. import { readFileSync, readdirSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; import { dirname, join } from 'node:path'; import { runWeatherSuite } from './weather.selftest.js'; const here = dirname(fileURLToPath(import.meta.url)); const stormDir = join(here, '..', '..', 'data', 'storms'); const storms = {}; for (const f of readdirSync(stormDir).filter((f) => f.endsWith('.json')).sort()) { storms[f.replace(/\.json$/, '')] = JSON.parse(readFileSync(join(stormDir, f), 'utf8')); } const r = runWeatherSuite(storms); for (const res of r.results) { console.log(res.ok ? ` ok ${res.name}` : ` FAIL ${res.name}\n ${res.err}`); } console.log('\n metrics (Lane B: tune cloth rho against these):'); for (const [k, v] of Object.entries(r.metrics)) console.log(` ${k.padEnd(32)} ${v}`); console.log(`\n ${r.pass} passed, ${r.fail} failed\n`); process.exit(r.fail ? 1 : 0);