mirror of
https://github.com/Benexl/FastAnime.git
synced 2025-12-27 13:13:25 -08:00
116 lines
4.7 KiB
Python
116 lines
4.7 KiB
Python
"""Tests for episode range parser."""
|
|
|
|
import pytest
|
|
|
|
from fastanime.cli.utils.parser import parse_episode_range
|
|
|
|
|
|
class TestParseEpisodeRange:
|
|
"""Test cases for the parse_episode_range function."""
|
|
|
|
@pytest.fixture
|
|
def episodes(self):
|
|
"""Sample episode list for testing."""
|
|
return ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
|
|
|
|
def test_no_range_returns_all_episodes(self, episodes):
|
|
"""Test that None or empty range returns all episodes."""
|
|
result = list(parse_episode_range(None, episodes))
|
|
assert result == episodes
|
|
|
|
def test_colon_only_returns_all_episodes(self, episodes):
|
|
"""Test that ':' returns all episodes."""
|
|
result = list(parse_episode_range(":", episodes))
|
|
assert result == episodes
|
|
|
|
def test_start_end_range(self, episodes):
|
|
"""Test start:end range format."""
|
|
result = list(parse_episode_range("2:5", episodes))
|
|
assert result == ["3", "4", "5"]
|
|
|
|
def test_start_only_range(self, episodes):
|
|
"""Test start: range format."""
|
|
result = list(parse_episode_range("5:", episodes))
|
|
assert result == ["6", "7", "8", "9", "10"]
|
|
|
|
def test_end_only_range(self, episodes):
|
|
"""Test :end range format."""
|
|
result = list(parse_episode_range(":3", episodes))
|
|
assert result == ["1", "2", "3"]
|
|
|
|
def test_start_end_step_range(self, episodes):
|
|
"""Test start:end:step range format."""
|
|
result = list(parse_episode_range("2:8:2", episodes))
|
|
assert result == ["3", "5", "7"]
|
|
|
|
def test_single_number_range(self, episodes):
|
|
"""Test single number format (start from index)."""
|
|
result = list(parse_episode_range("5", episodes))
|
|
assert result == ["6", "7", "8", "9", "10"]
|
|
|
|
def test_empty_start_end_in_three_part_range_raises_error(self, episodes):
|
|
"""Test that empty parts in start:end:step format raise error."""
|
|
with pytest.raises(ValueError, match="When using 3 parts"):
|
|
list(parse_episode_range(":5:2", episodes))
|
|
|
|
with pytest.raises(ValueError, match="When using 3 parts"):
|
|
list(parse_episode_range("2::2", episodes))
|
|
|
|
with pytest.raises(ValueError, match="When using 3 parts"):
|
|
list(parse_episode_range("2:5:", episodes))
|
|
|
|
def test_invalid_integer_raises_error(self, episodes):
|
|
"""Test that invalid integers raise ValueError."""
|
|
with pytest.raises(ValueError, match="Must be a valid integer"):
|
|
list(parse_episode_range("abc", episodes))
|
|
|
|
with pytest.raises(ValueError, match="Start and end must be valid integers"):
|
|
list(parse_episode_range("2:abc", episodes))
|
|
|
|
with pytest.raises(ValueError, match="All parts must be valid integers"):
|
|
list(parse_episode_range("2:5:abc", episodes))
|
|
|
|
def test_zero_step_raises_error(self, episodes):
|
|
"""Test that zero step raises ValueError."""
|
|
with pytest.raises(ValueError, match="Step value must be positive"):
|
|
list(parse_episode_range("2:5:0", episodes))
|
|
|
|
def test_negative_step_raises_error(self, episodes):
|
|
"""Test that negative step raises ValueError."""
|
|
with pytest.raises(ValueError, match="Step value must be positive"):
|
|
list(parse_episode_range("2:5:-1", episodes))
|
|
|
|
def test_too_many_colons_raises_error(self, episodes):
|
|
"""Test that too many colons raise ValueError."""
|
|
with pytest.raises(ValueError, match="Too many colon separators"):
|
|
list(parse_episode_range("2:5:7:9", episodes))
|
|
|
|
def test_edge_case_empty_list(self):
|
|
"""Test behavior with empty episode list."""
|
|
result = list(parse_episode_range(":", []))
|
|
assert result == []
|
|
|
|
def test_edge_case_single_episode(self):
|
|
"""Test behavior with single episode."""
|
|
episodes = ["1"]
|
|
result = list(parse_episode_range(":", episodes))
|
|
assert result == ["1"]
|
|
|
|
result = list(parse_episode_range("0:1", episodes))
|
|
assert result == ["1"]
|
|
|
|
def test_numerical_sorting(self):
|
|
"""Test that episodes are sorted numerically, not lexicographically."""
|
|
episodes = ["10", "2", "1", "11", "3"]
|
|
result = list(parse_episode_range(":", episodes))
|
|
assert result == ["1", "2", "3", "10", "11"]
|
|
|
|
def test_index_out_of_bounds_behavior(self, episodes):
|
|
"""Test behavior when indices exceed available episodes."""
|
|
# Python slicing handles out-of-bounds gracefully
|
|
result = list(parse_episode_range("15:", episodes))
|
|
assert result == [] # No episodes beyond index 15
|
|
|
|
result = list(parse_episode_range(":20", episodes))
|
|
assert result == episodes # All episodes (slice stops at end)
|