Update tests

This commit is contained in:
Veronica Berglyd Olsen
2023-11-30 22:30:12 +01:00
parent 4f42407c23
commit 5278eb7895
6 changed files with 86 additions and 82 deletions
+2
View File
@@ -118,6 +118,8 @@ def fncPath():
fncPath = _TMP_ROOT / "function"
if fncPath.is_dir():
shutil.rmtree(fncPath)
elif fncPath.is_file():
fncPath.unlink()
fncPath.mkdir(exist_ok=True)
return fncPath
+44 -43
View File
@@ -34,8 +34,8 @@ from novelwriter.gui.noveltree import NovelTreeColumn
@pytest.mark.core
def testCoreOptions_LoadSave(monkeypatch, mockGUI, fncPath):
"""Test loading and saving from the OptionState class."""
theProject = NWProject()
theOpts = OptionState(theProject)
project = NWProject()
options = OptionState(project)
metaDir = fncPath / "meta"
metaDir.mkdir()
@@ -58,25 +58,26 @@ def testCoreOptions_LoadSave(monkeypatch, mockGUI, fncPath):
}), encoding="utf-8")
# Load and save with no path set
theProject.storage._runtimePath = None
assert theOpts.loadSettings() is False
assert theOpts.saveSettings() is False
project.storage._runtimePath = None
assert options.loadSettings() is False
assert options.saveSettings() is False
# Set path
theProject.storage._runtimePath = fncPath
assert theProject.storage.getMetaFile(nwFiles.OPTS_FILE) == optFile
project.storage._runtimePath = fncPath
project.storage._ready = True
assert project.storage.getMetaFile(nwFiles.OPTS_FILE) == optFile
# Cause open() to fail
with monkeypatch.context() as mp:
mp.setattr("builtins.open", causeOSError)
assert theOpts.loadSettings() is False
assert theOpts.saveSettings() is False
assert options.loadSettings() is False
assert options.saveSettings() is False
# Load proper
assert theOpts.loadSettings()
assert options.loadSettings()
# Check that unwanted items have been removed
assert theOpts._state == {
assert options._state == {
"GuiProjectSettings": {
"winWidth": 570,
"winHeight": 375,
@@ -87,11 +88,11 @@ def testCoreOptions_LoadSave(monkeypatch, mockGUI, fncPath):
}
# Save proper
assert theOpts.saveSettings()
assert options.saveSettings()
# Load again to check we get the values back
assert theOpts.loadSettings()
assert theOpts._state == {
assert options.loadSettings()
assert options._state == {
"GuiProjectSettings": {
"winWidth": 570,
"winHeight": 375,
@@ -107,48 +108,48 @@ def testCoreOptions_LoadSave(monkeypatch, mockGUI, fncPath):
@pytest.mark.core
def testCoreOptions_SetGet(mockGUI):
"""Test setting and getting values from the OptionState class."""
theProject = NWProject()
theOpts = OptionState(theProject)
project = NWProject()
options = OptionState(project)
nwColHidden = NovelTreeColumn.HIDDEN
# Set invalid values
assert theOpts.setValue("MockGroup", "mockItem", None) is False
assert theOpts.setValue("GuiProjectSettings", "mockItem", None) is False
assert options.setValue("MockGroup", "mockItem", None) is False
assert options.setValue("GuiProjectSettings", "mockItem", None) is False
# Set valid value
assert theOpts.setValue("GuiProjectSettings", "winWidth", 100) is True
assert options.setValue("GuiProjectSettings", "winWidth", 100) is True
# Set some values of different types
assert theOpts.setValue("GuiProjectDetails", "winWidth", 100) is True
assert theOpts.setValue("GuiProjectDetails", "winHeight", 12.34) is True
assert theOpts.setValue("GuiProjectDetails", "clearDouble", True) is True
assert theOpts.setValue("GuiNovelView", "lastCol", nwColHidden) is True
assert options.setValue("GuiProjectDetails", "winWidth", 100) is True
assert options.setValue("GuiProjectDetails", "winHeight", 12.34) is True
assert options.setValue("GuiProjectDetails", "clearDouble", True) is True
assert options.setValue("GuiNovelView", "lastCol", nwColHidden) is True
# Generic get, doesn't check type
assert theOpts.getValue("GuiProjectDetails", "winWidth", None) == 100
assert theOpts.getValue("GuiProjectDetails", "winHeight", None) == 12.34
assert theOpts.getValue("GuiProjectDetails", "clearDouble", None) is True
assert theOpts.getValue("GuiProjectDetails", "mockItem", None) is None
assert options.getValue("GuiProjectDetails", "winWidth", None) == 100
assert options.getValue("GuiProjectDetails", "winHeight", None) == 12.34
assert options.getValue("GuiProjectDetails", "clearDouble", None) is True
assert options.getValue("GuiProjectDetails", "mockItem", None) is None
# Get type-specific
assert theOpts.getString("GuiProjectDetails", "winWidth", None) is None
assert theOpts.getString("GuiProjectDetails", "mockItem", None) is None
assert theOpts.getInt("GuiProjectDetails", "winWidth", None) == 100
assert theOpts.getInt("GuiProjectDetails", "textFont", None) is None
assert theOpts.getInt("GuiProjectDetails", "mockItem", None) is None
assert theOpts.getFloat("GuiProjectDetails", "winWidth", None) == 100.0
assert theOpts.getFloat("GuiProjectDetails", "mockItem", None) is None
assert theOpts.getBool("GuiProjectDetails", "clearDouble", None) is True
assert theOpts.getBool("GuiProjectDetails", "mockItem", None) is None
assert theOpts.getEnum("GuiNovelView", "lastCol", NovelTreeColumn, nwColHidden) == nwColHidden
assert options.getString("GuiProjectDetails", "winWidth", None) is None # type: ignore
assert options.getString("GuiProjectDetails", "mockItem", None) is None # type: ignore
assert options.getInt("GuiProjectDetails", "winWidth", None) == 100 # type: ignore
assert options.getInt("GuiProjectDetails", "textFont", None) is None # type: ignore
assert options.getInt("GuiProjectDetails", "mockItem", None) is None # type: ignore
assert options.getFloat("GuiProjectDetails", "winWidth", None) == 100.0 # type: ignore
assert options.getFloat("GuiProjectDetails", "mockItem", None) is None # type: ignore
assert options.getBool("GuiProjectDetails", "clearDouble", None) is True # type: ignore
assert options.getBool("GuiProjectDetails", "mockItem", None) is None # type: ignore
assert options.getEnum("GuiNovelView", "lastCol", NovelTreeColumn, nwColHidden) == nwColHidden
# Get from non-existent groups
assert theOpts.getValue("SomeGroup", "mockItem", None) is None
assert theOpts.getString("SomeGroup", "mockItem", None) is None
assert theOpts.getInt("SomeGroup", "mockItem", None) is None
assert theOpts.getFloat("SomeGroup", "mockItem", None) is None
assert theOpts.getBool("SomeGroup", "mockItem", None) is None
assert theOpts.getEnum("SomeGroup", "mockItem", NovelTreeColumn, None) is None
assert options.getValue("SomeGroup", "mockItem", None) is None
assert options.getString("SomeGroup", "mockItem", None) is None # type: ignore
assert options.getInt("SomeGroup", "mockItem", None) is None # type: ignore
assert options.getFloat("SomeGroup", "mockItem", None) is None # type: ignore
assert options.getBool("SomeGroup", "mockItem", None) is None # type: ignore
assert options.getEnum("SomeGroup", "mockItem", NovelTreeColumn, None) is None # type: ignore
# END Test testCoreOptions_SetGet
+4 -4
View File
@@ -172,18 +172,18 @@ def testCoreProject_Open(monkeypatch, caplog, mockGUI, fncPath, mockRnd):
# Initialising the storage class fails
with monkeypatch.context() as mp:
mp.setattr("novelwriter.core.storage.NWStorage.openProjectInPlace", lambda *a, **k: False)
mp.setattr("novelwriter.core.storage.NWStorage.initProjectStorage", lambda *a, **k: False)
assert theProject.openProject(fncPath) is False
# Fail on lock file
theProject.storage._lockFilePath = fncPath / nwFiles.PROJ_LOCK
assert theProject.storage.writeLockFile() is True
assert theProject.storage._writeLockFile() is True
assert theProject.openProject(fncPath) is False
assert isinstance(theProject.lockStatus, list)
# Fail to read lockfile (which still opens the project)
with monkeypatch.context() as mp:
mp.setattr("novelwriter.core.storage.NWStorage.readLockFile", lambda *a: ["ERROR"])
mp.setattr("novelwriter.core.storage.NWStorage._readLockFile", lambda *a: ["ERROR"])
caplog.clear()
assert theProject.openProject(fncPath) is True
assert "Failed to check lock file" in caplog.text
@@ -191,7 +191,7 @@ def testCoreProject_Open(monkeypatch, caplog, mockGUI, fncPath, mockRnd):
# Force open with lockfile
theProject.storage._lockFilePath = fncPath / nwFiles.PROJ_LOCK
assert theProject.storage.writeLockFile() is True
assert theProject.storage._writeLockFile() is True
assert theProject.openProject(fncPath, clearLock=True) is True
theProject.closeProject()
assert theProject.lockStatus is None
+20 -19
View File
@@ -25,6 +25,7 @@ import pytest
from shutil import copyfile
from datetime import datetime
from novelwriter.constants import nwFiles
from tools import cmpFiles, writeFile
from mocked import causeOSError
@@ -62,7 +63,7 @@ def testCoreProjectXML_ReadCurrent(monkeypatch, tstPaths, fncPath):
xmlReader = ProjectXMLReader(xmlFile)
assert xmlReader.state == XMLReadState.NO_ACTION
data = NWProjectData(MockProject())
data = NWProjectData(MockProject()) # type: ignore
content = []
# With no valid files, the read should fail
@@ -132,7 +133,7 @@ def testCoreProjectXML_ReadCurrent(monkeypatch, tstPaths, fncPath):
assert xmlReader.state == XMLReadState.WAS_LEGACY
# Reset data objects
data = NWProjectData(MockProject())
data = NWProjectData(MockProject()) # type: ignore
content = []
# Parse a valid, complete file
@@ -215,13 +216,13 @@ def testCoreProjectXML_ReadCurrent(monkeypatch, tstPaths, fncPath):
mockProject = MockProject()
mockProject.__setattr__("data", data)
for entry in content:
item = NWItem(mockProject, "0000000000000")
item = NWItem(mockProject, "0000000000000") # type: ignore
item.unpack(entry)
packedContent.append(item.pack())
# Save the project again, which should produce an identical project xml
timeStamp = int(datetime.fromisoformat(xmlReader.timeStamp).timestamp())
xmlWriter = ProjectXMLWriter(fncPath)
xmlWriter = ProjectXMLWriter(fncPath / nwFiles.PROJ_FILE)
# Fail saving
with monkeypatch.context() as mp:
@@ -254,7 +255,7 @@ def testCoreProjectXML_ReadLegacy10(tstPaths, fncPath, mockRnd):
xmlReader = ProjectXMLReader(xmlFile)
assert xmlReader.state == XMLReadState.NO_ACTION
data = NWProjectData(MockProject())
data = NWProjectData(MockProject()) # type: ignore
content = []
assert xmlReader.read(data, content) is True
@@ -335,7 +336,7 @@ def testCoreProjectXML_ReadLegacy10(tstPaths, fncPath, mockRnd):
mockProject.__setattr__("data", data)
status = {}
for entry in content:
item = NWItem(mockProject, "0000000000000")
item = NWItem(mockProject, "0000000000000") # type: ignore
item.unpack(entry)
status[item.itemHandle] = item.getImportStatus(incIcon=False)[0]
packedContent.append(item.pack())
@@ -367,7 +368,7 @@ def testCoreProjectXML_ReadLegacy10(tstPaths, fncPath, mockRnd):
# Save the project again, which should produce an identical project xml
timeStamp = int(datetime.fromisoformat(xmlReader.timeStamp).timestamp())
xmlWriter = ProjectXMLWriter(fncPath)
xmlWriter = ProjectXMLWriter(fncPath / nwFiles.PROJ_FILE)
data.setUuid("d0f3fe10-c6e6-4310-8bfd-181eb4224eed")
assert xmlWriter.write(data, packedContent, timeStamp, 1000) is True
testFile = tstPaths.outDir / "projectXML_ReadLegacy10.nwx"
@@ -389,7 +390,7 @@ def testCoreProjectXML_ReadLegacy11(tstPaths, fncPath, mockRnd):
xmlReader = ProjectXMLReader(xmlFile)
assert xmlReader.state == XMLReadState.NO_ACTION
data = NWProjectData(MockProject())
data = NWProjectData(MockProject()) # type: ignore
content = []
assert xmlReader.read(data, content) is True
@@ -470,7 +471,7 @@ def testCoreProjectXML_ReadLegacy11(tstPaths, fncPath, mockRnd):
mockProject.__setattr__("data", data)
status = {}
for entry in content:
item = NWItem(mockProject, "0000000000000")
item = NWItem(mockProject, "0000000000000") # type: ignore
item.unpack(entry)
status[item.itemHandle] = item.getImportStatus(incIcon=False)[0]
packedContent.append(item.pack())
@@ -502,7 +503,7 @@ def testCoreProjectXML_ReadLegacy11(tstPaths, fncPath, mockRnd):
# Save the project again, which should produce an identical project xml
timeStamp = int(datetime.fromisoformat(xmlReader.timeStamp).timestamp())
xmlWriter = ProjectXMLWriter(fncPath)
xmlWriter = ProjectXMLWriter(fncPath / nwFiles.PROJ_FILE)
data.setUuid("d0f3fe10-c6e6-4310-8bfd-181eb4224eed")
assert xmlWriter.write(data, packedContent, timeStamp, 1000) is True
testFile = tstPaths.outDir / "projectXML_ReadLegacy11.nwx"
@@ -524,7 +525,7 @@ def testCoreProjectXML_ReadLegacy12(tstPaths, fncPath, mockRnd):
xmlReader = ProjectXMLReader(xmlFile)
assert xmlReader.state == XMLReadState.NO_ACTION
data = NWProjectData(MockProject())
data = NWProjectData(MockProject()) # type: ignore
content = []
assert xmlReader.read(data, content) is True
@@ -605,7 +606,7 @@ def testCoreProjectXML_ReadLegacy12(tstPaths, fncPath, mockRnd):
mockProject.__setattr__("data", data)
status = {}
for entry in content:
item = NWItem(mockProject, "0000000000000")
item = NWItem(mockProject, "0000000000000") # type: ignore
item.unpack(entry)
status[item.itemHandle] = item.getImportStatus(incIcon=False)[0]
packedContent.append(item.pack())
@@ -640,7 +641,7 @@ def testCoreProjectXML_ReadLegacy12(tstPaths, fncPath, mockRnd):
# Save the project again, which should produce an identical project xml
timeStamp = int(datetime.fromisoformat(xmlReader.timeStamp).timestamp())
xmlWriter = ProjectXMLWriter(fncPath)
xmlWriter = ProjectXMLWriter(fncPath / nwFiles.PROJ_FILE)
data.setUuid("d0f3fe10-c6e6-4310-8bfd-181eb4224eed")
assert xmlWriter.write(data, packedContent, timeStamp, 1000) is True
testFile = tstPaths.outDir / "projectXML_ReadLegacy12.nwx"
@@ -662,7 +663,7 @@ def testCoreProjectXML_ReadLegacy13(tstPaths, fncPath, mockRnd):
xmlReader = ProjectXMLReader(xmlFile)
assert xmlReader.state == XMLReadState.NO_ACTION
data = NWProjectData(MockProject())
data = NWProjectData(MockProject()) # type: ignore
content = []
assert xmlReader.read(data, content) is True
@@ -743,7 +744,7 @@ def testCoreProjectXML_ReadLegacy13(tstPaths, fncPath, mockRnd):
mockProject.__setattr__("data", data)
status = {}
for entry in content:
item = NWItem(mockProject, "0000000000000")
item = NWItem(mockProject, "0000000000000") # type: ignore
item.unpack(entry)
status[item.itemHandle] = item.getImportStatus(incIcon=False)[0]
packedContent.append(item.pack())
@@ -778,7 +779,7 @@ def testCoreProjectXML_ReadLegacy13(tstPaths, fncPath, mockRnd):
# Save the project again, which should produce an identical project xml
timeStamp = int(datetime.fromisoformat(xmlReader.timeStamp).timestamp())
xmlWriter = ProjectXMLWriter(fncPath)
xmlWriter = ProjectXMLWriter(fncPath / nwFiles.PROJ_FILE)
data.setUuid("d0f3fe10-c6e6-4310-8bfd-181eb4224eed")
assert xmlWriter.write(data, packedContent, timeStamp, 1000) is True
testFile = tstPaths.outDir / "projectXML_ReadLegacy13.nwx"
@@ -800,7 +801,7 @@ def testCoreProjectXML_ReadLegacy14(tstPaths, fncPath, mockRnd):
xmlReader = ProjectXMLReader(xmlFile)
assert xmlReader.state == XMLReadState.NO_ACTION
data = NWProjectData(MockProject())
data = NWProjectData(MockProject()) # type: ignore
content = []
assert xmlReader.read(data, content) is True
@@ -881,7 +882,7 @@ def testCoreProjectXML_ReadLegacy14(tstPaths, fncPath, mockRnd):
mockProject.__setattr__("data", data)
status = {}
for entry in content:
item = NWItem(mockProject, "0000000000000")
item = NWItem(mockProject, "0000000000000") # type: ignore
item.unpack(entry)
status[item.itemHandle] = item.getImportStatus(incIcon=False)[0]
packedContent.append(item.pack())
@@ -918,7 +919,7 @@ def testCoreProjectXML_ReadLegacy14(tstPaths, fncPath, mockRnd):
# Save the project again, which should produce an identical project xml
timeStamp = int(datetime.fromisoformat(xmlReader.timeStamp).timestamp())
xmlWriter = ProjectXMLWriter(fncPath)
xmlWriter = ProjectXMLWriter(fncPath / nwFiles.PROJ_FILE)
data.setUuid("d0f3fe10-c6e6-4310-8bfd-181eb4224eed")
assert xmlWriter.write(data, packedContent, timeStamp, 1000) is True
testFile = tstPaths.outDir / "projectXML_ReadLegacy14.nwx"
+15 -15
View File
@@ -67,16 +67,16 @@ def testCoreStorage_OpenProjectInPlace(mockGUI, fncPath, mockRnd):
assert storage.scanContent() == []
# Open project as a new project should fail
assert storage.openProjectInPlace(fncPath, newProject=True) is False
assert storage.initProjectStorage(fncPath, newProject=True) is False
# Opening as a non-new project is fine
assert storage.openProjectInPlace(fncPath, newProject=False) is True
assert storage.initProjectStorage(fncPath, newProject=False) is True
# Opening the project file is also fine
assert storage.openProjectInPlace(fncPath / nwFiles.PROJ_FILE, newProject=False) is True
assert storage.initProjectStorage(fncPath / nwFiles.PROJ_FILE, newProject=False) is True
# Opening as a non-new project on a non-existing folder should fail
assert storage.openProjectInPlace(fncPath / "foobar", newProject=False) is False
assert storage.initProjectStorage(fncPath / "foobar", newProject=False) is False
# Check settings
assert storage.storagePath == fncPath
@@ -123,36 +123,36 @@ def testCoreStorage_LockFile(monkeypatch, fncPath):
assert storage.isOpen() is False
# Project not open, so cannot read/write lock file
assert storage.readLockFile() == ["ERROR"]
assert storage.writeLockFile() is False
assert storage.clearLockFile() is False
assert storage._readLockFile() == ["ERROR"]
assert storage._writeLockFile() is False
assert storage._clearLockFile() is False
# Set a path to work with
lockFilePath = fncPath / nwFiles.PROJ_LOCK
storage._lockFilePath = lockFilePath
# Path is set, but there is no lockfile
assert storage.readLockFile() == []
assert storage._readLockFile() == []
# Write lockfile fails
with monkeypatch.context() as mp:
mp.setattr("pathlib.Path.write_text", causeOSError)
assert storage.writeLockFile() is False
assert storage._writeLockFile() is False
assert not lockFilePath.exists()
# Successful write
assert storage.writeLockFile() is True
assert storage._writeLockFile() is True
assert lockFilePath.exists()
assert lockFilePath.read_text().split(";")[3] == "1000"
# Read lockfile fails
with monkeypatch.context() as mp:
mp.setattr("pathlib.Path.read_text", causeOSError)
assert storage.readLockFile() == ["ERROR"]
assert storage._readLockFile() == ["ERROR"]
assert lockFilePath.exists()
# Successful read
assert storage.readLockFile() == [
assert storage._readLockFile() == [
CONFIG.hostName,
CONFIG.osType,
CONFIG.kernelVer,
@@ -161,16 +161,16 @@ def testCoreStorage_LockFile(monkeypatch, fncPath):
# Write an invalid lockfile
writeFile(lockFilePath, "a;b;c")
assert storage.readLockFile() == ["ERROR"]
assert storage._readLockFile() == ["ERROR"]
# Fail to remove lockfile
with monkeypatch.context() as mp:
mp.setattr("pathlib.Path.unlink", causeOSError)
assert storage.clearLockFile() is False
assert storage._clearLockFile() is False
assert lockFilePath.exists()
# Successful remove
assert storage.clearLockFile() is True
assert storage._clearLockFile() is True
assert not lockFilePath.exists()
# END Test testCoreStorage_LockFile
+1 -1
View File
@@ -171,7 +171,7 @@ def buildTestProject(obj, projPath):
nwGUI = obj
project = SHARED.project
project.storage.openProjectInPlace(projPath)
project.storage.createNewProject(projPath)
project.setDefaultStatusImport()
project.data.setUuid("d0f3fe10-c6e6-4310-8bfd-181eb4224eed")