def nwConf(nwRef, nwTemp): """Temporary novelWriter configuration used for the dummy instance of novelWriter's main GUI. """ theConf = Config() theConf.initConfig(nwRef, nwTemp) return theConf
def tmpConf(nwTemp): """Create a temporary novelWriter configuration object. """ theConf = Config() theConf.initConfig(nwTemp, nwTemp) theConf.setLastPath("") return theConf
def tmpConf(tmpDir): """Create a temporary novelWriter configuration object. """ confFile = os.path.join(tmpDir, "novelwriter.conf") if os.path.isfile(confFile): os.unlink(confFile) theConf = Config() theConf.initConfig(tmpDir, tmpDir) theConf.setLastPath("") return theConf
def fncConf(fncDir): """Create a temporary novelWriter configuration object. """ confFile = os.path.join(fncDir, "novelwriter.conf") if os.path.isfile(confFile): os.unlink(confFile) theConf = Config() theConf.initConfig(fncDir, fncDir) theConf.setLastPath("") theConf.guiLang = "en_GB" return theConf
def testBaseConfig_Init(monkeypatch, tmpDir, fncDir, outDir, refDir, filesDir): """Test config intialisation. """ tstConf = Config() confFile = os.path.join(tmpDir, "novelwriter.conf") testFile = os.path.join(outDir, "baseConfig_novelwriter.conf") compFile = os.path.join(refDir, "baseConfig_novelwriter.conf") # Make sure we don't have any old conf file if os.path.isfile(confFile): os.unlink(confFile) # Let the config class figure out the path with monkeypatch.context() as mp: mp.setattr("PyQt5.QtCore.QStandardPaths.writableLocation", lambda *args: fncDir) tstConf.verQtValue = 50600 tstConf.initConfig() assert tstConf.confPath == os.path.join(fncDir, tstConf.appHandle) assert tstConf.dataPath == os.path.join(fncDir, tstConf.appHandle) assert not os.path.isfile(confFile) tstConf.verQtValue = 50000 tstConf.initConfig() assert tstConf.confPath == os.path.join(fncDir, tstConf.appHandle) assert tstConf.dataPath == os.path.join(fncDir, tstConf.appHandle) assert not os.path.isfile(confFile) # Fail to make folders with monkeypatch.context() as mp: mp.setattr("os.mkdir", causeOSError) tstConfDir = os.path.join(fncDir, "test_conf") tstConf.initConfig(confPath=tstConfDir, dataPath=tmpDir) assert tstConf.confPath is None assert tstConf.dataPath == tmpDir assert not os.path.isfile(confFile) tstDataDir = os.path.join(fncDir, "test_data") tstConf.initConfig(confPath=tmpDir, dataPath=tstDataDir) assert tstConf.confPath == tmpDir assert tstConf.dataPath is None assert os.path.isfile(confFile) os.unlink(confFile) # Test load/save with no path tstConf.confPath = None assert not tstConf.loadConfig() assert not tstConf.saveConfig() # Run again and set the paths directly and correctly # This should create a config file as well with monkeypatch.context() as mp: mp.setattr("os.path.expanduser", lambda *args: "") tstConf.spellTool = nwConst.SP_INTERNAL tstConf.initConfig(confPath=tmpDir, dataPath=tmpDir) assert tstConf.confPath == tmpDir assert tstConf.dataPath == tmpDir assert os.path.isfile(confFile) copyfile(confFile, testFile) assert cmpFiles(testFile, compFile, [2, 9, 10]) # Load and save with OSError with monkeypatch.context() as mp: mp.setattr("builtins.open", causeOSError) assert not tstConf.loadConfig() assert tstConf.hasError is True assert tstConf.errData != [] assert tstConf.getErrData().startswith("Could not") assert tstConf.hasError is False assert tstConf.errData == [] assert not tstConf.saveConfig() assert tstConf.hasError is True assert tstConf.errData != [] assert tstConf.getErrData().startswith("Could not") assert tstConf.hasError is False assert tstConf.errData == [] assert tstConf.loadConfig() assert tstConf.saveConfig() # Test Correcting Quote Settings origDbl = tstConf.fmtDoubleQuotes origSng = tstConf.fmtSingleQuotes orDoDbl = tstConf.doReplaceDQuote orDoSng = tstConf.doReplaceSQuote tstConf.fmtDoubleQuotes = ["\"", "\""] tstConf.fmtSingleQuotes = ["'", "'"] tstConf.doReplaceDQuote = True tstConf.doReplaceSQuote = True assert tstConf.saveConfig() assert tstConf.loadConfig() assert not tstConf.doReplaceDQuote assert not tstConf.doReplaceSQuote tstConf.fmtDoubleQuotes = origDbl tstConf.fmtSingleQuotes = origSng tstConf.doReplaceDQuote = orDoDbl tstConf.doReplaceSQuote = orDoSng assert tstConf.saveConfig() # Localisation i18nDir = os.path.join(fncDir, "i18n") os.mkdir(i18nDir) os.mkdir(os.path.join(i18nDir, "stuff")) tstConf.nwLangPath = i18nDir copyfile(os.path.join(filesDir, "nw_en_GB.qm"), os.path.join(fncDir, "nw_en_GB.qm")) writeFile(os.path.join(i18nDir, "nw_en_GB.ts"), "") writeFile(os.path.join(i18nDir, "nw_abcd.qm"), "") tstApp = DummyApp() tstConf.initLocalisation(tstApp) theList = tstConf.listLanguages(tstConf.LANG_NW) assert theList == [("en_GB", "British English")] copyfile(confFile, testFile) assert cmpFiles(testFile, compFile, [2, 9, 10])
def testBaseConfig_Init(monkeypatch, tmpDir, fncDir, outDir, refDir): """Test config intialisation. """ tstConf = Config() confFile = os.path.join(tmpDir, "novelwriter.conf") testFile = os.path.join(outDir, "baseConfig_novelwriter.conf") compFile = os.path.join(refDir, "baseConfig_novelwriter.conf") # Make sure we don't have any old conf file if os.path.isfile(confFile): os.unlink(confFile) # Let the config class figure out the path monkeypatch.setattr("PyQt5.QtCore.QStandardPaths.writableLocation", lambda *args: fncDir) tstConf.verQtValue = 50600 tstConf.initConfig() assert tstConf.confPath == os.path.join(fncDir, tstConf.appHandle) assert tstConf.dataPath == os.path.join(fncDir, tstConf.appHandle) assert not os.path.isfile(confFile) tstConf.verQtValue = 50000 tstConf.initConfig() assert tstConf.confPath == os.path.join(fncDir, tstConf.appHandle) assert tstConf.dataPath == os.path.join(fncDir, tstConf.appHandle) assert not os.path.isfile(confFile) monkeypatch.undo() # Fail to make folders monkeypatch.setattr("os.mkdir", causeOSError) tstConfDir = os.path.join(fncDir, "test_conf") tstConf.initConfig(confPath=tstConfDir, dataPath=tmpDir) assert tstConf.confPath is None assert tstConf.dataPath == tmpDir assert not os.path.isfile(confFile) tstDataDir = os.path.join(fncDir, "test_data") tstConf.initConfig(confPath=tmpDir, dataPath=tstDataDir) assert tstConf.confPath == tmpDir assert tstConf.dataPath is None assert os.path.isfile(confFile) os.unlink(confFile) monkeypatch.undo() # Test load/save with no path tstConf.confPath = None assert not tstConf.loadConfig() assert not tstConf.saveConfig() # Run again and set the paths directly and correctly # This should create a config file as well monkeypatch.setattr("os.path.expanduser", lambda *args: "") tstConf.spellTool = nwConst.SP_INTERNAL tstConf.initConfig(confPath=tmpDir, dataPath=tmpDir) assert tstConf.confPath == tmpDir assert tstConf.dataPath == tmpDir assert os.path.isfile(confFile) copyfile(confFile, testFile) assert cmpFiles(testFile, compFile, [2, 9]) monkeypatch.undo() # Load and save with OSError monkeypatch.setattr("builtins.open", causeOSError) assert not tstConf.loadConfig() assert tstConf.hasError is True assert tstConf.errData != [] assert tstConf.getErrData().startswith("Could not") assert tstConf.hasError is False assert tstConf.errData == [] assert not tstConf.saveConfig() assert tstConf.hasError is True assert tstConf.errData != [] assert tstConf.getErrData().startswith("Could not") assert tstConf.hasError is False assert tstConf.errData == [] monkeypatch.undo() assert tstConf.loadConfig() assert tstConf.saveConfig() copyfile(confFile, testFile) assert cmpFiles(testFile, compFile, [2, 9])
def testGuiPreferences_Main(qtbot, monkeypatch, fncDir, outDir, refDir): """Test the load project wizard. """ # Block message box monkeypatch.setattr(QMessageBox, "question", lambda *args: QMessageBox.Yes) monkeypatch.setattr(QMessageBox, "information", lambda *args: QMessageBox.Yes) # Must create a clean config and GUI object as the test-wide # nw.CONFIG object is created on import an can be tainted by other tests confFile = os.path.join(fncDir, "novelwriter.conf") if os.path.isfile(confFile): os.unlink(confFile) theConf = Config() theConf.initConfig(fncDir, fncDir) theConf.setLastPath("") origConf = nw.CONFIG nw.CONFIG = theConf nwGUI = nw.main( ["--testmode", "--config=%s" % fncDir, "--data=%s" % fncDir]) qtbot.addWidget(nwGUI) nwGUI.show() qtbot.waitForWindowShown(nwGUI) qtbot.wait(20) theConf = nwGUI.mainConf assert theConf.confPath == fncDir monkeypatch.setattr(GuiPreferences, "exec_", lambda *args: None) monkeypatch.setattr(GuiPreferences, "result", lambda *args: QDialog.Accepted) nwGUI.mainMenu.aPreferences.activate(QAction.Trigger) qtbot.waitUntil(lambda: getGuiItem("GuiPreferences") is not None, timeout=1000) nwPrefs = getGuiItem("GuiPreferences") assert isinstance(nwPrefs, GuiPreferences) nwPrefs.show() assert nwPrefs.mainConf.confPath == fncDir # qtbot.stopForInteraction() # General Settings qtbot.wait(keyDelay) tabGeneral = nwPrefs.tabGeneral nwPrefs._tabBox.setCurrentWidget(tabGeneral) qtbot.wait(keyDelay) assert not tabGeneral.preferDarkIcons.isChecked() qtbot.mouseClick(tabGeneral.preferDarkIcons, Qt.LeftButton) assert tabGeneral.preferDarkIcons.isChecked() qtbot.wait(keyDelay) assert tabGeneral.showFullPath.isChecked() qtbot.mouseClick(tabGeneral.showFullPath, Qt.LeftButton) assert not tabGeneral.showFullPath.isChecked() qtbot.wait(keyDelay) assert not tabGeneral.hideVScroll.isChecked() qtbot.mouseClick(tabGeneral.hideVScroll, Qt.LeftButton) assert tabGeneral.hideVScroll.isChecked() qtbot.wait(keyDelay) assert not tabGeneral.hideHScroll.isChecked() qtbot.mouseClick(tabGeneral.hideHScroll, Qt.LeftButton) assert tabGeneral.hideHScroll.isChecked() # Check font button monkeypatch.setattr(QFontDialog, "getFont", lambda font, obj: (font, True)) qtbot.mouseClick(tabGeneral.fontButton, Qt.LeftButton) qtbot.wait(keyDelay) tabGeneral.guiFontSize.setValue(12) # Projects Settings qtbot.wait(keyDelay) tabProjects = nwPrefs.tabProjects nwPrefs._tabBox.setCurrentWidget(tabProjects) tabProjects.backupPath = "no/where" qtbot.wait(keyDelay) assert not tabProjects.backupOnClose.isChecked() qtbot.mouseClick(tabProjects.backupOnClose, Qt.LeftButton) assert tabProjects.backupOnClose.isChecked() # Check Browse button monkeypatch.setattr(QFileDialog, "getExistingDirectory", lambda *args, **kwargs: "") assert not tabProjects._backupFolder() monkeypatch.setattr(QFileDialog, "getExistingDirectory", lambda *args, **kwargs: "some/dir") qtbot.mouseClick(tabProjects.backupGetPath, Qt.LeftButton) qtbot.wait(keyDelay) tabProjects.autoSaveDoc.setValue(20) tabProjects.autoSaveProj.setValue(40) # Text Layout Settings qtbot.wait(keyDelay) tabLayout = nwPrefs.tabLayout nwPrefs._tabBox.setCurrentWidget(tabLayout) qtbot.wait(keyDelay) qtbot.mouseClick(tabLayout.fontButton, Qt.LeftButton) qtbot.wait(keyDelay) tabLayout.textStyleSize.setValue(13) tabLayout.textFlowMax.setValue(700) tabLayout.focusDocWidth.setValue(900) tabLayout.textMargin.setValue(45) tabLayout.tabWidth.setValue(45) qtbot.wait(keyDelay) assert not tabLayout.textFlowFixed.isChecked() qtbot.mouseClick(tabLayout.textFlowFixed, Qt.LeftButton) assert tabLayout.textFlowFixed.isChecked() qtbot.wait(keyDelay) assert not tabLayout.hideFocusFooter.isChecked() qtbot.mouseClick(tabLayout.hideFocusFooter, Qt.LeftButton) assert tabLayout.hideFocusFooter.isChecked() qtbot.wait(keyDelay) assert not tabLayout.textJustify.isChecked() qtbot.mouseClick(tabLayout.textJustify, Qt.LeftButton) assert tabLayout.textJustify.isChecked() qtbot.wait(keyDelay) assert tabLayout.scrollPastEnd.isChecked() qtbot.mouseClick(tabLayout.scrollPastEnd, Qt.LeftButton) assert not tabLayout.scrollPastEnd.isChecked() qtbot.wait(keyDelay) assert not tabLayout.autoScroll.isChecked() qtbot.mouseClick(tabLayout.autoScroll, Qt.LeftButton) assert tabLayout.autoScroll.isChecked() # Editor Settings qtbot.wait(keyDelay) tabEditing = nwPrefs.tabEditing nwPrefs._tabBox.setCurrentWidget(tabEditing) qtbot.wait(keyDelay) assert tabEditing.highlightQuotes.isChecked() qtbot.mouseClick(tabEditing.highlightQuotes, Qt.LeftButton) assert not tabEditing.highlightQuotes.isChecked() qtbot.wait(keyDelay) assert tabEditing.highlightEmph.isChecked() qtbot.mouseClick(tabEditing.highlightEmph, Qt.LeftButton) assert not tabEditing.highlightEmph.isChecked() qtbot.wait(keyDelay) assert not tabEditing.showTabsNSpaces.isChecked() qtbot.mouseClick(tabEditing.showTabsNSpaces, Qt.LeftButton) assert tabEditing.showTabsNSpaces.isChecked() qtbot.wait(keyDelay) assert not tabEditing.showLineEndings.isChecked() qtbot.mouseClick(tabEditing.showLineEndings, Qt.LeftButton) assert tabEditing.showLineEndings.isChecked() qtbot.wait(keyDelay) tabEditing.bigDocLimit.setValue(500) # Auto-Replace Settings qtbot.wait(keyDelay) tabAutoRep = nwPrefs.tabAutoRep nwPrefs._tabBox.setCurrentWidget(tabAutoRep) qtbot.wait(keyDelay) assert tabAutoRep.autoSelect.isChecked() qtbot.mouseClick(tabAutoRep.autoSelect, Qt.LeftButton) assert not tabAutoRep.autoSelect.isChecked() qtbot.wait(keyDelay) assert tabAutoRep.autoReplaceMain.isChecked() qtbot.mouseClick(tabAutoRep.autoReplaceMain, Qt.LeftButton) assert not tabAutoRep.autoReplaceMain.isChecked() qtbot.wait(keyDelay) assert not tabAutoRep.autoReplaceSQ.isEnabled() assert not tabAutoRep.autoReplaceDQ.isEnabled() assert not tabAutoRep.autoReplaceDash.isEnabled() assert not tabAutoRep.autoReplaceDots.isEnabled() monkeypatch.setattr(QuotesDialog, "selectedQuote", "'") monkeypatch.setattr(QuotesDialog, "exec_", lambda *args: QDialog.Accepted) qtbot.mouseClick(tabAutoRep.btnDoubleStyleC, Qt.LeftButton) # Save and Check Config qtbot.mouseClick(nwPrefs.buttonBox.button(QDialogButtonBox.Ok), Qt.LeftButton) nwPrefs._doClose() assert theConf.confChanged theConf.lastPath = "" assert nwGUI.mainConf.saveConfig() projFile = os.path.join(fncDir, "novelwriter.conf") testFile = os.path.join(outDir, "guiPreferences_novelwriter.conf") compFile = os.path.join(refDir, "guiPreferences_novelwriter.conf") copyfile(projFile, testFile) ignoreLines = [ 2, # Timestamp 9, # Release Notes 12, 13, 14, 15, 16, 17, 18, # Window sizes 7, 28, # Fonts (depends on system default) ] assert cmpFiles(testFile, compFile, ignoreLines) # Clean up nw.CONFIG = origConf nwGUI.closeMain()