diff options
Diffstat (limited to 'tests/unit/test_qt_machinery.py')
-rw-r--r-- | tests/unit/test_qt_machinery.py | 263 |
1 files changed, 163 insertions, 100 deletions
diff --git a/tests/unit/test_qt_machinery.py b/tests/unit/test_qt_machinery.py index 1618e9e6f..32f63043b 100644 --- a/tests/unit/test_qt_machinery.py +++ b/tests/unit/test_qt_machinery.py @@ -23,6 +23,7 @@ import html import argparse import typing from typing import Any, Optional, List, Dict, Union +import dataclasses import pytest @@ -214,7 +215,7 @@ def modules(): reason=machinery.SelectionReason.auto, outcomes={ "PyQt6": "ImportError: Fake ImportError for PyQt6.", - } + }, ), id="import-error", ), @@ -230,111 +231,157 @@ def test_autoselect( assert machinery._autoselect_wrapper() == expected -@pytest.mark.parametrize( - "args, env, expected", - [ - # Defaults with no overrides - ( - None, - None, - machinery.SelectionInfo( - wrapper="PyQt5", reason=machinery.SelectionReason.default +@dataclasses.dataclass +class SelectWrapperCase: + name: str + expected: machinery.SelectionInfo + args: Optional[argparse.Namespace] = None + env: Optional[str] = None + override: Optional[str] = None + + def __str__(self): + return self.name + + +class TestSelectWrapper: + @pytest.mark.parametrize( + "tc", + [ + # Only argument given + SelectWrapperCase( + "pyqt6-arg", + args=argparse.Namespace(qt_wrapper="PyQt6"), + expected=machinery.SelectionInfo( + wrapper="PyQt6", reason=machinery.SelectionReason.cli + ), ), - ), - ( - argparse.Namespace(qt_wrapper=None), - None, - machinery.SelectionInfo( - wrapper="PyQt5", reason=machinery.SelectionReason.default + SelectWrapperCase( + "pyqt5-arg", + args=argparse.Namespace(qt_wrapper="PyQt5"), + expected=machinery.SelectionInfo( + wrapper="PyQt5", reason=machinery.SelectionReason.cli + ), ), - ), - ( - argparse.Namespace(qt_wrapper=None), - "", - machinery.SelectionInfo( - wrapper="PyQt5", reason=machinery.SelectionReason.default + SelectWrapperCase( + "pyqt6-arg-empty-env", + args=argparse.Namespace(qt_wrapper="PyQt5"), + env="", + expected=machinery.SelectionInfo( + wrapper="PyQt5", reason=machinery.SelectionReason.cli + ), ), - ), - # Only argument given - ( - argparse.Namespace(qt_wrapper="PyQt6"), - None, - machinery.SelectionInfo( - wrapper="PyQt6", reason=machinery.SelectionReason.cli + # Only environment variable given + SelectWrapperCase( + "pyqt6-env", + env="PyQt6", + expected=machinery.SelectionInfo( + wrapper="PyQt6", reason=machinery.SelectionReason.env + ), ), - ), - ( - argparse.Namespace(qt_wrapper="PyQt5"), - None, - machinery.SelectionInfo( - wrapper="PyQt5", reason=machinery.SelectionReason.cli + SelectWrapperCase( + "pyqt5-env", + env="PyQt5", + expected=machinery.SelectionInfo( + wrapper="PyQt5", reason=machinery.SelectionReason.env + ), ), - ), - ( - argparse.Namespace(qt_wrapper="PyQt5"), - "", - machinery.SelectionInfo( - wrapper="PyQt5", reason=machinery.SelectionReason.cli + # Both given + SelectWrapperCase( + "pyqt5-arg-pyqt6-env", + args=argparse.Namespace(qt_wrapper="PyQt5"), + env="PyQt6", + expected=machinery.SelectionInfo( + wrapper="PyQt5", reason=machinery.SelectionReason.cli + ), ), - ), - # Only environment variable given - ( - None, - "PyQt6", - machinery.SelectionInfo( - wrapper="PyQt6", reason=machinery.SelectionReason.env + SelectWrapperCase( + "pyqt6-arg-pyqt5-env", + args=argparse.Namespace(qt_wrapper="PyQt6"), + env="PyQt5", + expected=machinery.SelectionInfo( + wrapper="PyQt6", reason=machinery.SelectionReason.cli + ), ), - ), - ( - None, - "PyQt5", - machinery.SelectionInfo( - wrapper="PyQt5", reason=machinery.SelectionReason.env + SelectWrapperCase( + "pyqt6-arg-pyqt6-env", + args=argparse.Namespace(qt_wrapper="PyQt6"), + env="PyQt6", + expected=machinery.SelectionInfo( + wrapper="PyQt6", reason=machinery.SelectionReason.cli + ), ), - ), - # Both given - ( - argparse.Namespace(qt_wrapper="PyQt5"), - "PyQt6", - machinery.SelectionInfo( - wrapper="PyQt5", reason=machinery.SelectionReason.cli + # Override + SelectWrapperCase( + "override-only", + override="PyQt6", + expected=machinery.SelectionInfo( + wrapper="PyQt6", reason=machinery.SelectionReason.override + ), ), - ), - ( - argparse.Namespace(qt_wrapper="PyQt6"), - "PyQt5", - machinery.SelectionInfo( - wrapper="PyQt6", reason=machinery.SelectionReason.cli + SelectWrapperCase( + "override-arg", + args=argparse.Namespace(qt_wrapper="PyQt5"), + override="PyQt6", + expected=machinery.SelectionInfo( + wrapper="PyQt5", reason=machinery.SelectionReason.cli + ), ), - ), - ( - argparse.Namespace(qt_wrapper="PyQt6"), - "PyQt6", - machinery.SelectionInfo( - wrapper="PyQt6", reason=machinery.SelectionReason.cli + SelectWrapperCase( + "override-env", + env="PyQt5", + override="PyQt6", + expected=machinery.SelectionInfo( + wrapper="PyQt5", reason=machinery.SelectionReason.env + ), ), - ), - ], -) -def test_select_wrapper( - args: Optional[argparse.Namespace], - env: Optional[str], - expected: machinery.SelectionInfo, - monkeypatch: pytest.MonkeyPatch, - undo_init: None, -): - if env is None: - monkeypatch.delenv("QUTE_QT_WRAPPER", raising=False) - else: - monkeypatch.setenv("QUTE_QT_WRAPPER", env) + ], + ids=str, + ) + def test_select(self, tc: SelectWrapperCase, monkeypatch: pytest.MonkeyPatch): + if tc.env is None: + monkeypatch.delenv("QUTE_QT_WRAPPER", raising=False) + else: + monkeypatch.setenv("QUTE_QT_WRAPPER", tc.env) + + if tc.override is not None: + monkeypatch.setattr(machinery, "_WRAPPER_OVERRIDE", tc.override) + + assert machinery._select_wrapper(tc.args) == tc.expected + + @pytest.mark.parametrize( + "args, env", + [ + (None, None), + (argparse.Namespace(qt_wrapper=None), None), + (argparse.Namespace(qt_wrapper=None), ""), + ], + ) + def test_autoselect_by_default( + self, + args: Optional[argparse.Namespace], + env: Optional[str], + monkeypatch: pytest.MonkeyPatch, + ): + """Test that the default behavior is to autoselect a wrapper. + + Autoselection itself is tested further down. + """ + if env is None: + monkeypatch.delenv("QUTE_QT_WRAPPER", raising=False) + else: + monkeypatch.setenv("QUTE_QT_WRAPPER", env) - assert machinery._select_wrapper(args) == expected + assert machinery._select_wrapper(args).reason == machinery.SelectionReason.auto + def test_after_qt_import(self, monkeypatch: pytest.MonkeyPatch): + monkeypatch.setitem(sys.modules, "PyQt6", None) + with pytest.warns(UserWarning, match="PyQt6 already imported"): + machinery._select_wrapper(args=None) -def test_select_wrapper_after_qt_import(monkeypatch: pytest.MonkeyPatch): - monkeypatch.setitem(sys.modules, "PyQt6", None) - with pytest.warns(UserWarning, match="PyQt6 already imported"): - machinery._select_wrapper(args=None) + def test_invalid_override(self, monkeypatch: pytest.MonkeyPatch): + monkeypatch.setattr(machinery, "_WRAPPER_OVERRIDE", "invalid") + with pytest.raises(AssertionError): + machinery._select_wrapper(args=None) class TestInit: @@ -359,15 +406,34 @@ class TestInit: ): machinery.init(args=empty_args) + @pytest.fixture(params=["auto", "", None]) + def qt_auto_env( + self, + request: pytest.FixtureRequest, + monkeypatch: pytest.MonkeyPatch, + ): + """Trigger wrapper autoselection via environment variable. + + Autoselection should be used in three scenarios: + + - The environment variable is set to "auto". + - The environment variable is set to an empty string. + - The environment variable is not set at all. + + We run test_none_available_*() for all three scenarios. + """ + if request.param is None: + monkeypatch.delenv("QUTE_QT_WRAPPER", raising=False) + else: + monkeypatch.setenv("QUTE_QT_WRAPPER", request.param) + def test_none_available_implicit( self, stubs: Any, modules: Dict[str, bool], monkeypatch: pytest.MonkeyPatch, - undo_init: None, + qt_auto_env: None, ): - # FIXME:qt6 Also try without this once auto is default - monkeypatch.setenv("QUTE_QT_WRAPPER", "auto") stubs.ImportFake(modules, monkeypatch).patch() message_lines = [ @@ -391,10 +457,8 @@ class TestInit: modules: Dict[str, bool], monkeypatch: pytest.MonkeyPatch, empty_args: argparse.Namespace, - undo_init: None, + qt_auto_env: None, ): - # FIXME:qt6 Also try without this once auto is default - monkeypatch.setenv("QUTE_QT_WRAPPER", "auto") stubs.ImportFake(modules, monkeypatch).patch() info = machinery.init(args=empty_args) @@ -403,7 +467,7 @@ class TestInit: reason=machinery.SelectionReason.auto, outcomes={ "PyQt6": "ImportError: Fake ImportError for PyQt6.", - } + }, ) @pytest.mark.parametrize( @@ -422,7 +486,6 @@ class TestInit: true_vars: str, explicit: bool, empty_args: argparse.Namespace, - undo_init: None, ): info = machinery.SelectionInfo( wrapper=selected_wrapper, |