EpisodeMatcher/tests/test_episode_matcher.py
Jarian f1aa2c4cda test: add test suite with 90% coverage
- 176 unit tests covering ConfigManager, FileClassifier, EpisodeRenamer,
  TVDBClient, MockTVDBClient, TVDBCache, and episode_matcher CLI
- Tests organized in tests/ with conftest.py shared fixtures
- pytest-cov configured with 90% coverage threshold in pyproject.toml
- CI workflow updated with COVERAGE_CORE=sysmon for Python 3.13 compat
- .gitignore updated for coverage artifacts and venv
2026-07-06 14:31:22 +00:00

111 lines
3.7 KiB
Python

"""Tests for episode_matcher.py - parse_disc_mapping and CLI."""
import sys
from pathlib import Path
from unittest.mock import patch
sys.path.insert(0, str(Path(__file__).parent.parent))
import pytest
from episode_matcher import parse_disc_mapping
class TestParseDiscMapping:
def test_single_disc_range(self):
result = parse_disc_mapping("1:1-3")
assert result == {1: [1, 2, 3]}
def test_single_disc_single_ep(self):
result = parse_disc_mapping("1:5")
assert result == {1: [5]}
def test_multi_disc(self):
result = parse_disc_mapping("1:1-3,2:4-6,3:7-9,4:10")
assert result == {1: [1, 2, 3], 2: [4, 5, 6], 3: [7, 8, 9], 4: [10]}
def test_spaces(self):
result = parse_disc_mapping("1:1-3 , 2:4-6")
assert result == {1: [1, 2, 3], 2: [4, 5, 6]}
def test_empty_string(self):
result = parse_disc_mapping("")
assert result == {}
def test_none(self):
result = parse_disc_mapping(None)
assert result == {}
def test_single_ep_per_disc(self):
result = parse_disc_mapping("1:1,2:2,3:3")
assert result == {1: [1], 2: [2], 3: [3]}
def test_large_numbers(self):
result = parse_disc_mapping("1:1-22")
assert result == {1: list(range(1, 23))}
def test_invalid_format_exits(self, capsys):
with pytest.raises(SystemExit):
parse_disc_mapping("invalid")
def test_missing_colon_exits(self, capsys):
with pytest.raises(SystemExit):
parse_disc_mapping("1,2,3")
class TestArgParse:
def test_parser_basic_args(self):
import argparse
from episode_matcher import main
with patch("sys.argv", [
"episode_matcher.py",
"/tmp/episodes",
"Test Show",
"1",
]):
with patch("pathlib.Path.exists", return_value=True):
with patch("pathlib.Path.is_dir", return_value=True):
with patch("episode_matcher.TVDBClient") as mock_tvdb:
mock_instance = mock_tvdb.return_value
mock_instance.authenticate.return_value = False
with patch("episode_matcher.MockTVDBClient") as mock_mock:
m = mock_mock.return_value
m.authenticate.return_value = True
m.get_episode_durations.return_value = []
with patch("episode_matcher.FileClassifier") as mock_fc:
fc = mock_fc.return_value
fc.file_info = []
fc.classify_files.return_value = ([], [])
with pytest.raises(SystemExit):
main()
def test_parser_dry_run_flag(self):
import sys as real_sys
orig_argv = real_sys.argv
try:
real_sys.argv = [
"episode_matcher.py", "/tmp/e", "Show", "1", "--dry-run", "--verbose"
]
from importlib import reload
import episode_matcher
parser = episode_matcher.__dict__.get("_parser", None)
from episode_matcher import main
finally:
real_sys.argv = orig_argv
class TestParseDiscMappingEdgeCases:
def test_range_to_self(self):
result = parse_disc_mapping("1:5-5")
assert result == {1: [5]}
def test_multiple_ranges_same_ep(self):
result = parse_disc_mapping("1:1-3,2:3-5")
assert 3 in result[1]
assert 3 in result[2]
def test_disc_number_large(self):
result = parse_disc_mapping("99:1-3")
assert 99 in result