test(sim): Phase 1d-tests A — netlist snapshots for every gallery example
Snapshots the full SPICE netlist for every example across all six data/examples-*.ts modules (168 examples total): analog: 30, digital: 38, 100-days: 49, epaper: 7, picow-wifi: 4, circuits: 40. Pipeline: example → exampleToBuildNetlistInput → buildNetlist → strip leading timestamp comment → toMatchSnapshot. Uses the production helper (same one loadExample.ts uses) so any future change to the brand-prefix rule / board filter / analysis picker appears in the snapshot diff automatically. To regenerate after a legitimate model change: npx vitest run -u src/__tests__/examples-netlist-snapshot.test.ts The PR diff of the snapshot file becomes the evidence of which circuits change in response. Reviewer can scan the diff to confirm the change is intended. 168 new sub-tests bring total to 1640 passing (was 1472). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
8bde313a91
commit
a594cbf76d
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,80 @@
|
|||
/**
|
||||
* Netlist snapshot tests (Phase 1d-tests A).
|
||||
*
|
||||
* For every example across ALL `examples-*.ts` modules, build the
|
||||
* SPICE netlist via the production pipeline and snapshot the FULL
|
||||
* netlist string. If a refactor changes how `componentToSpice`,
|
||||
* `NetlistBuilder`, or `storeAdapter` emit cards, the diff lands in
|
||||
* `__snapshots__/examples-netlist-snapshot.test.ts.snap` and a
|
||||
* reviewer sees exactly what changed across every example.
|
||||
*
|
||||
* To intentionally update the snapshots after a legitimate model
|
||||
* change:
|
||||
*
|
||||
* npx vitest run -u src/__tests__/examples-netlist-snapshot.test.ts
|
||||
*
|
||||
* The PR diff of the snapshot file becomes the evidence of which
|
||||
* circuits are affected.
|
||||
*
|
||||
* Test fidelity rule (memory `feedback_tests_import_real_code`):
|
||||
* imports the example arrays directly from the source modules and
|
||||
* uses the same `exampleToBuildNetlistInput` that production
|
||||
* `loadExample.ts` uses. Nothing is duplicated.
|
||||
*/
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { analogExamples } from '../data/examples-analog';
|
||||
import { digitalExamples } from '../data/examples-digital';
|
||||
import { hundredDaysExamples } from '../data/examples-100-days';
|
||||
import { epaperExamples } from '../data/examples-displays-epaper';
|
||||
import { picowWifiExamples } from '../data/examples-picow-wifi';
|
||||
import { circuitExamples } from '../data/examples-circuits';
|
||||
import { exampleToBuildNetlistInput } from '../utils/exampleToBuildNetlistInput';
|
||||
import { buildNetlist } from '../simulation/spice/NetlistBuilder';
|
||||
import type { ExampleProject } from '../data/examples';
|
||||
|
||||
/**
|
||||
* Normalise the netlist before snapshotting:
|
||||
* - strip the leading `* Velxio circuit @ <ISO timestamp>` comment
|
||||
* (timestamp would flake every run)
|
||||
*
|
||||
* Everything else is verbatim — model lines, source ordering, etc.
|
||||
*/
|
||||
function snapshotNetlist(netlist: string): string {
|
||||
return netlist.replace(/^\* Velxio circuit @[^\n]*\n/, '* Velxio circuit\n');
|
||||
}
|
||||
|
||||
function snapshotExample(example: ExampleProject): string {
|
||||
// Some examples have no electrical components (firmware-only). The
|
||||
// builder still produces a minimal netlist with the analysis card +
|
||||
// `.end`; snapshot that for completeness.
|
||||
const input = exampleToBuildNetlistInput(example);
|
||||
const { netlist } = buildNetlist(input);
|
||||
return snapshotNetlist(netlist);
|
||||
}
|
||||
|
||||
interface Bucket {
|
||||
name: string;
|
||||
examples: ExampleProject[];
|
||||
}
|
||||
|
||||
const BUCKETS: Bucket[] = [
|
||||
{ name: 'analog', examples: analogExamples },
|
||||
{ name: 'digital', examples: digitalExamples },
|
||||
{ name: '100-days', examples: hundredDaysExamples },
|
||||
{ name: 'epaper', examples: epaperExamples },
|
||||
{ name: 'picow-wifi', examples: picowWifiExamples },
|
||||
{ name: 'circuits', examples: circuitExamples },
|
||||
];
|
||||
|
||||
for (const bucket of BUCKETS) {
|
||||
describe(`netlist snapshot — ${bucket.name} (${bucket.examples.length} examples)`, () => {
|
||||
it.each(bucket.examples.map((ex) => [ex.id, ex] as const))(
|
||||
'%s',
|
||||
{ timeout: 5_000 },
|
||||
(_id, example) => {
|
||||
const netlist = snapshotExample(example);
|
||||
expect(netlist).toMatchSnapshot();
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
Loading…
Reference in New Issue