test: add tests for translations (#833)

* refactor: simplify pathlib imports

* feat: add tests for invalid format keys and missing / unnecessary translations

* feat: parametrise format key test

* feat: parametrise completeness test

* fix: include more useful information in the error message

* refactor: remove unused method

* refactor: extract translation loading to a separate function

* fix: include more useful information in the error message

* fix: don't fail test when language hasn't been completely translated
This commit is contained in:
Jann Stute
2025-03-07 00:28:48 +01:00
committed by GitHub
parent 4fe76f13fd
commit 6d1ff90355
6 changed files with 77 additions and 27 deletions

View File

@@ -1,11 +1,11 @@
import pathlib
import sys
from pathlib import Path
from tempfile import TemporaryDirectory
from unittest.mock import Mock, patch
import pytest
CWD = pathlib.Path(__file__).parent
CWD = Path(__file__).parent
# this needs to be above `src` imports
sys.path.insert(0, str(CWD.parent))
@@ -23,24 +23,24 @@ def cwd():
def file_mediatypes_library():
lib = Library()
status = lib.open_library(pathlib.Path(""), ":memory:")
status = lib.open_library(Path(""), ":memory:")
assert status.success
entry1 = Entry(
folder=lib.folder,
path=pathlib.Path("foo.png"),
path=Path("foo.png"),
fields=lib.default_fields,
)
entry2 = Entry(
folder=lib.folder,
path=pathlib.Path("bar.png"),
path=Path("bar.png"),
fields=lib.default_fields,
)
entry3 = Entry(
folder=lib.folder,
path=pathlib.Path("baz.apng"),
path=Path("baz.apng"),
fields=lib.default_fields,
)
@@ -61,7 +61,7 @@ def library(request):
library_path = request.param
lib = Library()
status = lib.open_library(pathlib.Path(library_path), ":memory:")
status = lib.open_library(Path(library_path), ":memory:")
assert status.success
tag = Tag(
@@ -92,7 +92,7 @@ def library(request):
entry = Entry(
id=1,
folder=lib.folder,
path=pathlib.Path("foo.txt"),
path=Path("foo.txt"),
fields=lib.default_fields,
)
assert lib.add_tags_to_entries(entry.id, tag.id)
@@ -100,7 +100,7 @@ def library(request):
entry2 = Entry(
id=2,
folder=lib.folder,
path=pathlib.Path("one/two/bar.md"),
path=Path("one/two/bar.md"),
fields=lib.default_fields,
)
assert lib.add_tags_to_entries(entry2.id, tag2.id)
@@ -114,7 +114,7 @@ def library(request):
@pytest.fixture
def search_library() -> Library:
lib = Library()
lib.open_library(pathlib.Path(CWD / "fixtures" / "search_library"))
lib.open_library(Path(CWD / "fixtures" / "search_library"))
return lib
@@ -133,8 +133,8 @@ def qt_driver(qtbot, library):
with TemporaryDirectory() as tmp_dir:
class Args:
config_file = pathlib.Path(tmp_dir) / "tagstudio.ini"
open = pathlib.Path(tmp_dir)
config_file = Path(tmp_dir) / "tagstudio.ini"
open = Path(tmp_dir)
ci = True
with patch("src.qt.ts_qt.Consumer"), patch("src.qt.ts_qt.CustomRunnable"):

View File

@@ -1,22 +1,22 @@
import pathlib
from pathlib import Path
from src.core.library import Entry
from src.core.utils.dupe_files import DupeRegistry
CWD = pathlib.Path(__file__).parent
CWD = Path(__file__).parent
def test_refresh_dupe_files(library):
library.library_dir = "/tmp/"
entry = Entry(
folder=library.folder,
path=pathlib.Path("bar/foo.txt"),
path=Path("bar/foo.txt"),
fields=library.default_fields,
)
entry2 = Entry(
folder=library.folder,
path=pathlib.Path("foo/foo.txt"),
path=Path("foo/foo.txt"),
fields=library.default_fields,
)
@@ -30,7 +30,7 @@ def test_refresh_dupe_files(library):
assert len(registry.groups) == 1
paths = [entry.path for entry in registry.groups[0]]
assert paths == [
pathlib.Path("bar/foo.txt"),
pathlib.Path("foo.txt"),
pathlib.Path("foo/foo.txt"),
Path("bar/foo.txt"),
Path("foo.txt"),
Path("foo/foo.txt"),
]

View File

@@ -1,4 +1,4 @@
import pathlib
from pathlib import Path
from tempfile import TemporaryDirectory
import pytest
@@ -6,7 +6,7 @@ from src.core.library import Library
from src.core.library.alchemy.enums import FilterState
from src.core.utils.missing_files import MissingRegistry
CWD = pathlib.Path(__file__).parent
CWD = Path(__file__).parent
# NOTE: Does this test actually work?
@@ -28,4 +28,4 @@ def test_refresh_missing_files(library: Library):
# `bar.md` should be relinked to new correct path
results = library.search_library(FilterState.from_path("bar.md"))
assert results[0].path == pathlib.Path("bar.md")
assert results[0].path == Path("bar.md")

View File

@@ -1,11 +1,11 @@
import pathlib
from pathlib import Path
from tempfile import TemporaryDirectory
import pytest
from src.core.enums import LibraryPrefs
from src.core.utils.refresh_dir import RefreshDirTracker
CWD = pathlib.Path(__file__).parent
CWD = Path(__file__).parent
@pytest.mark.parametrize("exclude_mode", [True, False])
@@ -22,4 +22,4 @@ def test_refresh_new_files(library, exclude_mode):
assert len(list(registry.refresh_dir(library.library_dir))) == 1
# Then
assert registry.files_not_in_library == [pathlib.Path("FOO.MD")]
assert registry.files_not_in_library == [Path("FOO.MD")]

View File

@@ -2,13 +2,13 @@
# Licensed under the GPL-3.0 License.
# Created for TagStudio: https://github.com/CyanVoxel/TagStudio
import pathlib
from pathlib import Path
from time import time
from src.core.enums import LibraryPrefs
from src.qt.widgets.migration_modal import JsonMigrationModal
CWD = pathlib.Path(__file__)
CWD = Path(__file__)
def test_json_migration():

View File

@@ -0,0 +1,50 @@
import string
from pathlib import Path
import pytest
import ujson as json
CWD = Path(__file__).parent
TRANSLATION_DIR = CWD / ".." / "resources" / "translations"
def load_translation(filename: str) -> dict[str, str]:
with open(TRANSLATION_DIR / filename, encoding="utf-8") as f:
return json.load(f)
def get_translation_filenames() -> list[tuple[str]]:
return [(a.name,) for a in TRANSLATION_DIR.glob("*.json")]
def find_format_keys(format_string: str) -> set[str]:
formatter = string.Formatter()
return set([field[1] for field in formatter.parse(format_string) if field[1] is not None])
@pytest.mark.parametrize(["translation_filename"], get_translation_filenames())
def test_format_key_validity(translation_filename: str):
default_translation = load_translation("en.json")
translation = load_translation(translation_filename)
for key in default_translation:
if key not in translation:
continue
default_keys = find_format_keys(default_translation[key])
translation_keys = find_format_keys(translation[key])
assert default_keys.issuperset(
translation_keys
), f"Translation {translation_filename} for key {key} is using an invalid format key ({translation_keys.difference(default_keys)})" # noqa: E501
assert translation_keys.issuperset(
default_keys
), f"Translation {translation_filename} for key {key} is missing format keys ({default_keys.difference(translation_keys)})" # noqa: E501
@pytest.mark.parametrize(["translation_filename"], get_translation_filenames())
def test_for_unnecessary_translations(translation_filename: str):
default_translation = load_translation("en.json")
translation = load_translation(translation_filename)
assert set(
default_translation.keys()
).issuperset(
translation.keys()
), f"Translation {translation_filename} has unnecessary keys ({set(translation.keys()).difference(default_translation.keys())})" # noqa: E501