generated from coulomb/repo-seed
test: harden suite with error-path contracts + coverage floor (98%)
Adds tests/test_error_paths.py covering real failure contracts (red-link single() KeyError, unknown/unattached-shard apply_overlay, kernel.delete missing, conformance survives a broken profile, Placement str). Adds a [tool.coverage.report] fail_under=90 floor (engages on pytest --cov, not bare pytest). 76 tests, 98% coverage, pyflakes clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -36,6 +36,11 @@ pythonpath = ["src"]
|
||||
branch = true
|
||||
source = ["shard_wiki"]
|
||||
|
||||
[tool.coverage.report]
|
||||
show_missing = true
|
||||
# Quality floor for `pytest --cov` / `coverage report` (not forced on a bare `pytest` run).
|
||||
fail_under = 90
|
||||
|
||||
[tool.ruff]
|
||||
src = ["src", "tests"]
|
||||
target-version = "py311"
|
||||
|
||||
76
tests/test_error_paths.py
Normal file
76
tests/test_error_paths.py
Normal file
@@ -0,0 +1,76 @@
|
||||
"""Error-path / contract tests across modules (keeps the suite honest about failure behaviour)."""
|
||||
|
||||
from collections.abc import Iterable
|
||||
|
||||
import pytest
|
||||
|
||||
from shard_wiki import InformationSpace
|
||||
from shard_wiki.adapters import FolderAdapter, ShardAdapter, run_conformance
|
||||
from shard_wiki.engine import EngineKernel
|
||||
from shard_wiki.model import CapabilityProfile, Identity, Page, Placement
|
||||
from shard_wiki.provenance import ProvenanceEnvelope
|
||||
from shard_wiki.union import ResolutionKind, UnionGraph
|
||||
|
||||
|
||||
def _folder(tmp_path, name, files, writable=False):
|
||||
root = tmp_path / name
|
||||
root.mkdir(parents=True, exist_ok=True)
|
||||
for rel, text in files.items():
|
||||
(root / rel).write_text(text, encoding="utf-8")
|
||||
return FolderAdapter(name, root, writable=writable)
|
||||
|
||||
|
||||
def test_resolution_single_on_red_link_raises():
|
||||
u = UnionGraph("s")
|
||||
res = u.resolve("ghost")
|
||||
assert res.kind is ResolutionKind.RED_LINK
|
||||
with pytest.raises(KeyError):
|
||||
res.single()
|
||||
|
||||
|
||||
def test_apply_unknown_overlay_raises(tmp_path):
|
||||
space = InformationSpace("t")
|
||||
space.attach(_folder(tmp_path, "w", {"Home.md": "x"}, writable=True))
|
||||
with pytest.raises(KeyError):
|
||||
space.apply_overlay("does-not-exist")
|
||||
|
||||
|
||||
def test_apply_overlay_for_unattached_shard_raises(tmp_path):
|
||||
space = InformationSpace("t")
|
||||
space.attach(_folder(tmp_path, "w", {"Home.md": "x"}, writable=True))
|
||||
# draft an overlay whose target shard is not attached -> apply can't find an adapter
|
||||
ov = space.overlays.draft(Identity("ghost", "X"), "body", base_rev=None)
|
||||
with pytest.raises(KeyError):
|
||||
space.apply_overlay(ov.overlay_id)
|
||||
|
||||
|
||||
def test_kernel_delete_missing_raises():
|
||||
with pytest.raises(KeyError):
|
||||
EngineKernel("eng").delete("nope")
|
||||
|
||||
|
||||
def test_placement_str():
|
||||
assert str(Placement("shardA", "sub/Page")) == "shardA/sub/Page"
|
||||
|
||||
|
||||
class _BrokenProfileAdapter(ShardAdapter):
|
||||
"""profile() raises — the conformance battery must report failure, not crash."""
|
||||
|
||||
@property
|
||||
def shard_id(self) -> str:
|
||||
return "broken"
|
||||
|
||||
def profile(self) -> CapabilityProfile:
|
||||
raise RuntimeError("profile blew up")
|
||||
|
||||
def keys(self) -> Iterable[str]:
|
||||
return []
|
||||
|
||||
def read(self, key: str) -> Page:
|
||||
return Page(Identity("broken", key), "x", ProvenanceEnvelope(source_shard="broken"))
|
||||
|
||||
|
||||
def test_conformance_survives_a_broken_profile():
|
||||
report = run_conformance(_BrokenProfileAdapter())
|
||||
assert not report.ok
|
||||
assert any(c.name == "profile-validates" and not c.ok for c in report.checks)
|
||||
Reference in New Issue
Block a user