"""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)