Skip to content

Commit 8ac57f9

Browse files
committed
tests: add test cases for media types
1 parent b27581b commit 8ac57f9

3 files changed

Lines changed: 124 additions & 1 deletion

File tree

src/tagstudio/core/media_types.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44

55
import re
6+
from typing import Any
67

78
import structlog
89

@@ -108,6 +109,25 @@ class MediaTypes(metaclass=SanitizedAttr):
108109
all_groups: list[MediaTypeGroup] = []
109110
equivalent_exts: dict[str, set[str]] = {}
110111

112+
@classmethod
113+
def _snapshot(cls) -> dict[str, Any]:
114+
"""Return a snapshot of the class's attributes. Used in tests."""
115+
return {attr: getattr(cls, attr) for attr in dir(cls) if not attr.startswith("__")}
116+
117+
@classmethod
118+
def _restore(cls, attrs: dict[str, Any]) -> None:
119+
"""Restore the state of the class from a snapshot. Used in tests."""
120+
attrs_to_delete: list[str] = []
121+
for name in cls.__dict__:
122+
if not name.startswith("__"):
123+
try:
124+
setattr(cls, name, attrs[name])
125+
except KeyError:
126+
attrs_to_delete.append(name)
127+
128+
for attr in attrs_to_delete:
129+
delattr(cls, attr)
130+
111131
@classmethod
112132
def add_name_aliases(cls, group_key: str, names: str | list[str]) -> None:
113133
"""Adds one or more user-facing names for a MediaTypeGroup.

tests/conftest.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# SPDX-FileCopyrightText: (c) TagStudio Contributors
22
# SPDX-License-Identifier: GPL-3.0-only
33

4+
# pyright: reportPrivateUsage=false
5+
# pyright: reportUnusedFunction=false
6+
47

58
import sys
69
from collections.abc import Callable, Generator
@@ -13,6 +16,7 @@
1316
from pytestqt.qtbot import QtBot
1417

1518
from tagstudio.core.library.alchemy.fields import TextField
19+
from tagstudio.core.media_types import MediaTypes
1620

1721
CWD = Path(__file__).parent
1822
# this needs to be above `src` imports
@@ -148,11 +152,25 @@ def entry_full(library: Library):
148152

149153

150154
@pytest.fixture(autouse=True)
151-
def _init_qtbot(qtbot: QtBot): # pyright: ignore[reportUnusedFunction]
155+
def _init_qtbot(qtbot: QtBot):
152156
"""Ensures that a QtBot is initialized for all subsequent tests, regardless of order."""
153157
return qtbot
154158

155159

160+
@pytest.fixture(autouse=True)
161+
def _reset_media_types():
162+
"""Snapshot the MediaTypes state before each test, then restore it after."""
163+
pre_snapshop = MediaTypes._snapshot()
164+
165+
yield
166+
167+
post_snapshop = MediaTypes._snapshot()
168+
169+
if pre_snapshop != post_snapshop:
170+
MediaTypes._restore(pre_snapshop)
171+
assert pre_snapshop == MediaTypes._snapshot(), "The MediaTypes state was not restored!"
172+
173+
156174
@pytest.fixture
157175
def qt_driver(library: Library, library_dir: Path):
158176
class Args:

tests/core/test_media_types.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# SPDX-FileCopyrightText: (c) TagStudio Contributors
2+
# SPDX-License-Identifier: MIT
3+
4+
5+
from pytestqt.exceptions import pytest
6+
7+
from tagstudio.core.media_types import MediaTypes
8+
9+
10+
def test_register_and_contains():
11+
MediaTypes.register("zzztest.basic", ".zzzfoo", "SEARCH")
12+
13+
assert MediaTypes.contains("zzztest.basic", ".zzzfoo", "SEARCH")
14+
assert not MediaTypes.contains("zzztest.basic", ".zzzfoo", "RENDER")
15+
16+
17+
def test_additive_register():
18+
MediaTypes.register("zzztest.additive", ".zzzfoo", "SEARCH")
19+
MediaTypes.register("zzztest.additive", ".zzzbar", "SEARCH")
20+
21+
assert MediaTypes.contains("zzztest.additive", ".zzzfoo", "SEARCH")
22+
assert MediaTypes.contains("zzztest.additive", ".zzzbar", "SEARCH")
23+
24+
25+
def test_contains_missing_group_raises_error():
26+
with pytest.raises(AttributeError, match=r"is not registered"):
27+
MediaTypes.contains("zzztest.does_not_exist", ".zzzfoo", "SEARCH")
28+
29+
30+
def test_dot_notation_chains_to_parents():
31+
MediaTypes.register("zzztest.chain.parent.child", ".zzzchild", "SEARCH")
32+
33+
assert MediaTypes.contains("zzztest.chain.parent.child", ".zzzchild", "SEARCH")
34+
assert MediaTypes.contains("zzztest.chain.parent", ".zzzchild", "SEARCH")
35+
assert MediaTypes.contains("zzztest.chain", ".zzzchild", "SEARCH")
36+
37+
38+
def test_explicit_chain_group():
39+
MediaTypes.chain_group("zzztest.composite", ["zzztest.composite_child"])
40+
MediaTypes.register("zzztest.composite_child", ".zzzcomposite", "SEARCH")
41+
42+
assert MediaTypes.contains("zzztest.composite", ".zzzcomposite", "SEARCH")
43+
44+
45+
def test_equivalent_extensions():
46+
MediaTypes.register("zzztest.equiv", [".zzzone", ".zzztwo"], "SEARCH")
47+
48+
assert MediaTypes.get_equivalent_exts(".zzzone") == {".zzzone", ".zzztwo"}
49+
assert MediaTypes.get_equivalent_exts(".zzztwo") == {".zzzone", ".zzztwo"}
50+
assert MediaTypes.contains("zzztest.equiv", ".zzzone", "SEARCH")
51+
assert MediaTypes.contains("zzztest.equiv", ".zzztwo", "SEARCH")
52+
53+
54+
def test_get_equivalent_exts_defaults_to_itself():
55+
assert MediaTypes.get_equivalent_exts(".zzzunregistered") == {".zzzunregistered"}
56+
57+
58+
def test_find():
59+
MediaTypes.register("zzztest.find_a", ".zzzfind", "SEARCH")
60+
MediaTypes.register("zzztest.find_b", ".zzzfind", "RENDER")
61+
62+
search_keys = {group.key for group in MediaTypes.find(".zzzfind", "SEARCH")}
63+
render_keys = {group.key for group in MediaTypes.find(".zzzfind", "RENDER")}
64+
65+
assert "zzztest.find_a" in search_keys
66+
assert "zzztest.find_a" not in render_keys
67+
assert "zzztest.find_b" in render_keys
68+
assert "zzztest.find_b" not in search_keys
69+
70+
71+
def test_add_name_aliases_and_lookup():
72+
MediaTypes.register("zzztest.alias_target", ".zzzalias", "SEARCH")
73+
MediaTypes.add_name_aliases("zzztest.alias_target", ["ZZZ Test Group", "zzztest"])
74+
75+
assert MediaTypes.get_group_key_from_name("ZZZ Test Group") == "zzztest.alias_target"
76+
assert MediaTypes.get_group_key_from_name("zzz test group", case_sensitive=False) == (
77+
"zzztest.alias_target"
78+
)
79+
assert (
80+
MediaTypes.get_group_key_from_name(
81+
"zzztestGroup", case_sensitive=False, ignore_whitespace=True
82+
)
83+
== "zzztest.alias_target"
84+
)
85+
assert MediaTypes.get_group_key_from_name("Not A Real Alias") is None

0 commit comments

Comments
 (0)