generated from coulomb/repo-seed
Files-first catalog (one JSON per pattern, id = source-key). Single idempotent upsert path: added / unchanged / updated (status-only, no bump) / versioned (content change bumps semver + archives prior to <id>.history.jsonl). Dedup is structural on pattern id. 5 new tests; suite 52/52 green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
87 lines
2.7 KiB
Python
87 lines
2.7 KiB
Python
"""Versioned Pattern Catalog tests (T02): round-trip, dedup, idempotent upsert."""
|
|
|
|
import os
|
|
import sys
|
|
|
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
|
|
from session_memory.curate.catalog import ( # noqa: E402
|
|
ADDED,
|
|
UNCHANGED,
|
|
UPDATED,
|
|
VERSIONED,
|
|
Catalog,
|
|
)
|
|
from session_memory.curate.schema import ( # noqa: E402
|
|
Provenance,
|
|
Resolution,
|
|
Scope,
|
|
SolutionPattern,
|
|
)
|
|
|
|
|
|
def _pattern(src="success:clean_pass:outcome", problem="ran tests, clean finish"):
|
|
return SolutionPattern(
|
|
id=SolutionPattern.make_id(src),
|
|
name="Run tests before declaring success",
|
|
version="1.0.0",
|
|
polarity="success",
|
|
problem=problem,
|
|
resolutions=[Resolution(summary="run the suite")],
|
|
scope=Scope(flavors=["claude", "grok"]),
|
|
provenance=Provenance(source_key=src, evidence={"frequency": 18}),
|
|
)
|
|
|
|
|
|
def test_add_then_load_round_trips(tmp_path):
|
|
cat = Catalog(str(tmp_path))
|
|
assert cat.upsert(_pattern()) == ADDED
|
|
loaded = cat.load(SolutionPattern.make_id("success:clean_pass:outcome"))
|
|
assert loaded is not None
|
|
assert loaded.problem == "ran tests, clean finish"
|
|
assert loaded.created_at and loaded.updated_at
|
|
assert [p.id for p in cat.list()] == [loaded.id]
|
|
|
|
|
|
def test_resave_identical_is_noop(tmp_path):
|
|
cat = Catalog(str(tmp_path))
|
|
cat.upsert(_pattern())
|
|
assert cat.upsert(_pattern()) == UNCHANGED
|
|
# version not bumped, no history written
|
|
assert cat.load(_pattern().id).version == "1.0.0"
|
|
assert cat.history(_pattern().id) == []
|
|
|
|
|
|
def test_dedup_on_source_key(tmp_path):
|
|
cat = Catalog(str(tmp_path))
|
|
cat.upsert(_pattern())
|
|
cat.upsert(_pattern()) # same source key -> same id -> one file
|
|
assert len(cat.list()) == 1
|
|
|
|
|
|
def test_content_change_bumps_version_and_archives(tmp_path):
|
|
cat = Catalog(str(tmp_path))
|
|
cat.upsert(_pattern())
|
|
assert cat.upsert(_pattern(problem="now with more nuance")) == VERSIONED
|
|
current = cat.load(_pattern().id)
|
|
assert current.version == "1.0.1"
|
|
assert current.problem == "now with more nuance"
|
|
hist = cat.history(_pattern().id)
|
|
assert len(hist) == 1
|
|
assert hist[0]["version"] == "1.0.0"
|
|
assert hist[0]["status"] == "superseded"
|
|
|
|
|
|
def test_status_only_change_updates_without_bump(tmp_path):
|
|
cat = Catalog(str(tmp_path))
|
|
cat.upsert(_pattern())
|
|
p = _pattern()
|
|
p.status = "approved"
|
|
p.distribution_ready = True
|
|
assert cat.upsert(p) == UPDATED
|
|
current = cat.load(p.id)
|
|
assert current.status == "approved"
|
|
assert current.distribution_ready is True
|
|
assert current.version == "1.0.0" # metadata change, no bump
|
|
assert cat.history(p.id) == []
|