Files
i18n-key-sync/tests/test_cli.py
7000pctAUTO 51f56399a4
Some checks failed
CI / test (push) Has been cancelled
Add test files
2026-02-02 03:58:36 +00:00

276 lines
8.5 KiB
Python

"""Tests for CLI commands."""
import json
import tempfile
from pathlib import Path
from click.testing import CliRunner
from i18n_key_sync.cli import main
class TestCLIExtract:
"""Tests for extract command."""
def test_extract_from_python_file(self, sample_python_code):
"""Test extracting keys from Python file."""
with tempfile.NamedTemporaryFile(mode="w", suffix=".py", delete=False) as f:
f.write(sample_python_code)
f.flush()
f_path = f.name
runner = CliRunner()
result = runner.invoke(main, ["extract", f_path])
assert result.exit_code == 0
assert "hello" in result.output or "hello" in result.output.lower()
assert "goodbye" in result.output or "goodbye" in result.output.lower()
Path(f_path).unlink()
def test_extract_json_output(self, sample_python_code):
"""Test extract with JSON output format."""
with tempfile.NamedTemporaryFile(mode="w", suffix=".py", delete=False) as f:
f.write('_("test_key")')
f.flush()
f_path = f.name
runner = CliRunner()
result = runner.invoke(main, ["--output-format", "json", "extract", f_path])
assert result.exit_code == 0
data = json.loads(result.output)
assert "test_key" in data
Path(f_path).unlink()
def test_extract_with_patterns(self, sample_python_code):
"""Test extract with custom patterns."""
with tempfile.NamedTemporaryFile(mode="w", suffix=".py", delete=False) as f:
f.write('t("custom_key")')
f.flush()
f_path = f.name
runner = CliRunner()
result = runner.invoke(main, ["extract", f_path, "--patterns", "t"])
assert result.exit_code == 0
assert "custom_key" in result.output
Path(f_path).unlink()
class TestCLIValidate:
"""Tests for validate command."""
def test_validate_valid_keys(self, temp_project_dir, temp_locale_dir):
"""Test validation with all keys present."""
runner = CliRunner()
result = runner.invoke(main, [
"--locale-dir", str(temp_locale_dir),
"validate",
str(temp_project_dir / "src"),
])
assert result.exit_code == 0
assert "valid" in result.output.lower() or "matching" in result.output.lower()
def test_validate_missing_keys(self, tmp_path, temp_locale_dir):
"""Test validation with missing keys."""
src_dir = tmp_path / "src"
src_dir.mkdir()
code_file = src_dir / "main.py"
code_file.write_text('_("nonexistent_key")')
runner = CliRunner()
result = runner.invoke(main, [
"--locale-dir", str(temp_locale_dir),
"validate",
str(src_dir),
])
assert result.exit_code in [0, 1]
assert "missing" in result.output.lower() or "nonexistent_key" in result.output
def test_validate_strict_mode(self, tmp_path, temp_locale_dir):
"""Test validation in strict mode."""
src_dir = tmp_path / "src"
src_dir.mkdir()
code_file = src_dir / "main.py"
code_file.write_text('_("missing_key")\n_("unused_in_locale")')
locale_file = temp_locale_dir / "en.json"
locale_data = json.loads(locale_file.read_text())
locale_data["unused_in_locale"] = "Unused"
locale_file.write_text(json.dumps(locale_data, indent=2))
runner = CliRunner()
result = runner.invoke(main, [
"--locale-dir", str(temp_locale_dir),
"validate",
str(src_dir),
"--strict",
])
assert result.exit_code == 3
def test_validate_json_output(self, temp_project_dir, temp_locale_dir):
"""Test validate with JSON output."""
runner = CliRunner()
result = runner.invoke(main, [
"--output-format", "json",
"--locale-dir", str(temp_locale_dir),
"validate",
str(temp_project_dir / "src"),
])
assert result.exit_code == 0
data = json.loads(result.output)
assert "missing_keys" in data
assert "unused_keys" in data
assert "matching_keys" in data
class TestCLISync:
"""Tests for sync command."""
def test_sync_dry_run(self, tmp_path, temp_locale_dir):
"""Test sync in dry run mode."""
src_dir = tmp_path / "src"
src_dir.mkdir()
code_file = src_dir / "main.py"
code_file.write_text('_("new_key")')
runner = CliRunner()
result = runner.invoke(main, [
"--locale-dir", str(temp_locale_dir),
"sync",
str(src_dir),
"--dry-run",
])
assert result.exit_code == 0
assert "DRY RUN" in result.output or "dry" in result.output.lower()
locale_file = temp_locale_dir / "en.json"
locale_data = json.loads(locale_file.read_text())
assert "new_key" not in locale_data
def test_sync_actual(self, tmp_path, temp_locale_dir):
"""Test actual sync modifies files."""
src_dir = tmp_path / "src"
src_dir.mkdir()
code_file = src_dir / "main.py"
code_file.write_text('_("new_sync_key")')
runner = CliRunner()
result = runner.invoke(main, [
"--locale-dir", str(temp_locale_dir),
"sync",
str(src_dir),
])
assert result.exit_code == 0
locale_file = temp_locale_dir / "en.json"
locale_data = json.loads(locale_file.read_text())
assert "new_sync_key" in locale_data
def test_sync_custom_placeholder(self, tmp_path, temp_locale_dir):
"""Test sync with custom placeholder value."""
src_dir = tmp_path / "src"
src_dir.mkdir()
code_file = src_dir / "main.py"
code_file.write_text('_("placeholder_key")')
runner = CliRunner()
result = runner.invoke(main, [
"--locale-dir", str(temp_locale_dir),
"sync",
str(src_dir),
"--value", "TRANSLATE_ME",
])
assert result.exit_code == 0
locale_file = temp_locale_dir / "en.json"
locale_data = json.loads(locale_file.read_text())
assert locale_data["placeholder_key"] == "TRANSLATE_ME"
class TestCLIReport:
"""Tests for report command."""
def test_report_generates_output(self, temp_project_dir, temp_locale_dir):
"""Test report command generates output."""
runner = CliRunner()
result = runner.invoke(main, [
"--locale-dir", str(temp_locale_dir),
"report",
str(temp_project_dir / "src"),
])
assert result.exit_code == 0
assert len(result.output) > 0
def test_report_json_format(self, temp_project_dir, temp_locale_dir):
"""Test report with JSON format."""
runner = CliRunner()
result = runner.invoke(main, [
"--locale-dir", str(temp_locale_dir),
"report",
str(temp_project_dir / "src"),
"--format", "json",
])
assert result.exit_code == 0
data = json.loads(result.output)
assert "summary" in data
def test_report_markdown_format(self, temp_project_dir, temp_locale_dir):
"""Test report with markdown format."""
runner = CliRunner()
result = runner.invoke(main, [
"--locale-dir", str(temp_locale_dir),
"report",
str(temp_project_dir / "src"),
"--format", "markdown",
])
assert result.exit_code == 0
assert "# i18n Key Report" in result.output
def test_report_to_file(self, temp_project_dir, temp_locale_dir, tmp_path):
"""Test report output to file."""
output_file = tmp_path / "report.md"
runner = CliRunner()
result = runner.invoke(main, [
"--locale-dir", str(temp_locale_dir),
"report",
str(temp_project_dir / "src"),
"--output", str(output_file),
"--format", "markdown",
])
assert result.exit_code == 0
assert output_file.exists()
content = output_file.read_text()
assert "# i18n Key Report" in content
class TestCLIVersion:
"""Tests for version flag."""
def test_version_flag(self):
"""Test --version flag displays version."""
runner = CliRunner()
result = runner.invoke(main, ["--version"])
assert result.exit_code == 0
assert "i18n-key-sync" in result.output