mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-07-04 21:03:15 +02:00
Fix ruff violations in ~15 source files and ~60+ test files to minimize per-file-ignores in pyproject.toml. Remaining ignores are justified with comments explaining why each suppression is necessary. Source fixes: FBT003 (keyword args), S310 (URL validation), SLF001 (private access), T201 (print→logging), C901 (complexity), E501 (line length), E402 (import order). Test fixes: SIM117 (combined with), FBT (boolean args), PERF203 (try in loop), S310/S607 (URLs/executables), E402/E501 (imports/lines), S108 (tmp paths), PLR0913 (too many args), ARG (unused args), ANN (type annotations), RUF059 (unused unpacked vars), PT019 (fixture naming). Remaining per-file-ignores (with justifications): - Tests: ARG, D, PLC0415, PLR2004, S101, SLF001 - music_gen sources: PLC0415 (heavy ML lazy imports) - moviepy_showcase: PLC0415 (circular dependency) - generate_images: PLR0913 (matplotlib helpers need many params) - praca_magisterska_video: E501, E402 (long paths, mpl.use)
287 lines
10 KiB
Python
287 lines
10 KiB
Python
"""Tests for translator module - part 1 (results, translation, batch, formatting)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
import pytest
|
|
|
|
from python_pkg.word_frequency import translator
|
|
from python_pkg.word_frequency._translator_helpers import (
|
|
TranslationResult,
|
|
format_translations,
|
|
)
|
|
from python_pkg.word_frequency.tests._translator_helpers import ArgosAvailableMock
|
|
from python_pkg.word_frequency.translator import (
|
|
translate_word,
|
|
translate_words,
|
|
translate_words_batch,
|
|
)
|
|
|
|
# TranslationResult tests
|
|
|
|
|
|
class TestTranslationResult:
|
|
"""Tests for TranslationResult namedtuple."""
|
|
|
|
def test_successful_result(self) -> None:
|
|
"""Test creating a successful translation result."""
|
|
result = TranslationResult(
|
|
source_word="hello",
|
|
translated_word="hola",
|
|
source_lang="en",
|
|
target_lang="es",
|
|
success=True,
|
|
)
|
|
assert result.source_word == "hello"
|
|
assert result.translated_word == "hola"
|
|
assert result.source_lang == "en"
|
|
assert result.target_lang == "es"
|
|
assert result.success is True
|
|
assert result.error is None
|
|
|
|
def test_failed_result(self) -> None:
|
|
"""Test creating a failed translation result."""
|
|
result = TranslationResult(
|
|
source_word="xyz",
|
|
translated_word="",
|
|
source_lang="en",
|
|
target_lang="xx",
|
|
success=False,
|
|
error="Language not supported",
|
|
)
|
|
assert result.success is False
|
|
assert result.error == "Language not supported"
|
|
|
|
def test_result_is_tuple(self) -> None:
|
|
"""Test that TranslationResult is a namedtuple."""
|
|
result = TranslationResult("a", "b", "en", "es", success=True)
|
|
assert isinstance(result, tuple)
|
|
assert len(result) == 6
|
|
|
|
|
|
# translate_word tests
|
|
|
|
|
|
class TestTranslateWord:
|
|
"""Tests for translate_word function - offline-first behavior."""
|
|
|
|
def test_translate_word_argos_unavailable_raises(self) -> None:
|
|
"""Test that translation raises ImportError when argos is unavailable."""
|
|
# Mock _ensure_argos_installed to raise ImportError
|
|
with (
|
|
patch.object(
|
|
translator,
|
|
"_ensure_argos_installed",
|
|
side_effect=ImportError("argostranslate not available"),
|
|
),
|
|
pytest.raises(ImportError, match="argostranslate not available"),
|
|
):
|
|
translate_word("hello", "en", "es", use_cache=False)
|
|
|
|
def test_translate_word_success(self) -> None:
|
|
"""Test successful word translation."""
|
|
with ArgosAvailableMock("hola"):
|
|
result = translate_word("hello", "en", "es", use_cache=False)
|
|
|
|
assert result.source_word == "hello"
|
|
assert result.translated_word == "hola"
|
|
assert result.success is True
|
|
|
|
def test_translate_word_argos_exception_returns_error(self) -> None:
|
|
"""Test that argos exception returns failed result with error."""
|
|
# Mock argos being available but translate raising an exception
|
|
with ArgosAvailableMock(RuntimeError("Translation failed")):
|
|
result = translate_word("hello", "en", "es", use_cache=False)
|
|
|
|
assert result.success is False
|
|
assert "Translation failed" in str(result.error)
|
|
|
|
|
|
# translate_words tests
|
|
|
|
|
|
class TestTranslateWords:
|
|
"""Tests for translate_words function."""
|
|
|
|
def test_translate_empty_list(self) -> None:
|
|
"""Test translating empty list."""
|
|
# Empty list returns empty result without calling translation
|
|
results = translate_words([], "en", "es")
|
|
assert results == []
|
|
|
|
def test_translate_multiple_words(self) -> None:
|
|
"""Test translating multiple words."""
|
|
with ArgosAvailableMock(["hola", "mundo"]) as mock:
|
|
mock.side_effect = ["hola", "mundo"]
|
|
results = translate_words(["hello", "world"], "en", "es", use_cache=False)
|
|
|
|
assert len(results) == 2
|
|
assert results[0].translated_word == "hola"
|
|
assert results[1].translated_word == "mundo"
|
|
|
|
def test_translate_words_argos_unavailable_raises(self) -> None:
|
|
"""Test that translating words raises ImportError when argos unavailable."""
|
|
with (
|
|
patch.object(
|
|
translator,
|
|
"_ensure_argos_installed",
|
|
side_effect=ImportError("argostranslate not available"),
|
|
),
|
|
pytest.raises(ImportError, match="argostranslate not available"),
|
|
):
|
|
translate_words(["hello", "world"], "en", "es", use_cache=False)
|
|
|
|
|
|
# translate_words_batch tests
|
|
|
|
|
|
class TestTranslateWordsBatch:
|
|
"""Tests for translate_words_batch function - offline-first."""
|
|
|
|
def test_batch_empty_list(self) -> None:
|
|
"""Test batch translation of empty list."""
|
|
# Empty list doesn't require argos
|
|
with patch.object(translator, "_ensure_argos_installed", lambda: None):
|
|
results = translate_words_batch([], "en", "es")
|
|
assert results == []
|
|
|
|
def test_batch_small_list(self) -> None:
|
|
"""Test batch translation of small list (uses batch mode anyway)."""
|
|
with ArgosAvailableMock("uno\ndos\ntres") as mock:
|
|
results = translate_words_batch(
|
|
["one", "two", "three"], "en", "es", use_cache=False
|
|
)
|
|
|
|
assert len(results) == 3
|
|
# Batch translation
|
|
assert mock.call_count == 1
|
|
|
|
def test_batch_large_list_success(self) -> None:
|
|
"""Test batch translation of large list."""
|
|
words = ["one", "two", "three", "four", "five"]
|
|
|
|
with ArgosAvailableMock("uno\ndos\ntres\ncuatro\ncinco") as mock:
|
|
results = translate_words_batch(words, "en", "es", use_cache=False)
|
|
|
|
assert len(results) == 5
|
|
# Batch translation called once
|
|
mock.assert_called_once()
|
|
assert results[0].translated_word == "uno"
|
|
assert results[4].translated_word == "cinco"
|
|
|
|
def test_batch_fallback_on_mismatch(self) -> None:
|
|
"""Test batch falls back to individual on result count mismatch."""
|
|
words = ["one", "two", "three", "four"]
|
|
# First call (batch) returns wrong count, subsequent calls are individual
|
|
with ArgosAvailableMock(["wrong", "uno", "dos", "tres", "cuatro"]) as mock:
|
|
results = translate_words_batch(words, "en", "es", use_cache=False)
|
|
|
|
assert len(results) == 4
|
|
# Fallback to individual argos translation
|
|
assert mock.call_count == 5
|
|
|
|
def test_batch_fallback_on_exception(self) -> None:
|
|
"""Test batch translation raises on exception (no fallback to online)."""
|
|
words = ["one", "two", "three", "four"]
|
|
|
|
# Create mock that raises
|
|
mock_translate = MagicMock(side_effect=RuntimeError("Batch failed"))
|
|
mock_translate_module = MagicMock()
|
|
mock_translate_module.translate = mock_translate
|
|
mock_package_module = MagicMock()
|
|
mock_parent = MagicMock()
|
|
mock_parent.translate = mock_translate_module
|
|
mock_parent.package = mock_package_module
|
|
|
|
with (
|
|
patch.object(translator, "check_argos", return_value=True),
|
|
patch.object(translator, "argostranslate", mock_parent, create=True),
|
|
patch.dict(
|
|
"sys.modules",
|
|
{
|
|
"argostranslate": mock_parent,
|
|
"argostranslate.translate": mock_translate_module,
|
|
"argostranslate.package": mock_package_module,
|
|
},
|
|
),
|
|
patch.object(translator, "_ensure_argos_installed", lambda: None),
|
|
patch.object(translator, "_ensure_language_pair", lambda _f, _t: None),
|
|
pytest.raises(RuntimeError, match="Translation failed"),
|
|
):
|
|
translate_words_batch(words, "en", "es", use_cache=False)
|
|
|
|
def test_batch_argos_unavailable_raises(self) -> None:
|
|
"""Test that batch translation raises ImportError when argos unavailable."""
|
|
with (
|
|
patch.object(
|
|
translator,
|
|
"_ensure_argos_installed",
|
|
side_effect=ImportError("argostranslate not available"),
|
|
),
|
|
pytest.raises(ImportError, match="argostranslate not available"),
|
|
):
|
|
translate_words_batch(["hello", "world"], "en", "es", use_cache=False)
|
|
|
|
|
|
# format_translations tests
|
|
|
|
|
|
class TestFormatTranslations:
|
|
"""Tests for format_translations function."""
|
|
|
|
def test_format_empty(self) -> None:
|
|
"""Test formatting empty results."""
|
|
output = format_translations([])
|
|
assert output == "No translations."
|
|
|
|
def test_format_single_translation(self) -> None:
|
|
"""Test formatting single translation."""
|
|
results = [
|
|
TranslationResult("hello", "hola", "en", "es", success=True),
|
|
]
|
|
output = format_translations(results)
|
|
|
|
assert "en -> es" in output
|
|
assert "hello" in output
|
|
assert "hola" in output
|
|
|
|
def test_format_multiple_translations(self) -> None:
|
|
"""Test formatting multiple translations."""
|
|
results = [
|
|
TranslationResult("hello", "hola", "en", "es", success=True),
|
|
TranslationResult("world", "mundo", "en", "es", success=True),
|
|
]
|
|
output = format_translations(results)
|
|
|
|
assert "hello" in output
|
|
assert "hola" in output
|
|
assert "world" in output
|
|
assert "mundo" in output
|
|
|
|
def test_format_with_errors(self) -> None:
|
|
"""Test formatting with failed translations."""
|
|
results = [
|
|
TranslationResult("hello", "hola", "en", "es", success=True),
|
|
TranslationResult(
|
|
"xyz", "", "en", "es", success=False, error="Unknown word"
|
|
),
|
|
]
|
|
output = format_translations(results, show_errors=True)
|
|
|
|
assert "hello" in output
|
|
assert "Error: Unknown word" in output
|
|
|
|
def test_format_hide_errors(self) -> None:
|
|
"""Test formatting with errors hidden."""
|
|
results = [
|
|
TranslationResult("hello", "hola", "en", "es", success=True),
|
|
TranslationResult(
|
|
"xyz", "", "en", "es", success=False, error="Unknown word"
|
|
),
|
|
]
|
|
output = format_translations(results, show_errors=False)
|
|
|
|
assert "hello" in output
|
|
assert "Unknown word" not in output
|