Files
govoplan/tests/test_devkit_coverage.py
T
zemion 2ffdb23f69
Dependency Audit / dependency-audit (push) Successful in 1m45s
Deployment Installer / deployment-installer (push) Successful in 6s
Security Audit / security-audit (push) Successful in 11m30s
feat(devkit): add resumable workspace automation and UI review tooling
Verified with the coordinated workspace changes by devkit full run
2026-09-08T225814-186389-0000-3e3ed7cd (all seven phases passed).
This shared UI pass does not mark the individual module reviews complete.
2026-09-09 02:03:17 +02:00

340 lines
13 KiB
Python
Executable File

"""Coverage inventory is explicit intent, never execution or guessed completion."""
import json
from pathlib import Path
import re
import shutil
import sys
from unittest.mock import patch
import pytest
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT / "tools/devkit"))
from govoplan_devkit.catalog import build_coverage, build_stages, module_ui_stages # noqa: E402
from govoplan_devkit.coverage import canonical_invocations # noqa: E402
from govoplan_devkit.package_tests import ( # noqa: E402
CORE_COMPONENT_SUITES,
declared_tests,
read_package,
)
from govoplan_devkit.workspace import Project, Repository # noqa: E402
@pytest.fixture
def fixture(tmp_path):
core = Repository("govoplan-core", tmp_path / "govoplan-core", ("core",))
meta = Repository("govoplan", tmp_path / "govoplan", ("meta",))
module = Repository("govoplan-example", tmp_path / "govoplan-example", ("example",))
for repo in (core, meta, module):
(repo.path / "webui/scripts").mkdir(parents=True)
(repo.path / "webui/tests").mkdir()
scripts = {
"test:components": "node scripts/run-component-tests.mjs",
**{
f"test:{name}": f"node scripts/run-component-tests.mjs {name}"
for name in CORE_COMPONENT_SUITES
},
}
(core.path / "webui/package.json").write_text(json.dumps({"scripts": scripts}))
(core.path / "webui/scripts/run-component-tests.mjs").write_text("// fixture")
(module.path / "webui/package.json").write_text(
json.dumps(
{
"scripts": {
"test:safe": "node --test tests/source.test.mjs",
"test:compound": "tsc && node test.js",
"test:bad-quote": "node 'broken",
}
}
)
)
(module.path / "webui/tests/source.test.mjs").write_text("// fixture")
script = meta.path / "tools/checks/check-focused.sh"
script.parent.mkdir(parents=True)
phase_metadata = ROOT / "tools/checks/focused-phases.json"
shutil.copyfile(phase_metadata, script.with_name("focused-phases.json"))
bodies = {
"core-ui": 'cd "$ROOT/webui"\n"$NPM" run test:components -- layout-primitives page-layout data-grid-actions mail-components\n',
"module-ui": 'cd "$WORKSPACE_ROOT/govoplan-example/webui"\n"$NPM" run test:compound\n',
}
script.write_text(
"\n".join(
f"focused_phase_{phase['id'].replace('-', '_')}() {{\n# devkit-phase: {phase['id']} begin\n"
+ bodies.get(phase["id"], 'cd "$ROOT"\n')
+ f"# devkit-phase: {phase['id']} end\n}}\n"
for phase in json.loads(phase_metadata.read_text())["phases"]
)
)
project = Project("Fixture", (meta, core, module), {})
with (
patch("govoplan_devkit.workspace.load_project", return_value=project),
patch("govoplan_devkit.coverage.load_project", return_value=project),
):
yield tmp_path, core, module, project
def rows(coverage, repo="govoplan-core"):
return {row["name"]: row for row in coverage["suites"] if row["repo"] == repo}
def test_core_aliases_are_explicitly_excluded_in_quick_and_covered_by_one_ui_stage(
fixture,
):
root, _, _, _ = fixture
quick = rows(build_coverage(root, "quick", [], False))
ui = rows(build_coverage(root, "ui", [], False))
for suite in CORE_COMPONENT_SUITES:
assert quick["test:" + suite]["disposition"] == "excluded"
assert "quick" in quick["test:" + suite]["reason"]
assert ui["test:" + suite]["disposition"] == "covered_elsewhere"
assert ui["test:" + suite]["covering_stage"] == "core.component-batch"
assert ui["test:components"]["covered_components"] == list(CORE_COMPONENT_SUITES)
def test_full_reports_only_four_of_sixteen_components_and_exact_shell_suite(fixture):
root, _, _, _ = fixture
result = build_coverage(root, "full", ["example"], False)
core = rows(result)
aliases = [core["test:" + suite] for suite in CORE_COMPONENT_SUITES]
assert sum(item["disposition"] == "covered_elsewhere" for item in aliases) == 4
assert sum(item["disposition"] == "excluded" for item in aliases) == 12
assert len(core["test:components"]["covered_components"]) == 4
assert "4/16" in core["test:components"]["reason"]
module = rows(result, "govoplan-example")
assert module["test:compound"]["disposition"] == "planned"
assert module["test:safe"]["disposition"] == "excluded"
assert result["stages"] == [
"focused." + phase["id"]
for phase in json.loads(
(ROOT / "tools/checks/focused-phases.json").read_text()
)["phases"]
]
assert core["test:components"]["covering_stage"] == "focused.core-ui"
assert module["test:compound"]["covering_stage"] == "focused.module-ui"
def test_prebuilt_plan_avoids_replanning(fixture):
root, _, _, _ = fixture
stages = build_stages(root, "quick", [], False)
with patch(
"govoplan_devkit.catalog.build_stages",
side_effect=AssertionError("must not replan"),
):
result = build_coverage(root, "quick", [], False, stages=stages)
assert rows(result, "govoplan-example")["test:safe"]["disposition"] == "planned"
assert sum(result["counts"].values()) == result["suite_count"]
assert all(item["reason"] for item in result["suites"])
def test_missing_or_spoofed_phase_stage_does_not_grant_component_coverage(fixture):
root, _, _, _ = fixture
stages = build_stages(root, "full", [], False)
without_core = [item for item in stages if item["id"] != "focused.core-ui"]
result = build_coverage(root, "full", [], False, stages=without_core)
assert rows(result)["test:components"]["covered_components"] == []
assert (
rows(result, "govoplan-example")["test:compound"]["covering_stage"]
== "focused.module-ui"
)
next(item for item in stages if item["id"] == "focused.core-ui")["argv"] = ["true"]
spoofed = build_coverage(root, "full", [], False, stages=stages)
assert rows(spoofed)["test:components"]["covered_components"] == []
@pytest.mark.parametrize("wrapper", ["heredoc", "function", "conditional"])
def test_lookalike_phase_wrappers_outside_top_level_do_not_grant_coverage(
fixture, wrapper
):
root, core, _, project = fixture
meta = next(repo.path for repo in project.repositories if repo.name == "govoplan")
path = meta / "tools/checks/check-focused.sh"
fake = 'focused_phase_core_ui() {\n# devkit-phase: core-ui begin\ncd "$ROOT/webui"\n"$NPM" run test:spoof\n# devkit-phase: core-ui end\n}\n'
prefix = {
"heredoc": "cat <<'BODY'\n" + fake + "BODY\n",
"function": "unused() {\n" + fake + "}\n",
"conditional": "if false; then\n" + fake + "fi\n",
}[wrapper]
path.write_text(prefix + path.read_text())
result = canonical_invocations(root, meta, core.path)
assert result["notes"] == []
assert [item["name"] for item in result["npm"]] == [
"test:components",
"test:compound",
]
@pytest.mark.parametrize("damage", ["missing", "duplicate", "bad-end"])
def test_invalid_marked_phase_bodies_do_not_infer_coverage(fixture, damage):
root, core, _, project = fixture
meta = next(repo.path for repo in project.repositories if repo.name == "govoplan")
path = meta / "tools/checks/check-focused.sh"
text = path.read_text()
if damage == "missing":
text = text.replace("focused_phase_core_ui()", "unregistered_core_ui()")
elif damage == "duplicate":
text += text
else:
text = text.replace(
"# devkit-phase: core-ui end", "# devkit-phase: another end"
)
path.write_text(text)
result = canonical_invocations(root, meta, core.path)
assert result["npm"] == [] and result["node"] == []
assert "no phase coverage inferred" in result["notes"][0]
@pytest.mark.parametrize(
"repo_name,name,command",
[
("govoplan-example", "test:components", "node scripts/run-component-tests.mjs"),
(
"govoplan-core",
"test:dialog-focus",
"node scripts/run-component-tests.mjs dialog-focus && npm run dev",
),
(
"govoplan-core",
"test:unrecognized",
"node scripts/run-component-tests.mjs dialog-focus",
),
],
)
def test_component_alias_exemption_is_exact_and_core_only(
tmp_path, repo_name, name, command
):
repo = Repository(repo_name, tmp_path / repo_name)
package = repo.path / "webui/package.json"
package.parent.mkdir(parents=True)
package.write_text(json.dumps({"scripts": {name: command}}))
declared = declared_tests(repo, package)
assert declared[0]["component_suite"] is None
assert declared[0]["_argv"] is None
assert module_ui_stages(repo, reason="fixture") == []
@pytest.mark.parametrize(
"body",
[
"[]",
"null",
'{"scripts":[]}',
'{"scripts":{"test:bad":42}}',
'{"scripts":{"test:one":"node a","test:one":"node b"}}',
"[" * 2000 + "]" * 2000,
],
)
def test_malformed_package_metadata_is_a_controlled_error(tmp_path, body):
package = tmp_path / "package.json"
package.write_text(body)
with pytest.raises(ValueError):
read_package(package)
def test_oversize_package_and_symlinked_test_are_not_discovered(tmp_path):
repo = Repository("example", tmp_path)
webui = tmp_path / "webui"
(webui / "tests").mkdir(parents=True)
package = webui / "package.json"
package.write_text(" " * (1024 * 1024 + 1))
with pytest.raises(ValueError):
read_package(package)
package.write_text(
json.dumps({"scripts": {"test:escape": "node tests/escape.mjs"}})
)
(webui / "tests/escape.mjs").symlink_to(tmp_path / "outside.mjs")
(tmp_path / "outside.mjs").write_text("// fixture")
assert module_ui_stages(repo, reason="fixture") == []
def test_unparseable_and_sensitive_commands_do_not_leak_into_coverage(fixture):
root, _, module, _ = fixture
package = module.path / "webui/package.json"
package.write_text(
json.dumps(
{
"scripts": {
"test:secret": "node tests/source.test.mjs --token unknown-private-value",
"test:broken": "node 'unknown-other-secret",
}
}
)
)
result = build_coverage(root, "quick", [], False)
encoded = json.dumps(result)
assert (
"unknown-private-value" not in encoded and "unknown-other-secret" not in encoded
)
assert "_argv" not in encoded and '"command"' not in encoded
assert all(
item["disposition"] == "unsupported"
for item in rows(result, "govoplan-example").values()
)
def test_custom_check_coverage_redacts_separate_token_and_includes_unselected(tmp_path):
project = tmp_path / "project.json"
project.write_text(
json.dumps(
{
"schema_version": 1,
"repositories": [{"name": "app", "path": "."}],
"checks": [
{
"id": "one",
"argv": ["check", "--token", "unknown-private-value"],
},
{"id": "two", "argv": ["true"]},
],
"profiles": {"quick": ["one"]},
}
)
)
result = build_coverage(tmp_path, "quick", [], False, project)
assert "unknown-private-value" not in json.dumps(result)
assert result["counts"]["planned"] == 1 and result["counts"]["excluded"] == 1
def test_canonical_parser_does_not_credit_comments_heredocs_conditionals_or_chains(
tmp_path,
):
meta, core = tmp_path / "govoplan", tmp_path / "govoplan-core"
path = meta / "tools/checks/check-focused.sh"
path.parent.mkdir(parents=True)
path.write_text(
'cd "$ROOT/webui"\n# "$NPM" run test:comment\n"$PYTHON" - <<\'PY\'\n"$NPM" run test:heredoc\nPY\nif false; then\n"$NPM" run test:conditional\nfi\n"$NPM" run test:compound && true\n"$NPM" run test:real\n'
)
result = canonical_invocations(tmp_path, meta, core)
assert [item["name"] for item in result["npm"]] == ["test:real"]
def test_real_canonical_gate_has_four_explicit_component_suites():
result = canonical_invocations(ROOT.parent, ROOT, ROOT.parent / "govoplan-core")
calls = [item for item in result["npm"] if item["name"] == "test:components"]
assert len(calls) == 1
assert calls[0]["args"] == [
"layout-primitives",
"page-layout",
"data-grid-actions",
"mail-components",
]
assert calls[0]["phase"] == "core-ui"
for name, phase in (
("test:module-permutations", "module-builds"),
("test:conformance", "browser"),
):
matching = [item for item in result["npm"] if item["name"] == name]
assert len(matching) == 1 and matching[0]["phase"] == phase
def test_known_core_component_aliases_match_the_owned_runner_registry():
runner = (
ROOT.parent / "govoplan-core/webui/scripts/run-component-tests.mjs"
).read_text()
block = runner.split("export const componentSuites = Object.freeze({", 1)[1].split(
"});", 1
)[0]
assert set(re.findall(r'^ "([a-z0-9-]+)":', block, re.M)) == set(
CORE_COMPONENT_SUITES
)