88 lines
3.9 KiB
Python
88 lines
3.9 KiB
Python
from __future__ import annotations
|
|
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parents[1]
|
|
|
|
|
|
def _run_node(script: str) -> str:
|
|
"""Execute a short Node.js script and return stdout."""
|
|
completed = subprocess.run(
|
|
["node", "-e", script],
|
|
cwd=REPO_ROOT,
|
|
capture_output=True,
|
|
text=True,
|
|
encoding="utf-8",
|
|
check=True,
|
|
)
|
|
return completed.stdout.strip()
|
|
|
|
|
|
def test_metric_presenter_applies_thresholds_and_noise_direction() -> None:
|
|
"""MetricPresenter should centralize thresholds and inverse noise semantics."""
|
|
metric_js = (REPO_ROOT / "webapp" / "static" / "js" / "metric_presenter.js").as_posix()
|
|
script = f"""
|
|
const fs = require("fs");
|
|
const vm = require("vm");
|
|
const code = fs.readFileSync("{metric_js}", "utf8");
|
|
const sandbox = {{ window: {{}}, console }};
|
|
vm.runInNewContext(code, sandbox);
|
|
const p = sandbox.window.MetricPresenter;
|
|
const result = {{
|
|
faith085: p.scoreClass("faithfulness", 0.85),
|
|
faith070: p.scoreClass("faithfulness", 0.70),
|
|
faith064: p.scoreClass("faithfulness", 0.64),
|
|
noise010: p.scoreClass("noise_sensitivity", 0.10),
|
|
noise030: p.scoreClass("noise_sensitivity", 0.30),
|
|
noise050: p.scoreClass("noise_sensitivity", 0.50),
|
|
desc: p.describeMetric("faithfulness"),
|
|
noiseDesc: p.describeMetric("noise_sensitivity"),
|
|
noiseBin: p.binColor("noise_sensitivity", 0.0),
|
|
faithBin: p.binColor("faithfulness", 0.8),
|
|
lowerBetterNoise: p.isLowerBetter("noise_sensitivity"),
|
|
lowerBetterFaith: p.isLowerBetter("faithfulness"),
|
|
upHigher: p.deltaInfo("faithfulness", 0.80, 0.60),
|
|
downHigher: p.deltaInfo("faithfulness", 0.60, 0.80),
|
|
noiseImproved: p.deltaInfo("noise_sensitivity", 0.10, 0.30),
|
|
noiseWorse: p.deltaInfo("noise_sensitivity", 0.30, 0.10),
|
|
noBaseline: p.deltaInfo("faithfulness", 0.80, null)
|
|
}};
|
|
console.log(JSON.stringify(result));
|
|
"""
|
|
output = _run_node(script)
|
|
assert '"faith085":"good"' in output
|
|
assert '"faith070":"warn"' in output
|
|
assert '"faith064":"bad"' in output
|
|
assert '"noise010":"good"' in output
|
|
assert '"noise030":"warn"' in output
|
|
assert '"noise050":"bad"' in output
|
|
assert '"desc":"' in output
|
|
assert '"noiseDesc":"' in output
|
|
assert '"noiseBin":"#16a34a"' in output
|
|
assert '"faithBin":"#16a34a"' in output
|
|
assert '"lowerBetterNoise":true' in output
|
|
assert '"lowerBetterFaith":false' in output
|
|
# higher-better: rising value is an improvement (green ▲); falling is a regression (red ▼)
|
|
assert '"upHigher":{"hasData":true,"delta":0.2,"improved":true,"arrow":"▲","magnitude":"0.20","cls":"delta-good"}' in output
|
|
assert '"downHigher":{"hasData":true,"delta":-0.2,"improved":false,"arrow":"▼","magnitude":"0.20","cls":"delta-bad"}' in output
|
|
# noise_sensitivity (lower-better): falling value is an improvement (green ▼)
|
|
assert '"noiseImproved":{"hasData":true,"delta":-0.2,"improved":true,"arrow":"▼","magnitude":"0.20","cls":"delta-good"}' in output
|
|
assert '"noiseWorse":{"hasData":true,"delta":0.2,"improved":false,"arrow":"▲","magnitude":"0.20","cls":"delta-bad"}' in output
|
|
assert '"noBaseline":{"hasData":false' in output
|
|
|
|
|
|
def test_report_and_index_load_metric_presenter_helper() -> None:
|
|
"""The report page should use the shared helper for card descriptions and colors."""
|
|
index_html = (REPO_ROOT / "webapp" / "static" / "index.html").read_text(encoding="utf-8")
|
|
report_js = (REPO_ROOT / "webapp" / "static" / "js" / "report.js").read_text(encoding="utf-8")
|
|
app_js = (REPO_ROOT / "webapp" / "static" / "js" / "app.js").read_text(encoding="utf-8")
|
|
|
|
assert "js/metric_presenter.js" in index_html
|
|
assert "MetricPresenter.describeMetric" in report_js
|
|
assert "MetricPresenter.scoreClass" in app_js
|
|
# history comparison table uses the direction-aware delta helper
|
|
assert "MetricPresenter.deltaInfo" in report_js
|
|
assert "history-table" in report_js
|