Updated existing NWProject tests

This commit is contained in:
Veronica K. B. Olsen
2020-12-04 21:28:35 +01:00
parent 91ece2b7f2
commit 57397fa2bc
9 changed files with 101 additions and 87 deletions
-1
View File
@@ -1,6 +1,5 @@
[pytest] [pytest]
markers = markers =
project: Project classes tests
error: Test various error handling scenarios error: Test various error handling scenarios
core: Core functionality tests core: Core functionality tests
gui: Qt5 GUI tests gui: Qt5 GUI tests
+1
View File
@@ -69,4 +69,5 @@ The commands for the respective test categories are listed below.
| Unit | NWStatus class | nw/core/status.py | `-m core` | `-k testCoreStatus` | | Unit | NWStatus class | nw/core/status.py | `-m core` | `-k testCoreStatus` |
| Unit | NWTree class | nw/core/tree.py | `-m core` | `-k testCoreTree` | | Unit | NWTree class | nw/core/tree.py | `-m core` | `-k testCoreTree` |
| Unit | OptionsState class | nw/core/options.py | `-m core` | `-k testCoreOptions` | | Unit | OptionsState class | nw/core/options.py | `-m core` | `-k testCoreOptions` |
| Unit | ToHtml class | nw/core/tohtml.py | `-m core` | `-k testCoreToHtml` |
| Unit | Tokenizer class | nw/core/tokenizer.py | `-m core` | `-k testCoreToken` | | Unit | Tokenizer class | nw/core/tokenizer.py | `-m core` | `-k testCoreToken` |
+14 -22
View File
@@ -51,6 +51,20 @@ def outDir(tmpDir):
os.mkdir(theDir) os.mkdir(theDir)
return theDir return theDir
@pytest.fixture(scope="function")
def fncDir(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
## ##
# novelWriter Objects # novelWriter Objects
## ##
@@ -158,32 +172,10 @@ def yesToAll(monkeypatch):
# =============================================================================================== # # =============================================================================================== #
##
# 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 # 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") @pytest.fixture(scope="session")
def nwTempGUI(tmpDir): def nwTempGUI(tmpDir):
"""A temporary folder for GUI tests. """A temporary folder for GUI tests.
@@ -13,13 +13,13 @@ from tools import cmpFiles
from nw.core.project import NWProject from nw.core.project import NWProject
from nw.constants import nwItemClass, nwItemType, nwItemLayout, nwFiles from nw.constants import nwItemClass, nwItemType, nwItemLayout, nwFiles
@pytest.mark.project @pytest.mark.core
def testProjectNewOpenSave(nwFuncTemp, nwTempProj, refDir, tmpDir, dummyGUI): def testCoreProject_NewOpenSave(fncDir, outDir, refDir, tmpDir, dummyGUI):
"""Test that a basic project can be created, and opened and saved. """Test that a basic project can be created, opened and saved.
""" """
projFile = os.path.join(nwFuncTemp, "nwProject.nwx") projFile = os.path.join(fncDir, "nwProject.nwx")
testFile = os.path.join(nwTempProj, "1_nwProject.nwx") testFile = os.path.join(outDir, "coreProject_1_nwProject.nwx")
refFile = os.path.join(refDir, "proj", "1_nwProject.nwx") compFile = os.path.join(refDir, "coreProject_1_nwProject.nwx")
theProject = NWProject(dummyGUI) theProject = NWProject(dummyGUI)
theProject.projTree.setSeed(42) theProject.projTree.setSeed(42)
@@ -28,17 +28,17 @@ def testProjectNewOpenSave(nwFuncTemp, nwTempProj, refDir, tmpDir, dummyGUI):
assert not theProject.newProject({}) assert not theProject.newProject({})
# Try again with a proper path # Try again with a proper path
assert theProject.newProject({"projPath": nwFuncTemp}) assert theProject.newProject({"projPath": fncDir})
assert theProject.setProjectPath(nwFuncTemp) assert theProject.setProjectPath(fncDir)
assert theProject.saveProject() assert theProject.saveProject()
assert theProject.closeProject() assert theProject.closeProject()
# Creating the project once more should fail # Creating the project once more should fail
assert not theProject.newProject({"projPath": nwFuncTemp}) assert not theProject.newProject({"projPath": fncDir})
# Check the new project # Check the new project
copyfile(projFile, testFile) copyfile(projFile, testFile)
assert cmpFiles(testFile, refFile, [2, 6, 7, 8]) assert cmpFiles(testFile, compFile, [2, 6, 7, 8])
# Open again # Open again
assert theProject.openProject(projFile) assert theProject.openProject(projFile)
@@ -47,7 +47,7 @@ def testProjectNewOpenSave(nwFuncTemp, nwTempProj, refDir, tmpDir, dummyGUI):
assert theProject.saveProject() assert theProject.saveProject()
assert theProject.closeProject() assert theProject.closeProject()
copyfile(projFile, testFile) copyfile(projFile, testFile)
assert cmpFiles(testFile, refFile, [2, 6, 7, 8]) assert cmpFiles(testFile, compFile, [2, 6, 7, 8])
assert not theProject.projChanged assert not theProject.projChanged
# Open a second time # Open a second time
@@ -57,21 +57,23 @@ def testProjectNewOpenSave(nwFuncTemp, nwTempProj, refDir, tmpDir, dummyGUI):
assert theProject.saveProject() assert theProject.saveProject()
assert theProject.closeProject() assert theProject.closeProject()
copyfile(projFile, testFile) copyfile(projFile, testFile)
assert cmpFiles(testFile, refFile, [2, 6, 7, 8]) assert cmpFiles(testFile, compFile, [2, 6, 7, 8])
@pytest.mark.project # END Test testCoreProject_NewOpenSave
def testProjectNewRoot(nwFuncTemp, nwTempProj, refDir, dummyGUI):
@pytest.mark.core
def testCoreProject_NewRoot(fncDir, outDir, refDir, dummyGUI):
"""Check that new root folders can be added to the project. """Check that new root folders can be added to the project.
""" """
projFile = os.path.join(nwFuncTemp, "nwProject.nwx") projFile = os.path.join(fncDir, "nwProject.nwx")
testFile = os.path.join(nwTempProj, "2_nwProject.nwx") testFile = os.path.join(outDir, "coreProject_2_nwProject.nwx")
refFile = os.path.join(refDir, "proj", "2_nwProject.nwx") compFile = os.path.join(refDir, "coreProject_2_nwProject.nwx")
theProject = NWProject(dummyGUI) theProject = NWProject(dummyGUI)
theProject.projTree.setSeed(42) theProject.projTree.setSeed(42)
assert theProject.newProject({"projPath": nwFuncTemp}) assert theProject.newProject({"projPath": fncDir})
assert theProject.setProjectPath(nwFuncTemp) assert theProject.setProjectPath(fncDir)
assert theProject.saveProject() assert theProject.saveProject()
assert theProject.closeProject() assert theProject.closeProject()
assert theProject.openProject(projFile) assert theProject.openProject(projFile)
@@ -90,22 +92,24 @@ def testProjectNewRoot(nwFuncTemp, nwTempProj, refDir, dummyGUI):
assert theProject.closeProject() assert theProject.closeProject()
copyfile(projFile, testFile) copyfile(projFile, testFile)
assert cmpFiles(testFile, refFile, [2, 6, 7, 8]) assert cmpFiles(testFile, compFile, [2, 6, 7, 8])
assert not theProject.projChanged assert not theProject.projChanged
@pytest.mark.project # END Test testCoreProject_NewRoot
def testProjectNewFile(nwFuncTemp, nwTempProj, refDir, dummyGUI):
@pytest.mark.core
def testCoreProject_NewFile(fncDir, outDir, refDir, dummyGUI):
"""Check that new files can be added to the project. """Check that new files can be added to the project.
""" """
projFile = os.path.join(nwFuncTemp, "nwProject.nwx") projFile = os.path.join(fncDir, "nwProject.nwx")
testFile = os.path.join(nwTempProj, "3_nwProject.nwx") testFile = os.path.join(outDir, "coreProject_3_nwProject.nwx")
refFile = os.path.join(refDir, "proj", "3_nwProject.nwx") compFile = os.path.join(refDir, "coreProject_3_nwProject.nwx")
theProject = NWProject(dummyGUI) theProject = NWProject(dummyGUI)
theProject.projTree.setSeed(42) theProject.projTree.setSeed(42)
assert theProject.newProject({"projPath": nwFuncTemp}) assert theProject.newProject({"projPath": fncDir})
assert theProject.setProjectPath(nwFuncTemp) assert theProject.setProjectPath(fncDir)
assert theProject.saveProject() assert theProject.saveProject()
assert theProject.closeProject() assert theProject.closeProject()
assert theProject.openProject(projFile) assert theProject.openProject(projFile)
@@ -117,23 +121,25 @@ def testProjectNewFile(nwFuncTemp, nwTempProj, refDir, dummyGUI):
assert theProject.closeProject() assert theProject.closeProject()
copyfile(projFile, testFile) copyfile(projFile, testFile)
assert cmpFiles(testFile, refFile, [2, 6, 7, 8]) assert cmpFiles(testFile, compFile, [2, 6, 7, 8])
assert not theProject.projChanged assert not theProject.projChanged
@pytest.mark.project # END Test testCoreProject_NewFile
def testProjectNewCustomA(nwFuncTemp, nwTempProj, refDir, dummyGUI):
@pytest.mark.core
def testCoreProject_NewCustomA(fncDir, outDir, refDir, dummyGUI):
"""Create a new project from a project wizard dictionary. """Create a new project from a project wizard dictionary.
Custom type with chapters and scenes. Custom type with chapters and scenes.
""" """
projFile = os.path.join(nwFuncTemp, "nwProject.nwx") projFile = os.path.join(fncDir, "nwProject.nwx")
testFile = os.path.join(nwTempProj, "4_nwProject.nwx") testFile = os.path.join(outDir, "coreProject_4_nwProject.nwx")
refFile = os.path.join(refDir, "proj", "4_nwProject.nwx") compFile = os.path.join(refDir, "coreProject_4_nwProject.nwx")
projData = { projData = {
"projName": "Test Custom", "projName": "Test Custom",
"projTitle": "Test Novel", "projTitle": "Test Novel",
"projAuthors": "Jane Doe\nJohn Doh\n", "projAuthors": "Jane Doe\nJohn Doh\n",
"projPath": nwFuncTemp, "projPath": fncDir,
"popSample": False, "popSample": False,
"popMinimal": False, "popMinimal": False,
"popCustom": True, "popCustom": True,
@@ -157,22 +163,24 @@ def testProjectNewCustomA(nwFuncTemp, nwTempProj, refDir, dummyGUI):
assert theProject.closeProject() assert theProject.closeProject()
copyfile(projFile, testFile) copyfile(projFile, testFile)
assert cmpFiles(testFile, refFile, [2, 6, 7, 8]) assert cmpFiles(testFile, compFile, [2, 6, 7, 8])
@pytest.mark.project # END Test testCoreProject_NewCustomA
def testProjectNewCustomB(nwFuncTemp, nwTempProj, refDir, dummyGUI):
@pytest.mark.core
def testCoreProject_NewCustomB(fncDir, outDir, refDir, dummyGUI):
"""Create a new project from a project wizard dictionary. """Create a new project from a project wizard dictionary.
Custom type without chapters, but with scenes. Custom type without chapters, but with scenes.
""" """
projFile = os.path.join(nwFuncTemp, "nwProject.nwx") projFile = os.path.join(fncDir, "nwProject.nwx")
testFile = os.path.join(nwTempProj, "5_nwProject.nwx") testFile = os.path.join(outDir, "coreProject_5_nwProject.nwx")
refFile = os.path.join(refDir, "proj", "5_nwProject.nwx") compFile = os.path.join(refDir, "coreProject_5_nwProject.nwx")
projData = { projData = {
"projName": "Test Custom", "projName": "Test Custom",
"projTitle": "Test Novel", "projTitle": "Test Novel",
"projAuthors": "Jane Doe\nJohn Doh\n", "projAuthors": "Jane Doe\nJohn Doh\n",
"projPath": nwFuncTemp, "projPath": fncDir,
"popSample": False, "popSample": False,
"popMinimal": False, "popMinimal": False,
"popCustom": True, "popCustom": True,
@@ -196,10 +204,12 @@ def testProjectNewCustomB(nwFuncTemp, nwTempProj, refDir, dummyGUI):
assert theProject.closeProject() assert theProject.closeProject()
copyfile(projFile, testFile) copyfile(projFile, testFile)
assert cmpFiles(testFile, refFile, [2, 6, 7, 8]) assert cmpFiles(testFile, compFile, [2, 6, 7, 8])
@pytest.mark.project # END Test testCoreProject_NewCustomB
def testProjectNewSampleA(nwFuncTemp, nwConf, dummyGUI, tmpDir):
@pytest.mark.core
def testCoreProject_NewSampleA(fncDir, tmpConf, dummyGUI, tmpDir):
"""Check that we can create a new project can be created from the """Check that we can create a new project can be created from the
provided sample project via a zip file. provided sample project via a zip file.
""" """
@@ -207,22 +217,22 @@ def testProjectNewSampleA(nwFuncTemp, nwConf, dummyGUI, tmpDir):
"projName": "Test Sample", "projName": "Test Sample",
"projTitle": "Test Novel", "projTitle": "Test Novel",
"projAuthors": "Jane Doe\nJohn Doh\n", "projAuthors": "Jane Doe\nJohn Doh\n",
"projPath": nwFuncTemp, "projPath": fncDir,
"popSample": True, "popSample": True,
"popMinimal": False, "popMinimal": False,
"popCustom": False, "popCustom": False,
} }
theProject = NWProject(dummyGUI) theProject = NWProject(dummyGUI)
theProject.projTree.setSeed(42) theProject.projTree.setSeed(42)
theProject.mainConf = nwConf theProject.mainConf = tmpConf
# Sample set, but no path # Sample set, but no path
assert not theProject.newProject({"popSample": True}) assert not theProject.newProject({"popSample": True})
# Force the lookup path for assets to our temp folder # Force the lookup path for assets to our temp folder
srcSample = os.path.abspath(os.path.join(nwConf.appRoot, "sample")) srcSample = os.path.abspath(os.path.join(tmpConf.appRoot, "sample"))
dstSample = os.path.join(tmpDir, "sample.zip") dstSample = os.path.join(tmpDir, "sample.zip")
nwConf.assetPath = tmpDir tmpConf.assetPath = tmpDir
# Create and open a defective zip file # Create and open a defective zip file
with open(dstSample, mode="w+") as outFile: with open(dstSample, mode="w+") as outFile:
@@ -239,14 +249,16 @@ def testProjectNewSampleA(nwFuncTemp, nwConf, dummyGUI, tmpDir):
zipObj.write(srcDoc, "content/"+docFile) zipObj.write(srcDoc, "content/"+docFile)
assert theProject.newProject(projData) assert theProject.newProject(projData)
assert theProject.openProject(nwFuncTemp) assert theProject.openProject(fncDir)
assert theProject.projName == "Sample Project" assert theProject.projName == "Sample Project"
assert theProject.saveProject() assert theProject.saveProject()
assert theProject.closeProject() assert theProject.closeProject()
os.unlink(dstSample) os.unlink(dstSample)
@pytest.mark.project # END Test testCoreProject_NewSampleA
def testProjectNewSampleB(monkeypatch, nwFuncTemp, nwConf, dummyGUI, tmpDir):
@pytest.mark.core
def testCoreProject_NewSampleB(monkeypatch, fncDir, tmpConf, dummyGUI, tmpDir):
"""Check that we can create a new project can be created from the """Check that we can create a new project can be created from the
provided sample project folder. provided sample project folder.
""" """
@@ -254,17 +266,17 @@ def testProjectNewSampleB(monkeypatch, nwFuncTemp, nwConf, dummyGUI, tmpDir):
"projName": "Test Sample", "projName": "Test Sample",
"projTitle": "Test Novel", "projTitle": "Test Novel",
"projAuthors": "Jane Doe\nJohn Doh\n", "projAuthors": "Jane Doe\nJohn Doh\n",
"projPath": nwFuncTemp, "projPath": fncDir,
"popSample": True, "popSample": True,
"popMinimal": False, "popMinimal": False,
"popCustom": False, "popCustom": False,
} }
theProject = NWProject(dummyGUI) theProject = NWProject(dummyGUI)
theProject.projTree.setSeed(42) theProject.projTree.setSeed(42)
theProject.mainConf = nwConf theProject.mainConf = tmpConf
# Make sure we do not pick up the nw/assets/sample.zip file # Make sure we do not pick up the nw/assets/sample.zip file
nwConf.assetPath = tmpDir tmpConf.assetPath = tmpDir
# Set a fake project file name # Set a fake project file name
monkeypatch.setattr(nwFiles, "PROJ_FILE", "nothing.nwx") monkeypatch.setattr(nwFiles, "PROJ_FILE", "nothing.nwx")
@@ -272,17 +284,19 @@ def testProjectNewSampleB(monkeypatch, nwFuncTemp, nwConf, dummyGUI, tmpDir):
monkeypatch.setattr(nwFiles, "PROJ_FILE", "nwProject.nwx") monkeypatch.setattr(nwFiles, "PROJ_FILE", "nwProject.nwx")
assert theProject.newProject(projData) assert theProject.newProject(projData)
assert theProject.openProject(nwFuncTemp) assert theProject.openProject(fncDir)
assert theProject.projName == "Sample Project" assert theProject.projName == "Sample Project"
assert theProject.saveProject() assert theProject.saveProject()
assert theProject.closeProject() assert theProject.closeProject()
# Misdirect the appRoot path so neither is possible # Misdirect the appRoot path so neither is possible
nwConf.appRoot = tmpDir tmpConf.appRoot = tmpDir
assert not theProject.newProject(projData) assert not theProject.newProject(projData)
@pytest.mark.project # END Test testCoreProject_NewSampleB
def testProjectMethods(monkeypatch, nwMinimal, dummyGUI):
@pytest.mark.core
def testCoreProject_Methods(monkeypatch, nwMinimal, dummyGUI):
"""Test other project class methods and functions. """Test other project class methods and functions.
""" """
theProject = NWProject(dummyGUI) theProject = NWProject(dummyGUI)
@@ -323,8 +337,10 @@ 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 # END Test testCoreProject_Methods
def testProjectOrphanedFiles(dummyGUI, nwLipsum):
@pytest.mark.core
def testCoreProject_OrphanedFiles(dummyGUI, nwLipsum):
"""Check that files in the content folder that are not tracked in """Check that files in the content folder that are not tracked in
the project XML file are handled correctly by the orphaned files the project XML file are handled correctly by the orphaned files
function. It should also restore as much meta data as possible from function. It should also restore as much meta data as possible from
@@ -392,8 +408,10 @@ def testProjectOrphanedFiles(dummyGUI, nwLipsum):
assert theProject.saveProject(nwLipsum) assert theProject.saveProject(nwLipsum)
assert theProject.closeProject() assert theProject.closeProject()
@pytest.mark.project # END Test testCoreProject_OrphanedFiles
def testProjectOldFormat(dummyGUI, nwOldProj):
@pytest.mark.core
def testCoreProject_OldFormat(dummyGUI, nwOldProj):
"""Test that a project folder structure of version 1.0 can be """Test that a project folder structure of version 1.0 can be
converted to the latest folder structure. Version 1.0 split the converted to the latest folder structure. Version 1.0 split the
documents into 'data_0' ... 'data_f' folders, which are now all documents into 'data_0' ... 'data_f' folders, which are now all
@@ -482,8 +500,10 @@ def testProjectOldFormat(dummyGUI, nwOldProj):
assert os.path.isfile(os.path.join(nwOldProj, "meta", "sessionStats.log")) assert os.path.isfile(os.path.join(nwOldProj, "meta", "sessionStats.log"))
assert os.path.isfile(os.path.join(nwOldProj, "ToC.txt")) assert os.path.isfile(os.path.join(nwOldProj, "ToC.txt"))
@pytest.mark.project # END Test testCoreProject_OldFormat
def testProjectBackup(dummyGUI, nwMinimal, tmpDir):
@pytest.mark.core
def testCoreProject_Backup(dummyGUI, nwMinimal, tmpDir):
"""Test the automated backup feature of the project class. The test """Test the automated backup feature of the project class. The test
creates a backup of the Minimal test project, and then unzips the creates a backup of the Minimal test project, and then unzips the
backupd file and checks that the project XML file is identical to backupd file and checks that the project XML file is identical to
@@ -530,3 +550,5 @@ def testProjectBackup(dummyGUI, nwMinimal, tmpDir):
assert cmpFiles( assert cmpFiles(
os.path.join(nwMinimal, "nwProject.nwx"), os.path.join(tmpDir, "extract", "nwProject.nwx") os.path.join(nwMinimal, "nwProject.nwx"), os.path.join(tmpDir, "extract", "nwProject.nwx")
) )
# END Test testCoreProject_Backup