testsAndMisc/python_pkg/wsg_grabber/tests/test_review.py
Krzysztof kuhy Rudnicki e03fbd17e9 Split wsg_grabber/tests/test_review.py under the 250-line cap
Split along the same seams the source took: test_review_render.py covers what
now lives in review._render, test_review_undo.py covers review._undo.

The two fixture builders they share moved into the existing conftest.py rather
than a _helpers.py -- the name-tests-test hook requires everything else under
tests/ to be named test_*.py, and syncyomi_guard/tests/conftest.py is the
precedent for plain shared builders living there. Sharing beats copying: jscpd
fails the commit above 2% duplication and this repo already carries four partN
test files.

277 passed, the same count as before, so nothing was dropped. Two intermediate
runs caught real NameErrors from imports the extracted module needed.

test_review.py 297 -> 112, test_review_render.py 102, test_review_undo.py 79.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011w2Pj4Ek3ZNMQVYcFHgXDY
2026-08-16 16:24:48 +02:00

113 lines
3.5 KiB
Python

"""Tests for the reviewer's behaviour.
Because every decision lives here rather than in the Tk module, the whole UI is
specified by these tests and none of them need a display.
"""
from __future__ import annotations
from python_pkg.wsg_grabber import review
from python_pkg.wsg_grabber.models import (
Downloaded,
Emptiness,
FileReady,
Indexed,
ScanFinished,
Verdict,
WorkerFailed,
)
from python_pkg.wsg_grabber.tests.conftest import item as _item
def test_the_first_download_goes_straight_on_screen() -> None:
"""Watching starts as soon as one file lands, not when all of them do."""
state = review.initial_state(indexed=9000, ready=[])
assert state.current is None
state = review.on_new_files(state, [_item("a")])
assert state.current is not None
assert state.current.md5 == "a-md5"
assert state.pending == ()
def test_later_downloads_queue_behind_the_current_one() -> None:
state = review.initial_state(9000, [_item("a")])
state = review.on_new_files(state, [_item("b"), _item("c")])
assert state.current is not None
assert state.current.md5 == "a-md5"
assert [item.md5 for item in state.pending] == ["b-md5", "c-md5"]
def test_new_files_with_nothing_to_add_is_a_no_op() -> None:
state = review.initial_state(1, [_item("a")])
assert review.on_new_files(state, []) is state
def test_a_previous_run_resumes_with_its_unreviewed_videos() -> None:
state = review.initial_state(50, [_item("a"), _item("b")])
assert state.current is not None
assert state.current.md5 == "a-md5"
assert len(state.pending) == 1
def test_keep_counts_and_advances() -> None:
state = review.initial_state(2, [_item("a"), _item("b")])
state = review.on_verdict(state, Verdict.KEEP)
assert state.kept == 1
assert state.passed == 0
assert state.current is not None
assert state.current.md5 == "b-md5"
def test_pass_counts_and_advances() -> None:
state = review.initial_state(2, [_item("a"), _item("b")])
state = review.on_verdict(state, Verdict.SKIP)
assert state.passed == 1
assert state.kept == 0
assert state.current is not None
assert state.current.md5 == "b-md5"
def test_the_last_verdict_empties_the_screen() -> None:
state = review.initial_state(1, [_item("a")])
state = review.on_verdict(state, Verdict.KEEP)
assert state.current is None
assert review.emptiness(state) is Emptiness.WAITING
def test_a_verdict_with_nothing_showing_is_ignored() -> None:
state = review.initial_state(0, [])
assert review.on_verdict(state, Verdict.KEEP) is state
def test_a_vanished_file_is_skipped() -> None:
state = review.initial_state(2, [_item("a"), _item("b")])
state = review.on_missing_locally(state)
assert state.current is not None
assert state.current.md5 == "b-md5"
assert state.kept == 0
assert state.passed == 0
def test_missing_with_nothing_showing_is_ignored() -> None:
state = review.initial_state(0, [])
assert review.on_missing_locally(state) is state
def test_events_fold_into_the_state() -> None:
state = review.initial_state(0, [])
state = review.on_event(state, Indexed(known=9028))
assert state.indexed == 9028
state = review.on_event(state, FileReady(item=_item("a")))
assert state.current is not None
state = review.on_event(state, Downloaded(count=7))
assert state.downloaded == 7
state = review.on_event(state, ScanFinished())
assert state.scan_complete
state = review.on_event(state, WorkerFailed(message="no route to host"))
assert state.error == "no route to host"