Rewritten Config class test
This commit is contained in:
+51
-40
@@ -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:
|
||||
|
||||
@@ -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("")
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user