- Add pyproject.toml with modern Python packaging (PEP 517/518) - Add uv-based dependency management replacing inline venv bootstrap - Add requirements.txt and requirements-dev.txt for compatibility - Add mise.toml with dev tasks (test, lint, run, sync, ci) - Add .python-version pinned to Python 3.12 - Add comprehensive pytest test suite (73 tests) for: - engine/config, filter, terminal, sources, mic, ntfy modules - Configure pytest with coverage reporting (16% total, 100% on tested modules) - Configure ruff for linting with Python 3.10+ target - Remove redundant venv bootstrap code from mainline.py - Update .gitignore for uv/venv artifacts Run 'uv sync' to install dependencies, 'uv run pytest' to test.
94 lines
2.7 KiB
Python
94 lines
2.7 KiB
Python
"""
|
|
Tests for engine.sources module - data validation.
|
|
"""
|
|
|
|
from engine import sources
|
|
|
|
|
|
class TestFeeds:
|
|
"""Tests for FEEDS data."""
|
|
|
|
def test_feeds_is_dict(self):
|
|
"""FEEDS is a dictionary."""
|
|
assert isinstance(sources.FEEDS, dict)
|
|
|
|
def test_feeds_has_entries(self):
|
|
"""FEEDS has feed entries."""
|
|
assert len(sources.FEEDS) > 0
|
|
|
|
def test_feeds_have_valid_urls(self):
|
|
"""All feeds have valid URL format."""
|
|
for name, url in sources.FEEDS.items():
|
|
assert name
|
|
assert url.startswith("http://") or url.startswith("https://")
|
|
|
|
|
|
class TestPoetrySources:
|
|
"""Tests for POETRY_SOURCES data."""
|
|
|
|
def test_poetry_is_dict(self):
|
|
"""POETRY_SOURCES is a dictionary."""
|
|
assert isinstance(sources.POETRY_SOURCES, dict)
|
|
|
|
def test_poetry_has_entries(self):
|
|
"""POETRY_SOURCES has entries."""
|
|
assert len(sources.POETRY_SOURCES) > 0
|
|
|
|
def test_poetry_have_gutenberg_urls(self):
|
|
"""All poetry sources are from Gutenberg."""
|
|
for _name, url in sources.POETRY_SOURCES.items():
|
|
assert "gutenberg.org" in url
|
|
|
|
|
|
class TestSourceLangs:
|
|
"""Tests for SOURCE_LANGS mapping."""
|
|
|
|
def test_source_langs_is_dict(self):
|
|
"""SOURCE_LANGS is a dictionary."""
|
|
assert isinstance(sources.SOURCE_LANGS, dict)
|
|
|
|
def test_source_langs_valid_language_codes(self):
|
|
"""Language codes are valid ISO codes."""
|
|
valid_codes = {"de", "fr", "ja", "zh-cn", "ar", "hi"}
|
|
for code in sources.SOURCE_LANGS.values():
|
|
assert code in valid_codes
|
|
|
|
|
|
class TestLocationLangs:
|
|
"""Tests for LOCATION_LANGS mapping."""
|
|
|
|
def test_location_langs_is_dict(self):
|
|
"""LOCATION_LANGS is a dictionary."""
|
|
assert isinstance(sources.LOCATION_LANGS, dict)
|
|
|
|
def test_location_langs_has_patterns(self):
|
|
"""LOCATION_LANGS has regex patterns."""
|
|
assert len(sources.LOCATION_LANGS) > 0
|
|
|
|
|
|
class TestScriptFonts:
|
|
"""Tests for SCRIPT_FONTS mapping."""
|
|
|
|
def test_script_fonts_is_dict(self):
|
|
"""SCRIPT_FONTS is a dictionary."""
|
|
assert isinstance(sources.SCRIPT_FONTS, dict)
|
|
|
|
def test_script_fonts_has_paths(self):
|
|
"""All script fonts have paths."""
|
|
for _lang, path in sources.SCRIPT_FONTS.items():
|
|
assert path
|
|
|
|
|
|
class TestNoUpper:
|
|
"""Tests for NO_UPPER set."""
|
|
|
|
def test_no_upper_is_set(self):
|
|
"""NO_UPPER is a set."""
|
|
assert isinstance(sources.NO_UPPER, set)
|
|
|
|
def test_no_upper_contains_scripts(self):
|
|
"""NO_UPPER contains non-Latin scripts."""
|
|
assert "zh-cn" in sources.NO_UPPER
|
|
assert "ja" in sources.NO_UPPER
|
|
assert "ar" in sources.NO_UPPER
|