Remove main app testmode flag
This commit is contained in:
+13
-16
@@ -97,7 +97,6 @@ def main(sysArgs: list | None = None) -> GuiMain | None:
|
|||||||
"style=",
|
"style=",
|
||||||
"config=",
|
"config=",
|
||||||
"data=",
|
"data=",
|
||||||
"testmode",
|
|
||||||
"meminfo"
|
"meminfo"
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -127,7 +126,6 @@ def main(sysArgs: list | None = None) -> GuiMain | None:
|
|||||||
fmtFlags = 0b00
|
fmtFlags = 0b00
|
||||||
confPath = None
|
confPath = None
|
||||||
dataPath = None
|
dataPath = None
|
||||||
testMode = False
|
|
||||||
qtStyle = "Fusion"
|
qtStyle = "Fusion"
|
||||||
cmdOpen = None
|
cmdOpen = None
|
||||||
|
|
||||||
@@ -163,8 +161,6 @@ def main(sysArgs: list | None = None) -> GuiMain | None:
|
|||||||
confPath = inArg
|
confPath = inArg
|
||||||
elif inOpt == "--data":
|
elif inOpt == "--data":
|
||||||
dataPath = inArg
|
dataPath = inArg
|
||||||
elif inOpt == "--testmode":
|
|
||||||
testMode = True
|
|
||||||
elif inOpt == "--meminfo":
|
elif inOpt == "--meminfo":
|
||||||
CONFIG.memInfo = True
|
CONFIG.memInfo = True
|
||||||
|
|
||||||
@@ -257,18 +253,8 @@ def main(sysArgs: list | None = None) -> GuiMain | None:
|
|||||||
from novelwriter.gui.theme import GuiTheme
|
from novelwriter.gui.theme import GuiTheme
|
||||||
from novelwriter.guimain import GuiMain
|
from novelwriter.guimain import GuiMain
|
||||||
|
|
||||||
if testMode:
|
# Create App
|
||||||
# Only used for testing where the test framework creates the app
|
app = _createApp(qtStyle)
|
||||||
CONFIG.loadConfig()
|
|
||||||
SHARED.initTheme(GuiTheme())
|
|
||||||
return GuiMain()
|
|
||||||
|
|
||||||
app = QApplication([CONFIG.appName, (f"-style={qtStyle}")])
|
|
||||||
app.setApplicationName(CONFIG.appName)
|
|
||||||
app.setApplicationVersion(__version__)
|
|
||||||
app.setOrganizationDomain(__domain__)
|
|
||||||
app.setOrganizationName(__domain__)
|
|
||||||
app.setDesktopFileName(CONFIG.appName)
|
|
||||||
|
|
||||||
# Connect the exception handler before making the main GUI
|
# Connect the exception handler before making the main GUI
|
||||||
sys.excepthook = exceptionHandler
|
sys.excepthook = exceptionHandler
|
||||||
@@ -283,3 +269,14 @@ def main(sysArgs: list | None = None) -> GuiMain | None:
|
|||||||
nwGUI.postLaunchTasks(cmdOpen)
|
nwGUI.postLaunchTasks(cmdOpen)
|
||||||
|
|
||||||
sys.exit(app.exec())
|
sys.exit(app.exec())
|
||||||
|
|
||||||
|
|
||||||
|
def _createApp(style: str) -> QApplication:
|
||||||
|
"""Create the app."""
|
||||||
|
app = QApplication([CONFIG.appName, (f"-style={style}")])
|
||||||
|
app.setApplicationName(CONFIG.appName)
|
||||||
|
app.setApplicationVersion(__version__)
|
||||||
|
app.setOrganizationDomain(__domain__)
|
||||||
|
app.setOrganizationName(__domain__)
|
||||||
|
app.setDesktopFileName(CONFIG.appName)
|
||||||
|
return app
|
||||||
|
|||||||
@@ -23,147 +23,153 @@ from __future__ import annotations
|
|||||||
import logging
|
import logging
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
from unittest.mock import Mock
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from novelwriter import CONFIG, logger, main
|
from PyQt6.QtWidgets import QApplication
|
||||||
|
|
||||||
from tests.mocked import MockGuiMain
|
from novelwriter import (
|
||||||
|
C_BLUE, C_END, C_WHITE, CONFIG, L_FILE, L_LINE, L_LVLC, L_LVLP, L_TEXT,
|
||||||
|
L_TIME, _createApp, logger, main
|
||||||
|
)
|
||||||
|
|
||||||
|
from tests.tools import clearLogHandlers
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.base
|
@pytest.mark.base
|
||||||
def testBaseInit_Launch(caplog, monkeypatch, fncPath):
|
def testBaseInit_Launch(caplog, monkeypatch, fncPath):
|
||||||
"""Check launching the main GUI."""
|
"""Check launching the main GUI. This test """
|
||||||
monkeypatch.setattr("novelwriter.guimain.GuiMain", MockGuiMain)
|
monkeypatch.setattr("novelwriter._createApp", lambda *a: Mock())
|
||||||
|
monkeypatch.setattr("novelwriter.guimain.GuiMain", Mock())
|
||||||
|
monkeypatch.setattr(sys, "exit", Mock())
|
||||||
|
|
||||||
# TestMode Launch
|
# Default Launch
|
||||||
nwGUI = main(["--testmode", f"--config={fncPath}", f"--data={fncPath}"])
|
main([f"--config={fncPath}", f"--data={fncPath}"])
|
||||||
assert isinstance(nwGUI, MockGuiMain)
|
assert CONFIG._confPath == fncPath
|
||||||
|
assert CONFIG._dataPath == fncPath
|
||||||
|
|
||||||
# Darwin Launch
|
# Darwin Launch Error Handling
|
||||||
caplog.clear()
|
|
||||||
osDarwin = CONFIG.osDarwin
|
|
||||||
CONFIG.osDarwin = True
|
|
||||||
with monkeypatch.context() as mp:
|
with monkeypatch.context() as mp:
|
||||||
mp.setitem(sys.modules, "Foundation", None)
|
mp.setitem(sys.modules, "Foundation", None)
|
||||||
nwGUI = main(["--testmode", f"--config={fncPath}", f"--data={fncPath}"])
|
main([f"--config={fncPath}", f"--data={fncPath}"])
|
||||||
assert isinstance(nwGUI, MockGuiMain)
|
|
||||||
|
|
||||||
CONFIG.osDarwin = osDarwin
|
# Windows Launch Error Handling
|
||||||
|
|
||||||
# Windows Launch
|
|
||||||
caplog.clear()
|
|
||||||
osWindows = CONFIG.osWindows
|
|
||||||
CONFIG.osWindows = True
|
|
||||||
with monkeypatch.context() as mp:
|
with monkeypatch.context() as mp:
|
||||||
mp.setitem(sys.modules, "ctypes", None)
|
mp.setitem(sys.modules, "ctypes", None)
|
||||||
nwGUI = main(["--testmode", f"--config={fncPath}", f"--data={fncPath}"])
|
main([f"--config={fncPath}", f"--data={fncPath}"])
|
||||||
assert isinstance(nwGUI, MockGuiMain)
|
|
||||||
|
|
||||||
CONFIG.osWindows = osWindows
|
|
||||||
|
|
||||||
# Normal Launch
|
@pytest.mark.base
|
||||||
with monkeypatch.context() as mp:
|
def testBaseInit_CreateApp(caplog, monkeypatch, fncPath):
|
||||||
mp.setattr("PyQt6.QtWidgets.QApplication.__init__", lambda *a: None)
|
"""Check creating the Qt app."""
|
||||||
mp.setattr("PyQt6.QtWidgets.QApplication.setApplicationName", lambda *a: None)
|
monkeypatch.setattr("PyQt6.QtWidgets.QApplication.__init__", lambda *a: None)
|
||||||
mp.setattr("PyQt6.QtWidgets.QApplication.setApplicationVersion", lambda *a: None)
|
monkeypatch.setattr("PyQt6.QtWidgets.QApplication.setApplicationName", lambda *a: None)
|
||||||
mp.setattr("PyQt6.QtWidgets.QApplication.setWindowIcon", lambda *a: None)
|
monkeypatch.setattr("PyQt6.QtWidgets.QApplication.setApplicationVersion", lambda *a: None)
|
||||||
mp.setattr("PyQt6.QtWidgets.QApplication.setOrganizationDomain", lambda *a: None)
|
monkeypatch.setattr("PyQt6.QtWidgets.QApplication.setWindowIcon", lambda *a: None)
|
||||||
mp.setattr("PyQt6.QtWidgets.QApplication.exec", lambda *a: 0)
|
monkeypatch.setattr("PyQt6.QtWidgets.QApplication.setOrganizationDomain", lambda *a: None)
|
||||||
with pytest.raises(SystemExit) as ex:
|
monkeypatch.setattr("PyQt6.QtWidgets.QApplication.exec", lambda *a: 0)
|
||||||
main([f"--config={fncPath}", f"--data={fncPath}"])
|
|
||||||
assert ex.value.code == 0
|
app = _createApp("Fusion")
|
||||||
|
assert isinstance(app, QApplication)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.base
|
@pytest.mark.base
|
||||||
def testBaseInit_Options(monkeypatch, fncPath):
|
def testBaseInit_Options(monkeypatch, fncPath):
|
||||||
"""Test command line options for logging level."""
|
"""Test command line options for logging level."""
|
||||||
monkeypatch.setattr("novelwriter.guimain.GuiMain", MockGuiMain)
|
gui = Mock()
|
||||||
|
app = Mock()
|
||||||
|
app.exec = Mock(return_value=0)
|
||||||
|
|
||||||
|
monkeypatch.setattr("novelwriter._createApp", lambda *a: app)
|
||||||
|
monkeypatch.setattr("novelwriter.guimain.GuiMain", lambda *a: gui)
|
||||||
monkeypatch.setattr(sys, "argv", [
|
monkeypatch.setattr(sys, "argv", [
|
||||||
"novelWriter.py", "--testmode", "--meminfo", f"--config={fncPath}", f"--data={fncPath}"
|
"novelWriter.py", f"--config={fncPath}", f"--data={fncPath}"
|
||||||
])
|
])
|
||||||
|
|
||||||
# Defaults w/None Args
|
# Defaults wo/Args
|
||||||
nwGUI = main()
|
gui.reset_mock()
|
||||||
assert nwGUI is not None
|
with pytest.raises(SystemExit) as ex:
|
||||||
|
main()
|
||||||
|
assert ex.value.code == 0
|
||||||
assert logger.getEffectiveLevel() == logging.WARNING
|
assert logger.getEffectiveLevel() == logging.WARNING
|
||||||
assert nwGUI.closeMain() == "closeMain"
|
gui.postLaunchTasks.assert_called_once()
|
||||||
|
gui.postLaunchTasks.assert_called_with(None)
|
||||||
|
|
||||||
# Defaults
|
# Defaults
|
||||||
nwGUI = main(
|
with pytest.raises(SystemExit) as ex:
|
||||||
["--testmode", f"--config={fncPath}", f"--data={fncPath}", "--style=Fusion"]
|
main([f"--config={fncPath}", f"--data={fncPath}", "--style=Fusion", "--meminfo"])
|
||||||
)
|
assert ex.value.code == 0
|
||||||
assert nwGUI is not None
|
assert CONFIG.memInfo is True
|
||||||
assert logger.getEffectiveLevel() == logging.WARNING
|
|
||||||
assert nwGUI.closeMain() == "closeMain"
|
def getFormat() -> str:
|
||||||
|
formatter = logger.handlers[0].formatter
|
||||||
|
assert formatter is not None
|
||||||
|
fmt = formatter._fmt
|
||||||
|
assert fmt is not None
|
||||||
|
return fmt
|
||||||
|
|
||||||
# Log Levels w/Color
|
# Log Levels w/Color
|
||||||
nwGUI = main(
|
clearLogHandlers()
|
||||||
["--testmode", "--info", "--color", f"--config={fncPath}", f"--data={fncPath}"]
|
with pytest.raises(SystemExit) as ex:
|
||||||
)
|
main(["--info", "--color", f"--config={fncPath}", f"--data={fncPath}"])
|
||||||
assert nwGUI is not None
|
assert ex.value.code == 0
|
||||||
assert logger.getEffectiveLevel() == logging.INFO
|
assert logger.getEffectiveLevel() == logging.INFO
|
||||||
assert nwGUI.closeMain() == "closeMain"
|
assert getFormat() == f"{L_LVLC} {L_TEXT}"
|
||||||
|
|
||||||
nwGUI = main(
|
clearLogHandlers()
|
||||||
["--testmode", "--debug", "--color", f"--config={fncPath}", f"--data={fncPath}"]
|
with pytest.raises(SystemExit) as ex:
|
||||||
)
|
main(["--debug", "--color", f"--config={fncPath}", f"--data={fncPath}"])
|
||||||
assert nwGUI is not None
|
assert ex.value.code == 0
|
||||||
assert logger.getEffectiveLevel() == logging.DEBUG
|
assert logger.getEffectiveLevel() == logging.DEBUG
|
||||||
assert nwGUI.closeMain() == "closeMain"
|
assert getFormat() == (
|
||||||
|
f"{L_TIME} {C_BLUE}{L_FILE}{C_END}:{C_WHITE}{L_LINE}{C_END} {L_LVLC} {L_TEXT}"
|
||||||
|
)
|
||||||
|
|
||||||
# Log Levels wo/Color
|
# Log Levels wo/Color
|
||||||
nwGUI = main(
|
clearLogHandlers()
|
||||||
["--testmode", "--info", f"--config={fncPath}", f"--data={fncPath}"]
|
with pytest.raises(SystemExit) as ex:
|
||||||
)
|
main(["--info", f"--config={fncPath}", f"--data={fncPath}"])
|
||||||
assert nwGUI is not None
|
assert ex.value.code == 0
|
||||||
assert logger.getEffectiveLevel() == logging.INFO
|
assert logger.getEffectiveLevel() == logging.INFO
|
||||||
assert nwGUI.closeMain() == "closeMain"
|
assert getFormat() == f"{L_LVLP} {L_TEXT}"
|
||||||
|
|
||||||
nwGUI = main(
|
clearLogHandlers()
|
||||||
["--testmode", "--debug", f"--config={fncPath}", f"--data={fncPath}"]
|
with pytest.raises(SystemExit) as ex:
|
||||||
)
|
main(["--debug", f"--config={fncPath}", f"--data={fncPath}"])
|
||||||
assert nwGUI is not None
|
assert ex.value.code == 0
|
||||||
assert logger.getEffectiveLevel() == logging.DEBUG
|
assert logger.getEffectiveLevel() == logging.DEBUG
|
||||||
assert nwGUI.closeMain() == "closeMain"
|
assert getFormat() == f"{L_TIME} {L_FILE}:{L_LINE} {L_LVLP} {L_TEXT}"
|
||||||
|
|
||||||
# Help and Version
|
# Help and Version
|
||||||
with pytest.raises(SystemExit) as ex:
|
with pytest.raises(SystemExit) as ex:
|
||||||
nwGUI = main(
|
main(["--help", f"--config={fncPath}", f"--data={fncPath}"])
|
||||||
["--testmode", "--help", f"--config={fncPath}", f"--data={fncPath}"]
|
|
||||||
)
|
|
||||||
assert nwGUI is not None
|
|
||||||
assert nwGUI.closeMain() == "closeMain"
|
|
||||||
assert ex.value.code == 0
|
assert ex.value.code == 0
|
||||||
|
|
||||||
with pytest.raises(SystemExit) as ex:
|
with pytest.raises(SystemExit) as ex:
|
||||||
nwGUI = main(
|
main(["--version", f"--config={fncPath}", f"--data={fncPath}"])
|
||||||
["--testmode", "--version", f"--config={fncPath}", f"--data={fncPath}"]
|
|
||||||
)
|
|
||||||
assert nwGUI is not None
|
|
||||||
assert nwGUI.closeMain() == "closeMain"
|
|
||||||
assert ex.value.code == 0
|
assert ex.value.code == 0
|
||||||
|
|
||||||
# Invalid options
|
# Invalid options
|
||||||
with pytest.raises(SystemExit) as ex:
|
with pytest.raises(SystemExit) as ex:
|
||||||
nwGUI = main(
|
main(["--invalid", f"--config={fncPath}", f"--data={fncPath}"])
|
||||||
["--testmode", "--invalid", f"--config={fncPath}", f"--data={fncPath}"]
|
|
||||||
)
|
|
||||||
assert nwGUI is not None
|
|
||||||
assert nwGUI.closeMain() == "closeMain"
|
|
||||||
assert ex.value.code == 2
|
assert ex.value.code == 2
|
||||||
|
|
||||||
# Project Path
|
# Project Path
|
||||||
nwGUI = main(
|
gui.reset_mock()
|
||||||
["--testmode", f"--config={fncPath}", f"--data={fncPath}", "sample/"]
|
with pytest.raises(SystemExit) as ex:
|
||||||
)
|
main([f"--config={fncPath}", f"--data={fncPath}", "sample/"])
|
||||||
assert nwGUI is not None
|
assert ex.value.code == 0
|
||||||
assert nwGUI.closeMain() == "closeMain"
|
gui.postLaunchTasks.assert_called_once()
|
||||||
|
gui.postLaunchTasks.assert_called_with("sample/")
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.base
|
@pytest.mark.base
|
||||||
def testBaseInit_Imports(caplog, monkeypatch, fncPath):
|
def testBaseInit_Imports(caplog, monkeypatch, fncPath):
|
||||||
"""Check import error handling."""
|
"""Check import error handling."""
|
||||||
monkeypatch.setattr("novelwriter.guimain.GuiMain", MockGuiMain)
|
monkeypatch.setattr("novelwriter._createApp", lambda *a: Mock())
|
||||||
|
monkeypatch.setattr("novelwriter.guimain.GuiMain", lambda *a: Mock())
|
||||||
|
|
||||||
monkeypatch.setattr("PyQt6.QtWidgets.QApplication.__init__", lambda *a: None)
|
monkeypatch.setattr("PyQt6.QtWidgets.QApplication.__init__", lambda *a: None)
|
||||||
monkeypatch.setattr("PyQt6.QtWidgets.QApplication.exec", lambda *a: 0)
|
monkeypatch.setattr("PyQt6.QtWidgets.QApplication.exec", lambda *a: 0)
|
||||||
monkeypatch.setattr("PyQt6.QtWidgets.QErrorMessage.__init__", lambda *a: None)
|
monkeypatch.setattr("PyQt6.QtWidgets.QErrorMessage.__init__", lambda *a: None)
|
||||||
@@ -174,9 +180,7 @@ def testBaseInit_Imports(caplog, monkeypatch, fncPath):
|
|||||||
monkeypatch.setattr("novelwriter.CONFIG.verPyQtValue", 0x050000)
|
monkeypatch.setattr("novelwriter.CONFIG.verPyQtValue", 0x050000)
|
||||||
|
|
||||||
with pytest.raises(SystemExit) as ex:
|
with pytest.raises(SystemExit) as ex:
|
||||||
_ = main(
|
main([f"--config={fncPath}", f"--data={fncPath}"])
|
||||||
["--testmode", f"--config={fncPath}", f"--data={fncPath}"]
|
|
||||||
)
|
|
||||||
|
|
||||||
assert ex.value.code & 4 == 4 # Python version not satisfied # type: ignore
|
assert ex.value.code & 4 == 4 # Python version not satisfied # type: ignore
|
||||||
assert ex.value.code & 8 == 8 # Qt version not satisfied # type: ignore
|
assert ex.value.code & 8 == 8 # Qt version not satisfied # type: ignore
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ from pathlib import Path
|
|||||||
|
|
||||||
from PyQt6.QtWidgets import QDialog, QVBoxLayout, QWidget
|
from PyQt6.QtWidgets import QDialog, QVBoxLayout, QWidget
|
||||||
|
|
||||||
|
from novelwriter import logger
|
||||||
|
|
||||||
XML_IGNORE = ("<novelWriterXML", "<project")
|
XML_IGNORE = ("<novelWriterXML", "<project")
|
||||||
ODT_IGNORE = ("<meta:generator", "<meta:creation-date", "<dc:date", "<meta:editing")
|
ODT_IGNORE = ("<meta:generator", "<meta:creation-date", "<dc:date", "<meta:editing")
|
||||||
NWD_IGNORE = ("%%~date:",)
|
NWD_IGNORE = ("%%~date:",)
|
||||||
@@ -155,6 +157,12 @@ def cleanProject(path: str | Path):
|
|||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def clearLogHandlers():
|
||||||
|
"""Clear all log handlers."""
|
||||||
|
for handler in logger.handlers:
|
||||||
|
logger.removeHandler(handler)
|
||||||
|
|
||||||
|
|
||||||
def buildTestProject(obj: object, projPath: Path) -> None:
|
def buildTestProject(obj: object, projPath: Path) -> None:
|
||||||
"""Build a standard test project in projPath using the project
|
"""Build a standard test project in projPath using the project
|
||||||
object as the parent.
|
object as the parent.
|
||||||
|
|||||||
Reference in New Issue
Block a user