From 739a1374b703e6eadd50d81d1cbee25f80acacd9 Mon Sep 17 00:00:00 2001 From: Fabian Arndt Date: Wed, 18 Dec 2024 00:17:52 +0100 Subject: [PATCH] Fixed unit tests - Fixed relative imports - Removed import handling via ImportError exception - Fixed CI by running via module, instead of file - Added / improved handling in __init__.py for unit tests --- .github/workflows/ci.yml | 6 +++++- __init__.py | 28 ++++++++++++++++++++-------- checks.py | 5 +---- config.py | 4 +++- config_base.py | 4 ++-- engine.py | 1 + fix.py | 15 +++++---------- protonfixes_test.py | 16 +++++++++------- util.py | 11 +++-------- 9 files changed, 49 insertions(+), 41 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ff60907e..59bf272a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,6 +53,10 @@ jobs: python3 .github/scripts/check_gamefixes.py python3 .github/scripts/check_verbs.py + # We need a known parent package in the unit tests, so we need to change to the parent dir + # As "umu-protonfixes" is not a valid package name, we create a symbolic link to "protonfixes" - name: Test with unittest run: | - python3 protonfixes_test.py + cd .. + ln -s umu-protonfixes protonfixes + python3 -m protonfixes.protonfixes_test diff --git a/__init__.py b/__init__.py index 6605138c..f5e9517d 100644 --- a/__init__.py +++ b/__init__.py @@ -2,17 +2,29 @@ import os import sys +import traceback -RUN_CONDITIONS = [ - 'STEAM_COMPAT_DATA_PATH' in os.environ, - 'PROTONFIXES_DISABLE' not in os.environ, - 'waitforexitandrun' in sys.argv[1], -] +from . import fix +from .logger import log -if all(RUN_CONDITIONS): - import traceback - from . import fix +def check_conditions() -> bool: + return len(sys.argv) >= 1 and \ + 'STEAM_COMPAT_DATA_PATH' in os.environ and \ + 'PROTONFIXES_DISABLE' not in os.environ and \ + 'waitforexitandrun' in sys.argv[1] +def check_iscriptevaluator() -> bool: + return len(sys.argv) >= 2 and \ + 'iscriptevaluator.exe' in sys.argv[2] + +# Determine, if the actual game was executed +if check_iscriptevaluator(): + log.debug('Skipping fix execution. We are running "iscriptevaluator.exe".') +# Determine, if we were called from Proton or externally +elif not check_conditions(): + log.warn('Skipping fix execution. We are probably running an unit test.') +# We are good to go +else: try: fix.main() diff --git a/checks.py b/checks.py index 064e0651..b560056d 100644 --- a/checks.py +++ b/checks.py @@ -1,9 +1,6 @@ """Run some tests and generate warnings for proton configuration issues""" -try: - from .logger import log -except ImportError: - from logger import log +from .logger import log def esync_file_limits() -> bool: diff --git a/config.py b/config.py index c83e195d..e6719468 100644 --- a/config.py +++ b/config.py @@ -1,9 +1,11 @@ """Load configuration settings for protonfixes""" -from config_base import ConfigBase from dataclasses import dataclass from pathlib import Path +from .config_base import ConfigBase + + class Config(ConfigBase): """Configuration for umu-protonfix""" diff --git a/config_base.py b/config_base.py index 2263d4a0..a66e6dc1 100644 --- a/config_base.py +++ b/config_base.py @@ -5,11 +5,11 @@ from configparser import ConfigParser from dataclasses import is_dataclass from pathlib import Path - from typing import Any from collections.abc import Callable -from logger import log, LogLevel +from .logger import log, LogLevel + class ConfigBase: """Base class for configuration objects. diff --git a/engine.py b/engine.py index ae0fbc1a..2719fe30 100644 --- a/engine.py +++ b/engine.py @@ -2,6 +2,7 @@ import os import sys + from .logger import log, LogLevel diff --git a/fix.py b/fix.py index f5f70c21..df4aaabc 100644 --- a/fix.py +++ b/fix.py @@ -4,20 +4,15 @@ import re import sys import csv + from functools import lru_cache from importlib import import_module from typing import Optional -try: - from .config import config - from .util import proton_version - from .checks import run_checks - from .logger import log -except ImportError: - from config import config - from util import proton_version - from checks import run_checks - from logger import log +from .config import config +from .util import proton_version +from .checks import run_checks +from .logger import log try: import __main__ as protonmain diff --git a/protonfixes_test.py b/protonfixes_test.py index e8d4b71a..f63f8d4b 100644 --- a/protonfixes_test.py +++ b/protonfixes_test.py @@ -1,11 +1,13 @@ -import unittest +import io import os import tempfile +import unittest +import urllib.request + from pathlib import Path from unittest.mock import patch, mock_open -import io -import urllib.request -import fix + +from . import fix class TestProtonfixes(unittest.TestCase): @@ -315,7 +317,7 @@ def testGetGameNameDBFileNotFound(self): with patch('builtins.open', mock_open()) as mocked_open: mocked_open.side_effect = FileNotFoundError - with patch('fix.log') as mocked_log: # Mock the logger separately + with patch('protonfixes.fix.log') as mocked_log: # Mock the logger separately func = fix.get_game_name.__wrapped__ # Do not reference the cache result = func() self.assertEqual(result, 'UNKNOWN') @@ -329,7 +331,7 @@ def testGetGameNameDbOS(self): with patch('builtins.open', mock_open()) as mocked_open: mocked_open.side_effect = OSError - with patch('fix.log') as mocked_log: # Mock the logger separately + with patch('protonfixes.fix.log') as mocked_log: # Mock the logger separately func = fix.get_game_name.__wrapped__ # Do not reference the cache result = func() self.assertEqual(result, 'UNKNOWN') @@ -357,7 +359,7 @@ def testGetGameNameDbUnicode(self): with patch('builtins.open', mock_open()) as mocked_open: mocked_open.side_effect = UnicodeDecodeError('utf-8', b'', 0, 1, '') - with patch('fix.log') as mocked_log: # Mock the logger separately + with patch('protonfixes.fix.log') as mocked_log: # Mock the logger separately func = fix.get_game_name.__wrapped__ # Do not reference the cache result = func() self.assertEqual(result, 'UNKNOWN') diff --git a/util.py b/util.py index 6e3eec0c..a6796ddf 100644 --- a/util.py +++ b/util.py @@ -20,14 +20,9 @@ from typing import Any, Union, Optional from collections.abc import Mapping, Callable -try: - from .logger import log - from .config import config - from .steamhelper import install_app -except ImportError: - from logger import log - from config import config - from steamhelper import install_app +from .logger import log +from .config import config +from .steamhelper import install_app try: import __main__ as protonmain