From a4ee1e112c2b62f3c49cb0e48098752379344a79 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Mon, 7 Dec 2020 20:00:58 +0100 Subject: [PATCH] Updated and extended the testing of the main function --- nw/__init__.py | 29 ++++----- tests/README.md | 2 + tests/dummy.py | 14 +++-- tests/test_base_init.py | 134 +++++++++++++++++++++++++++++++--------- 4 files changed, 132 insertions(+), 47 deletions(-) diff --git a/nw/__init__.py b/nw/__init__.py index a5960f30..65ab7f59 100644 --- a/nw/__init__.py +++ b/nw/__init__.py @@ -246,19 +246,20 @@ def main(sysArgs=None): errorCode |= 32 if errorData: - if not testMode: - errApp = QApplication([]) - errMsg = QErrorMessage() - errMsg.resize(500, 300) - errMsg.showMessage(( - "

A critical error has been encountered

" - "

novelWriter cannot start due to the following issues:

" - "

 - %s

" - "

Shutting down ...

" - ) % ( - "
 - ".join(errorData) - )) - errApp.exec_() + errApp = QApplication([]) + errMsg = QErrorMessage() + errMsg.resize(500, 300) + errMsg.showMessage(( + "

A critical error has been encountered

" + "

novelWriter cannot start due to the following issues:

" + "

 - %s

" + "

Shutting down ...

" + ) % ( + "
 - ".join(errorData) + )) + for errMsg in errorData: + logger.critical(errMsg) + errApp.exec_() sys.exit(errorCode) # Finish initialising config @@ -293,4 +294,4 @@ def main(sysArgs=None): nwGUI = GuiMain() sys.exit(nwApp.exec_()) - return +# END Function main diff --git a/tests/README.md b/tests/README.md index 8be3b5b5..09dcd6ce 100644 --- a/tests/README.md +++ b/tests/README.md @@ -61,7 +61,9 @@ The commands for the respective test categories are listed below. | Type | Test Target | Source File(s) | Marker | Filter | | :--- | :----------------- | :-------------------- | :-------- | :-------------------- | +| Unit | Main function | nw/\_\_init\_\_.py | `-m base` | `-k testBaseInit` | | Unit | Common functions | nw/common.py | `-m base` | `-k testBaseCommon` | +| Unit | Error handlers | nw/error.py | `-m base` | `-k testBaseError` | | Unit | Core functions | nw/core/tools.py | `-m core` | `-k testCoreTools` | | Unit | NWDoc class | nw/core/document.py | `-m core` | `-k testCoreDocument` | | Unit | NWIndex class | nw/core/index.py | `-m core` | `-k testCoreIndex` | diff --git a/tests/dummy.py b/tests/dummy.py index 2807578a..daf0e070 100644 --- a/tests/dummy.py +++ b/tests/dummy.py @@ -13,7 +13,7 @@ class DummyMain(): self.hasProject = True self.theIndex = None self.theProject = None - self.statusBar = StatusBar() + self.statusBar = DummyStatusBar() # Test Variables self.askResponse = True @@ -42,6 +42,12 @@ class DummyMain(): def rebuildIndex(self): return + def closeMain(self): + return "closeMain" + + def close(self): + return "close" + # Test Functions def undo(self): @@ -52,9 +58,9 @@ class DummyMain(): self.lastAlert = "" return -# END Class GuiMain +# END Class DummyMain -class StatusBar(): +class DummyStatusBar(): def __init__(self): return @@ -62,7 +68,7 @@ class StatusBar(): def setStatus(self, theText): return -# END Class StatusBar +# END Class DummyStatusBar # =========================================================================== # # Error Functions diff --git a/tests/test_base_init.py b/tests/test_base_init.py index c45dc65f..b691bfa1 100644 --- a/tests/test_base_init.py +++ b/tests/test_base_init.py @@ -7,81 +7,157 @@ import pytest import logging import sys +from dummy import DummyMain + @pytest.mark.base -def testBaseInit_Launch(qtbot, monkeypatch, fncDir, tmpDir): - """Test the main __init__.py file. +def testBaseInit_Launch(caplog, monkeypatch, tmpDir): + """Check launching the main GUI. """ + monkeypatch.setattr("nw.guimain.GuiMain", DummyMain) + + # Testmode launch + nwGUI = nw.main( + ["--testmode", "--config=%s" % tmpDir, "--data=%s" % tmpDir] + ) + assert isinstance(nwGUI, DummyMain) + + # Darwin launch + monkeypatch.setitem(sys.modules, "Foundation", None) + osDarwin = nw.CONFIG.osDarwin + nw.CONFIG.osDarwin = True + nwGUI = nw.main( + ["--testmode", "--config=%s" % tmpDir, "--data=%s" % tmpDir] + ) + assert isinstance(nwGUI, DummyMain) + assert "Foundation" in caplog.messages[1] + nw.CONFIG.osDarwin = osDarwin + + # Normal launch + monkeypatch.setattr("PyQt5.QtWidgets.QApplication.__init__", lambda *args: None) + monkeypatch.setattr("PyQt5.QtWidgets.QApplication.setApplicationName", lambda *args: None) + monkeypatch.setattr("PyQt5.QtWidgets.QApplication.setApplicationVersion", lambda *args: None) + monkeypatch.setattr("PyQt5.QtWidgets.QApplication.setWindowIcon", lambda *args: None) + monkeypatch.setattr("PyQt5.QtWidgets.QApplication.setOrganizationDomain", lambda *args: None) + monkeypatch.setattr("PyQt5.QtWidgets.QApplication.exec_", lambda *args: 0) + with pytest.raises(SystemExit) as ex: + nw.main(["--config=%s" % tmpDir, "--data=%s" % tmpDir]) + + assert ex.value.code == 0 + + monkeypatch.undo() + +# END Test testBaseInit_Launch + +@pytest.mark.base +def testBaseInit_Options(monkeypatch, tmpDir): + """Test command line options for logging level. + """ + monkeypatch.setattr("nw.guimain.GuiMain", DummyMain) + monkeypatch.setattr(sys, "argv", [ + "novelWriter.py", "--testmode", "--config=%s" % tmpDir, "--data=%s" % tmpDir + ]) + + # Defaults w/None Args + nwGUI = nw.main() + assert nw.logger.getEffectiveLevel() == logging.WARNING + assert nw.CONFIG.debugInfo is False + assert nw.CONFIG.showGUI is False + assert nwGUI.closeMain() == "closeMain" + # Defaults nwGUI = nw.main( - ["--testmode", "--config=%s" % fncDir, "--data=%s" % tmpDir, "--style=Fusion"] + ["--testmode", "--config=%s" % tmpDir, "--data=%s" % tmpDir, "--style=Fusion"] ) assert nw.logger.getEffectiveLevel() == logging.WARNING - nwGUI.closeMain() - nwGUI.close() + assert nw.CONFIG.debugInfo is False + assert nwGUI.closeMain() == "closeMain" # Log Levels nwGUI = nw.main( - ["--testmode", "--info", "--config=%s" % fncDir, "--data=%s" % tmpDir] + ["--testmode", "--info", "--config=%s" % tmpDir, "--data=%s" % tmpDir] ) assert nw.logger.getEffectiveLevel() == logging.INFO - nwGUI.closeMain() - nwGUI.close() + assert nw.CONFIG.debugInfo is False + assert nwGUI.closeMain() == "closeMain" nwGUI = nw.main( - ["--testmode", "--debug", "--config=%s" % fncDir, "--data=%s" % tmpDir] + ["--testmode", "--debug", "--config=%s" % tmpDir, "--data=%s" % tmpDir] ) assert nw.logger.getEffectiveLevel() == logging.DEBUG - nwGUI.closeMain() - nwGUI.close() + assert nw.CONFIG.debugInfo is True + assert nwGUI.closeMain() == "closeMain" nwGUI = nw.main( - ["--testmode", "--verbose", "--config=%s" % fncDir, "--data=%s" % tmpDir] + ["--testmode", "--verbose", "--config=%s" % tmpDir, "--data=%s" % tmpDir] ) assert nw.logger.getEffectiveLevel() == 5 - nwGUI.closeMain() - nwGUI.close() + assert nw.CONFIG.debugInfo is True + assert nwGUI.closeMain() == "closeMain" # Help and Version with pytest.raises(SystemExit) as ex: nwGUI = nw.main( - ["--testmode", "--help", "--config=%s" % fncDir, "--data=%s" % tmpDir] + ["--testmode", "--help", "--config=%s" % tmpDir, "--data=%s" % tmpDir] ) - nwGUI.closeMain() - nwGUI.close() + assert nwGUI.closeMain() == "closeMain" assert ex.value.code == 0 with pytest.raises(SystemExit) as ex: nwGUI = nw.main( - ["--testmode", "--version", "--config=%s" % fncDir, "--data=%s" % tmpDir] + ["--testmode", "--version", "--config=%s" % tmpDir, "--data=%s" % tmpDir] ) - nwGUI.closeMain() - nwGUI.close() + assert nwGUI.closeMain() == "closeMain" assert ex.value.code == 0 # Invalid options with pytest.raises(SystemExit) as ex: nwGUI = nw.main( - ["--testmode", "--invalid", "--config=%s" % fncDir, "--data=%s" % tmpDir] + ["--testmode", "--invalid", "--config=%s" % tmpDir, "--data=%s" % tmpDir] ) - nwGUI.closeMain() - nwGUI.close() + assert nwGUI.closeMain() == "closeMain" assert ex.value.code == 2 - # Simulate import error + # Project Path + nwGUI = nw.main( + ["--testmode", "--config=%s" % tmpDir, "--data=%s" % tmpDir, "sample/"] + ) + assert nw.CONFIG.cmdOpen == "sample/" + assert nwGUI.closeMain() == "closeMain" + + monkeypatch.undo() + +# END Test testBaseInit_Options + +@pytest.mark.base +def testBaseInit_Imports(caplog, monkeypatch, tmpDir): + """Check import error handling. + """ + monkeypatch.setattr("nw.guimain.GuiMain", DummyMain) + monkeypatch.setattr("PyQt5.QtWidgets.QApplication.__init__", lambda *args: None) + monkeypatch.setattr("PyQt5.QtWidgets.QApplication.exec_", lambda *args: 0) + monkeypatch.setattr("PyQt5.QtWidgets.QErrorMessage.__init__", lambda *args: None) + monkeypatch.setattr("PyQt5.QtWidgets.QErrorMessage.resize", lambda *args: None) + monkeypatch.setattr("PyQt5.QtWidgets.QErrorMessage.showMessage", lambda *args: None) monkeypatch.setitem(sys.modules, "lxml", None) monkeypatch.setattr("sys.hexversion", 0x0) monkeypatch.setattr("nw.CONFIG.verQtValue", 50000) monkeypatch.setattr("nw.CONFIG.verPyQtValue", 50000) + with pytest.raises(SystemExit) as ex: - nwGUI = nw.main( - ["--testmode", "--config=%s" % fncDir, "--data=%s" % tmpDir] + _ = nw.main( + ["--testmode", "--config=%s" % tmpDir, "--data=%s" % tmpDir] ) - nwGUI.closeMain() - nwGUI.close() + assert ex.value.code & 4 == 4 # Python version not satisfied assert ex.value.code & 8 == 8 # Qt version not satisfied assert ex.value.code & 16 == 16 # PyQt version not satisfied assert ex.value.code & 32 == 32 # lxml package missing + + assert "At least Python" in caplog.messages[0] + assert "At least Qt5" in caplog.messages[1] + assert "At least PyQt5" in caplog.messages[2] + assert "lxml" in caplog.messages[3] + monkeypatch.undo() -# END Test testBaseInit_Launch +# END Test testBaseInit_Imports