"""Tests for the adapter conformance suite (SHARD-WP-0007 T4).""" from collections.abc import Iterable import pytest from shard_wiki.adapters import ( ConformanceError, FolderAdapter, ShardAdapter, assert_conformant, run_conformance, ) from shard_wiki.model import CapabilityProfile, Identity, Page from shard_wiki.provenance import ProvenanceEnvelope def test_folder_adapter_is_conformant(tmp_path): (tmp_path / "Home.md").write_text("# Home", encoding="utf-8") report = assert_conformant(FolderAdapter("shardA", tmp_path)) assert report.ok assert report.diff() == "conformant" class _LyingReadAdapter(ShardAdapter): """Claims READ but read() is broken — must fail conformance.""" def __init__(self, profile: CapabilityProfile) -> None: self._profile = profile @property def shard_id(self) -> str: return "liar" def profile(self) -> CapabilityProfile: return self._profile def keys(self) -> Iterable[str]: return ["Home"] def read(self, key: str) -> Page: # Returns a page attributed to the WRONG shard — a lie about its own content. return Page(Identity("someone-else", key), "x", ProvenanceEnvelope(source_shard="x")) def test_lying_read_adapter_fails_with_precise_diff(tmp_path): good = FolderAdapter("shardA", tmp_path).profile() # a valid read-only profile liar = _LyingReadAdapter(good) report = run_conformance(liar) assert not report.ok assert "read-round-trips" in report.diff() with pytest.raises(ConformanceError, match="read-round-trips"): assert_conformant(liar) class _DishonestWriteAdapter(FolderAdapter): """Declares no WRITE (inherits read-only folder profile) but write() silently succeeds.""" def write(self, key: str, body: str) -> Page: # noqa: ARG002 return self.read(next(iter(self.keys()))) def test_dishonest_absence_fails(tmp_path): (tmp_path / "Home.md").write_text("x", encoding="utf-8") report = run_conformance(_DishonestWriteAdapter("shardA", tmp_path)) assert not report.ok assert "honest-absence:write" in report.diff()