diff options
| author | Craig Jennings <c@cjennings.net> | 2026-05-23 13:02:47 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-05-23 13:02:47 -0500 |
| commit | 3f802eb819bc9be572b230ac1bd142b7ce13d87f (patch) | |
| tree | 60be68db7167d064669c608cfb8402812eeae5c2 /.ai/scripts/tests | |
| parent | 7f2aea1e022c93f3eb463e5222bdb0d8ae6288b9 (diff) | |
| download | rulesets-3f802eb819bc9be572b230ac1bd142b7ce13d87f.tar.gz rulesets-3f802eb819bc9be572b230ac1bd142b7ce13d87f.zip | |
chore(ai): resync workflow and script mirror with canonical
The .ai/ mirror lagged claude-templates/.ai/ for three workflows (task-audit, task-review, triage-intake) and two scripts (screenshot.py and its test) — earlier commits updated the canonical copies without resyncing the mirror in the same commit. The startup rsync caught it up; this commit tracks the result so the two stay identical.
Diffstat (limited to '.ai/scripts/tests')
| -rw-r--r-- | .ai/scripts/tests/test_screenshot.py | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/.ai/scripts/tests/test_screenshot.py b/.ai/scripts/tests/test_screenshot.py new file mode 100644 index 0000000..357caec --- /dev/null +++ b/.ai/scripts/tests/test_screenshot.py @@ -0,0 +1,97 @@ +"""Tests for screenshot.py — the pure helpers behind Wayland screenshot capture. + +The script is mostly thin wrappers around grim/hyprctl (I/O boundaries, verified +functionally). The logic worth testing is pure: size parsing, grim geometry +strings, window matching, the Hyprland exec-rule body, and floating-window +centering. Those are imported and exercised directly here; the subprocess +wrappers and the capture orchestration are not unit-tested. +""" + +import sys +from pathlib import Path + +import pytest + +sys.path.insert(0, str(Path(__file__).parent.parent)) +import screenshot # noqa: E402 + + +# ------------------------------- parse_size ---------------------------------- + +def test_parse_size_normal(): + assert screenshot.parse_size("1600x1000") == (1600, 1000) + +def test_parse_size_boundary_zero_and_one(): + assert screenshot.parse_size("0x0") == (0, 0) + assert screenshot.parse_size("1x1") == (1, 1) + +@pytest.mark.parametrize("bad", ["", "bad", "100", "100x", "x100", "100X100", " 1x1"]) +def test_parse_size_error_malformed_dies(bad): + with pytest.raises(SystemExit): + screenshot.parse_size(bad) + + +# ------------------------------ geometry_str --------------------------------- + +def test_geometry_str_normal(): + assert screenshot.geometry_str({"at": [10, 20], "size": [800, 600]}) == "10,20 800x600" + +def test_geometry_str_boundary_origin_and_unit(): + assert screenshot.geometry_str({"at": [0, 0], "size": [1, 1]}) == "0,0 1x1" + + +# ------------------------------ match_windows -------------------------------- + +CLIENTS = [ + {"class": "Emacs", "title": "Emacs 30.2 : agent [.emacs.d]"}, + {"class": "firefox", "title": "TrueNAS — Mozilla Firefox"}, + {"class": "foot", "title": "foot"}, +] + +def test_match_windows_normal_by_class(): + assert screenshot.match_windows(CLIENTS, "firefox") == [CLIENTS[1]] + +def test_match_windows_normal_by_title(): + assert screenshot.match_windows(CLIENTS, "TrueNAS") == [CLIENTS[1]] + +def test_match_windows_case_insensitive(): + assert screenshot.match_windows(CLIENTS, "EMACS") == [CLIENTS[0]] + +def test_match_windows_multiple(): + # "o" appears in firefox and foot classes + assert len(screenshot.match_windows(CLIENTS, "foo")) == 1 + assert len(screenshot.match_windows(CLIENTS, "e")) >= 2 # Emacs + firefox (title/class) + +def test_match_windows_boundary_empty_clients(): + assert screenshot.match_windows([], "anything") == [] + +def test_match_windows_boundary_missing_fields(): + # client with no class/title keys must not raise + assert screenshot.match_windows([{"class": None, "title": None}], "x") == [] + +def test_match_windows_error_no_match(): + assert screenshot.match_windows(CLIENTS, "nonexistent-zzz") == [] + + +# ------------------------------- launch_rule --------------------------------- + +def test_launch_rule_tiled_default(): + assert screenshot.launch_rule(2, "tiled") == "workspace 2 silent" + +def test_launch_rule_monocle_adds_fullscreen(): + assert screenshot.launch_rule(2, "monocle") == "workspace 2 silent;fullscreen 1" + +def test_launch_rule_floating_adds_float(): + assert screenshot.launch_rule(7, "floating") == "workspace 7 silent;float" + + +# ------------------------------ center_offset -------------------------------- + +def test_center_offset_normal(): + assert screenshot.center_offset(1920, 1080, 800, 600) == (560, 240) + +def test_center_offset_boundary_exact_fit(): + assert screenshot.center_offset(1920, 1080, 1920, 1080) == (0, 0) + +def test_center_offset_error_window_larger_than_output_clamps(): + assert screenshot.center_offset(800, 600, 1000, 700) == (0, 0) |
