New test for NWDoc class

This commit is contained in:
Veronica K. B. Olsen
2020-12-01 22:19:18 +01:00
parent 2018d44ba8
commit 8cc6fa6030
6 changed files with 218 additions and 93 deletions
+2 -1
View File
@@ -168,7 +168,8 @@ class NWDoc():
os.unlink(docPath)
os.rename(docTemp, docPath)
self.theParent.setStatus("Saved Document: %s" % self._theItem.itemName)
if self._theItem is not None:
self.theParent.setStatus("Saved Document: %s" % self._theItem.itemName)
return True
+7 -6
View File
@@ -59,10 +59,11 @@ Available markers are:
To filter specific groups of tests, use the `-k` switch.
The commands for the respective test categories are listed below.
| Type | Test Target | Source File(s) | Marker | Filter |
| :--- | :------------- | :--------------- | :-------- | :----------------- |
| Unit | Core functions | nw/core/tools.py | `-m core` | `-k testCoreTools` |
| Unit | NWIndex class | nw/core/index.py | `-m core` | `-k testCoreIndex` |
| Unit | NWItem class | nw/core/item.py | `-m core` | `-k testCoreItem` |
| Unit | NWTree class | nw/core/tree.py | `-m core` | `-k testCoreTree` |
| Type | Test Target | Source File(s) | Marker | Filter |
| :--- | :------------- | :------------------ | :-------- | :-------------------- |
| Unit | Core functions | nw/core/tools.py | `-m core` | `-k testCoreTools` |
| Unit | NWDoc class | nw/core/document.py | `-m core` | `-k testCoreDocument` |
| Unit | NWIndex class | nw/core/index.py | `-m core` | `-k testCoreIndex` |
| Unit | NWItem class | nw/core/item.py | `-m core` | `-k testCoreItem` |
| Unit | NWTree class | nw/core/tree.py | `-m core` | `-k testCoreTree` |
+61 -61
View File
@@ -72,68 +72,8 @@ def dummyGUI(tmpConf):
theDummy.mainConf = tmpConf
return theDummy
# =============================================================================================== #
##
# novelWriter Objects
##
@pytest.fixture(scope="session")
def nwConf(refDir, tmpDir):
"""Temporary novelWriter configuration used for the dummy instance
of novelWriter's main GUI.
"""
theConf = Config()
theConf.initConfig(refDir, tmpDir)
return theConf
##
# Temporary Test Folders
##
@pytest.fixture(scope="session")
def nwTempProj(tmpDir):
"""A temporary folder for project tests.
"""
projDir = os.path.join(tmpDir, "proj")
if not os.path.isdir(projDir):
os.mkdir(projDir)
return projDir
@pytest.fixture(scope="session")
def nwTempGUI(tmpDir):
"""A temporary folder for GUI tests.
"""
guiDir = os.path.join(tmpDir, "gui")
if not os.path.isdir(guiDir):
os.mkdir(guiDir)
return guiDir
@pytest.fixture(scope="session")
def nwTempBuild(tmpDir):
"""A temporary folder for build tests.
"""
buildDir = os.path.join(tmpDir, "build")
if not os.path.isdir(buildDir):
os.mkdir(buildDir)
return buildDir
@pytest.fixture(scope="function")
def nwFuncTemp(tmpDir):
"""A temporary folder for a single test function.
"""
funcDir = os.path.join(tmpDir, "ftemp")
if os.path.isdir(funcDir):
shutil.rmtree(funcDir)
if not os.path.isdir(funcDir):
os.mkdir(funcDir)
yield funcDir
if os.path.isdir(funcDir):
shutil.rmtree(funcDir)
return
##
# Temp Folders for Projects
# Temp Project Folders
##
@pytest.fixture(scope="function")
@@ -215,3 +155,63 @@ def yesToAll(monkeypatch):
QMessageBox, "critical", lambda *args, **kwargs: QMessageBox.Yes
)
return
# =============================================================================================== #
##
# novelWriter Objects
##
@pytest.fixture(scope="session")
def nwConf(refDir, tmpDir):
"""Temporary novelWriter configuration used for the dummy instance
of novelWriter's main GUI.
"""
theConf = Config()
theConf.initConfig(refDir, tmpDir)
return theConf
##
# Temporary Test Folders
##
@pytest.fixture(scope="session")
def nwTempProj(tmpDir):
"""A temporary folder for project tests.
"""
projDir = os.path.join(tmpDir, "proj")
if not os.path.isdir(projDir):
os.mkdir(projDir)
return projDir
@pytest.fixture(scope="session")
def nwTempGUI(tmpDir):
"""A temporary folder for GUI tests.
"""
guiDir = os.path.join(tmpDir, "gui")
if not os.path.isdir(guiDir):
os.mkdir(guiDir)
return guiDir
@pytest.fixture(scope="session")
def nwTempBuild(tmpDir):
"""A temporary folder for build tests.
"""
buildDir = os.path.join(tmpDir, "build")
if not os.path.isdir(buildDir):
os.mkdir(buildDir)
return buildDir
@pytest.fixture(scope="function")
def nwFuncTemp(tmpDir):
"""A temporary folder for a single test function.
"""
funcDir = os.path.join(tmpDir, "ftemp")
if os.path.isdir(funcDir):
shutil.rmtree(funcDir)
if not os.path.isdir(funcDir):
os.mkdir(funcDir)
yield funcDir
if os.path.isdir(funcDir):
shutil.rmtree(funcDir)
return
+146
View File
@@ -0,0 +1,146 @@
# -*- coding: utf-8 -*-
"""novelWriter NWDoc Class Tester
"""
import os
import pytest
from nw.core import NWProject, NWDoc
from nw.core.item import NWItem
from nw.constants import nwItemClass, nwItemLayout
@pytest.mark.core
def testCoreDocument_LoadSave(monkeypatch, dummyGUI, nwMinimal):
"""Test loading and saving a document with the NWDoc class.
"""
theProject = NWProject(dummyGUI)
assert theProject.openProject(nwMinimal)
assert theProject.projPath == nwMinimal
theDoc = NWDoc(theProject, dummyGUI)
sHandle = "8c659a11cd429"
# Not a valid handle
assert theDoc.openDocument("dummy") is None
# Non-existent handle
assert theDoc.openDocument("0000000000000") is None
# Cause open() to fail while loading
def dummyOpen(*args, **kwargs):
raise OSError
monkeypatch.setattr("builtins.open", dummyOpen)
assert theDoc.openDocument(sHandle) is None
monkeypatch.undo()
# Load the text
assert theDoc.openDocument(sHandle) == "### New Scene\n\n"
# Try to open a new (non-existent) file
nHandle = theProject.projTree.findRoot(nwItemClass.NOVEL)
assert nHandle is not None
xHandle = theProject.newFile("New File", nwItemClass.NOVEL, nHandle)
assert theDoc.openDocument(xHandle) == ""
# Check cached item
assert isinstance(theDoc._theItem, NWItem)
assert theDoc.openDocument(xHandle, isOrphan=True) == ""
assert theDoc._theItem is None
# Set handle and save again
theText = "### Test File\n\nText ...\n\n"
assert theDoc.openDocument(xHandle) == ""
assert theDoc.saveDocument(theText)
# Save again to ensure temp file and previous file is handled
assert theDoc.saveDocument(theText)
# Check file content
docPath = os.path.join(nwMinimal, "content", xHandle+".nwd")
with open(docPath, mode="r", encoding="utf8") as inFile:
assert inFile.read() == (
"%%~name: New File\n"
f"%%~path: a508bb932959c/{xHandle}\n"
"%%~kind: NOVEL/SCENE\n"
"### Test File\n\n"
"Text ...\n\n"
)
# Force no meta data
theDoc._theItem = None
assert theDoc.saveDocument(theText)
with open(docPath, mode="r", encoding="utf8") as inFile:
assert inFile.read() == theText
# Cause open() to fail while saving
def dummyIO(*args, **kwargs):
raise OSError
monkeypatch.setattr("builtins.open", dummyIO)
assert not theDoc.saveDocument(theText)
monkeypatch.undo()
# Saving with no handle
theDoc.clearDocument()
assert not theDoc.saveDocument(theText)
# Delete the last document
assert not theDoc.deleteDocument("dummy")
assert os.path.isfile(docPath)
# Cause the delete to fail
monkeypatch.setattr("os.unlink", dummyIO)
assert not theDoc.deleteDocument(xHandle)
monkeypatch.undo()
# Make the delete pass
assert theDoc.deleteDocument(xHandle)
assert not os.path.isfile(docPath)
# END Test testCoreDocument_Load
@pytest.mark.core
def testCoreDocument_Methods(monkeypatch, dummyGUI, nwMinimal):
"""Test other methods of the NWDoc class.
"""
theProject = NWProject(dummyGUI)
assert theProject.openProject(nwMinimal)
assert theProject.projPath == nwMinimal
theDoc = NWDoc(theProject, dummyGUI)
sHandle = "8c659a11cd429"
docPath = os.path.join(nwMinimal, "content", sHandle+".nwd")
assert theDoc.openDocument(sHandle) == "### New Scene\n\n"
# Check location
assert theDoc.getFileLocation() == docPath
# Check the item
assert theDoc.getCurrentItem() is not None
assert theDoc.getCurrentItem().itemHandle == sHandle
# Check the meta
theName, theParent, theClass, theLayout = theDoc.getMeta()
assert theName == "New Scene"
assert theParent == "a6d311a93600a"
assert theClass == nwItemClass.NOVEL
assert theLayout == nwItemLayout.SCENE
# Add meta data garbage
assert theDoc.saveDocument("%%~ stuff\n### Test File\n\nText ...\n\n")
with open(docPath, mode="r", encoding="utf8") as inFile:
assert inFile.read() == (
"%%~name: New Scene\n"
f"%%~path: a6d311a93600a/{sHandle}\n"
"%%~kind: NOVEL/SCENE\n"
"%%~ stuff\n"
"### Test File\n\n"
"Text ...\n\n"
)
assert theDoc.openDocument(sHandle) == "### Test File\n\nText ...\n\n"
# END Test testCoreDocument_Methods
+2 -1
View File
@@ -6,7 +6,8 @@ import pytest
from lxml import etree
from nw.core.project import NWProject, NWItem
from nw.core import NWProject
from nw.core.item import NWItem
from nw.constants import nwItemClass, nwItemType, nwItemLayout
@pytest.mark.core
-24
View File
@@ -325,30 +325,6 @@ def testProjectMethods(monkeypatch, nwMinimal, dummyGUI):
assert theProject.setBookAuthors(" Jane Doe \n John Doh \n ")
assert theProject.bookAuthors == ["Jane Doe", "John Doh"]
@pytest.mark.project
def testDocMeta(dummyGUI, nwLipsum):
"""Check that the document meta data string is parsed correctly.
"""
theProject = NWProject(dummyGUI)
theProject.projTree.setSeed(42)
assert theProject.openProject(nwLipsum)
aDoc = NWDoc(theProject, dummyGUI)
assert aDoc.openDocument("47666c91c7ccf")
theName, theParent, theClass, theLayout = aDoc.getMeta()
assert theName == "Scene Five"
assert theParent == "6bd935d2490cd"
assert theClass == nwItemClass.NOVEL
assert theLayout == nwItemLayout.SCENE
aDoc._docMeta = {"stuff": None}
theName, theParent, theClass, theLayout = aDoc.getMeta()
assert theName == ""
assert theParent is None
assert theClass is None
assert theLayout is None
@pytest.mark.project
def testSpellEnchant(tmpDir, nwConf):
wList = os.path.join(tmpDir, "wordlist.txt")