generated from coulomb/repo-seed
Writable mode: write(key, body) stages and commits the file (skipping a no-op so no empty commit is created), returning the page at the new commit sha. The writable profile declares WRITE + VERSION with PER_PAGE granularity. current_rev is the per-path commit sha, so a write — or an external commit to the same path — moves it, driving apply-under-drift. Passes the conformance positive-write probe. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
90 lines
3.3 KiB
Python
90 lines
3.3 KiB
Python
"""Tests for GitShardAdapter write=commit + current_rev drift (SHARD-WP-0012 T2)."""
|
|
|
|
import os
|
|
import subprocess
|
|
|
|
from shard_wiki.adapters import GitShardAdapter, run_conformance
|
|
from shard_wiki.model import Verb
|
|
|
|
_ENV = {
|
|
"GIT_AUTHOR_NAME": "t", "GIT_AUTHOR_EMAIL": "t@t",
|
|
"GIT_COMMITTER_NAME": "t", "GIT_COMMITTER_EMAIL": "t@t",
|
|
"PATH": os.environ.get("PATH", ""),
|
|
}
|
|
|
|
|
|
def _git(repo, *args, capture=False):
|
|
return subprocess.run(
|
|
["git", "-C", str(repo), *args], check=True, capture_output=True, text=True, env=_ENV
|
|
).stdout.strip()
|
|
|
|
|
|
def _repo(tmp_path, files):
|
|
repo = tmp_path / "repo"
|
|
repo.mkdir()
|
|
_git(repo, "init", "--quiet")
|
|
for rel, text in files.items():
|
|
(repo / rel).write_text(text, encoding="utf-8")
|
|
_git(repo, "add", rel)
|
|
_git(repo, "commit", "-m", "seed")
|
|
return repo
|
|
|
|
|
|
def test_writable_profile_declares_write_and_version(tmp_path):
|
|
profile = GitShardAdapter("git", _repo(tmp_path, {"Home.md": "h"}), writable=True).profile()
|
|
assert profile.supports(Verb.WRITE)
|
|
assert profile.supports(Verb.VERSION)
|
|
profile.validate() # PER_PAGE + WRITE is a consistent combination
|
|
|
|
|
|
def test_write_creates_a_commit(tmp_path):
|
|
repo = _repo(tmp_path, {"Home.md": "old"})
|
|
adapter = GitShardAdapter("git", repo, writable=True)
|
|
before = _git(repo, "rev-list", "--count", "HEAD")
|
|
page = adapter.write("Home", "new body")
|
|
after = _git(repo, "rev-list", "--count", "HEAD")
|
|
assert int(after) == int(before) + 1 # one new commit
|
|
assert page.body == "new body"
|
|
assert page.envelope.source_rev == _git(repo, "rev-parse", "HEAD") # page is at the new sha
|
|
|
|
|
|
def test_write_advances_current_rev(tmp_path):
|
|
repo = _repo(tmp_path, {"Home.md": "old"})
|
|
adapter = GitShardAdapter("git", repo, writable=True)
|
|
rev_before = adapter.current_rev("Home")
|
|
adapter.write("Home", "changed")
|
|
assert adapter.current_rev("Home") != rev_before # sha moved → drift detectable
|
|
|
|
|
|
def test_write_new_key_tracks_it(tmp_path):
|
|
repo = _repo(tmp_path, {"Home.md": "h"})
|
|
adapter = GitShardAdapter("git", repo, writable=True)
|
|
adapter.write("docs/New", "fresh page")
|
|
assert "docs/New" in set(adapter.keys())
|
|
assert adapter.read("docs/New").body == "fresh page"
|
|
|
|
|
|
def test_noop_write_creates_no_empty_commit(tmp_path):
|
|
repo = _repo(tmp_path, {"Home.md": "same"})
|
|
adapter = GitShardAdapter("git", repo, writable=True)
|
|
before = _git(repo, "rev-list", "--count", "HEAD")
|
|
adapter.write("Home", "same") # identical body → nothing to commit
|
|
assert _git(repo, "rev-list", "--count", "HEAD") == before
|
|
|
|
|
|
def test_current_rev_reflects_external_commit(tmp_path):
|
|
repo = _repo(tmp_path, {"Home.md": "h"})
|
|
adapter = GitShardAdapter("git", repo, writable=True)
|
|
rev = adapter.current_rev("Home")
|
|
# An out-of-band commit to the same path (another writer) moves the per-path sha.
|
|
(repo / "Home.md").write_text("externally edited", encoding="utf-8")
|
|
_git(repo, "add", "Home.md")
|
|
_git(repo, "commit", "-m", "external")
|
|
assert adapter.current_rev("Home") != rev
|
|
|
|
|
|
def test_conformance_positive_write_probe_passes(tmp_path):
|
|
adapter = GitShardAdapter("git", _repo(tmp_path, {"Home.md": "body"}), writable=True)
|
|
report = run_conformance(adapter)
|
|
assert report.ok, report.diff()
|