From 257fa790a5b5e3639aa731e9d105490c16021ab3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20Gro=C3=9F?= Date: Mon, 16 Feb 2026 14:58:22 +0100 Subject: [PATCH 1/3] run python tests in CI --- .github/workflows/python.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/workflows/python.yml diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml new file mode 100644 index 00000000..59c8f933 --- /dev/null +++ b/.github/workflows/python.yml @@ -0,0 +1,18 @@ +name: Python + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + test: + name: Python Tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: astral-sh/setup-uv@v6 + - name: Run tests + working-directory: PythonScripts + run: uv run pytest From 14e225bbe48a0de7bf8301d795aef31a9d31aa75 Mon Sep 17 00:00:00 2001 From: Moritz Date: Mon, 16 Feb 2026 15:21:57 +0100 Subject: [PATCH 2/3] use pytest fixture to make console output tests portable --- PythonScripts/audit_translations/auditor.py | 4 ++-- .../audit_translations/tests/test_auditor.py | 19 +++++++++++++++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/PythonScripts/audit_translations/auditor.py b/PythonScripts/audit_translations/auditor.py index 0fac4d2a..9644cad0 100644 --- a/PythonScripts/audit_translations/auditor.py +++ b/PythonScripts/audit_translations/auditor.py @@ -53,11 +53,11 @@ def collect_from(directory: Path, root: Path) -> None: return for f in directory.glob("*.yaml"): if f.name != "prefs.yaml": # Skip prefs.yaml as it's not translated - files.add(str(f.relative_to(root))) + files.add(f.relative_to(root).as_posix()) shared_dir = directory / "SharedRules" if shared_dir.exists(): for f in shared_dir.glob("*.yaml"): - files.add(str(f.relative_to(root))) + files.add(f.relative_to(root).as_posix()) collect_from(lang_dir, lang_dir) if region_dir: diff --git a/PythonScripts/audit_translations/tests/test_auditor.py b/PythonScripts/audit_translations/tests/test_auditor.py index 6fcc5e07..cbada522 100644 --- a/PythonScripts/audit_translations/tests/test_auditor.py +++ b/PythonScripts/audit_translations/tests/test_auditor.py @@ -4,10 +4,21 @@ from pathlib import Path +import pytest + from ..auditor import collect_issues, compare_files, console, get_yaml_files, list_languages, print_warnings from ..dataclasses import ComparisonResult, RuleDifference, RuleInfo +@pytest.fixture() +def fixed_console_width(): + """Pin Rich console to 80 columns so golden-file comparisons are portable.""" + old = console.width + console.width = 80 + yield + console.width = old + + def make_rule(name: str, tag: str, line: int, raw: str) -> RuleInfo: return RuleInfo( name=name, @@ -183,9 +194,11 @@ def test_list_languages_includes_region_codes(tmp_path) -> None: assert "zz-aa" in output -def test_print_warnings_omits_snippets_when_not_verbose() -> None: +def test_print_warnings_omits_snippets_when_not_verbose(fixed_console_width) -> None: """ Ensure the print_warnings output matches the non-verbose golden snapshot. + + Uses pytest fixture for console width. """ base_dir = Path(__file__).parent fixtures_dir = base_dir / "fixtures" @@ -202,9 +215,11 @@ def test_print_warnings_omits_snippets_when_not_verbose() -> None: assert output == golden_path.read_text(encoding="utf-8") -def test_print_warnings_includes_snippets_when_verbose() -> None: +def test_print_warnings_includes_snippets_when_verbose(fixed_console_width) -> None: """ Ensure the print_warnings output matches the verbose golden snapshot. + + Uses pytest fixture for console width. """ base_dir = Path(__file__).parent fixtures_dir = base_dir / "fixtures" From d97027d9094f3440a7e69c47c3dc298921bf7083 Mon Sep 17 00:00:00 2001 From: Moritz Date: Mon, 16 Feb 2026 15:32:23 +0100 Subject: [PATCH 3/3] use Path-type instead of str for storing paths to Rules-files. --- PythonScripts/audit_translations/auditor.py | 10 +++++----- PythonScripts/audit_translations/tests/test_auditor.py | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/PythonScripts/audit_translations/auditor.py b/PythonScripts/audit_translations/auditor.py index 9644cad0..593475f6 100644 --- a/PythonScripts/audit_translations/auditor.py +++ b/PythonScripts/audit_translations/auditor.py @@ -44,20 +44,20 @@ def get_rules_dir(rules_dir: Optional[str] = None) -> Path: return package_dir.parent.parent / "Rules" / "Languages" -def get_yaml_files(lang_dir: Path, region_dir: Optional[Path] = None) -> List[str]: +def get_yaml_files(lang_dir: Path, region_dir: Optional[Path] = None) -> List[Path]: """Get all YAML files to audit for a language, including region overrides.""" - files: set[str] = set() + files: set[Path] = set() def collect_from(directory: Path, root: Path) -> None: if not directory.exists(): return for f in directory.glob("*.yaml"): if f.name != "prefs.yaml": # Skip prefs.yaml as it's not translated - files.add(f.relative_to(root).as_posix()) + files.add(f.relative_to(root)) shared_dir = directory / "SharedRules" if shared_dir.exists(): for f in shared_dir.glob("*.yaml"): - files.add(f.relative_to(root).as_posix()) + files.add(f.relative_to(root)) collect_from(lang_dir, lang_dir) if region_dir: @@ -177,7 +177,7 @@ def print_diff_item(diff: RuleDifference, line_en: int, line_tr: int, verbose: b def issue_base(rule: RuleInfo, file_name: str, language: str) -> dict: return { "language": language, - "file": file_name, + "file": Path(file_name).as_posix(), "rule_name": rule.name or "", "rule_tag": rule.tag or "", "rule_key": rule.key, diff --git a/PythonScripts/audit_translations/tests/test_auditor.py b/PythonScripts/audit_translations/tests/test_auditor.py index cbada522..8ed22a96 100644 --- a/PythonScripts/audit_translations/tests/test_auditor.py +++ b/PythonScripts/audit_translations/tests/test_auditor.py @@ -166,7 +166,7 @@ def test_get_yaml_files_includes_region(tmp_path) -> None: (region_dir / "unicode.yaml").write_text("---", encoding="utf-8") files = get_yaml_files(lang_dir, region_dir) - assert set(files) == {"base.yaml", "SharedRules/shared.yaml", "unicode.yaml"} + assert set(files) == {Path("base.yaml"), Path("SharedRules/shared.yaml"), Path("unicode.yaml")} def test_list_languages_includes_region_codes(tmp_path) -> None: