From e29433b388885f1a09a97517cd6ba89e0c09ef44 Mon Sep 17 00:00:00 2001 From: aclist <92275929+aclist@users.noreply.github.com> Date: Thu, 12 Nov 2026 05:08:54 +0900 Subject: [PATCH 1/6] chore: typehint tests --- tests/fixtures/__init__.py | 6 ++++-- tests/test_app_download_settings.py | 12 +++++++----- tests/test_bare_conf_files.py | 14 ++++++++++---- tests/test_changelog.py | 4 ++-- tests/test_client_name.py | 9 +++++++-- tests/test_colorscheme.py | 4 ++-- tests/test_columns.py | 27 +++++++++++++++++++++------ tests/test_config.py | 29 +++++++++++++++++------------ tests/test_flatpak_override.py | 18 +++++++++++------- tests/test_flatpak_toggle.py | 3 ++- tests/test_geo_file.py | 9 ++++++--- tests/test_html_escaping.py | 18 +++++++++++------- tests/test_ip.py | 2 +- tests/test_list_store.py | 18 +++++++++++------- tests/test_locale.py | 13 +++++++++---- tests/test_log_redaction.py | 6 +++--- tests/test_path_conversion.py | 7 ++++++- tests/test_paused_downloads.py | 8 +++++++- tests/test_pefile.py | 18 +++++++++--------- tests/test_process_detection.py | 14 +++++++------- tests/test_remote_api.py | 13 +++++++++---- tests/test_server_metadata.py | 2 +- tests/test_shortcuts.py | 9 +++++++-- 23 files changed, 170 insertions(+), 93 deletions(-) diff --git a/tests/fixtures/__init__.py b/tests/fixtures/__init__.py index 31577b5..043f9fc 100644 --- a/tests/fixtures/__init__.py +++ b/tests/fixtures/__init__.py @@ -1,5 +1,7 @@ from pathlib import Path CWD = Path(__file__).parent -def fixture_path(fixture: str) -> str: - return str(CWD / fixture) + + +def fixture_path(fixture: str) -> Path: + return Path(CWD).joinpath(fixture) diff --git a/tests/test_app_download_settings.py b/tests/test_app_download_settings.py index ad2639b..f47c337 100644 --- a/tests/test_app_download_settings.py +++ b/tests/test_app_download_settings.py @@ -43,23 +43,25 @@ def patch_api() -> None: mp.undo() -def test_no_last_update(steam_path) -> None: +def test_no_last_update(steam_path: Path) -> None: assert get_last_updated(steam_path, 555) is None -def test_last_update(steam_path) -> None: +def test_last_update(steam_path: Path) -> None: assert get_last_updated(steam_path, 444) == "2026-10-22 00:09:33" -def test_app_allows_downloads(steam_path) -> None: +def test_app_allows_downloads(steam_path: Path) -> None: assert get_app_allows_downloads(steam_path, 111) is True -def test_app_disallows_downloads(steam_path): +def test_app_disallows_downloads(steam_path: Path) -> None: assert get_app_allows_downloads(steam_path, 222) is False -def test_app_delegates_downloads(monkeypatch, steam_path, client_allows): +def test_app_delegates_downloads( + monkeypatch: MonkeyPatch, steam_path: Path, client_allows: Path +) -> None: monkeypatch.setattr("dzgui.api.steam.get_config", mock_config_disallows) assert get_app_allows_downloads(steam_path, 333) is False monkeypatch.setattr("dzgui.api.steam.get_config", mock_config_allows) diff --git a/tests/test_bare_conf_files.py b/tests/test_bare_conf_files.py index 052b829..e8ecf40 100644 --- a/tests/test_bare_conf_files.py +++ b/tests/test_bare_conf_files.py @@ -1,6 +1,8 @@ import pytest import tempfile +from typing import TYPE_CHECKING + from dzgui.app_init import copy_bare_configs from dzgui.config.xdg import get_xdg_paths, parse_filepaths @@ -8,9 +10,13 @@ from dzgui.config.xdg import get_xdg_paths, parse_filepaths CONF_STRING = "DZGUI_CONF\n" STATE_STRING = "DZGUI_STATE\n" +if TYPE_CHECKING: + from _pytest.monkeypatch import MonkeyPatch + from dzgui.config.xdg import Xdg + @pytest.fixture -def state_files(): +def state_files() -> list[str]: state = [ "dzg.history", "dzg.versions", @@ -25,7 +31,7 @@ def state_files(): @pytest.fixture -def xdg_paths(monkeypatch): +def xdg_paths(monkeypatch: "MonkeyPatch") -> "Xdg": routes = { "XDG_CONFIG_HOME": "", "XDG_STATE_HOME": "", @@ -42,7 +48,7 @@ def xdg_paths(monkeypatch): @pytest.mark.mods -def test_config_file_import(xdg_paths, state_files): +def test_config_file_import(xdg_paths: "Xdg", state_files: list[str]) -> None: # NOTE: write bare files in root tmp_conf = xdg_paths.config.parent.parent @@ -67,7 +73,7 @@ def test_config_file_import(xdg_paths, state_files): @pytest.mark.mods -def test_config_file_no_import(xdg_paths, state_files): +def test_config_file_no_import(xdg_paths: "Xdg", state_files: list[str]) -> None: for subdir in xdg_paths.config.parent, xdg_paths.resolution.parent: subdir.mkdir() diff --git a/tests/test_changelog.py b/tests/test_changelog.py index e897571..95490d3 100644 --- a/tests/test_changelog.py +++ b/tests/test_changelog.py @@ -5,7 +5,7 @@ from pathlib import Path @pytest.fixture -def changelog(request) -> None: +def changelog(request: pytest.FixtureRequest) -> str: root = request.config.rootpath changelog = Path(root).joinpath("CHANGELOG.md").read_text() return changelog @@ -19,7 +19,7 @@ def count_hash(line: str) -> int: return cnt -def test_changelog_prefix(changelog) -> None: +def test_changelog_prefix(changelog: str) -> None: r = r".*(\[.*\]).*" lines = changelog.splitlines() sort = sorted(lines) diff --git a/tests/test_client_name.py b/tests/test_client_name.py index 27f81fc..294b71b 100644 --- a/tests/test_client_name.py +++ b/tests/test_client_name.py @@ -1,14 +1,19 @@ import pytest +from typing import Any, TYPE_CHECKING + from dzgui.const.constants import FLATPAK_RUN_CMD, STEAM_CMD from dzgui.controllers.mc import Controller +if TYPE_CHECKING: + from _pytest.monkeypatch import MonkeyPatch + @pytest.mark.parametrize( "value, expected", [(FLATPAK_RUN_CMD, "Flatpak"), (STEAM_CMD, "Steam")] ) -def test_human_name(monkeypatch, value, expected) -> None: - def mock_query_config(*args) -> str: +def test_human_name(monkeypatch: "MonkeyPatch", value: str, expected: str) -> None: + def mock_query_config(*args: Any) -> str: return value monkeypatch.setattr( diff --git a/tests/test_colorscheme.py b/tests/test_colorscheme.py index a8818dc..089f46d 100644 --- a/tests/test_colorscheme.py +++ b/tests/test_colorscheme.py @@ -10,7 +10,7 @@ gi.require_version("Gtk", "3.0") from gi.repository import Gtk, Gio, GLib # noqa -class DummyWidget(ColorAwareApp, Gtk.Button): +class DummyWidget(ColorAwareApp, Gtk.Button): # type: ignore def __init__(self) -> None: super().__init__() @@ -27,7 +27,7 @@ def widget() -> DummyWidget: @pytest.mark.parametrize("key, expect", [("default", False), ("prefer-dark", True)]) -def test_light_mode(widget, key: str, expect: bool) -> None: +def test_light_mode(widget: DummyWidget, key: str, expect: bool) -> None: local_pref = subprocess.run( ["gsettings", "get", "org.gnome.desktop.interface", "color-scheme"], capture_output=True, diff --git a/tests/test_columns.py b/tests/test_columns.py index e0a06f6..0567cbb 100644 --- a/tests/test_columns.py +++ b/tests/test_columns.py @@ -1,33 +1,48 @@ import pytest +from typing import TYPE_CHECKING + from dzgui.init.migrate import convert_cols_file from tests.fixtures import fixture_path +if TYPE_CHECKING: + from pathlib import Path + + @pytest.fixture -def columns_with_perspective(): +def columns_with_perspective() -> "Path": return fixture_path("columns_1") + @pytest.fixture -def columns_without_perspective(): +def columns_without_perspective() -> "Path": return fixture_path("columns_2") + @pytest.fixture -def columns_with_view(): +def columns_with_view() -> "Path": return fixture_path("columns_3") + @pytest.mark.config -def test_columns_with_perspective(columns_with_perspective): +def test_columns_with_perspective(columns_with_perspective: "Path") -> None: j = convert_cols_file(columns_with_perspective) + if j is None: + return assert "View" in j["cols"] assert "Max" in j["cols"] + @pytest.mark.config -def test_columns_without_perspective(columns_without_perspective): +def test_columns_without_perspective(columns_without_perspective: "Path") -> None: j = convert_cols_file(columns_without_perspective) + if j is None: + return assert "View" not in j["cols"] assert "Max" not in j["cols"] + @pytest.mark.config -def test_columns_with_view(columns_with_view): +def test_columns_with_view(columns_with_view: "Path") -> None: j = convert_cols_file(columns_with_view) assert j is None diff --git a/tests/test_config.py b/tests/test_config.py index 9bbe872..da4bf4e 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1,25 +1,30 @@ import json import pytest +from typing import Any, TYPE_CHECKING + from dzgui.const.boilerplate import config_boilerplate from dzgui.config.query import get_config from dzgui.config.xdg import get_xdg_paths, parse_filepaths from dzgui.config import convert from tests.fixtures import fixture_path +if TYPE_CHECKING: + from pathlib import Path + @pytest.fixture -def legacy_config(): +def legacy_config() -> "Path": return fixture_path("dztuirc_1") @pytest.fixture -def unset_values(): +def unset_values() -> "Path": return fixture_path("dztuirc_3") @pytest.fixture -def keys(): +def keys() -> list[str]: return [ "fav_server", "fav_label", @@ -36,7 +41,7 @@ def keys(): # TODO: use a static fixture instead of system config @pytest.fixture -def config(): +def config() -> Any: paths = get_xdg_paths() xdg = parse_filepaths(paths) return get_config(xdg.config) @@ -44,21 +49,21 @@ def config(): @pytest.mark.post_install @pytest.mark.realconfig -def test_invalid_config_value(config): +def test_invalid_config_value(config: Any) -> None: with pytest.raises(Exception): assert config["foo"] is None @pytest.mark.post_install @pytest.mark.realconfig -def test_default_config_values(keys, config): +def test_default_config_values(keys: list[str], config: Any) -> None: for key in keys: assert config[key] is not None @pytest.mark.post_install @pytest.mark.realconfig -def test_contains_invalid_values(keys, config): +def test_contains_invalid_values(keys: list[str], config: Any) -> None: for key in config: assert key in keys @@ -70,15 +75,15 @@ def test_contains_invalid_values(keys, config): ("dztuirc_2", (False, False, False)), ], ) -def test_bool_conversion(fixture, expect): - fixture = fixture_path(fixture) - j = convert.rc2json(fixture) +def test_bool_conversion(fixture: str, expect: tuple[bool, bool, bool]) -> None: + fixture_p = fixture_path(fixture) + j = convert.rc2json(fixture_p) j = json.loads(j) assert j["fullscreen"] == expect[0] assert not j["use_miles"] -def test_key_conversion(legacy_config): +def test_key_conversion(legacy_config: "Path") -> None: j = convert.rc2json(legacy_config) j = json.loads(j) keys = [ @@ -92,7 +97,7 @@ def test_key_conversion(legacy_config): assert key not in j -def test_missing_values(unset_values): +def test_missing_values(unset_values: "Path") -> None: j = convert.rc2json(unset_values) j = json.loads(j) assert j.keys() == config_boilerplate.keys() diff --git a/tests/test_flatpak_override.py b/tests/test_flatpak_override.py index eeb640a..6a5fcdd 100644 --- a/tests/test_flatpak_override.py +++ b/tests/test_flatpak_override.py @@ -1,6 +1,8 @@ import configparser import pytest +from pathlib import Path + from dzgui.const.constants import FLATPAK_APPID, GTK_APP_ID, TMP_PATH from dzgui.config.xdg import get_xdg_paths from dzgui.util.flatpak import apply_overrides @@ -13,17 +15,17 @@ pytestmark = pytest.mark.flatpak @pytest.fixture -def xdg_paths() -> dict[str, str]: +def xdg_paths() -> dict[str, Path]: return get_xdg_paths() @pytest.fixture -def override(xdg_paths) -> None: +def override(xdg_paths: dict[str, Path]) -> None: apply_overrides(xdg_paths) @pytest.fixture -def config(xdg_paths) -> configparser.ConfigParser: +def config(xdg_paths: dict[str, Path]) -> configparser.ConfigParser: conf_path = xdg_paths["XDG_DATA_HOME"].parent.joinpath( f"flatpak/overrides/{FLATPAK_APPID}" ) @@ -32,14 +34,16 @@ def config(xdg_paths) -> configparser.ConfigParser: return config -def test_session_bus(override, config) -> None: +def test_session_bus(override: None, config: configparser.ConfigParser) -> None: bus = config[BUS_KEY][GTK_APP_ID] assert bus == "own" -def test_paths(override, xdg_paths, config) -> None: - expect: list[str] = [] - expect.append(TMP_PATH) +def test_paths( + override: None, xdg_paths: dict[str, Path], config: configparser.ConfigParser +) -> None: + expect: list[Path] = [] + expect.append(Path(TMP_PATH)) expect.extend([*xdg_paths.values()]) paths = config[PATHS_KEY][PATHS_SUBKEY].split(";") assert all(str(path) in paths for path in expect) diff --git a/tests/test_flatpak_toggle.py b/tests/test_flatpak_toggle.py index eec56e7..ca17f7a 100644 --- a/tests/test_flatpak_toggle.py +++ b/tests/test_flatpak_toggle.py @@ -2,10 +2,11 @@ import pytest from dzgui.const.constants import FLATPAK_RUN_CMD, FLATPAK_SANDBOX from dzgui.const.enum import Preferences +from dzgui.controllers.mc import Controller from dzgui.views.pages.options import FlatpakToggleField -class MockController: +class MockController(Controller): def __init__(self) -> None: self.command: str diff --git a/tests/test_geo_file.py b/tests/test_geo_file.py index 17c195f..6d962e5 100644 --- a/tests/test_geo_file.py +++ b/tests/test_geo_file.py @@ -20,20 +20,23 @@ def get_db_len(path: Path) -> int: c = conn.cursor() c.execute("SELECT COUNT(*) from ips") db_len = c.fetchone()[0] - return db_len + return int(db_len) @pytest.fixture def csv() -> Path: csv = Path(tempfile.NamedTemporaryFile().name) url = find_download_url(DB_IP) + if url is None: + raise ValueError() tmp = serialize(url) unzip(tmp, csv) strip_ipv6(csv) return csv + @pytest.mark.slow -def test_stripping(csv): +def test_stripping(csv: Path) -> None: with open(csv, "rb") as f: first = f.readline().decode().rstrip() try: @@ -52,7 +55,7 @@ def test_stripping(csv): @pytest.mark.slow -def test_row_parity(csv) -> None: +def test_row_parity(csv: Path) -> None: rows = csv.read_text().splitlines() db = Path(tempfile.NamedTemporaryFile().name) diff --git a/tests/test_html_escaping.py b/tests/test_html_escaping.py index 2c3c03c..ed9e42a 100644 --- a/tests/test_html_escaping.py +++ b/tests/test_html_escaping.py @@ -1,26 +1,30 @@ +import gi import pytest +from typing import Any from dzgui.api.servers import Details +from dzgui.controllers.mc import Controller +from dzgui.controllers.emitter import Emitter +from dzgui.views.base import OuterWindow from dzgui.views.dialogs.servers import ServerDetailsDialog -import gi gi.require_version("Gtk", "3.0") from gi.repository import Gtk -class MockController: +class MockController(Controller): def __init__(self) -> None: - self.window = Gtk.Window() + pass - def get_window(self) -> Gtk.Window: - return self.window + def get_window(self) -> None: # type: ignore[override] + return None def get_server_name(self) -> str: return "My server" - def get_emitter(self) -> None: - return None + def get_emitter(self) -> Emitter: + return Emitter() @pytest.mark.filterwarnings("ignore::DeprecationWarning") diff --git a/tests/test_ip.py b/tests/test_ip.py index 3178b80..899c5da 100644 --- a/tests/test_ip.py +++ b/tests/test_ip.py @@ -15,7 +15,7 @@ from dzgui.views.components.entry import validate_ip_truthy ("192.168.1.101:27016", True), ], ) -def test_ip_entry(ip) -> None: +def test_ip_entry(ip: tuple[str, bool]) -> None: string, state = ip assert validate_ip_truthy(string) is state diff --git a/tests/test_list_store.py b/tests/test_list_store.py index 88ff1bd..4342b8c 100644 --- a/tests/test_list_store.py +++ b/tests/test_list_store.py @@ -1,27 +1,29 @@ import pytest +from typing import Any + from dzgui.model.model_factory import FastInsertListStore @pytest.fixture -def heterogeneous_list() -> None: +def heterogeneous_list() -> list[list[Any]]: return [["a", 0, True], ["b", 1, False]] @pytest.fixture -def mismatched_length_list() -> None: +def mismatched_length_list() -> list[list[Any]]: return [["a", 0, True], ["b", 1, False, 0]] @pytest.fixture -def extended_list(heterogeneous_list) -> None: +def extended_list(heterogeneous_list: list[list[Any]]) -> FastInsertListStore: fs = FastInsertListStore(str, int, bool) fs.extend(heterogeneous_list) return fs @pytest.fixture -def appended_list(heterogeneous_list) -> None: +def appended_list(heterogeneous_list: list[list[Any]]) -> FastInsertListStore: fs = FastInsertListStore(str, int, bool) for row in heterogeneous_list: fs.append(row) @@ -29,19 +31,21 @@ def appended_list(heterogeneous_list) -> None: @pytest.mark.parametrize("target", ["extended_list", "appended_list"]) -def test_list_parity(heterogeneous_list, request, target) -> None: +def test_list_parity( + heterogeneous_list: list[list[Any]], request: pytest.FixtureRequest, target: str +) -> None: target = request.getfixturevalue(target) extracted = [[el for el in row] for row in target] assert heterogeneous_list == extracted -def test_type_disparity(heterogeneous_list) -> None: +def test_type_disparity(heterogeneous_list: list[list[Any]]) -> None: with pytest.raises(TypeError): fs = FastInsertListStore(str, bool, bool) fs.extend(heterogeneous_list) -def test_length_disparity(mismatched_length_list) -> None: +def test_length_disparity(mismatched_length_list: list[list[Any]]) -> None: with pytest.raises(ValueError): fs = FastInsertListStore(str, int, bool) fs.extend(mismatched_length_list) diff --git a/tests/test_locale.py b/tests/test_locale.py index 53a3f59..0cec0bf 100644 --- a/tests/test_locale.py +++ b/tests/test_locale.py @@ -1,27 +1,32 @@ +from typing import TYPE_CHECKING + from dzgui.util import localize +if TYPE_CHECKING: + from _pytest.monkeypatch import MonkeyPatch -def test_de(monkeypatch): + +def test_de(monkeypatch: "MonkeyPatch") -> None: monkeypatch.setenv("LC_ALL", "de_DE.UTF-8") localize.set_locale() assert localize.number(9900) == "9.900" assert localize.number(99.88) == "99,88" -def test_en(monkeypatch): +def test_en(monkeypatch: "MonkeyPatch") -> None: monkeypatch.setenv("LC_ALL", "en_US.UTF-8") localize.set_locale() assert localize.number(9900) == "9,900" assert localize.number(99.88) == "99.88" -def test_none(monkeypatch): +def test_none(monkeypatch: "MonkeyPatch") -> None: localize.set_locale() assert localize.number(9900) == "9,900" assert localize.number(99.88) == "99.88" -def test_empty(monkeypatch): +def test_empty(monkeypatch: "MonkeyPatch") -> None: monkeypatch.setenv("LC_ALL", "") localize.set_locale() assert localize.number(9900) == "9,900" diff --git a/tests/test_log_redaction.py b/tests/test_log_redaction.py index 438a195..adff66f 100644 --- a/tests/test_log_redaction.py +++ b/tests/test_log_redaction.py @@ -7,13 +7,13 @@ from dzgui.util.redact import RedactionFilter, REDACTION_PATTERNS class RecordsListHandler(logging.Handler): def __init__(self) -> None: super().__init__() - self.records_list = [] + self.records_list: list[logging.LogRecord] = [] def emit(self, record: logging.LogRecord) -> None: self.records_list.append(record) - def pop(self) -> None: - return self.records_list[-1].msg + def pop(self) -> str: + return str(self.records_list[-1].msg) @pytest.mark.redact diff --git a/tests/test_path_conversion.py b/tests/test_path_conversion.py index c9b1710..c2d1185 100644 --- a/tests/test_path_conversion.py +++ b/tests/test_path_conversion.py @@ -1,8 +1,13 @@ from pathlib import Path +from typing import TYPE_CHECKING + from dzgui.config.xdg import get_xdg_paths +if TYPE_CHECKING: + from _pytest.monkeypatch import MonkeyPatch -def test_path_fallback(monkeypatch) -> None: + +def test_path_fallback(monkeypatch: "MonkeyPatch") -> None: envs = ["XDG_DATA_HOME", "XDG_STATE_HOME", "XDG_CONFIG_HOME", "XDG_CACHE_HOME"] for env in envs: monkeypatch.setenv(env, "/etc/dzgui") diff --git a/tests/test_paused_downloads.py b/tests/test_paused_downloads.py index 1c45ca2..6183e93 100644 --- a/tests/test_paused_downloads.py +++ b/tests/test_paused_downloads.py @@ -1,8 +1,12 @@ import pytest from pathlib import Path +from typing import TYPE_CHECKING from dzgui.api.steam import is_dayz_downloading +if TYPE_CHECKING: + from _pytest.monkeypatch import MonkeyPatch + @pytest.mark.parametrize( "file_list, expect", @@ -16,7 +20,9 @@ from dzgui.api.steam import is_dayz_downloading (["state_221100_1111"], False), ], ) -def test_dayz_patch_pending(monkeypatch, file_list: list[str], expect: bool) -> None: +def test_dayz_patch_pending( + monkeypatch: "MonkeyPatch", file_list: list[str], expect: bool +) -> None: def mock_get_pending_downloads(steam_path: Path, appid: int) -> None: files = [Path(file) for file in file_list] return files diff --git a/tests/test_pefile.py b/tests/test_pefile.py index ebcfb0e..6d6be0a 100644 --- a/tests/test_pefile.py +++ b/tests/test_pefile.py @@ -7,7 +7,7 @@ from dzgui.api.steam import ( VDFLoadError, AppNotInstalledError, AppMovedError, - get_app_path + get_app_path, ) from dzgui.config.query import get_config @@ -20,16 +20,14 @@ pytestmark = pytest.mark.apitest @pytest.fixture -def default_steam_path(): +def default_steam_path() -> str: paths = get_xdg_paths() xdg = parse_filepaths(paths) conf = get_config(xdg.config) - return conf["default_steam_path"] + return str(conf["default_steam_path"]) -# TODO: split into separate test file -# FIXME: use fixtures -def test_pefile_length(default_steam_path): +def test_pefile_length(default_steam_path: str) -> None: try: pe_file_path = PeFile.get_pefile_path(Path(default_steam_path), APPID_DAYZ) vers = PeFile.get_dayz_version(pe_file_path) @@ -39,7 +37,7 @@ def test_pefile_length(default_steam_path): assert len(st) == 3 -def test_invalid_pefile_path(): +def test_invalid_pefile_path() -> None: with pytest.raises(VDFLoadError): try: PeFile.get_pefile_path(Path("/not/a/path"), APPID_DAYZ) @@ -57,6 +55,7 @@ def test_invalid_pefile_path(): ) def test_not_in_library(monkeypatch, fixture, exception): import dzgui.api.steam as steam + monkeypatch.setattr(steam, "LIBRARYFOLDERS_PATH", fixture) folder_path = Path(fixture_path("api")) @@ -68,12 +67,13 @@ def test_not_in_library(monkeypatch, fixture, exception): @pytest.fixture -def second_drive(): +def second_drive() -> str: return "in_library_on_second_drive.vdf" -def test_on_second_drive(monkeypatch, second_drive): +def test_on_second_drive(monkeypatch, second_drive: str) -> None: import dzgui.api.steam as steam + monkeypatch.setattr(steam, "LIBRARYFOLDERS_PATH", second_drive) folder_path = Path(fixture_path("api")) path = get_app_path(folder_path, APPID_DAYZ) diff --git a/tests/test_process_detection.py b/tests/test_process_detection.py index 8b25c9b..cc89f05 100644 --- a/tests/test_process_detection.py +++ b/tests/test_process_detection.py @@ -14,9 +14,9 @@ pytestmark = pytest.mark.flatpak class TestSteamDetection(unittest.TestCase): - def test_flatpak_detection_with_multiple_running_apps(self): - def flatpak_output(args, *, text): - # Default `flatpak ps` includes instance, PID, app and runtime columns. + def test_flatpak_detection_with_multiple_running_apps(self) -> None: + def flatpak_output(args, *, text: str) -> str: + # Default 'flatpak ps' includes instance, PID, app and runtime columns. if args == ["flatpak", "ps", "--columns=application"]: return f"com.spotify.Client\n{FLATPAK_APPID}\n{FLATPAK_APPID}\n" return f"3904921611\t1257689\t{FLATPAK_APPID}\torg.freedesktop.Platform\n" @@ -29,7 +29,7 @@ class TestSteamDetection(unittest.TestCase): with self.subTest(client=client): self.assertTrue(proc.is_steam_running(client)) - def test_flatpak_not_running(self): + def test_flatpak_not_running(self) -> None: with patch.object(proc, "has_cmd", return_value=True): for output in ("", "com.spotify.Client\n", f"{FLATPAK_APPID}Helper\n"): with ( @@ -38,7 +38,7 @@ class TestSteamDetection(unittest.TestCase): ): self.assertFalse(proc.is_flatpak_steam_running()) - def test_flatpak_not_installed(self): + def test_flatpak_not_installed(self) -> None: with ( patch.object(proc, "has_cmd", return_value=False), patch.object(proc.subprocess, "check_output") as check_output, @@ -46,7 +46,7 @@ class TestSteamDetection(unittest.TestCase): self.assertFalse(proc.is_flatpak_steam_running()) check_output.assert_not_called() - def test_native_steam(self): + def test_native_steam(self) -> None: with patch.object(proc, "has_cmd", return_value=True): for output, expected in ( ( @@ -73,6 +73,6 @@ class TestSteamDetection(unittest.TestCase): ): self.assertEqual(proc.is_native_steam_running(), expected) - def test_invalid_client(self): + def test_invalid_client(self) -> None: with self.assertRaises(TypeError): proc.is_steam_running("invalid-client") diff --git a/tests/test_remote_api.py b/tests/test_remote_api.py index bebd184..a340510 100644 --- a/tests/test_remote_api.py +++ b/tests/test_remote_api.py @@ -1,23 +1,28 @@ import pytest +from typing import TYPE_CHECKING + +from dzgui.api import probe from dzgui.config.query import get_config from dzgui.config.xdg import get_xdg_paths, parse_filepaths -from dzgui.api import probe + +if TYPE_CHECKING: + from pathlib import Path pytestmark = pytest.mark.webtest @pytest.fixture -def config(): +def config() -> dict[str, "Path"]: paths = get_xdg_paths() xdg = parse_filepaths(paths) return get_config(xdg.config) -def test_ipdb(): +def test_ipdb() -> None: assert probe.test_ipdb() -def test_steam(config): +def test_steam(config: dict[str, "Path"]) -> None: key = config["steam_api"] assert probe.test_steam_api(key) diff --git a/tests/test_server_metadata.py b/tests/test_server_metadata.py index bdde14b..0c8eac7 100644 --- a/tests/test_server_metadata.py +++ b/tests/test_server_metadata.py @@ -23,7 +23,7 @@ def test_time_accel(details, key, expect) -> None: assert getattr(details, key) == expect -def test_gametime(details) -> None: +def test_gametime(details: Details | None) -> None: time_reg = r"^(0[0-9]|1[0-9]|2[0-3]):([0-5][0-9]$)" match = re.match(time_reg, details.gametime) assert match is not None diff --git a/tests/test_shortcuts.py b/tests/test_shortcuts.py index eea75e4..ac23e9d 100644 --- a/tests/test_shortcuts.py +++ b/tests/test_shortcuts.py @@ -1,12 +1,17 @@ import pytest import tempfile +from typing import TYPE_CHECKING + from pathlib import Path from _pytest.monkeypatch import MonkeyPatch from dzgui.api.shortcuts import Shortcuts from tests.fixtures import fixture_path +if TYPE_CHECKING: + from _pytest.monkeypatch import MonkeyPatch + pytestmark = pytest.mark.apitest @@ -22,13 +27,13 @@ def patch_api() -> None: mp.undo() -def test_no_shortcuts(monkeypatch) -> None: +def test_no_shortcuts(monkeypatch: "MonkeyPatch") -> None: s = Shortcuts(Path("")) assert len(s.shortcuts["shortcuts"]) == 0 @pytest.fixture -def dummy_app() -> None: +def dummy_app() -> dict[str, str]: d = { "AppName": "TEST APP", "StartDir": "TEST_DIR", From 3e7b49203ac515768a255d1c615c3edd0ad849bc Mon Sep 17 00:00:00 2001 From: aclist <92275929+aclist@users.noreply.github.com> Date: Thu, 12 Nov 2026 06:20:16 +0900 Subject: [PATCH 2/6] chore: add mark to test --- tests/test_server_metadata.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_server_metadata.py b/tests/test_server_metadata.py index 0c8eac7..dc3408c 100644 --- a/tests/test_server_metadata.py +++ b/tests/test_server_metadata.py @@ -3,6 +3,8 @@ import re from dzgui.api.servers import Details, Record, get_details +pytestmark = pytest.mark.slow + @pytest.fixture def details() -> Details: From f7d95d54072cab18f7a2e677a62801ccff095805 Mon Sep 17 00:00:00 2001 From: aclist <92275929+aclist@users.noreply.github.com> Date: Thu, 12 Nov 2026 07:10:27 +0900 Subject: [PATCH 3/6] chore: clear typehinting errors --- tests/test_app_download_settings.py | 3 +- tests/test_loginusers.py | 8 +++- tests/test_mod_signatures.py | 21 ++++++--- tests/test_modmeta.py | 3 ++ tests/test_paused_downloads.py | 4 +- tests/test_pefile.py | 12 +++-- tests/test_process_detection.py | 4 +- tests/test_remote_api.py | 6 +-- tests/test_server_metadata.py | 2 + tests/test_server_time.py | 24 +++++++--- tests/test_shortcuts.py | 73 ++++++++++++++--------------- 11 files changed, 99 insertions(+), 61 deletions(-) diff --git a/tests/test_app_download_settings.py b/tests/test_app_download_settings.py index f47c337..b30f44f 100644 --- a/tests/test_app_download_settings.py +++ b/tests/test_app_download_settings.py @@ -1,6 +1,7 @@ import pytest from _pytest.monkeypatch import MonkeyPatch +from collections.abc import Iterator from pathlib import Path from dzgui.api.steam import get_app_allows_downloads, get_last_updated @@ -36,7 +37,7 @@ def steam_path() -> Path: @pytest.fixture(scope="module", autouse=True) -def patch_api() -> None: +def patch_api() -> Iterator[None]: mp = MonkeyPatch() mp.setattr("dzgui.api.steam.get_app_path", mock_path) yield diff --git a/tests/test_loginusers.py b/tests/test_loginusers.py index db96c56..cfcba50 100644 --- a/tests/test_loginusers.py +++ b/tests/test_loginusers.py @@ -1,6 +1,7 @@ import pytest from pathlib import Path +from typing import TYPE_CHECKING from dzgui.api.steam import find_user_id from dzgui.const.constants import DEFAULT_STEAM_PATH @@ -8,6 +9,9 @@ from tests.fixtures import fixture_path pytestmark = pytest.mark.apitest +if TYPE_CHECKING: + from _pytest.monkeypatch import MonkeyPatch + @pytest.mark.parametrize( "fixture, expect", @@ -19,12 +23,14 @@ pytestmark = pytest.mark.apitest ("api/loginusers_beta_client_multiple_2.vdf", 0), ], ) -def test_loginusers(monkeypatch, fixture: str, expect: int) -> None: +def test_loginusers(monkeypatch: "MonkeyPatch", fixture: str, expect: int) -> None: def mock_loginusers(path: Path) -> Path: return fixture_path(fixture) monkeypatch.setattr("dzgui.api.steam.find_loginusers", mock_loginusers) uid = find_user_id(Path("")) + if uid is None: + raise ValueError() assert int(uid) == expect diff --git a/tests/test_mod_signatures.py b/tests/test_mod_signatures.py index 8aa5dd6..8de0fc7 100644 --- a/tests/test_mod_signatures.py +++ b/tests/test_mod_signatures.py @@ -11,27 +11,33 @@ import dzgui.config.query from tests.fixtures import fixture_path if TYPE_CHECKING: - from dzgui.const.enums import Preferences + from _pytest.monkeypatch import MonkeyPatch + from dzgui.const.enum import Preferences pytestmark = pytest.mark.mods + @pytest.fixture -def versions() -> str: +def versions() -> "Path": return fixture_path("dzg.versions") + @pytest.fixture def tmp() -> str: with tempfile.NamedTemporaryFile(delete=False) as f: tmp = f.name return tmp + def mock_local_ids(path: Path) -> list[int]: return [3410710885, 3739934289] + def mock_lookup(path: Path, prefs: "Preferences") -> str: return "" -def test_signatures(monkeypatch, tmp: str, versions: str) -> None: + +def test_signatures(monkeypatch: "MonkeyPatch", tmp: str, versions: str) -> None: ids = [1559212036, 1654462998] shutil.copyfile(versions, tmp) path = Path(tmp) @@ -41,12 +47,15 @@ def test_signatures(monkeypatch, tmp: str, versions: str) -> None: lines = f.readlines() assert ids not in lines -def test_signatures_with_no_ids(monkeypatch, tmp: str, versions: str) -> None: + +def test_signatures_with_no_ids( + monkeypatch: "MonkeyPatch", tmp: str, versions: str +) -> None: shutil.copyfile(versions, tmp) path = Path(tmp) monkeypatch.setattr("dzgui.api.mods.get_local_mod_ids", mock_local_ids) monkeypatch.setattr("dzgui.api.mods.lookup", mock_lookup) dzgui.api.mods.remove_stale_signatures(path, path) with open(tmp, "r") as f: - lines = f.readlines() - assert lines == ["3410710885,1752864732\n", "3739934289,1780855136\n"] + lines = [line.rstrip() for line in f.readlines()] + assert lines == ["3410710885,1752864732", "3739934289,1780855136"] diff --git a/tests/test_modmeta.py b/tests/test_modmeta.py index 8002825..f1ffa01 100644 --- a/tests/test_modmeta.py +++ b/tests/test_modmeta.py @@ -4,10 +4,13 @@ from pathlib import Path from dzgui.api.mods import tokenize from tests.fixtures import fixture_path + @pytest.mark.mods @pytest.mark.parametrize("i", range(1, 7)) def test_modmeta(i: int) -> None: fixture = fixture_path(f"cpp/mod{i}") path = Path(fixture) meta = tokenize(path) + if meta is None: + raise ValueError assert meta["name"] == "ModName" diff --git a/tests/test_paused_downloads.py b/tests/test_paused_downloads.py index 6183e93..255c4ef 100644 --- a/tests/test_paused_downloads.py +++ b/tests/test_paused_downloads.py @@ -23,11 +23,11 @@ if TYPE_CHECKING: def test_dayz_patch_pending( monkeypatch: "MonkeyPatch", file_list: list[str], expect: bool ) -> None: - def mock_get_pending_downloads(steam_path: Path, appid: int) -> None: + def mock_get_pending_downloads(steam_path: Path, appid: int) -> list[Path]: files = [Path(file) for file in file_list] return files monkeypatch.setattr( "dzgui.api.steam.get_pending_downloads", mock_get_pending_downloads ) - assert is_dayz_downloading(Path("/tmp"), Path("/tmp")) == expect + assert is_dayz_downloading(Path("/tmp"), 221100) == expect diff --git a/tests/test_pefile.py b/tests/test_pefile.py index 6d6be0a..e17a1d3 100644 --- a/tests/test_pefile.py +++ b/tests/test_pefile.py @@ -1,6 +1,7 @@ import pytest -from pathlib import Path +from pathlib import Path +from typing import TYPE_CHECKING import dzgui.api.pefile as PeFile from dzgui.api.steam import ( @@ -16,6 +17,9 @@ from dzgui.const.constants import APPID_DAYZ from tests.fixtures import fixture_path +if TYPE_CHECKING: + from _pytest.monkeypatch import MonkeyPatch + pytestmark = pytest.mark.apitest @@ -53,7 +57,9 @@ def test_invalid_pefile_path() -> None: ("malformed.vdf", VDFLoadError), ], ) -def test_not_in_library(monkeypatch, fixture, exception): +def test_not_in_library( + monkeypatch: "MonkeyPatch", fixture: str, exception: type[Exception] +) -> None: import dzgui.api.steam as steam monkeypatch.setattr(steam, "LIBRARYFOLDERS_PATH", fixture) @@ -71,7 +77,7 @@ def second_drive() -> str: return "in_library_on_second_drive.vdf" -def test_on_second_drive(monkeypatch, second_drive: str) -> None: +def test_on_second_drive(monkeypatch: "MonkeyPatch", second_drive: str) -> None: import dzgui.api.steam as steam monkeypatch.setattr(steam, "LIBRARYFOLDERS_PATH", second_drive) diff --git a/tests/test_process_detection.py b/tests/test_process_detection.py index cc89f05..f57ced3 100644 --- a/tests/test_process_detection.py +++ b/tests/test_process_detection.py @@ -1,6 +1,8 @@ import pytest import unittest + from unittest.mock import patch +from typing import Any from dzgui.const.constants import ( FLATPAK_APPID, @@ -15,7 +17,7 @@ pytestmark = pytest.mark.flatpak class TestSteamDetection(unittest.TestCase): def test_flatpak_detection_with_multiple_running_apps(self) -> None: - def flatpak_output(args, *, text: str) -> str: + def flatpak_output(args: Any, *, text: str) -> str: # Default 'flatpak ps' includes instance, PID, app and runtime columns. if args == ["flatpak", "ps", "--columns=application"]: return f"com.spotify.Client\n{FLATPAK_APPID}\n{FLATPAK_APPID}\n" diff --git a/tests/test_remote_api.py b/tests/test_remote_api.py index a340510..5e90498 100644 --- a/tests/test_remote_api.py +++ b/tests/test_remote_api.py @@ -1,6 +1,6 @@ import pytest -from typing import TYPE_CHECKING +from typing import Any, TYPE_CHECKING from dzgui.api import probe from dzgui.config.query import get_config @@ -13,7 +13,7 @@ pytestmark = pytest.mark.webtest @pytest.fixture -def config() -> dict[str, "Path"]: +def config() -> Any: paths = get_xdg_paths() xdg = parse_filepaths(paths) return get_config(xdg.config) @@ -23,6 +23,6 @@ def test_ipdb() -> None: assert probe.test_ipdb() -def test_steam(config: dict[str, "Path"]) -> None: +def test_steam(config: Any) -> None: key = config["steam_api"] assert probe.test_steam_api(key) diff --git a/tests/test_server_metadata.py b/tests/test_server_metadata.py index dc3408c..392af2a 100644 --- a/tests/test_server_metadata.py +++ b/tests/test_server_metadata.py @@ -27,6 +27,8 @@ def test_time_accel(details, key, expect) -> None: def test_gametime(details: Details | None) -> None: time_reg = r"^(0[0-9]|1[0-9]|2[0-3]):([0-5][0-9]$)" + if details is None: + raise ValueError match = re.match(time_reg, details.gametime) assert match is not None diff --git a/tests/test_server_time.py b/tests/test_server_time.py index 7bb7397..8bd32b4 100644 --- a/tests/test_server_time.py +++ b/tests/test_server_time.py @@ -1,7 +1,8 @@ import pytest -from hypothesis import given, strategies as st from datetime import datetime, timedelta +from hypothesis import given, strategies as st +from typing import Any from dzgui.views.dialogs.calc import ( LocalClock, @@ -17,12 +18,12 @@ class DummyEmitter: def __init__(self) -> None: pass - def connect(self, _, __) -> None: + def connect(self, _: Any, __: Any) -> None: pass @pytest.fixture(params=[("05:00", 10.0), ("15:30", 5.0)]) -def accel_server_clock(request) -> None: +def accel_server_clock(request) -> tuple[str, ServerClock]: clock_time, expect = request.param cur_time = Time(clock_time, 5.0, 2.0) emitter = DummyEmitter() @@ -31,13 +32,18 @@ def accel_server_clock(request) -> None: return expect, server_clock -def test_accel_factor(accel_server_clock) -> None: +def test_accel_factor(accel_server_clock: tuple[str, ServerClock]) -> None: """Static test checking times at known boundaries""" expect, clock = accel_server_clock assert clock.get_accel_factor(clock.cur_time) == expect -def reference_calc(start, end, day_factor, night_factor): +def reference_calc( + start: datetime, + end: datetime, + day_factor: float, + night_factor: float, +) -> timedelta: """ Reference implementation to test validity of UI-side calculator Aggregates total seconds and applies accel factors after @@ -80,7 +86,7 @@ night_accel = st.floats( @st.composite -def time_ranges(draw): +def time_ranges(draw: st.DrawFn) -> tuple[datetime, datetime]: start_time = draw(st.times()) deltas = st.timedeltas(min_value=timedelta(0), max_value=timedelta(days=1)) duration = draw(deltas) @@ -91,7 +97,11 @@ def time_ranges(draw): @given(span=time_ranges(), day_factor=day_accel, night_factor=night_accel) -def test_time_aggregation(span, day_factor, night_factor) -> None: +def test_time_aggregation( + span: tuple[datetime, datetime], + day_factor: float, + night_factor: float, +) -> None: start, end = span strtime = start.strftime("%H:%M") diff --git a/tests/test_shortcuts.py b/tests/test_shortcuts.py index ac23e9d..d92eda1 100644 --- a/tests/test_shortcuts.py +++ b/tests/test_shortcuts.py @@ -1,10 +1,11 @@ import pytest import tempfile -from typing import TYPE_CHECKING -from pathlib import Path from _pytest.monkeypatch import MonkeyPatch +from collections.abc import Iterator +from pathlib import Path +from typing import Any, cast, TYPE_CHECKING from dzgui.api.shortcuts import Shortcuts from tests.fixtures import fixture_path @@ -15,12 +16,12 @@ if TYPE_CHECKING: pytestmark = pytest.mark.apitest -def mock_find_shortcuts(self, steam_path: Path) -> Path: +def mock_find_shortcuts(self: Shortcuts, steam_path: Path) -> Path: return Path(fixture_path("api/no_shortcuts.vdf")) @pytest.fixture(scope="module", autouse=True) -def patch_api() -> None: +def patch_api() -> Iterator[None]: mp = MonkeyPatch() mp.setattr("dzgui.api.shortcuts.Shortcuts.find_shortcuts_path", mock_find_shortcuts) yield @@ -33,64 +34,62 @@ def test_no_shortcuts(monkeypatch: "MonkeyPatch") -> None: @pytest.fixture -def dummy_app() -> dict[str, str]: +def dummy_app() -> dict[str, Any]: d = { "AppName": "TEST APP", - "StartDir": "TEST_DIR", - "Exe": "TEST_DIR/TEST_EXE.EXE", - "icon": "IMAGES_DIR/TEST_IMAGE.PNG", + "StartDir": Path("TEST_DIR"), + "Exe": Path("TEST_DIR/TEST_EXE.EXE"), + "icon": Path("IMAGES_DIR/TEST_IMAGE.PNG"), } return d -def test_wrap_exe(dummy_app: dict[str, str]) -> None: +@pytest.fixture +def shortcuts(dummy_app: dict[str, Any]) -> Shortcuts: s = Shortcuts(Path("")) - s.add_shortcut(*dummy_app.values()) - assert s.shortcuts["shortcuts"]["0"]["Exe"][0] == '"' - assert s.shortcuts["shortcuts"]["0"]["Exe"][-1] == '"' + args = cast(tuple[str, Path, Path, Path], dummy_app.values()) + s.add_shortcut(*args) + return s -def test_add_shortcut(dummy_app: dict[str, str]) -> None: - s = Shortcuts(Path("")) - s.add_shortcut(*dummy_app.values()) - new = s.shortcuts["shortcuts"] +def test_wrap_exe(shortcuts: Shortcuts) -> None: + assert shortcuts.shortcuts["shortcuts"]["0"]["Exe"][0] == '"' + assert shortcuts.shortcuts["shortcuts"]["0"]["Exe"][-1] == '"' + + +def test_add_shortcut(shortcuts: Shortcuts, dummy_app: dict[str, Any]) -> None: + new = shortcuts.shortcuts["shortcuts"] ind = str(len(new) - 1) for k, v in dummy_app.items(): if k == "Exe": v = f'"{v}"' - assert new[ind][k] == v + assert new[ind][k] == str(v) -def test_save_shortcut(dummy_app: dict[str, str]) -> None: - s = Shortcuts(Path("")) - s.add_shortcut(*dummy_app.values()) +def test_save_shortcut(shortcuts: Shortcuts) -> None: with tempfile.NamedTemporaryFile() as f: tmp = Path(f.name) - s.shortcuts_path = tmp - s.save_shortcuts() - s._load_shortcuts(tmp) - assert len(s.shortcuts["shortcuts"]) == 1 + shortcuts.shortcuts_path = tmp + shortcuts.save_shortcuts() + shortcuts._load_shortcuts(tmp) + assert len(shortcuts.shortcuts["shortcuts"]) == 1 -def test_shortcut_crc(dummy_app: dict[str, str]) -> None: - s = Shortcuts(Path("")) - s.add_shortcut(*dummy_app.values()) - for key in s.shortcuts["shortcuts"].keys(): - entry = s.shortcuts["shortcuts"][key] +def test_shortcut_crc(shortcuts: Shortcuts) -> None: + for key in shortcuts.shortcuts["shortcuts"].keys(): + entry = shortcuts.shortcuts["shortcuts"][key] name = entry["AppName"] exe = entry["Exe"] uid = name + exe - bpid = s.gen_bpid(uid) + bpid = shortcuts.gen_bpid(uid) assert entry["appid"] & 0xFFFFFFFF == bpid -def test_reverse_crc(dummy_app: dict[str, str]) -> None: - s = Shortcuts(Path("")) - s.add_shortcut(*dummy_app.values()) - for key in s.shortcuts["shortcuts"].keys(): - entry = s.shortcuts["shortcuts"][key] +def test_reverse_crc(shortcuts: Shortcuts) -> None: + for key in shortcuts.shortcuts["shortcuts"].keys(): + entry = shortcuts.shortcuts["shortcuts"][key] name = entry["AppName"] exe = entry["Exe"] uid = name + exe - bpid = s.gen_bpid(uid) - assert s.find_appname_by_unsigned_id(bpid) == name + bpid = shortcuts.gen_bpid(uid) + assert shortcuts.find_appname_by_unsigned_id(bpid) == name From 307792ba5b8c895734e98d098fc0be22a38153a5 Mon Sep 17 00:00:00 2001 From: aclist <92275929+aclist@users.noreply.github.com> Date: Thu, 12 Nov 2026 07:11:20 +0900 Subject: [PATCH 4/6] chore: drop unused import --- dzgui/api/mods.py | 1 - 1 file changed, 1 deletion(-) diff --git a/dzgui/api/mods.py b/dzgui/api/mods.py index 234835d..1d59528 100644 --- a/dzgui/api/mods.py +++ b/dzgui/api/mods.py @@ -3,7 +3,6 @@ import logging import re from concurrent.futures import ThreadPoolExecutor, wait -from dataclasses import dataclass from pathlib import Path from typing import Any From f486cc506f738b1b0ca7077e850b0a410970ac18 Mon Sep 17 00:00:00 2001 From: aclist <92275929+aclist@users.noreply.github.com> Date: Thu, 12 Nov 2026 07:44:34 +0900 Subject: [PATCH 5/6] chore: clear typehinting errors --- tests/test_geo_file.py | 2 +- tests/test_html_escaping.py | 2 -- tests/test_loginusers.py | 2 +- tests/test_mod_signatures.py | 5 +++-- tests/test_modmeta.py | 2 +- tests/test_remote_api.py | 5 +---- tests/test_row_marshalling.py | 5 +++-- tests/test_server_metadata.py | 10 ++++++---- tests/test_server_time.py | 19 ++++++------------- tests/test_time.py | 3 ++- 10 files changed, 24 insertions(+), 31 deletions(-) diff --git a/tests/test_geo_file.py b/tests/test_geo_file.py index 6d962e5..0ff42b9 100644 --- a/tests/test_geo_file.py +++ b/tests/test_geo_file.py @@ -28,7 +28,7 @@ def csv() -> Path: csv = Path(tempfile.NamedTemporaryFile().name) url = find_download_url(DB_IP) if url is None: - raise ValueError() + raise TypeError tmp = serialize(url) unzip(tmp, csv) strip_ipv6(csv) diff --git a/tests/test_html_escaping.py b/tests/test_html_escaping.py index ed9e42a..ce30eca 100644 --- a/tests/test_html_escaping.py +++ b/tests/test_html_escaping.py @@ -1,11 +1,9 @@ import gi import pytest -from typing import Any from dzgui.api.servers import Details from dzgui.controllers.mc import Controller from dzgui.controllers.emitter import Emitter -from dzgui.views.base import OuterWindow from dzgui.views.dialogs.servers import ServerDetailsDialog diff --git a/tests/test_loginusers.py b/tests/test_loginusers.py index cfcba50..08e11dd 100644 --- a/tests/test_loginusers.py +++ b/tests/test_loginusers.py @@ -30,7 +30,7 @@ def test_loginusers(monkeypatch: "MonkeyPatch", fixture: str, expect: int) -> No monkeypatch.setattr("dzgui.api.steam.find_loginusers", mock_loginusers) uid = find_user_id(Path("")) if uid is None: - raise ValueError() + raise TypeError assert int(uid) == expect diff --git a/tests/test_mod_signatures.py b/tests/test_mod_signatures.py index 8de0fc7..db3bb6b 100644 --- a/tests/test_mod_signatures.py +++ b/tests/test_mod_signatures.py @@ -44,8 +44,9 @@ def test_signatures(monkeypatch: "MonkeyPatch", tmp: str, versions: str) -> None monkeypatch.setattr("dzgui.api.mods.lookup", mock_lookup) dzgui.api.mods.remove_stale_signatures(path, path, ids) with open(tmp, "r") as f: - lines = f.readlines() - assert ids not in lines + lines = [line.rstrip() for line in f.readlines()] + concat = ",".join(map(str, ids)) + assert concat not in lines def test_signatures_with_no_ids( diff --git a/tests/test_modmeta.py b/tests/test_modmeta.py index f1ffa01..f5415f7 100644 --- a/tests/test_modmeta.py +++ b/tests/test_modmeta.py @@ -12,5 +12,5 @@ def test_modmeta(i: int) -> None: path = Path(fixture) meta = tokenize(path) if meta is None: - raise ValueError + raise TypeError assert meta["name"] == "ModName" diff --git a/tests/test_remote_api.py b/tests/test_remote_api.py index 5e90498..0b24577 100644 --- a/tests/test_remote_api.py +++ b/tests/test_remote_api.py @@ -1,14 +1,11 @@ import pytest -from typing import Any, TYPE_CHECKING +from typing import Any from dzgui.api import probe from dzgui.config.query import get_config from dzgui.config.xdg import get_xdg_paths, parse_filepaths -if TYPE_CHECKING: - from pathlib import Path - pytestmark = pytest.mark.webtest diff --git a/tests/test_row_marshalling.py b/tests/test_row_marshalling.py index 7e59080..d586d72 100644 --- a/tests/test_row_marshalling.py +++ b/tests/test_row_marshalling.py @@ -18,9 +18,10 @@ def test_row_conversion() -> None: "Unofficial", False, ] - rows = [ServerRow(*data)] + rows = [ServerRow(*data)] # type: ignore marshalled = ServerRow.marshal_rows(rows) store = ModelFactory().make_server_store() store.extend(marshalled) - converted = [[el for el in row] for row in store] + cols = store.get_n_columns() + converted = [[row[i] for i in range(cols)] for row in store] assert data == converted[0] diff --git a/tests/test_server_metadata.py b/tests/test_server_metadata.py index 392af2a..1923566 100644 --- a/tests/test_server_metadata.py +++ b/tests/test_server_metadata.py @@ -7,7 +7,7 @@ pytestmark = pytest.mark.slow @pytest.fixture -def details() -> Details: +def details() -> Details | None: """ Static official server, metadata is expected to be invariate """ @@ -21,19 +21,21 @@ def test_invalid_server() -> None: @pytest.mark.parametrize("key, expect", [("day_accel", 2.3), ("night_accel", 6.8)]) -def test_time_accel(details, key, expect) -> None: +def test_time_accel(details: Details | None, key: str, expect: float) -> None: assert getattr(details, key) == expect def test_gametime(details: Details | None) -> None: time_reg = r"^(0[0-9]|1[0-9]|2[0-3]):([0-5][0-9]$)" if details is None: - raise ValueError + raise TypeError match = re.match(time_reg, details.gametime) assert match is not None -def test_metadata(details) -> None: +def test_metadata(details: Details | None) -> None: + if details is None: + raise TypeError for row in details.data: label, value = row match label: diff --git a/tests/test_server_time.py b/tests/test_server_time.py index 8bd32b4..d8af268 100644 --- a/tests/test_server_time.py +++ b/tests/test_server_time.py @@ -2,9 +2,10 @@ import pytest from datetime import datetime, timedelta from hypothesis import given, strategies as st -from typing import Any +from typing import Any, Callable from dzgui.views.dialogs.calc import ( + Emitter, LocalClock, ServerClock, Time, @@ -14,25 +15,17 @@ from dzgui.views.dialogs.calc import ( ) -class DummyEmitter: - def __init__(self) -> None: - pass - - def connect(self, _: Any, __: Any) -> None: - pass - - @pytest.fixture(params=[("05:00", 10.0), ("15:30", 5.0)]) -def accel_server_clock(request) -> tuple[str, ServerClock]: +def accel_server_clock(request: pytest.FixtureRequest) -> tuple[str, ServerClock]: clock_time, expect = request.param cur_time = Time(clock_time, 5.0, 2.0) - emitter = DummyEmitter() + emitter = Emitter() local_clock = LocalClock(emitter) server_clock = ServerClock(cur_time, emitter, local_clock) return expect, server_clock -def test_accel_factor(accel_server_clock: tuple[str, ServerClock]) -> None: +def test_accel_factor(accel_server_clock: tuple[float, ServerClock]) -> None: """Static test checking times at known boundaries""" expect, clock = accel_server_clock assert clock.get_accel_factor(clock.cur_time) == expect @@ -106,7 +99,7 @@ def test_time_aggregation( strtime = start.strftime("%H:%M") t = Time(strtime, day_factor, night_factor) - emitter = DummyEmitter() + emitter = Emitter() local_clock = LocalClock(emitter) server_clock = ServerClock(t, emitter, local_clock) h = end.time().hour diff --git a/tests/test_time.py b/tests/test_time.py index c9096b6..d5de922 100644 --- a/tests/test_time.py +++ b/tests/test_time.py @@ -2,7 +2,8 @@ import re from dzgui.model.proxy_model import DAY_REG, NIGHT_REG -def iterate(h: str, r: str) -> None: + +def iterate(h: int, r: str) -> None: for m in range(60): time = f"{h:02}:{m:02}" assert re.match(r, time) is not None From d5c9f24ad5f9f9fd8f3870b9814609830e1c40e4 Mon Sep 17 00:00:00 2001 From: aclist <92275929+aclist@users.noreply.github.com> Date: Thu, 12 Nov 2026 07:45:24 +0900 Subject: [PATCH 6/6] chore: clear typehinting errors --- tests/test_server_time.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/test_server_time.py b/tests/test_server_time.py index d8af268..ab246ff 100644 --- a/tests/test_server_time.py +++ b/tests/test_server_time.py @@ -2,8 +2,6 @@ import pytest from datetime import datetime, timedelta from hypothesis import given, strategies as st -from typing import Any, Callable - from dzgui.views.dialogs.calc import ( Emitter, LocalClock,