From c6578c05fe9a9e30572e57812b6ea14a004226ea Mon Sep 17 00:00:00 2001 From: Rbanh Date: Wed, 18 Feb 2026 20:42:56 -0500 Subject: [PATCH] Add compile performance budget regression test --- tests/perf-budget.test.js | 61 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 tests/perf-budget.test.js diff --git a/tests/perf-budget.test.js b/tests/perf-budget.test.js new file mode 100644 index 0000000..23db968 --- /dev/null +++ b/tests/perf-budget.test.js @@ -0,0 +1,61 @@ +import test from "node:test"; +import assert from "node:assert/strict"; +import { performance } from "node:perf_hooks"; +import { compile } from "../src/compile.js"; + +function createLargeModel(instanceCount = 220) { + const instances = []; + const nets = []; + + for (let i = 0; i < instanceCount; i += 1) { + const idx = i + 1; + instances.push({ + ref: `R${idx}`, + part: "resistor", + properties: { value: `${(idx % 100) + 1}k` }, + placement: { x: null, y: null, rotation: 0, locked: false } + }); + } + + for (let i = 0; i < instanceCount - 1; i += 1) { + const idx = i + 1; + nets.push({ + name: `SIG_${idx}`, + class: "signal", + nodes: [ + { ref: `R${idx}`, pin: "2" }, + { ref: `R${idx + 1}`, pin: "1" } + ] + }); + } + + nets.push({ + name: "GND", + class: "ground", + nodes: [ + { ref: "R1", pin: "1" }, + { ref: `R${instanceCount}`, pin: "2" } + ] + }); + + return { + meta: { title: "Perf chain" }, + symbols: {}, + instances, + nets, + constraints: {}, + annotations: [] + }; +} + +test("compile remains under baseline perf budget for large synthetic model", () => { + const model = createLargeModel(); + const started = performance.now(); + const result = compile(model); + const elapsedMs = performance.now() - started; + + assert.equal(result.ok, true); + assert.equal(typeof result.layout_metrics.crossings, "number"); + assert.equal(typeof result.layout_metrics.overlap_edges, "number"); + assert.ok(elapsedMs < 5_000, `compile exceeded baseline budget: ${elapsedMs.toFixed(1)}ms`); +});