"""Helper script for Robot Framework change tracking smoke tests.""" from __future__ import annotations import sys from pathlib import Path # Ensure src is importable when run from workspace root sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) from pydantic import ValidationError from cleveragents.domain.models.core.change import ( ChangeEntry, ChangeOperation, ChangeType, InMemoryInvocationTracker, SpecChangeSet, ToolInvocation, normalize_change_path, ) def test_changetype_alias() -> None: assert ChangeType is ChangeOperation assert ChangeType.CREATE == "create" print("changetype-ok") def test_change_entry_validator() -> None: # CREATE with before_hash should fail try: ChangeEntry( plan_id="p", resource_id="r", tool_name="t", operation=ChangeOperation.CREATE, path="x.py", before_hash="bad", after_hash="ok", ) print("validator-fail: no error raised") sys.exit(1) except (ValidationError, ValueError): pass # Valid CREATE e = ChangeEntry( plan_id="p", resource_id="r", tool_name="t", operation=ChangeOperation.CREATE, path="x.py", after_hash="ok", ) assert e.has_integrity_hashes is True print("validator-ok") def test_sorted_entries() -> None: from datetime import UTC, datetime entries = [ ChangeEntry( plan_id="p", resource_id="res-B", tool_name="t", operation=ChangeOperation.CREATE, path="z.py", after_hash="h", timestamp=datetime(2026, 1, 1, 0, 0, 1, tzinfo=UTC), ), ChangeEntry( plan_id="p", resource_id="res-A", tool_name="t", operation=ChangeOperation.CREATE, path="a.py", after_hash="h", timestamp=datetime(2026, 1, 1, 0, 0, 0, tzinfo=UTC), ), ] cs = SpecChangeSet(plan_id="p", entries=entries) s = cs.sorted_entries() assert s[0].resource_id == "res-A" assert s[1].resource_id == "res-B" print("sorted-ok") def test_invocation_tracker() -> None: tracker = InMemoryInvocationTracker() tracker.track( ToolInvocation( plan_id="p1", tool_name="t1", sequence_number=1, change_ids=["c1"], ) ) tracker.track( ToolInvocation( plan_id="p1", tool_name="t2", sequence_number=0, change_ids=["c2"], ) ) invs = tracker.get_invocations("p1") assert len(invs) == 2 assert invs[0].sequence_number == 0 # sorted changes = tracker.get_changes("p1") assert len(changes) == 2 print("tracker-ok") def test_normalize_path() -> None: result = normalize_change_path( "/home/user/project/src/main.py", "/home/user/project" ) assert result == "src/main.py", f"Got: {result}" print("normalize-ok") if __name__ == "__main__": dispatch = { "changetype": test_changetype_alias, "validator": test_change_entry_validator, "sorted": test_sorted_entries, "tracker": test_invocation_tracker, "normalize": test_normalize_path, } cmd = sys.argv[1] if len(sys.argv) > 1 else "changetype" fn = dispatch.get(cmd) if fn: fn() else: print(f"Unknown command: {cmd}", file=sys.stderr) sys.exit(1)