Rewritten Config class test

This commit is contained in:
Veronica K. B. Olsen
2020-12-07 23:34:12 +01:00
parent a4ee1e112c
commit 9772c85ece
5 changed files with 559 additions and 205 deletions
+51 -40
View File
@@ -27,12 +27,12 @@
import logging
import configparser
import shutil
import json
import sys
import os
from time import time
from shutil import which
from PyQt5.Qt import PYQT_VERSION_STR
from PyQt5.QtCore import QT_VERSION_STR, QStandardPaths, QSysInfo
@@ -44,10 +44,11 @@ logger = logging.getLogger(__name__)
class Config:
CNF_STR = 0
CNF_INT = 1
CNF_BOOL = 2
CNF_LIST = 3
CNF_STR = 0
CNF_INT = 1
CNF_BOOL = 2
CNF_S_LST = 3
CNF_I_LST = 4
def __init__(self):
@@ -211,12 +212,8 @@ class Config:
self.osUnknown = True
# Other System Info
if self.verQtValue >= 50600:
self.hostName = QSysInfo.machineHostName()
self.kernelVer = QSysInfo.kernelVersion()
else:
self.hostName = "Unknown"
self.kernelVer = "Unknown"
self.hostName = "Unknown"
self.kernelVer = "Unknown"
# Packages
self.hasEnchant = False # The pyenchant package
@@ -321,6 +318,11 @@ class Config:
self.errData.append(str(e))
self.dataPath = None
# Host and Kernel
if self.verQtValue >= 50600:
self.hostName = QSysInfo.machineHostName()
self.kernelVer = QSysInfo.kernelVersion()
# Load recent projects cache
self.loadRecentCache()
@@ -388,25 +390,25 @@ class Config:
## Sizes
cnfSec = "Sizes"
self.winGeometry = self._parseLine(
cnfParse, cnfSec, "geometry", self.CNF_LIST, self.winGeometry
cnfParse, cnfSec, "geometry", self.CNF_I_LST, self.winGeometry
)
self.treeColWidth = self._parseLine(
cnfParse, cnfSec, "treecols", self.CNF_LIST, self.treeColWidth
cnfParse, cnfSec, "treecols", self.CNF_I_LST, self.treeColWidth
)
self.projColWidth = self._parseLine(
cnfParse, cnfSec, "projcols", self.CNF_LIST, self.projColWidth
cnfParse, cnfSec, "projcols", self.CNF_I_LST, self.projColWidth
)
self.mainPanePos = self._parseLine(
cnfParse, cnfSec, "mainpane", self.CNF_LIST, self.mainPanePos
cnfParse, cnfSec, "mainpane", self.CNF_I_LST, self.mainPanePos
)
self.docPanePos = self._parseLine(
cnfParse, cnfSec, "docpane", self.CNF_LIST, self.docPanePos
cnfParse, cnfSec, "docpane", self.CNF_I_LST, self.docPanePos
)
self.viewPanePos = self._parseLine(
cnfParse, cnfSec, "viewpane", self.CNF_LIST, self.viewPanePos
cnfParse, cnfSec, "viewpane", self.CNF_I_LST, self.viewPanePos
)
self.outlnPanePos = self._parseLine(
cnfParse, cnfSec, "outlinepane", self.CNF_LIST, self.outlnPanePos
cnfParse, cnfSec, "outlinepane", self.CNF_I_LST, self.outlnPanePos
)
self.isFullScreen = self._parseLine(
cnfParse, cnfSec, "fullscreen", self.CNF_BOOL, self.isFullScreen
@@ -484,10 +486,10 @@ class Config:
cnfParse, cnfSec, "autoscrollpos", self.CNF_INT, self.autoScrollPos
)
self.fmtSingleQuotes = self._parseLine(
cnfParse, cnfSec, "fmtsinglequote", self.CNF_LIST, self.fmtSingleQuotes
cnfParse, cnfSec, "fmtsinglequote", self.CNF_S_LST, self.fmtSingleQuotes
)
self.fmtDoubleQuotes = self._parseLine(
cnfParse, cnfSec, "fmtdoublequote", self.CNF_LIST, self.fmtDoubleQuotes
cnfParse, cnfSec, "fmtdoublequote", self.CNF_S_LST, self.fmtDoubleQuotes
)
self.spellTool = self._parseLine(
cnfParse, cnfSec, "spelltool", self.CNF_STR, self.spellTool
@@ -901,23 +903,28 @@ class Config:
# Internal Functions
##
def _unpackList(self, inStr, listLen, listDefault, castTo=int):
"""Unpack a comma separated string of items into a list.
"""
inData = inStr.split(",")
outData = []
for i in range(listLen):
try:
outData.append(castTo(inData[i]))
except Exception:
outData.append(listDefault[i])
return outData
def _packList(self, inData):
"""Pack a list of items into a comma separated string.
"""Pack a list of items into a comma-separated string.
"""
return ", ".join([str(inVal) for inVal in inData])
def _unpackList(self, inStr, listDefault, cnfType):
"""Unpack a comma-separated string of items into a list.
"""
inData = inStr.split(",")
outData = listDefault.copy()
for i in range(min(len(inData), len(listDefault))):
try:
if cnfType == self.CNF_S_LST:
outData[i] = inData[i].strip()
elif cnfType == self.CNF_I_LST:
outData[i] = int(inData[i].strip())
else:
continue
except Exception:
continue
return outData
def _parseLine(self, cnfParse, cnfSec, cnfName, cnfType, cnfDefault):
"""Parse a line and return the correct datatype.
"""
@@ -930,18 +937,24 @@ class Config:
return cnfParse.getint(cnfSec, cnfName)
elif cnfType == self.CNF_BOOL:
return cnfParse.getboolean(cnfSec, cnfName)
elif cnfType == self.CNF_LIST:
elif cnfType == self.CNF_I_LST:
return self._unpackList(
cnfParse.get(cnfSec, cnfName), len(cnfDefault), cnfDefault
cnfParse.get(cnfSec, cnfName), cnfDefault, self.CNF_I_LST
)
elif cnfType == self.CNF_S_LST:
return self._unpackList(
cnfParse.get(cnfSec, cnfName), cnfDefault, self.CNF_S_LST
)
except ValueError as e:
logger.error("Failed to load value from config file.")
logger.error(str(e))
return cnfDefault
return cnfDefault
def _checkNone(self, checkVal):
"""Convert a string to a none type.
"""Return a NoneType if the value correspomds to None, otherwise
return the value unchanged.
"""
if checkVal is None:
return None
@@ -961,10 +974,8 @@ class Config:
self.hasEnchant = False
logger.debug("Checking package 'pyenchant': Missing")
try:
self.hasAssistant = which("assistant")
except Exception:
self.hasAssistant = False
assistPath = shutil.which("assistant")
self.hasAssistant = assistPath is not None
if self.hasAssistant:
logger.debug("Checking executable 'assistant': Ok")
else:
+3
View File
@@ -73,6 +73,9 @@ def fncDir(tmpDir):
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("")
+505
View File
@@ -0,0 +1,505 @@
# -*- coding: utf-8 -*-
"""novelWriter Config Class Tester
"""
import pytest
import sys
import os
import configparser
from shutil import copyfile
from dummy import causeOSError
from tools import cmpFiles, readFile
from nw.config import Config
from nw.constants import nwConst, nwFiles
@pytest.mark.base
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
monkeypatch.undo()
# 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
monkeypatch.undo()
# 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
monkeypatch.undo()
# 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
monkeypatch.undo()
# Other
monkeypatch.setattr("sys.platform", "some_ther_os")
tstConf = Config()
assert tstConf.osLinux is False
assert tstConf.osDarwin is False
assert tstConf.osWindows is False
assert tstConf.osUnknown is True
monkeypatch.undo()
# END Test testBaseConfig_Constructor
@pytest.mark.base
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])
# END Test testBaseConfig_Init
@pytest.mark.base
def testBaseConfig_RecentCache(monkeypatch, tmpConf, tmpDir, fncDir):
"""Test recent cache file.
"""
# Check failing
tmpConf.dataPath = None
assert not tmpConf.loadRecentCache()
assert not tmpConf.saveRecentCache()
tmpConf.dataPath = tmpDir
# Add a couple of values
pathOne = os.path.join(fncDir, "projPathOne", nwFiles.PROJ_FILE)
pathTwo = os.path.join(fncDir, "projPathTwo", nwFiles.PROJ_FILE)
assert tmpConf.updateRecentCache(pathOne, "Proj One", 100, 1600002000)
assert tmpConf.updateRecentCache(pathTwo, "Proj Two", 200, 1600005600)
assert tmpConf.recentProj == {
pathOne: {"time": 1600002000, "title": "Proj One", "words": 100},
pathTwo: {"time": 1600005600, "title": "Proj Two", "words": 200},
}
# Fail to Save
monkeypatch.setattr("builtins.open", causeOSError)
assert not tmpConf.saveRecentCache()
monkeypatch.undo()
# Save Proper
cacheFile = os.path.join(tmpDir, nwFiles.RECENT_FILE)
assert tmpConf.saveRecentCache()
assert tmpConf.saveRecentCache()
assert os.path.isfile(cacheFile)
# Fail to Load
monkeypatch.setattr("builtins.open", causeOSError)
tmpConf.recentProj = {}
assert not tmpConf.loadRecentCache()
assert tmpConf.recentProj == {}
monkeypatch.undo()
# Load Proper
tmpConf.recentProj = {}
assert tmpConf.loadRecentCache()
assert tmpConf.recentProj == {
pathOne: {"time": 1600002000, "title": "Proj One", "words": 100},
pathTwo: {"time": 1600005600, "title": "Proj Two", "words": 200},
}
# Remove Non-Existent Entry
assert not tmpConf.removeFromRecentCache("dummy")
assert tmpConf.recentProj == {
pathOne: {"time": 1600002000, "title": "Proj One", "words": 100},
pathTwo: {"time": 1600005600, "title": "Proj Two", "words": 200},
}
# Remove Second Entry
assert tmpConf.removeFromRecentCache(pathTwo)
assert tmpConf.recentProj == {
pathOne: {"time": 1600002000, "title": "Proj One", "words": 100},
}
# END Test testBaseConfig_RecentCache
@pytest.mark.base
def testBaseConfig_SetPath(tmpConf, tmpDir):
"""Test path setters.
"""
# Conf Path
assert tmpConf.setConfPath(None)
assert not tmpConf.setConfPath(os.path.join("somewhere", "over", "the", "rainbow"))
assert tmpConf.setConfPath(os.path.join(tmpDir, "novelwriter.conf"))
assert tmpConf.confPath == tmpDir
assert tmpConf.confFile == "novelwriter.conf"
assert not tmpConf.confChanged
# Data Path
assert tmpConf.setDataPath(None)
assert not tmpConf.setDataPath(os.path.join("somewhere", "over", "the", "rainbow"))
assert tmpConf.setDataPath(tmpDir)
assert tmpConf.dataPath == tmpDir
assert not tmpConf.confChanged
# Last Path
assert tmpConf.setLastPath(None)
assert tmpConf.lastPath == ""
assert tmpConf.setLastPath(os.path.join(tmpDir, "file.tmp"))
assert tmpConf.lastPath == tmpDir
assert tmpConf.setLastPath("")
assert tmpConf.lastPath == ""
# END Test testBaseConfig_SetPath
@pytest.mark.base
def testBaseConfig_SettersGetters(tmpConf, tmpDir, outDir, refDir):
"""Set various sizes and positions
"""
confFile = os.path.join(tmpDir, "novelwriter.conf")
testFile = os.path.join(outDir, "baseConfig_novelwriter.conf")
compFile = os.path.join(refDir, "baseConfig_novelwriter.conf")
# GUI Scaling
# ===========
tmpConf.guiScale = 1.0
assert tmpConf.pxInt(10) == 10
assert tmpConf.pxInt(13) == 13
assert tmpConf.rpxInt(10) == 10
assert tmpConf.rpxInt(13) == 13
tmpConf.guiScale = 2.0
assert tmpConf.pxInt(10) == 20
assert tmpConf.pxInt(13) == 26
assert tmpConf.rpxInt(10) == 5
assert tmpConf.rpxInt(13) == 6
# Setter + Getter Combos
# ======================
# Window Size
tmpConf.guiScale = 1.0
assert tmpConf.setWinSize(1205, 655)
assert not tmpConf.confChanged
tmpConf.guiScale = 2.0
assert tmpConf.setWinSize(70, 70)
assert tmpConf.getWinSize() == [70, 70]
assert tmpConf.winGeometry == [35, 35]
tmpConf.guiScale = 1.0
assert tmpConf.setWinSize(70, 70)
assert tmpConf.getWinSize() == [70, 70]
assert tmpConf.winGeometry == [70, 70]
assert tmpConf.setWinSize(1200, 650)
# Project Tree Columns
tmpConf.guiScale = 2.0
assert tmpConf.setTreeColWidths([10, 20, 25])
assert tmpConf.getTreeColWidths() == [10, 20, 24]
assert tmpConf.treeColWidth == [5, 10, 12]
tmpConf.guiScale = 1.0
assert tmpConf.setTreeColWidths([10, 20, 25])
assert tmpConf.getTreeColWidths() == [10, 20, 25]
assert tmpConf.treeColWidth == [10, 20, 25]
assert tmpConf.setTreeColWidths([200, 50, 30])
# Project Settings Tree Columns
tmpConf.guiScale = 2.0
assert tmpConf.setProjColWidths([10, 20, 30])
assert tmpConf.getProjColWidths() == [10, 20, 30]
assert tmpConf.projColWidth == [5, 10, 15]
tmpConf.guiScale = 1.0
assert tmpConf.setProjColWidths([10, 20, 30])
assert tmpConf.getProjColWidths() == [10, 20, 30]
assert tmpConf.projColWidth == [10, 20, 30]
assert tmpConf.setProjColWidths([200, 60, 140])
# Main Pane Splitter
tmpConf.guiScale = 2.0
assert tmpConf.setMainPanePos([200, 700])
assert tmpConf.getMainPanePos() == [200, 700]
assert tmpConf.mainPanePos == [100, 350]
tmpConf.guiScale = 1.0
assert tmpConf.setMainPanePos([200, 700])
assert tmpConf.getMainPanePos() == [200, 700]
assert tmpConf.mainPanePos == [200, 700]
assert tmpConf.setMainPanePos([300, 800])
# Doc Pane Splitter
tmpConf.guiScale = 2.0
assert tmpConf.setDocPanePos([300, 300])
assert tmpConf.getDocPanePos() == [300, 300]
assert tmpConf.docPanePos == [150, 150]
tmpConf.guiScale = 1.0
assert tmpConf.setDocPanePos([300, 300])
assert tmpConf.getDocPanePos() == [300, 300]
assert tmpConf.docPanePos == [300, 300]
assert tmpConf.setDocPanePos([400, 400])
# View Pane Splitter
tmpConf.guiScale = 2.0
assert tmpConf.setViewPanePos([400, 250])
assert tmpConf.getViewPanePos() == [400, 250]
assert tmpConf.viewPanePos == [200, 125]
tmpConf.guiScale = 1.0
assert tmpConf.setViewPanePos([400, 250])
assert tmpConf.getViewPanePos() == [400, 250]
assert tmpConf.viewPanePos == [400, 250]
assert tmpConf.setViewPanePos([500, 150])
# Outline Pane Splitter
tmpConf.guiScale = 2.0
assert tmpConf.setOutlinePanePos([400, 250])
assert tmpConf.getOutlinePanePos() == [400, 250]
assert tmpConf.outlnPanePos == [200, 125]
tmpConf.guiScale = 1.0
assert tmpConf.setOutlinePanePos([400, 250])
assert tmpConf.getOutlinePanePos() == [400, 250]
assert tmpConf.outlnPanePos == [400, 250]
assert tmpConf.setOutlinePanePos([500, 150])
# Getters Only
# ============
tmpConf.guiScale = 1.0
assert tmpConf.getTextWidth() == 600
assert tmpConf.getTextMargin() == 40
assert tmpConf.getTabWidth() == 40
assert tmpConf.getFocusWidth() == 800
tmpConf.guiScale = 2.0
assert tmpConf.getTextWidth() == 1200
assert tmpConf.getTextMargin() == 80
assert tmpConf.getTabWidth() == 80
assert tmpConf.getFocusWidth() == 1600
# Flag Setters
# ============
assert not tmpConf.setShowRefPanel(False)
assert not tmpConf.showRefPanel
assert tmpConf.setShowRefPanel(True)
assert not tmpConf.setViewComments(False)
assert not tmpConf.viewComments
assert tmpConf.setViewComments(True)
assert not tmpConf.setViewSynopsis(False)
assert not tmpConf.viewSynopsis
assert tmpConf.setViewSynopsis(True)
# Check Final File
# ================
assert tmpConf.confChanged
assert tmpConf.saveConfig()
assert not tmpConf.confChanged
copyfile(confFile, testFile)
assert cmpFiles(testFile, compFile, [2, 9])
# END Test testBaseConfig_SettersGetters
@pytest.mark.base
def testBaseConfig_Internal(monkeypatch, tmpConf):
"""Check internal functions.
"""
# Function _packList
assert tmpConf._packList(["A", 1, 2.0, None, False]) == "A, 1, 2.0, None, False"
# Function _unpackList
assert tmpConf._unpackList("1, 2, 3", [0, 0, 0], tmpConf.CNF_I_LST) == [1, 2, 3]
assert tmpConf._unpackList("1, 2 ", [0, 0, 0], tmpConf.CNF_I_LST) == [1, 2, 0]
assert tmpConf._unpackList("A, B, C", [0, 0, 0], tmpConf.CNF_I_LST) == [0, 0, 0]
assert tmpConf._unpackList("1, 2, 3", ["X", "Y", "Z"], tmpConf.CNF_S_LST) == ["1", "2", "3"]
assert tmpConf._unpackList("A, B ", ["X", "Y", "Z"], tmpConf.CNF_S_LST) == ["A", "B", "Z"]
assert tmpConf._unpackList("A, B, C", ["X", "Y", "Z"], tmpConf.CNF_S_LST) == ["A", "B", "C"]
assert tmpConf._unpackList("A, B, C", ["X", "Y", "Z"], tmpConf.CNF_STR) == ["X", "Y", "Z"]
# Function _parseLine
cnfParse = configparser.ConfigParser()
cnfParse.read_string(
"[Main]\n"
"val_string = dummy\n"
"val_int = 123\n"
"val_bool = True\n"
"val_list_string = A, B, C\n"
"val_list_int = 1, 2, 3\n"
)
assert tmpConf._parseLine(
cnfParse, "Main", "val_string", tmpConf.CNF_STR, "default"
) == "dummy"
assert tmpConf._parseLine(
cnfParse, "Main", "nope", tmpConf.CNF_STR, "default"
) == "default"
assert tmpConf._parseLine(
cnfParse, "Main", "val_int", tmpConf.CNF_INT, "0"
) == 123
assert tmpConf._parseLine(
cnfParse, "Main", "nope", tmpConf.CNF_INT, 0
) == 0
assert tmpConf._parseLine(
cnfParse, "Main", "val_string", tmpConf.CNF_INT, 0
) == 0
assert tmpConf._parseLine(
cnfParse, "Main", "val_bool", tmpConf.CNF_BOOL, False
) is True
assert tmpConf._parseLine(
cnfParse, "Main", "nope", tmpConf.CNF_BOOL, False
) is False
assert tmpConf._parseLine(
cnfParse, "Main", "val_string", tmpConf.CNF_BOOL, False
) is False
assert tmpConf._parseLine(
cnfParse, "Main", "val_list_string", tmpConf.CNF_S_LST, ["W", "X", "Y", "Z"]
) == ["A", "B", "C", "Z"]
assert tmpConf._parseLine(
cnfParse, "Main", "nope", tmpConf.CNF_S_LST, ["W", "X", "Y", "Z"]
) == ["W", "X", "Y", "Z"]
assert tmpConf._parseLine(
cnfParse, "Main", "val_list_int", tmpConf.CNF_I_LST, [6, 7, 8, 9]
) == [1, 2, 3, 9]
assert tmpConf._parseLine(
cnfParse, "Main", "nope", tmpConf.CNF_S_LST, [6, 7, 8, 9]
) == [6, 7, 8, 9]
# Function _checkNone
assert tmpConf._checkNone(None) is None
assert tmpConf._checkNone("None") is None
assert tmpConf._checkNone("stuff") == "stuff"
# Function _checkOptionalPackages
# (Assumes enchant package exists ans is importable)
tmpConf._checkOptionalPackages()
assert tmpConf.hasEnchant is True
monkeypatch.setitem(sys.modules, "enchant", None)
tmpConf._checkOptionalPackages()
assert tmpConf.hasEnchant is False
monkeypatch.undo()
monkeypatch.setattr("shutil.which", lambda *args: "dummy")
tmpConf._checkOptionalPackages()
assert tmpConf.hasAssistant is True
monkeypatch.undo()
monkeypatch.setattr("shutil.which", lambda *args: None)
tmpConf._checkOptionalPackages()
assert tmpConf.hasAssistant is False
monkeypatch.undo()
# END Test testBaseConfig_Internal
-165
View File
@@ -1,165 +0,0 @@
# -*- coding: utf-8 -*-
"""novelWriter Config Class Tester
"""
import pytest
import os
from tools import cmpFiles
@pytest.mark.core
def testConfigCore(tmpConf, tmpDir, refDir):
refConf = os.path.join(refDir, "novelwriter.conf")
testConf = os.path.join(tmpConf.confPath, "novelwriter.conf")
assert tmpConf.confPath == tmpDir
assert tmpConf.saveConfig()
assert cmpFiles(testConf, refConf, [2, 9])
assert not tmpConf.confChanged
assert tmpConf.loadConfig()
assert not tmpConf.confChanged
@pytest.mark.core
def testConfigSetConfPath(tmpConf, tmpDir):
assert tmpConf.setConfPath(None)
assert not tmpConf.setConfPath(os.path.join("somewhere", "over", "the", "rainbow"))
assert tmpConf.setConfPath(os.path.join(tmpDir, "novelwriter.conf"))
assert tmpConf.confPath == tmpDir
assert tmpConf.confFile == "novelwriter.conf"
assert not tmpConf.confChanged
@pytest.mark.core
def testConfigSetDataPath(tmpConf, tmpDir):
assert tmpConf.setDataPath(None)
assert not tmpConf.setDataPath(os.path.join("somewhere", "over", "the", "rainbow"))
assert tmpConf.setDataPath(tmpDir)
assert tmpConf.dataPath == tmpDir
assert not tmpConf.confChanged
@pytest.mark.core
def testConfigSetWinSize(tmpConf, tmpDir, refDir):
refConf = os.path.join(refDir, "novelwriter.conf")
testConf = os.path.join(tmpConf.confPath, "novelwriter.conf")
tmpConf.guiScale = 1.0
assert tmpConf.confPath == tmpDir
assert tmpConf.setWinSize(1205, 655)
assert not tmpConf.confChanged
assert tmpConf.setWinSize(70, 70)
assert tmpConf.confChanged
assert tmpConf.setWinSize(1200, 650)
assert tmpConf.saveConfig()
assert cmpFiles(testConf, refConf, [2, 9])
assert not tmpConf.confChanged
@pytest.mark.core
def testConfigSetTreeColWidths(tmpConf, tmpDir, refDir):
refConf = os.path.join(refDir, "novelwriter.conf")
testConf = os.path.join(tmpConf.confPath, "novelwriter.conf")
assert tmpConf.confPath == tmpDir
tmpConf.guiScale = 1.0
assert tmpConf.setTreeColWidths([10, 20, 25])
assert tmpConf.treeColWidth == [10, 20, 25]
assert tmpConf.setTreeColWidths([200, 50, 30])
assert tmpConf.setProjColWidths([10, 20, 30])
assert tmpConf.projColWidth == [10, 20, 30]
assert tmpConf.setProjColWidths([200, 60, 140])
assert tmpConf.confChanged
assert tmpConf.saveConfig()
assert cmpFiles(testConf, refConf, [2, 9])
assert not tmpConf.confChanged
@pytest.mark.core
def testConfigSetPanePos(tmpConf, tmpDir, refDir):
refConf = os.path.join(refDir, "novelwriter.conf")
testConf = os.path.join(tmpConf.confPath, "novelwriter.conf")
assert tmpConf.confPath == tmpDir
tmpConf.guiScale = 2.0
assert tmpConf.setMainPanePos([200, 700])
assert tmpConf.mainPanePos == [100, 350]
assert tmpConf.getMainPanePos() == [200, 700]
assert tmpConf.setDocPanePos([300, 300])
assert tmpConf.docPanePos == [150, 150]
assert tmpConf.getDocPanePos() == [300, 300]
assert tmpConf.setViewPanePos([400, 250])
assert tmpConf.viewPanePos == [200, 125]
assert tmpConf.getViewPanePos() == [400, 250]
assert tmpConf.setOutlinePanePos([400, 250])
assert tmpConf.outlnPanePos == [200, 125]
assert tmpConf.getOutlinePanePos() == [400, 250]
tmpConf.guiScale = 1.0
assert tmpConf.setMainPanePos([300, 800])
assert tmpConf.setDocPanePos([400, 400])
assert tmpConf.setViewPanePos([500, 150])
assert tmpConf.setOutlinePanePos([500, 150])
assert tmpConf.confChanged
assert tmpConf.saveConfig()
assert cmpFiles(testConf, refConf, [2, 9])
assert not tmpConf.confChanged
@pytest.mark.core
def testConfigFlags(tmpConf, tmpDir, refDir):
refConf = os.path.join(refDir, "novelwriter.conf")
testConf = os.path.join(tmpConf.confPath, "novelwriter.conf")
assert tmpConf.confPath == tmpDir
assert not tmpConf.setShowRefPanel(False)
assert tmpConf.setShowRefPanel(True)
assert not tmpConf.setViewComments(False)
assert not tmpConf.viewComments
assert tmpConf.setViewComments(True)
assert not tmpConf.setViewSynopsis(False)
assert not tmpConf.viewSynopsis
assert tmpConf.setViewSynopsis(True)
assert tmpConf.confChanged
assert tmpConf.saveConfig()
assert cmpFiles(testConf, refConf, [2, 9])
assert not tmpConf.confChanged
@pytest.mark.core
def testTextSizes(tmpConf, tmpDir, refDir):
assert tmpConf.confPath == tmpDir
tmpConf.guiScale = 2.0
assert tmpConf.getTextWidth() == 1200
assert tmpConf.getTextMargin() == 80
assert tmpConf.getTabWidth() == 80
assert tmpConf.getFocusWidth() == 1600
tmpConf.guiScale = 1.0
assert not tmpConf.confChanged
@pytest.mark.core
def testConfigErrors(tmpConf):
nonPath = os.path.join("somewhere", "over", "the", "rainbow")
assert tmpConf.initConfig(nonPath, nonPath)
assert tmpConf.hasError
assert not tmpConf.loadConfig()
assert not tmpConf.saveConfig()
assert not tmpConf.loadRecentCache()
assert len(tmpConf.getErrData()) > 0
@pytest.mark.core
def testConfigInternals(tmpConf):
assert tmpConf._checkNone(None) is None
assert tmpConf._checkNone("None") is None