Applied 236 return type annotations to functions with no return values across 100+ files (core modules, tests, scripts, simulations). Added Phase 4 to python_style_refactor track for remaining 597 items (untyped params, vars, and functions with return values). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
161 lines
5.9 KiB
Python
161 lines
5.9 KiB
Python
import pytest
|
|
from datetime import datetime, timezone, timedelta
|
|
|
|
# Import necessary classes from models.py
|
|
from models import Metadata, TrackState, Ticket
|
|
|
|
# --- Pytest Tests ---
|
|
|
|
def test_track_state_instantiation() -> None:
|
|
"""Test creating a TrackState object."""
|
|
now = datetime.now(timezone.utc)
|
|
metadata = Metadata(
|
|
id="track-123",
|
|
name="Initial Setup",
|
|
status="in_progress",
|
|
created_at=now - timedelta(days=1),
|
|
updated_at=now,
|
|
)
|
|
discussion = [
|
|
{"role": "user", "content": "Hello", "ts": now - timedelta(hours=1)},
|
|
{"role": "assistant", "content": "Hi there!", "ts": now - timedelta(hours=2)},
|
|
]
|
|
# Update Ticket instantiation to match models.py fields (description, assigned_to)
|
|
tasks = [
|
|
Ticket(id="task-a", description="Design UI", status="todo", assigned_to="dev1"),
|
|
Ticket(id="task-b", description="Implement Backend", status="todo", assigned_to="dev2"),
|
|
]
|
|
track_state = TrackState(
|
|
metadata=metadata,
|
|
discussion=discussion,
|
|
tasks=tasks,
|
|
)
|
|
assert track_state.metadata.id == "track-123"
|
|
assert len(track_state.discussion) == 2
|
|
assert len(track_state.tasks) == 2
|
|
assert isinstance(track_state.tasks[0], Ticket)
|
|
assert track_state.tasks[0].description == "Design UI"
|
|
assert track_state.tasks[0].assigned_to == "dev1"
|
|
|
|
def test_track_state_to_dict() -> None:
|
|
"""Test the to_dict() method for serialization."""
|
|
now = datetime.now(timezone.utc)
|
|
metadata = Metadata(
|
|
id="track-456",
|
|
name="Refinement Phase",
|
|
status="completed",
|
|
created_at=now - timedelta(days=5),
|
|
updated_at=now - timedelta(days=2),
|
|
)
|
|
discussion = [
|
|
{"role": "user", "content": "Need changes", "ts": now - timedelta(hours=3)},
|
|
{"role": "assistant", "content": "Understood.", "ts": now - timedelta(hours=4)},
|
|
]
|
|
# Update Ticket instantiation
|
|
tasks = [
|
|
Ticket(id="task-c", description="Add feature X", status="in_progress", assigned_to="dev3"),
|
|
]
|
|
track_state = TrackState(
|
|
metadata=metadata,
|
|
discussion=discussion,
|
|
tasks=tasks,
|
|
)
|
|
track_dict = track_state.to_dict()
|
|
assert track_dict["metadata"]["id"] == "track-456"
|
|
assert track_dict["metadata"]["created_at"] == metadata.created_at.isoformat()
|
|
assert track_dict["metadata"]["updated_at"] == metadata.updated_at.isoformat()
|
|
assert len(track_dict["discussion"]) == 2
|
|
assert track_dict["discussion"][0]["ts"] == discussion[0]["ts"].isoformat()
|
|
assert len(track_dict["tasks"]) == 1
|
|
# Use the Ticket's to_dict method for serialization
|
|
assert track_dict["tasks"][0]["id"] == "task-c"
|
|
assert track_dict["tasks"][0]["description"] == "Add feature X"
|
|
assert track_dict["tasks"][0]["assigned_to"] == "dev3"
|
|
|
|
def test_track_state_from_dict() -> None:
|
|
"""Test the from_dict() class method for deserialization."""
|
|
now = datetime.now(timezone.utc)
|
|
track_dict_data = {
|
|
"metadata": {
|
|
"id": "track-789",
|
|
"name": "Final Review",
|
|
"status": "pending",
|
|
"created_at": (now - timedelta(days=10)).isoformat(),
|
|
"updated_at": (now - timedelta(days=9)).isoformat(),
|
|
},
|
|
"discussion": [
|
|
{"role": "user", "content": "Review complete.", "ts": (now - timedelta(hours=5)).isoformat()},
|
|
],
|
|
"tasks": [
|
|
# Use fields from models.py Ticket definition for deserialization
|
|
{"id": "task-d", "description": "Deploy", "status": "completed", "assigned_to": "ops1"},
|
|
],
|
|
}
|
|
track_state = TrackState.from_dict(track_dict_data)
|
|
assert isinstance(track_state, TrackState)
|
|
assert track_state.metadata.id == "track-789"
|
|
assert isinstance(track_state.metadata.created_at, datetime)
|
|
assert track_state.metadata.created_at.isoformat() == track_dict_data["metadata"]["created_at"]
|
|
assert len(track_state.discussion) == 1
|
|
assert isinstance(track_state.discussion[0]["ts"], datetime)
|
|
assert track_state.discussion[0]["ts"].isoformat() == track_dict_data["discussion"][0]["ts"]
|
|
assert len(track_state.tasks) == 1
|
|
assert isinstance(track_state.tasks[0], Ticket)
|
|
assert track_state.tasks[0].id == "task-d"
|
|
assert track_state.tasks[0].description == "Deploy"
|
|
assert track_state.tasks[0].assigned_to == "ops1"
|
|
# Test case for empty lists and missing keys for robustness
|
|
|
|
def test_track_state_from_dict_empty_and_missing() -> None:
|
|
"""Test from_dict with empty lists and missing optional keys."""
|
|
track_dict_data = {
|
|
"metadata": {
|
|
"id": "track-empty",
|
|
"name": "Empty State",
|
|
# created_at, updated_at, status are optional in from_dict logic
|
|
},
|
|
"discussion": [], # Empty discussion list
|
|
"tasks": [], # Empty tasks list
|
|
}
|
|
track_state = TrackState.from_dict(track_dict_data)
|
|
assert isinstance(track_state, TrackState)
|
|
assert track_state.metadata.id == "track-empty"
|
|
assert track_state.metadata.name == "Empty State"
|
|
assert track_state.metadata.created_at is None
|
|
assert track_state.metadata.updated_at is None
|
|
assert track_state.metadata.status is None
|
|
assert len(track_state.discussion) == 0
|
|
assert len(track_state.tasks) == 0
|
|
# Test case for to_dict with None values or missing optional data
|
|
|
|
def test_track_state_to_dict_with_none() -> None:
|
|
"""Test to_dict with None values in optional fields."""
|
|
now = datetime.now(timezone.utc)
|
|
metadata = Metadata(
|
|
id="track-none",
|
|
name="None Test",
|
|
status=None, # None status
|
|
created_at=now,
|
|
updated_at=None, # None updated_at
|
|
)
|
|
discussion = [
|
|
{"role": "system", "content": "Info", "ts": None}, # None timestamp
|
|
]
|
|
# Update Ticket instantiation
|
|
tasks = [
|
|
Ticket(id="task-none", description="Task None", status="pending", assigned_to="anon"),
|
|
]
|
|
track_state = TrackState(
|
|
metadata=metadata,
|
|
discussion=discussion,
|
|
tasks=tasks,
|
|
)
|
|
track_dict = track_state.to_dict()
|
|
assert track_dict["metadata"]["status"] is None
|
|
# Check that isoformat was called on datetime object, not None
|
|
assert track_dict["metadata"]["created_at"] == now.isoformat()
|
|
assert track_dict["metadata"]["updated_at"] is None # This should be None as it's passed as None
|
|
assert track_dict["discussion"][0]["ts"] is None
|
|
assert track_dict["tasks"][0]["description"] == "Task None"
|
|
assert track_dict["tasks"][0]["assigned_to"] == "anon"
|