from __future__ import annotations from core.models import Bounds, Scene, SceneElement from semantic.models import SemanticScene, SemanticWidget from world.models import WorldEvent, WorldState def _scene() -> Scene: return Scene( width=10, height=20, elements=[ SceneElement( id="send", type="button", text="Send", bounds=Bounds(1, 2, 3, 4), ) ], ) def test_world_event_and_state_to_dict() -> None: semantic_scene = SemanticScene( page="Chat", intents=["send a message"], widgets=[SemanticWidget(element_id="send", purpose="send message")], ) event = WorldEvent( scene_summary=semantic_scene, action="tap", success=True, ) state = WorldState.with_history_bound(2) state.current_app = "com.example.chat" state.current_page = "Chat" state.variables["contact"] = "Zhang San" state.history.append(event) data = state.to_dict() assert data["current_app"] == "com.example.chat" assert data["current_page"] == "Chat" assert data["variables"] == {"contact": "Zhang San"} assert data["history"][0]["scene_summary"] == semantic_scene.to_dict() assert data["history"][0]["action"] == "tap" assert data["history"][0]["success"] is True assert data["history"][0]["timestamp"] def test_world_state_history_evicts_oldest_entry_at_bound() -> None: state = WorldState.with_history_bound(2) state.history.append(WorldEvent(_scene(), "first", True)) state.history.append(WorldEvent(_scene(), "second", True)) state.history.append(WorldEvent(_scene(), "third", True)) assert len(state.history) == 2 assert [event.action for event in state.history] == ["second", "third"] assert state.history.maxlen == 2