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