From e3d4626031eb1d319d1b1f166e1496186cad542f Mon Sep 17 00:00:00 2001 From: Huang Qi Date: Tue, 12 May 2026 00:20:13 +0800 Subject: [PATCH] test: capture scroll generate() golden output (pre-migration) --- scripts/build_golden_scroll.py | 48 ++++++++++++++++++++++++++++++ tests/unit/data/golden_scroll.npz | Bin 0 -> 9976 bytes 2 files changed, 48 insertions(+) create mode 100644 scripts/build_golden_scroll.py create mode 100644 tests/unit/data/golden_scroll.npz diff --git a/scripts/build_golden_scroll.py b/scripts/build_golden_scroll.py new file mode 100644 index 0000000..4937775 --- /dev/null +++ b/scripts/build_golden_scroll.py @@ -0,0 +1,48 @@ +"""Capture golden scroll event sequences from current torch implementation.""" +from __future__ import annotations + +import random +import sys +from pathlib import Path + +# Allow running as `uv run python scripts/build_golden_scroll.py` from project root. +sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) + +import numpy as np +import torch + +from ai_mouse import generate_scroll + +CASES: list[tuple[int, int, str]] = [ + (0, 1500, "target"), + (0, 500, "precise"), + (0, 5000, "fast"), + (2000, 0, "target"), # upward + (0, 800, "precise"), + (0, 3500, "fast"), + (1000, 1200, "precise"), # tiny scroll + (0, 10000, "fast"), # very long +] +SEEDS = (0, 1, 2, 3) + + +def main() -> None: + out: dict[str, np.ndarray] = {} + for case_idx, (start_y, end_y, mode) in enumerate(CASES): + for seed in SEEDS: + random.seed(seed) + np.random.seed(seed) + torch.manual_seed(seed) + events = generate_scroll(start_y, end_y, mode=mode) + arr = np.array( + [[e["deltaY"], e["deltaMode"], e["t"]] for e in events], + dtype=np.int64, + ) + out[f"case{case_idx}_seed{seed}"] = arr + out_path = Path("tests/unit/data/golden_scroll.npz") + np.savez_compressed(out_path, **out) + print(f"Wrote {len(out)} scroll golden traces to {out_path}") + + +if __name__ == "__main__": + main() diff --git a/tests/unit/data/golden_scroll.npz b/tests/unit/data/golden_scroll.npz new file mode 100644 index 0000000000000000000000000000000000000000..5d3dd6c37c9a98a7e0407b1e5e4dc2c6182544e4 GIT binary patch literal 9976 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