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.unlink(docPath)
os.rename(docTemp, 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 return True
+7 -6
View File
@@ -59,10 +59,11 @@ Available markers are:
To filter specific groups of tests, use the `-k` switch. To filter specific groups of tests, use the `-k` switch.
The commands for the respective test categories are listed below. The commands for the respective test categories are listed below.
| Type | Test Target | Source File(s) | Marker | Filter | | Type | Test Target | Source File(s) | Marker | Filter |
| :--- | :------------- | :--------------- | :-------- | :----------------- | | :--- | :------------- | :------------------ | :-------- | :-------------------- |
| Unit | Core functions | nw/core/tools.py | `-m core` | `-k testCoreTools` | | Unit | Core functions | nw/core/tools.py | `-m core` | `-k testCoreTools` |
| Unit | NWIndex class | nw/core/index.py | `-m core` | `-k testCoreIndex` | | Unit | NWDoc class | nw/core/document.py | `-m core` | `-k testCoreDocument` |
| Unit | NWItem class | nw/core/item.py | `-m core` | `-k testCoreItem` | | Unit | NWIndex class | nw/core/index.py | `-m core` | `-k testCoreIndex` |
| Unit | NWTree class | nw/core/tree.py | `-m core` | `-k testCoreTree` | | 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 theDummy.mainConf = tmpConf
return theDummy return theDummy
# =============================================================================================== #
## ##
# novelWriter Objects # Temp Project Folders
##
@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
## ##
@pytest.fixture(scope="function") @pytest.fixture(scope="function")
@@ -215,3 +155,63 @@ def yesToAll(monkeypatch):
QMessageBox, "critical", lambda *args, **kwargs: QMessageBox.Yes QMessageBox, "critical", lambda *args, **kwargs: QMessageBox.Yes
) )
return 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 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 from nw.constants import nwItemClass, nwItemType, nwItemLayout
@pytest.mark.core @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.setBookAuthors(" Jane Doe \n John Doh \n ")
assert theProject.bookAuthors == ["Jane Doe", "John Doh"] 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 @pytest.mark.project
def testSpellEnchant(tmpDir, nwConf): def testSpellEnchant(tmpDir, nwConf):
wList = os.path.join(tmpDir, "wordlist.txt") wList = os.path.join(tmpDir, "wordlist.txt")