139 lines
3.5 KiB
Python
139 lines
3.5 KiB
Python
"""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)
|