"""Tests for scroll generator.""" from __future__ import annotations import json from pathlib import Path import torch import pytest from ai_mouse.scroll.generator import generate_scroll from tools.scroll.models import ScrollCVAE @pytest.fixture def scroll_model_dir(tmp_path): model = ScrollCVAE(seq_len=32) torch.save(model.state_dict(), tmp_path / "scroll_model.pt") config = {"seq_len": 32, "epochs": 100} (tmp_path / "scroll_config.json").write_text(json.dumps(config)) return tmp_path class TestGenerateScroll: def test_returns_list_of_dicts(self, scroll_model_dir): result = generate_scroll(1000, 3000, mode="target", model_dir=str(scroll_model_dir)) assert isinstance(result, list) assert len(result) > 0 assert all("deltaY" in e and "t" in e and "deltaMode" in e for e in result) def test_timestamps_monotonic(self, scroll_model_dir): result = generate_scroll(1000, 3000, mode="target", model_dir=str(scroll_model_dir)) times = [e["t"] for e in result] for i in range(1, len(times)): assert times[i] >= times[i - 1] def test_total_scroll_approximately_matches_distance(self, scroll_model_dir): result = generate_scroll(1000, 3000, mode="target", model_dir=str(scroll_model_dir)) total = sum(e["deltaY"] for e in result) # Should be within 30% of target distance (2000px) assert abs(total - 2000) < 2000 * 0.4 def test_deltaY_are_integers(self, scroll_model_dir): result = generate_scroll(1000, 3000, mode="target", model_dir=str(scroll_model_dir)) assert all(isinstance(e["deltaY"], int) for e in result) def test_direction_up(self, scroll_model_dir): result = generate_scroll(3000, 1000, mode="target", model_dir=str(scroll_model_dir)) total = sum(e["deltaY"] for e in result) # Negative total for scrolling up assert total < 0