From b863d7972ceeec2d6af1b96c1d3153507ea472b6 Mon Sep 17 00:00:00 2001 From: krassowski Date: Thu, 21 Sep 2017 03:02:39 +0000 Subject: [PATCH 1/5] Allow to run App&GUI without entering the main event loop --- aqt/__init__.py | 14 ++++++++++---- tests/test_run.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 4 deletions(-) create mode 100644 tests/test_run.py diff --git a/aqt/__init__.py b/aqt/__init__.py index be49c7d56..8fc8123d7 100644 --- a/aqt/__init__.py +++ b/aqt/__init__.py @@ -233,11 +233,14 @@ def run(): "Please notify support of this error:\n\n"+ traceback.format_exc()) -def _run(): +def _run(argv=None, exec=True): global mw + if argv is None: + argv = sys.argv + # parse args - opts, args = parseArgs(sys.argv) + opts, args = parseArgs(argv) opts.base = opts.base or "" opts.profile = opts.profile or "" @@ -250,7 +253,7 @@ def _run(): QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling) # create the app - app = AnkiApp(sys.argv) + app = AnkiApp(argv) QCoreApplication.setApplicationName("Anki") if app.secondInstance(): # we've signaled the primary instance, so we should close @@ -285,4 +288,7 @@ environment points to a valid, writable folder.""") # load the main window import aqt.main mw = aqt.main.AnkiQt(app, pm, args) - app.exec_() + if exec: + app.exec() + else: + return app diff --git a/tests/test_run.py b/tests/test_run.py new file mode 100644 index 000000000..125c50652 --- /dev/null +++ b/tests/test_run.py @@ -0,0 +1,42 @@ +# coding: utf-8 +from contextlib import contextmanager + +import aqt +from aqt import _run +from aqt.profiles import ProfileManager + + +@contextmanager +def temporaryUser(name="__Temporary Test User__"): + + pm = ProfileManager(base="") + + if name in pm.profiles(): + raise Exception(f"Could not create a temporary user with name {name}") + + pm.create(name) + pm.name = name + + yield name + + pm.remove(name) + +def test_run(): + + # we need a new user for the test + with temporaryUser() as name: + app = _run(argv=["anki", "-p", name], exec=False) + assert app + + aqt.mw.cleanupAndExit() + + # clean up what was spoiled + aqt.mw = None + + # remove hooks added during app initialization + from anki import hooks + hooks._hooks = {} + + # test_nextIvl will fail on some systems if the locales are not restored + import locale + locale.setlocale(locale.LC_ALL, locale.getdefaultlocale()) From 153e560c3d93e9bf3e98ec3a09a745efa73486fe Mon Sep 17 00:00:00 2001 From: krassowski Date: Thu, 21 Sep 2017 03:46:46 +0000 Subject: [PATCH 2/5] Add requirements allowing to test GUI: PyQt5 and sip. --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index d2e5d467d..a022851b6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,7 @@ python: install: - sudo apt-get update - sudo apt-get install portaudio19-dev + - pip install PyQt5 sip - pip install -r requirements.txt - pip install nose - pip install coveralls From 3334cbd249405c94305377036ebed1661bcd5823 Mon Sep 17 00:00:00 2001 From: krassowski Date: Thu, 21 Sep 2017 03:52:03 +0000 Subject: [PATCH 3/5] Build GUI before running tests --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index a022851b6..94aeacdfc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ install: - sudo apt-get install portaudio19-dev - pip install PyQt5 sip - pip install -r requirements.txt + - bash tools/build_ui.sh - pip install nose - pip install coveralls From 755c9487c98684535ae90040ed6784a0321951f3 Mon Sep 17 00:00:00 2001 From: krassowski Date: Sat, 23 Sep 2017 15:01:29 +0000 Subject: [PATCH 4/5] Add docstring explaining introduced arguments of _run() --- aqt/__init__.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/aqt/__init__.py b/aqt/__init__.py index 8fc8123d7..ccfde23b3 100644 --- a/aqt/__init__.py +++ b/aqt/__init__.py @@ -234,6 +234,15 @@ def run(): traceback.format_exc()) def _run(argv=None, exec=True): + """Start AnkiQt application or reuse an existing instance if one exists. + + If the function is invoked with exec=False, the AnkiQt will not enter + the main event loop - instead the application object will be returned. + + The 'exec' and 'argv' arguments will be useful for testing purposes. + + If no 'argv' is supplied then 'sys.argv' will be used. + """ global mw if argv is None: From 7327452e717c9901922fe1ab8ee1660c58b2c40a Mon Sep 17 00:00:00 2001 From: krassowski Date: Sat, 23 Sep 2017 15:03:02 +0000 Subject: [PATCH 5/5] Remove test_run.py and changes introduced in .travis.yml --- .travis.yml | 2 -- tests/test_run.py | 42 ------------------------------------------ 2 files changed, 44 deletions(-) delete mode 100644 tests/test_run.py diff --git a/.travis.yml b/.travis.yml index 94aeacdfc..d2e5d467d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,9 +4,7 @@ python: install: - sudo apt-get update - sudo apt-get install portaudio19-dev - - pip install PyQt5 sip - pip install -r requirements.txt - - bash tools/build_ui.sh - pip install nose - pip install coveralls diff --git a/tests/test_run.py b/tests/test_run.py deleted file mode 100644 index 125c50652..000000000 --- a/tests/test_run.py +++ /dev/null @@ -1,42 +0,0 @@ -# coding: utf-8 -from contextlib import contextmanager - -import aqt -from aqt import _run -from aqt.profiles import ProfileManager - - -@contextmanager -def temporaryUser(name="__Temporary Test User__"): - - pm = ProfileManager(base="") - - if name in pm.profiles(): - raise Exception(f"Could not create a temporary user with name {name}") - - pm.create(name) - pm.name = name - - yield name - - pm.remove(name) - -def test_run(): - - # we need a new user for the test - with temporaryUser() as name: - app = _run(argv=["anki", "-p", name], exec=False) - assert app - - aqt.mw.cleanupAndExit() - - # clean up what was spoiled - aqt.mw = None - - # remove hooks added during app initialization - from anki import hooks - hooks._hooks = {} - - # test_nextIvl will fail on some systems if the locales are not restored - import locale - locale.setlocale(locale.LC_ALL, locale.getdefaultlocale())