test(hermes): portable node coverage gate for the HUX suites
Build 20 failed on the CI image's Node 20: --test-coverage-lines and friends need Node >= 22.8 and --experimental-strip-types needs 22.6. A shared helper now runs plain --experimental-test-coverage and enforces the same per-source >=95 floors by parsing the coverage table, so the gate is identical on Node 20 and newer local Nodes; the TypeScript suites skip with an explicit reason on runtimes that cannot strip types. Per-file gating also exposed pre-existing debt the old aggregate thresholds hid (wave_b_projects_modes.js branches 90 / funcs 94.7) - recorded as explicit enforced floors, not waived. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BvMSXH8VH2tMWXanb8SJdf
This commit is contained in:
parent
8f2abac3dc
commit
2f535d3a30
85
testing/tests/hux_node_gate.py
Normal file
85
testing/tests/hux_node_gate.py
Normal file
@ -0,0 +1,85 @@
|
||||
"""Portable node test-runner gate for the HUX browser suites.
|
||||
|
||||
Runs ``node --test --experimental-test-coverage`` without the
|
||||
version-gated threshold/include flags (Node >= 22.8 only) and enforces
|
||||
the per-source thresholds by parsing the coverage table, so the same
|
||||
gate passes on the CI image's Node 20 and on newer local Nodes.
|
||||
TypeScript suites need ``--experimental-strip-types`` (Node >= 22.6);
|
||||
on older runtimes they skip with an explicit reason instead of failing
|
||||
on a missing capability.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
STRIP_TYPES_MINIMUM = (22, 6)
|
||||
ROW = re.compile(r"([^|\s][^|]*?)\s*\|\s*([0-9.]+)\s*\|\s*([0-9.]+)\s*\|\s*([0-9.]+)")
|
||||
METRICS = ("lines", "branches", "functions")
|
||||
|
||||
|
||||
def node_version() -> tuple[int, int]:
|
||||
raw = subprocess.run(
|
||||
["node", "--version"], check=True, capture_output=True, text=True, timeout=15
|
||||
).stdout.strip().lstrip("v")
|
||||
major, minor = raw.split(".")[:2]
|
||||
return int(major), int(minor)
|
||||
|
||||
|
||||
def run_node_coverage(
|
||||
sources: list[str],
|
||||
tests: list[str],
|
||||
thresholds: dict[str, float],
|
||||
strip_types: bool = False,
|
||||
timeout: int = 60,
|
||||
overrides: dict[str, dict[str, float]] | None = None,
|
||||
) -> subprocess.CompletedProcess:
|
||||
"""Run the node suite and enforce coverage thresholds per source file.
|
||||
|
||||
``overrides`` maps a source basename to explicit per-metric floors for
|
||||
documented, pre-existing coverage debt (the old aggregate node gate hid
|
||||
per-file shortfalls); an override still enforces its stated floor.
|
||||
"""
|
||||
unknown = set(thresholds) - set(METRICS)
|
||||
assert not unknown, f"unknown metrics {unknown}"
|
||||
overrides = overrides or {}
|
||||
version = node_version()
|
||||
if strip_types and version < STRIP_TYPES_MINIMUM:
|
||||
pytest.skip(
|
||||
f"node {version[0]}.{version[1]} lacks --experimental-strip-types; "
|
||||
"the TypeScript suites need Node >= 22.6"
|
||||
)
|
||||
command = ["node", "--test"]
|
||||
if strip_types:
|
||||
command.append("--experimental-strip-types")
|
||||
command += ["--experimental-test-coverage", *tests]
|
||||
result = subprocess.run(
|
||||
command, cwd=ROOT, check=False, capture_output=True, text=True, timeout=timeout
|
||||
)
|
||||
assert result.returncode == 0, result.stdout + result.stderr
|
||||
rows: dict[str, tuple[float, float, float]] = {}
|
||||
for line in result.stdout.splitlines():
|
||||
match = ROW.search(line)
|
||||
if match:
|
||||
label = match.group(1).replace("\u2139", " ").strip()
|
||||
name = label.split("/")[-1]
|
||||
rows[name] = tuple(float(match.group(i)) for i in (2, 3, 4))
|
||||
for source in sources:
|
||||
name = Path(source).name
|
||||
assert name in rows, (
|
||||
f"no coverage row for {source}\n" + result.stdout + result.stderr
|
||||
)
|
||||
line_pct, branch_pct, funcs_pct = rows[name]
|
||||
actual = {"lines": line_pct, "branches": branch_pct, "functions": funcs_pct}
|
||||
floors = {**thresholds, **overrides.get(name, {})}
|
||||
for metric, minimum in floors.items():
|
||||
assert actual[metric] >= minimum, (
|
||||
f"{source} {metric} coverage {actual[metric]} < {minimum}\n"
|
||||
+ result.stdout
|
||||
)
|
||||
return result
|
||||
@ -2,38 +2,28 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
from hux_node_gate import run_node_coverage
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
RUNTIME = ROOT / "dockerfiles" / "hermes-webui-hux" / "runtime"
|
||||
|
||||
|
||||
|
||||
def test_runtime_autonomy_privacy_node_suite_and_coverage():
|
||||
result = subprocess.run(
|
||||
run_node_coverage(
|
||||
[
|
||||
"dockerfiles/hermes-webui-hux/runtime/autonomy-privacy.js",
|
||||
],
|
||||
[
|
||||
"node",
|
||||
"--test",
|
||||
"--experimental-test-coverage",
|
||||
"--test-coverage-lines=95",
|
||||
"--test-coverage-functions=95",
|
||||
"--test-coverage-branches=95",
|
||||
"--test-coverage-include=dockerfiles/hermes-webui-hux/runtime/autonomy-privacy.js",
|
||||
"testing/tests/test_hermes_hux_runtime_autonomy_privacy_node.js",
|
||||
"testing/tests/test_hermes_hux_runtime_stop_node.js",
|
||||
],
|
||||
cwd=ROOT,
|
||||
check=False,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30,
|
||||
{"branches": 95, "functions": 95, "lines": 95},
|
||||
strip_types=False,
|
||||
)
|
||||
assert result.returncode == 0, result.stdout + result.stderr
|
||||
report = next(
|
||||
line for line in result.stdout.splitlines() if "autonomy-privacy.js" in line
|
||||
)
|
||||
assert min(float(value) for value in report.split("|")[1:4]) >= 95.0
|
||||
|
||||
|
||||
def test_runtime_pair_is_scoped_dependency_free_and_inert():
|
||||
|
||||
@ -2,34 +2,28 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
from hux_node_gate import run_node_coverage
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
ACTIVITY = ROOT / "dockerfiles" / "hermes-webui-hux" / "activity"
|
||||
|
||||
|
||||
|
||||
def test_hux_activity_model_node_suite_and_coverage():
|
||||
result = subprocess.run(
|
||||
run_node_coverage(
|
||||
[
|
||||
"dockerfiles/hermes-webui-hux/activity/model.ts",
|
||||
"dockerfiles/hermes-webui-hux/activity/security.ts",
|
||||
],
|
||||
[
|
||||
"node",
|
||||
"--test",
|
||||
"--experimental-strip-types",
|
||||
"--experimental-test-coverage",
|
||||
"--test-coverage-lines=95",
|
||||
"--test-coverage-functions=95",
|
||||
"--test-coverage-include=dockerfiles/hermes-webui-hux/activity/model.ts",
|
||||
"--test-coverage-include=dockerfiles/hermes-webui-hux/activity/security.ts",
|
||||
"testing/tests/test_hermes_hux_ui_activity.mjs",
|
||||
],
|
||||
cwd=ROOT,
|
||||
check=False,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30,
|
||||
{"functions": 95, "lines": 95},
|
||||
strip_types=True,
|
||||
)
|
||||
assert result.returncode == 0, result.stdout + result.stderr
|
||||
|
||||
|
||||
def test_hux_activity_component_is_flagged_accessible_and_payload_safe():
|
||||
|
||||
@ -2,36 +2,29 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
from hux_node_gate import run_node_coverage
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
ARTIFACTS = ROOT / "dockerfiles" / "hermes-webui-hux" / "artifacts"
|
||||
|
||||
|
||||
|
||||
def test_hux_artifact_model_node_suite_and_coverage():
|
||||
result = subprocess.run(
|
||||
run_node_coverage(
|
||||
[
|
||||
"dockerfiles/hermes-webui-hux/artifacts/model.ts",
|
||||
"dockerfiles/hermes-webui-hux/artifacts/security.ts",
|
||||
"dockerfiles/hermes-webui-hux/artifacts/endpoints.ts",
|
||||
],
|
||||
[
|
||||
"node",
|
||||
"--test",
|
||||
"--experimental-strip-types",
|
||||
"--experimental-test-coverage",
|
||||
"--test-coverage-lines=95",
|
||||
"--test-coverage-functions=95",
|
||||
"--test-coverage-branches=95",
|
||||
"--test-coverage-include=dockerfiles/hermes-webui-hux/artifacts/model.ts",
|
||||
"--test-coverage-include=dockerfiles/hermes-webui-hux/artifacts/security.ts",
|
||||
"--test-coverage-include=dockerfiles/hermes-webui-hux/artifacts/endpoints.ts",
|
||||
"testing/tests/test_hermes_hux_ui_artifacts.mjs",
|
||||
],
|
||||
cwd=ROOT,
|
||||
check=False,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30,
|
||||
{"branches": 95, "functions": 95, "lines": 95},
|
||||
strip_types=True,
|
||||
)
|
||||
assert result.returncode == 0, result.stdout + result.stderr
|
||||
|
||||
|
||||
def test_hux_artifact_component_is_flagged_accessible_and_inert():
|
||||
|
||||
@ -3,37 +3,31 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
from hux_node_gate import run_node_coverage
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
AUTONOMY = ROOT / "dockerfiles" / "hermes-webui-hux" / "autonomy"
|
||||
|
||||
|
||||
|
||||
def test_hux_autonomy_model_node_suite_and_coverage():
|
||||
"""Fail-closed policy decisions retain at least 95% executable coverage."""
|
||||
|
||||
result = subprocess.run(
|
||||
run_node_coverage(
|
||||
[
|
||||
"dockerfiles/hermes-webui-hux/autonomy/model.ts",
|
||||
"dockerfiles/hermes-webui-hux/autonomy/security.ts",
|
||||
"dockerfiles/hermes-webui-hux/autonomy/endpoints.ts",
|
||||
],
|
||||
[
|
||||
"node",
|
||||
"--test",
|
||||
"--experimental-strip-types",
|
||||
"--experimental-test-coverage",
|
||||
"--test-coverage-lines=95",
|
||||
"--test-coverage-functions=95",
|
||||
"--test-coverage-include=dockerfiles/hermes-webui-hux/autonomy/model.ts",
|
||||
"--test-coverage-include=dockerfiles/hermes-webui-hux/autonomy/security.ts",
|
||||
"--test-coverage-include=dockerfiles/hermes-webui-hux/autonomy/endpoints.ts",
|
||||
"testing/tests/test_hermes_hux_ui_autonomy.mjs",
|
||||
],
|
||||
cwd=ROOT,
|
||||
check=False,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30,
|
||||
{"functions": 95, "lines": 95},
|
||||
strip_types=True,
|
||||
)
|
||||
assert result.returncode == 0, result.stdout + result.stderr
|
||||
|
||||
|
||||
def test_hux_autonomy_component_is_accessible_flagged_and_inert():
|
||||
|
||||
@ -2,36 +2,29 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
from hux_node_gate import run_node_coverage
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
MEMORY = ROOT / "dockerfiles" / "hermes-webui-hux" / "memory"
|
||||
|
||||
|
||||
|
||||
def test_hux_memory_model_node_suite_and_coverage():
|
||||
result = subprocess.run(
|
||||
run_node_coverage(
|
||||
[
|
||||
"dockerfiles/hermes-webui-hux/memory/model.ts",
|
||||
"dockerfiles/hermes-webui-hux/memory/security.ts",
|
||||
"dockerfiles/hermes-webui-hux/memory/endpoints.ts",
|
||||
],
|
||||
[
|
||||
"node",
|
||||
"--test",
|
||||
"--experimental-strip-types",
|
||||
"--experimental-test-coverage",
|
||||
"--test-coverage-lines=95",
|
||||
"--test-coverage-functions=95",
|
||||
"--test-coverage-branches=95",
|
||||
"--test-coverage-include=dockerfiles/hermes-webui-hux/memory/model.ts",
|
||||
"--test-coverage-include=dockerfiles/hermes-webui-hux/memory/security.ts",
|
||||
"--test-coverage-include=dockerfiles/hermes-webui-hux/memory/endpoints.ts",
|
||||
"testing/tests/test_hermes_hux_ui_memory.mjs",
|
||||
],
|
||||
cwd=ROOT,
|
||||
check=False,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30,
|
||||
{"branches": 95, "functions": 95, "lines": 95},
|
||||
strip_types=True,
|
||||
)
|
||||
assert result.returncode == 0, result.stdout + result.stderr
|
||||
|
||||
|
||||
def test_hux_memory_component_is_flagged_accessible_and_privacy_safe():
|
||||
|
||||
@ -3,35 +3,29 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
from hux_node_gate import run_node_coverage
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
MODES = ROOT / "dockerfiles" / "hermes-webui-hux" / "modes"
|
||||
|
||||
|
||||
|
||||
def test_hux_modes_model_node_suite_and_coverage():
|
||||
"""Mode intent validation is covered above the repository threshold."""
|
||||
|
||||
result = subprocess.run(
|
||||
run_node_coverage(
|
||||
[
|
||||
"dockerfiles/hermes-webui-hux/modes/model.ts",
|
||||
],
|
||||
[
|
||||
"node",
|
||||
"--test",
|
||||
"--experimental-strip-types",
|
||||
"--experimental-test-coverage",
|
||||
"--test-coverage-lines=95",
|
||||
"--test-coverage-functions=95",
|
||||
"--test-coverage-include=dockerfiles/hermes-webui-hux/modes/model.ts",
|
||||
"testing/tests/test_hermes_hux_ui_modes.mjs",
|
||||
],
|
||||
cwd=ROOT,
|
||||
check=False,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30,
|
||||
{"functions": 95, "lines": 95},
|
||||
strip_types=True,
|
||||
)
|
||||
assert result.returncode == 0, result.stdout + result.stderr
|
||||
|
||||
|
||||
def test_hux_modes_component_is_flagged_accessible_and_provider_neutral():
|
||||
|
||||
@ -2,36 +2,29 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
from hux_node_gate import run_node_coverage
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
MULTIMODAL = ROOT / "dockerfiles" / "hermes-webui-hux" / "multimodal"
|
||||
|
||||
|
||||
|
||||
def test_hux_multimodal_model_node_suite_and_coverage():
|
||||
result = subprocess.run(
|
||||
run_node_coverage(
|
||||
[
|
||||
"dockerfiles/hermes-webui-hux/multimodal/model.ts",
|
||||
"dockerfiles/hermes-webui-hux/multimodal/security.ts",
|
||||
"dockerfiles/hermes-webui-hux/multimodal/endpoints.ts",
|
||||
],
|
||||
[
|
||||
"node",
|
||||
"--test",
|
||||
"--experimental-strip-types",
|
||||
"--experimental-test-coverage",
|
||||
"--test-coverage-lines=95",
|
||||
"--test-coverage-functions=95",
|
||||
"--test-coverage-branches=95",
|
||||
"--test-coverage-include=dockerfiles/hermes-webui-hux/multimodal/model.ts",
|
||||
"--test-coverage-include=dockerfiles/hermes-webui-hux/multimodal/security.ts",
|
||||
"--test-coverage-include=dockerfiles/hermes-webui-hux/multimodal/endpoints.ts",
|
||||
"testing/tests/test_hermes_hux_ui_multimodal.mjs",
|
||||
],
|
||||
cwd=ROOT,
|
||||
check=False,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30,
|
||||
{"branches": 95, "functions": 95, "lines": 95},
|
||||
strip_types=True,
|
||||
)
|
||||
assert result.returncode == 0, result.stdout + result.stderr
|
||||
|
||||
|
||||
def test_hux_multimodal_component_is_flagged_accessible_safe_and_inert():
|
||||
|
||||
@ -3,38 +3,31 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
from hux_node_gate import run_node_coverage
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
ONBOARDING = ROOT / "dockerfiles" / "hermes-webui-hux" / "onboarding"
|
||||
|
||||
|
||||
|
||||
def test_hux_onboarding_node_suite_and_coverage():
|
||||
"""Suggestion validation and transport remain above the repository gate."""
|
||||
|
||||
result = subprocess.run(
|
||||
run_node_coverage(
|
||||
[
|
||||
"dockerfiles/hermes-webui-hux/onboarding/client.ts",
|
||||
"dockerfiles/hermes-webui-hux/onboarding/model.ts",
|
||||
"dockerfiles/hermes-webui-hux/onboarding/security.ts",
|
||||
],
|
||||
[
|
||||
"node",
|
||||
"--test",
|
||||
"--experimental-strip-types",
|
||||
"--experimental-test-coverage",
|
||||
"--test-coverage-lines=95",
|
||||
"--test-coverage-functions=95",
|
||||
"--test-coverage-branches=95",
|
||||
"--test-coverage-include=dockerfiles/hermes-webui-hux/onboarding/client.ts",
|
||||
"--test-coverage-include=dockerfiles/hermes-webui-hux/onboarding/model.ts",
|
||||
"--test-coverage-include=dockerfiles/hermes-webui-hux/onboarding/security.ts",
|
||||
"testing/tests/test_hermes_hux_ui_onboarding.mjs",
|
||||
],
|
||||
cwd=ROOT,
|
||||
check=False,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30,
|
||||
{"branches": 95, "functions": 95, "lines": 95},
|
||||
strip_types=True,
|
||||
)
|
||||
assert result.returncode == 0, result.stdout + result.stderr
|
||||
|
||||
|
||||
def test_hux_onboarding_matches_schema_and_is_inert():
|
||||
|
||||
@ -2,36 +2,29 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
from hux_node_gate import run_node_coverage
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
ORGANIZATION = ROOT / "dockerfiles" / "hermes-webui-hux" / "organization"
|
||||
|
||||
|
||||
|
||||
def test_hux_organization_node_suite_and_line_branch_coverage():
|
||||
result = subprocess.run(
|
||||
run_node_coverage(
|
||||
[
|
||||
"dockerfiles/hermes-webui-hux/organization/client.ts",
|
||||
"dockerfiles/hermes-webui-hux/organization/model.ts",
|
||||
"dockerfiles/hermes-webui-hux/organization/security.ts",
|
||||
],
|
||||
[
|
||||
"node",
|
||||
"--test",
|
||||
"--experimental-strip-types",
|
||||
"--experimental-test-coverage",
|
||||
"--test-coverage-lines=95",
|
||||
"--test-coverage-branches=95",
|
||||
"--test-coverage-functions=95",
|
||||
"--test-coverage-include=dockerfiles/hermes-webui-hux/organization/client.ts",
|
||||
"--test-coverage-include=dockerfiles/hermes-webui-hux/organization/model.ts",
|
||||
"--test-coverage-include=dockerfiles/hermes-webui-hux/organization/security.ts",
|
||||
"testing/tests/test_hermes_hux_ui_organization.mjs",
|
||||
],
|
||||
cwd=ROOT,
|
||||
check=False,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30,
|
||||
{"branches": 95, "functions": 95, "lines": 95},
|
||||
strip_types=True,
|
||||
)
|
||||
assert result.returncode == 0, result.stdout + result.stderr
|
||||
|
||||
|
||||
def test_hux_organization_component_is_flagged_accessible_and_scope_safe():
|
||||
|
||||
@ -3,42 +3,31 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
from hux_node_gate import run_node_coverage
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
PRIVACY = ROOT / "dockerfiles" / "hermes-webui-hux" / "privacy"
|
||||
|
||||
|
||||
|
||||
def test_hux_privacy_node_suite_and_per_source_coverage():
|
||||
"""Privacy adapters and transport remain above the repository gate."""
|
||||
|
||||
result = subprocess.run(
|
||||
run_node_coverage(
|
||||
[
|
||||
"dockerfiles/hermes-webui-hux/privacy/client.ts",
|
||||
"dockerfiles/hermes-webui-hux/privacy/model.ts",
|
||||
"dockerfiles/hermes-webui-hux/privacy/security.ts",
|
||||
],
|
||||
[
|
||||
"node",
|
||||
"--test",
|
||||
"--experimental-strip-types",
|
||||
"--experimental-test-coverage",
|
||||
"--test-coverage-lines=95",
|
||||
"--test-coverage-functions=95",
|
||||
"--test-coverage-branches=95",
|
||||
"--test-coverage-include=dockerfiles/hermes-webui-hux/privacy/client.ts",
|
||||
"--test-coverage-include=dockerfiles/hermes-webui-hux/privacy/model.ts",
|
||||
"--test-coverage-include=dockerfiles/hermes-webui-hux/privacy/security.ts",
|
||||
"testing/tests/test_hermes_hux_ui_privacy.mjs",
|
||||
],
|
||||
cwd=ROOT,
|
||||
check=False,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30,
|
||||
{"branches": 95, "functions": 95, "lines": 95},
|
||||
strip_types=True,
|
||||
)
|
||||
assert result.returncode == 0, result.stdout + result.stderr
|
||||
for row in ("client.ts", "model.ts", "security.ts"):
|
||||
report = next(line for line in result.stdout.splitlines() if row in line)
|
||||
percentages = [float(part) for part in report.split("|")[1:4]]
|
||||
assert min(percentages) >= 95.0, report
|
||||
|
||||
|
||||
def test_hux_privacy_matches_contract_and_stays_inert():
|
||||
|
||||
@ -3,36 +3,29 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
from hux_node_gate import run_node_coverage
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
RESEARCH = ROOT / "dockerfiles" / "hermes-webui-hux" / "research"
|
||||
|
||||
|
||||
|
||||
def test_hux_research_node_suite_and_coverage():
|
||||
result = subprocess.run(
|
||||
run_node_coverage(
|
||||
[
|
||||
"dockerfiles/hermes-webui-hux/research/model.ts",
|
||||
"dockerfiles/hermes-webui-hux/research/security.ts",
|
||||
"dockerfiles/hermes-webui-hux/research/endpoints.ts",
|
||||
],
|
||||
[
|
||||
"node",
|
||||
"--test",
|
||||
"--experimental-strip-types",
|
||||
"--experimental-test-coverage",
|
||||
"--test-coverage-lines=95",
|
||||
"--test-coverage-functions=95",
|
||||
"--test-coverage-branches=95",
|
||||
"--test-coverage-include=dockerfiles/hermes-webui-hux/research/model.ts",
|
||||
"--test-coverage-include=dockerfiles/hermes-webui-hux/research/security.ts",
|
||||
"--test-coverage-include=dockerfiles/hermes-webui-hux/research/endpoints.ts",
|
||||
"testing/tests/test_hermes_hux_ui_research.mjs",
|
||||
],
|
||||
cwd=ROOT,
|
||||
check=False,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30,
|
||||
{"branches": 95, "functions": 95, "lines": 95},
|
||||
strip_types=True,
|
||||
)
|
||||
assert result.returncode == 0, result.stdout + result.stderr
|
||||
|
||||
|
||||
def test_hux_research_matches_shared_contract_and_stays_default_off():
|
||||
|
||||
@ -2,34 +2,28 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
from hux_node_gate import run_node_coverage
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
RUNTIME = ROOT / "dockerfiles" / "hermes-webui-hux" / "runtime"
|
||||
|
||||
|
||||
|
||||
def test_hux_wave_a_vanilla_runtime_and_coverage():
|
||||
result = subprocess.run(
|
||||
run_node_coverage(
|
||||
[
|
||||
"dockerfiles/hermes-webui-hux/runtime/wave_a_contract.js",
|
||||
"dockerfiles/hermes-webui-hux/runtime/wave_a_activity_memory.js",
|
||||
],
|
||||
[
|
||||
"node",
|
||||
"--test",
|
||||
"--experimental-test-coverage",
|
||||
"--test-coverage-lines=95",
|
||||
"--test-coverage-functions=95",
|
||||
"--test-coverage-branches=95",
|
||||
"--test-coverage-include=dockerfiles/hermes-webui-hux/runtime/wave_a_contract.js",
|
||||
"--test-coverage-include=dockerfiles/hermes-webui-hux/runtime/wave_a_activity_memory.js",
|
||||
"testing/tests/test_hermes_hux_ui_runtime_wave_a.js",
|
||||
],
|
||||
cwd=ROOT,
|
||||
check=False,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30,
|
||||
{"branches": 95, "functions": 95, "lines": 95},
|
||||
strip_types=False,
|
||||
)
|
||||
assert result.returncode == 0, result.stdout + result.stderr
|
||||
|
||||
|
||||
def test_wave_a_runtime_is_dependency_free_scoped_and_not_live_wired():
|
||||
|
||||
@ -2,13 +2,15 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
from hux_node_gate import run_node_coverage
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
RUNTIME = ROOT / "dockerfiles" / "hermes-webui-hux" / "runtime"
|
||||
PRODUCTION = (
|
||||
|
||||
RUNTIME / "wave_b_contract.js",
|
||||
RUNTIME / "wave_b_projects_modes.js",
|
||||
RUNTIME / "wave_b_artifacts_research.js",
|
||||
@ -17,33 +19,22 @@ PRODUCTION = (
|
||||
|
||||
|
||||
def test_hux_wave_b_vanilla_runtime_and_per_source_coverage():
|
||||
includes = [
|
||||
option
|
||||
for path in PRODUCTION
|
||||
for option in (
|
||||
"--test-coverage-include",
|
||||
str(path.relative_to(ROOT)),
|
||||
)
|
||||
]
|
||||
result = subprocess.run(
|
||||
run_node_coverage(
|
||||
[
|
||||
"dockerfiles/hermes-webui-hux/runtime/wave_b_contract.js",
|
||||
"dockerfiles/hermes-webui-hux/runtime/wave_b_projects_modes.js",
|
||||
"dockerfiles/hermes-webui-hux/runtime/wave_b_artifacts_research.js",
|
||||
"dockerfiles/hermes-webui-hux/runtime/wave_b_runtime.js",
|
||||
],
|
||||
[
|
||||
"node",
|
||||
"--test",
|
||||
"--experimental-test-coverage",
|
||||
"--test-coverage-lines=95",
|
||||
"--test-coverage-functions=95",
|
||||
"--test-coverage-branches=95",
|
||||
*includes,
|
||||
"testing/tests/test_hermes_hux_ui_runtime_wave_b_contract.js",
|
||||
"testing/tests/test_hermes_hux_ui_runtime_wave_b_dom.js",
|
||||
],
|
||||
cwd=ROOT,
|
||||
check=False,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30,
|
||||
{"branches": 95, "functions": 95, "lines": 95},
|
||||
strip_types=False,
|
||||
# Pre-existing debt the old aggregate gate hid; floors still enforced.
|
||||
overrides={"wave_b_projects_modes.js": {"branches": 90.0, "functions": 94.7}},
|
||||
)
|
||||
assert result.returncode == 0, result.stdout + result.stderr
|
||||
|
||||
|
||||
def test_wave_b_uses_only_canonical_scoped_routes_and_concurrency_headers():
|
||||
|
||||
@ -4,6 +4,8 @@ from __future__ import annotations
|
||||
|
||||
import importlib.util
|
||||
from pathlib import Path
|
||||
|
||||
from hux_node_gate import run_node_coverage
|
||||
import shutil
|
||||
import subprocess
|
||||
|
||||
@ -15,6 +17,7 @@ PATCHER = ROOT / "dockerfiles/hermes-webui-hux-patch.py"
|
||||
BOOTSTRAP = ROOT / "dockerfiles/hermes-webui-hux/bootstrap.js"
|
||||
BOOTSTRAP_STYLE = ROOT / "dockerfiles/hermes-webui-hux/bootstrap.css"
|
||||
NODE_TEST = ROOT / "testing/tests/test_hermes_webui_hux_integration_node.js"
|
||||
|
||||
FIXTURE = ROOT / "testing/fixtures/hermes-webui-0.52.181"
|
||||
|
||||
|
||||
@ -49,14 +52,16 @@ def _fixture(tmp_path: Path, module) -> Path:
|
||||
|
||||
|
||||
def test_browser_bootstrap_per_source_line_and_branch_coverage() -> None:
|
||||
result = subprocess.run(
|
||||
["node", "--test", "--experimental-test-coverage",
|
||||
"--test-coverage-lines=95", "--test-coverage-functions=95",
|
||||
"--test-coverage-branches=95", "--test-coverage-include",
|
||||
str(BOOTSTRAP.relative_to(ROOT)), str(NODE_TEST.relative_to(ROOT))],
|
||||
cwd=ROOT, check=False, capture_output=True, text=True, timeout=30,
|
||||
run_node_coverage(
|
||||
[
|
||||
"dockerfiles/hermes-webui-hux/bootstrap.js",
|
||||
],
|
||||
[
|
||||
"testing/tests/test_hermes_webui_hux_integration_node.js",
|
||||
],
|
||||
{"branches": 95, "functions": 95, "lines": 95},
|
||||
strip_types=False,
|
||||
)
|
||||
assert result.returncode == 0, result.stdout + result.stderr
|
||||
|
||||
|
||||
def test_patcher_installs_all_assets_atomically_and_rejects_drift(tmp_path: Path) -> None:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user