diff --git a/Makefile b/Makefile index 207384a..702467c 100644 --- a/Makefile +++ b/Makefile @@ -66,7 +66,7 @@ bench-check: ## Type-check benchmark code without running it fi .PHONY: check -check: format-check lint test bench-check ## Run all checks (format-check, lint, test, bench-check) +check: format-check lint test bench-check viewer-test ## Run all checks (format-check, lint, test, bench-check, viewer-test) .PHONY: clean clean: ## Remove build output @@ -99,6 +99,14 @@ export-fixtures: ## Regenerate plan JSON for every tools/exporter/examples/*.sce examples: export-fixtures ## Regenerate fixtures from scenarios and run them through plan-runner against their oracles. @cargo test -p plan-runner --test examples +.PHONY: viewer-test +viewer-test: ## Check the plan viewer's JS engine against every fixture oracle (needs Node) + @if ! command -v node >/dev/null 2>&1; then \ + echo "node not found. Skipping plan viewer engine check."; \ + else \ + node tools/plan-viewer/test.js; \ + fi + VIEWER_PORT ?= 8000 .PHONY: viewer diff --git a/tools/plan-viewer/index.html b/tools/plan-viewer/index.html index 3965e01..6ccbab0 100644 Binary files a/tools/plan-viewer/index.html and b/tools/plan-viewer/index.html differ diff --git a/tools/plan-viewer/test.js b/tools/plan-viewer/test.js new file mode 100644 index 0000000..4dc3dd1 --- /dev/null +++ b/tools/plan-viewer/test.js @@ -0,0 +1,87 @@ +#!/usr/bin/env node +// Parity check for the plan viewer's JavaScript engine. +// +// Extracts the engine script block from index.html and runs every fixture +// in crates/plan-runner/fixtures/ through it, requiring the result to match +// the fixture's expected_bindings oracle, exactly as the Rust runner does. +// Also checks the provenance helpers: every output row of every node must +// have at least one contributing row in each of its inputs. +// +// The Rust crates remain the correctness oracle; this test only catches the +// viewer drifting away from them. + +"use strict"; + +const fs = require("fs"); +const path = require("path"); +const vm = require("vm"); + +const html = fs.readFileSync(path.join(__dirname, "index.html"), "utf8"); +const match = html.match(/