New test for NWDoc class
This commit is contained in:
+2
-1
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user