Exemple #1
0
def testBaseConfig_Constructor(monkeypatch):
    """Test config contructor.
    """
    # Linux
    monkeypatch.setattr("sys.platform", "linux")
    tstConf = Config()
    assert tstConf.osLinux is True
    assert tstConf.osDarwin is False
    assert tstConf.osWindows is False
    assert tstConf.osUnknown is False

    # macOS
    monkeypatch.setattr("sys.platform", "darwin")
    tstConf = Config()
    assert tstConf.osLinux is False
    assert tstConf.osDarwin is True
    assert tstConf.osWindows is False
    assert tstConf.osUnknown is False

    # Windows
    monkeypatch.setattr("sys.platform", "win32")
    tstConf = Config()
    assert tstConf.osLinux is False
    assert tstConf.osDarwin is False
    assert tstConf.osWindows is True
    assert tstConf.osUnknown is False

    # Cygwin
    monkeypatch.setattr("sys.platform", "cygwin")
    tstConf = Config()
    assert tstConf.osLinux is False
    assert tstConf.osDarwin is False
    assert tstConf.osWindows is True
    assert tstConf.osUnknown is False

    # Other
    monkeypatch.setattr("sys.platform", "some_other_os")
    tstConf = Config()
    assert tstConf.osLinux is False
    assert tstConf.osDarwin is False
    assert tstConf.osWindows is False
    assert tstConf.osUnknown is True
Exemple #2
0
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
Exemple #3
0
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 *a: 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 tstConf.loadConfig() is False
    assert tstConf.saveConfig() is False

    # 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 *a: "")
        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,
                        ignoreStart=("timestamp", "lastnotes", "guilang"))

    # 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 == []

    # Check handling of novelWriter as a package
    with monkeypatch.context() as mp:
        tstConf.initConfig(confPath=tmpDir, dataPath=tmpDir)
        assert tstConf.confPath == tmpDir
        assert tstConf.dataPath == tmpDir
        appRoot = tstConf.appRoot

        mp.setattr("os.path.isfile", lambda *a: True)
        tstConf.initConfig(confPath=tmpDir, dataPath=tmpDir)
        assert tstConf.confPath == tmpDir
        assert tstConf.dataPath == tmpDir
        assert tstConf.appRoot == os.path.dirname(appRoot)
        assert tstConf.appPath == os.path.dirname(appRoot)

    assert tstConf.loadConfig() is True
    assert tstConf.saveConfig() is True

    # 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() is True

    assert tstConf.loadConfig() is True
    assert tstConf.doReplaceDQuote is False
    assert tstConf.doReplaceSQuote is False

    tstConf.fmtDoubleQuotes = origDbl
    tstConf.fmtSingleQuotes = origSng
    tstConf.doReplaceDQuote = orDoDbl
    tstConf.doReplaceSQuote = orDoSng
    assert tstConf.saveConfig() is True

    # Test Correcting icon theme
    origIcons = tstConf.guiIcons

    tstConf.guiIcons = "typicons_colour_dark"
    assert tstConf.saveConfig() is True
    assert tstConf.loadConfig() is True
    assert tstConf.guiIcons == "typicons_dark"

    tstConf.guiIcons = "typicons_grey_dark"
    assert tstConf.saveConfig() is True
    assert tstConf.loadConfig() is True
    assert tstConf.guiIcons == "typicons_dark"

    tstConf.guiIcons = "typicons_colour_light"
    assert tstConf.saveConfig() is True
    assert tstConf.loadConfig() is True
    assert tstConf.guiIcons == "typicons_light"

    tstConf.guiIcons = "typicons_grey_light"
    assert tstConf.saveConfig() is True
    assert tstConf.loadConfig() is True
    assert tstConf.guiIcons == "typicons_light"

    tstConf.guiIcons = origIcons
    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(i18nDir, "nw_en_GB.qm"))
    writeFile(os.path.join(i18nDir, "nw_en_GB.ts"), "")
    writeFile(os.path.join(i18nDir, "nw_abcd.qm"), "")

    tstApp = MockApp()
    tstConf.initLocalisation(tstApp)

    # Check Lists
    theList = tstConf.listLanguages(tstConf.LANG_NW)
    assert theList == [("en_GB", "British English")]
    theList = tstConf.listLanguages(tstConf.LANG_PROJ)
    assert theList == [("en_GB", "British English")]
    theList = tstConf.listLanguages(None)
    assert theList == []

    # Add Language
    copyfile(os.path.join(filesDir, "nw_en_GB.qm"),
             os.path.join(i18nDir, "nw_fr.qm"))
    writeFile(os.path.join(i18nDir, "nw_fr.ts"), "")

    theList = tstConf.listLanguages(tstConf.LANG_NW)
    assert theList == [("en_GB", "British English"), ("fr", "Français")]

    copyfile(confFile, testFile)
    assert cmpFiles(testFile,
                    compFile,
                    ignoreStart=("timestamp", "lastnotes", "guilang"))
Exemple #4
0
def logVerbose(self, message, *args, **kws):
    if self.isEnabledFor(VERBOSE):
        self._log(VERBOSE, message, args, **kws)


logging.Logger.verbose = logVerbose

# Initiating logging
logger = logging.getLogger(__name__)

##
#  Main Program
##

# Load the main config as a global object
CONFIG = Config()


def main(sysArgs=None):
    """Parse command line, set up logging, and launch main GUI.
    """
    if sysArgs is None:
        sysArgs = sys.argv[1:]

    # Valid Input Options
    shortOpt = "hv"
    longOpt = [
        "help",
        "version",
        "info",
        "debug",
def testDlgPreferences_Main(qtbot, monkeypatch, fncDir, outDir, refDir):
    """Test the load project wizard.
    """
    # Block message box
    monkeypatch.setattr(QMessageBox, "warning", lambda *a: QMessageBox.Yes)
    monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
    monkeypatch.setattr(QMessageBox, "information", lambda *a: QMessageBox.Yes)

    # Must create a clean config and GUI object as the test-wide
    # novelwriter.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 = novelwriter.CONFIG
    novelwriter.CONFIG = theConf

    nwGUI = novelwriter.main(
        ["--testmode",
         "--config=%s" % fncDir,
         "--data=%s" % fncDir])
    qtbot.addWidget(nwGUI)
    nwGUI.show()
    qtbot.wait(stepDelay)

    theConf = nwGUI.mainConf
    assert theConf.confPath == fncDir

    monkeypatch.setattr(GuiPreferences, "exec_", lambda *a: None)
    monkeypatch.setattr(GuiPreferences, "result", lambda *a: QDialog.Accepted)
    monkeypatch.setattr(nwGUI.docEditor.spEnchant, "listDictionaries",
                        lambda: [("en", "none")])

    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

    # General Settings
    qtbot.wait(keyDelay)
    tabGeneral = nwPrefs.tabGeneral
    nwPrefs._tabBox.setCurrentWidget(tabGeneral)

    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()

    # qtbot.stopForInteraction()

    # Check Browse button
    monkeypatch.setattr(QFileDialog, "getExistingDirectory",
                        lambda *a, **k: "")
    assert not tabProjects._backupFolder()
    monkeypatch.setattr(QFileDialog, "getExistingDirectory",
                        lambda *a, **k: "some/dir")
    qtbot.mouseClick(tabProjects.backupGetPath, Qt.LeftButton)

    qtbot.wait(keyDelay)
    tabProjects.autoSaveDoc.setValue(20)
    tabProjects.autoSaveProj.setValue(40)

    # Document Settings
    qtbot.wait(keyDelay)
    tabDocs = nwPrefs.tabDocs
    nwPrefs._tabBox.setCurrentWidget(tabDocs)

    qtbot.wait(keyDelay)
    qtbot.mouseClick(tabDocs.fontButton, Qt.LeftButton)

    qtbot.wait(keyDelay)
    tabDocs.textSize.setValue(13)
    tabDocs.textWidth.setValue(700)
    tabDocs.focusWidth.setValue(900)
    tabDocs.textMargin.setValue(45)
    tabDocs.tabWidth.setValue(45)

    qtbot.wait(keyDelay)
    assert not tabDocs.hideFocusFooter.isChecked()
    qtbot.mouseClick(tabDocs.hideFocusFooter, Qt.LeftButton)
    assert tabDocs.hideFocusFooter.isChecked()

    qtbot.wait(keyDelay)
    assert not tabDocs.doJustify.isChecked()
    qtbot.mouseClick(tabDocs.doJustify, Qt.LeftButton)
    assert tabDocs.doJustify.isChecked()

    # Editor Settings
    qtbot.wait(keyDelay)
    tabEditor = nwPrefs.tabEditor
    nwPrefs._tabBox.setCurrentWidget(tabEditor)

    qtbot.wait(keyDelay)
    assert not tabEditor.showTabsNSpaces.isChecked()
    qtbot.mouseClick(tabEditor.showTabsNSpaces, Qt.LeftButton)
    assert tabEditor.showTabsNSpaces.isChecked()

    qtbot.wait(keyDelay)
    assert not tabEditor.showLineEndings.isChecked()
    qtbot.mouseClick(tabEditor.showLineEndings, Qt.LeftButton)
    assert tabEditor.showLineEndings.isChecked()

    qtbot.wait(keyDelay)
    assert not tabEditor.autoScroll.isChecked()
    qtbot.mouseClick(tabEditor.autoScroll, Qt.LeftButton)
    assert tabEditor.autoScroll.isChecked()

    qtbot.wait(keyDelay)
    tabEditor.scrollPastEnd.setValue(0)

    qtbot.wait(keyDelay)
    tabEditor.bigDocLimit.setValue(500)

    # Syntax Settings
    qtbot.wait(keyDelay)
    tabSyntax = nwPrefs.tabSyntax
    nwPrefs._tabBox.setCurrentWidget(tabSyntax)

    qtbot.wait(keyDelay)
    assert tabSyntax.highlightQuotes.isChecked()
    qtbot.mouseClick(tabSyntax.highlightQuotes, Qt.LeftButton)
    assert not tabSyntax.highlightQuotes.isChecked()

    qtbot.wait(keyDelay)
    assert tabSyntax.highlightEmph.isChecked()
    qtbot.mouseClick(tabSyntax.highlightEmph, Qt.LeftButton)
    assert not tabSyntax.highlightEmph.isChecked()

    # Automation Settings
    qtbot.wait(keyDelay)
    tabAuto = nwPrefs.tabAuto
    nwPrefs._tabBox.setCurrentWidget(tabAuto)

    qtbot.wait(keyDelay)
    assert tabAuto.autoSelect.isChecked()
    qtbot.mouseClick(tabAuto.autoSelect, Qt.LeftButton)
    assert not tabAuto.autoSelect.isChecked()

    qtbot.wait(keyDelay)
    assert tabAuto.doReplace.isChecked()
    qtbot.mouseClick(tabAuto.doReplace, Qt.LeftButton)
    assert not tabAuto.doReplace.isChecked()

    qtbot.wait(keyDelay)
    assert not tabAuto.doReplaceSQuote.isEnabled()
    assert not tabAuto.doReplaceDQuote.isEnabled()
    assert not tabAuto.doReplaceDash.isEnabled()
    assert not tabAuto.doReplaceDots.isEnabled()

    # Quotation Style
    qtbot.wait(keyDelay)
    tabQuote = nwPrefs.tabQuote
    nwPrefs._tabBox.setCurrentWidget(tabQuote)

    monkeypatch.setattr(GuiQuoteSelect, "selectedQuote", "'")
    monkeypatch.setattr(GuiQuoteSelect, "exec_",
                        lambda *args: QDialog.Accepted)
    qtbot.mouseClick(tabQuote.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)
    ignTuple = ("timestamp", "guifont", "lastnotes", "guilang", "geometry",
                "preferences", "treecols", "novelcols", "projcols", "mainpane",
                "docpane", "viewpane", "outlinepane", "textfont", "textsize")
    assert cmpFiles(testFile, compFile, ignoreStart=ignTuple)

    # Clean up
    novelwriter.CONFIG = origConf
    nwGUI.closeMain()