booru-viewer/tests/gui/test_window_state.py
pax 562c03071b test: Phase 2 — add 64 tests for extracted pure functions
5 new test files covering the pure-function extractions from Phase 1:
- test_search_controller.py (24): tag building, blacklist filtering, backfill
- test_window_state.py (16): geometry parsing, splitter parsing, hyprctl cmds
- test_media_controller.py (9): prefetch ring-expansion ordering
- test_post_actions.py (10): batch message detection, library membership
- test_popout_controller.py (3): video sync dict shape

All import-pure (no PySide6, no mpv, no httpx). Total suite: 186 tests.
2026-04-10 15:20:57 -05:00

147 lines
4.3 KiB
Python

"""Tests for window_state -- geometry parsing, Hyprland command building.
Pure Python. No Qt, no subprocess, no Hyprland.
"""
from __future__ import annotations
import pytest
from booru_viewer.gui.window_state import (
build_hyprctl_restore_cmds,
format_geometry,
parse_geometry,
parse_splitter_sizes,
)
# ======================================================================
# parse_geometry
# ======================================================================
def test_parse_geometry_valid():
assert parse_geometry("100,200,800,600") == (100, 200, 800, 600)
def test_parse_geometry_wrong_count():
assert parse_geometry("100,200,800") is None
def test_parse_geometry_non_numeric():
assert parse_geometry("abc,200,800,600") is None
def test_parse_geometry_empty():
assert parse_geometry("") is None
# ======================================================================
# format_geometry
# ======================================================================
def test_format_geometry_basic():
assert format_geometry(10, 20, 1920, 1080) == "10,20,1920,1080"
def test_format_and_parse_round_trip():
geo = (100, 200, 800, 600)
assert parse_geometry(format_geometry(*geo)) == geo
# ======================================================================
# parse_splitter_sizes
# ======================================================================
def test_parse_splitter_sizes_valid_2():
assert parse_splitter_sizes("300,700", 2) == [300, 700]
def test_parse_splitter_sizes_valid_3():
assert parse_splitter_sizes("200,500,300", 3) == [200, 500, 300]
def test_parse_splitter_sizes_wrong_count():
assert parse_splitter_sizes("300,700", 3) is None
def test_parse_splitter_sizes_negative():
assert parse_splitter_sizes("300,-1", 2) is None
def test_parse_splitter_sizes_all_zero():
assert parse_splitter_sizes("0,0", 2) is None
def test_parse_splitter_sizes_non_numeric():
assert parse_splitter_sizes("abc,700", 2) is None
def test_parse_splitter_sizes_empty():
assert parse_splitter_sizes("", 2) is None
# ======================================================================
# build_hyprctl_restore_cmds
# ======================================================================
def test_floating_to_floating_no_toggle():
"""Already floating, want floating: no togglefloating needed."""
cmds = build_hyprctl_restore_cmds(
addr="0xdead", x=100, y=200, w=800, h=600,
want_floating=True, cur_floating=True,
)
assert not any("togglefloating" in c for c in cmds)
assert any("resizewindowpixel" in c for c in cmds)
assert any("movewindowpixel" in c for c in cmds)
def test_tiled_to_floating_has_toggle():
"""Currently tiled, want floating: one togglefloating to enter float."""
cmds = build_hyprctl_restore_cmds(
addr="0xdead", x=100, y=200, w=800, h=600,
want_floating=True, cur_floating=False,
)
toggle_cmds = [c for c in cmds if "togglefloating" in c]
assert len(toggle_cmds) == 1
def test_tiled_primes_floating_cache():
"""Want tiled: primes Hyprland's floating cache with 2 toggles + no_anim."""
cmds = build_hyprctl_restore_cmds(
addr="0xdead", x=100, y=200, w=800, h=600,
want_floating=False, cur_floating=False,
)
toggle_cmds = [c for c in cmds if "togglefloating" in c]
no_anim_on = [c for c in cmds if "no_anim 1" in c]
no_anim_off = [c for c in cmds if "no_anim 0" in c]
# Two toggles: tiled->float (to prime), float->tiled (to restore)
assert len(toggle_cmds) == 2
assert len(no_anim_on) == 1
assert len(no_anim_off) == 1
def test_floating_to_tiled_one_toggle():
"""Currently floating, want tiled: one toggle to tile."""
cmds = build_hyprctl_restore_cmds(
addr="0xdead", x=100, y=200, w=800, h=600,
want_floating=False, cur_floating=True,
)
toggle_cmds = [c for c in cmds if "togglefloating" in c]
# Only the final toggle at the end of the tiled branch
assert len(toggle_cmds) == 1
def test_correct_address_in_all_cmds():
"""Every command references the given address."""
addr = "0xbeef"
cmds = build_hyprctl_restore_cmds(
addr=addr, x=0, y=0, w=1920, h=1080,
want_floating=True, cur_floating=False,
)
for cmd in cmds:
assert addr in cmd