Add coverage of new function in project class

This commit is contained in:
Veronica Berglyd Olsen
2022-10-11 21:48:40 +02:00
parent 07c93bcb7d
commit 417758a29a
3 changed files with 142 additions and 98 deletions
@@ -1,5 +1,5 @@
<?xml version='1.0' encoding='utf-8'?>
<novelWriterXML appVersion="1.7-beta1" hexVersion="0x010700b1" fileVersion="1.4" timeStamp="2022-07-31 18:40:28">
<novelWriterXML appVersion="2.0-beta1" hexVersion="0x020000b1" fileVersion="1.4" timeStamp="2022-10-11 21:40:10">
<project>
<name>New Project</name>
<title>New Novel</title>
@@ -17,9 +17,9 @@
<lastViewed>None</lastViewed>
<lastNovel>None</lastNovel>
<lastOutline>None</lastOutline>
<lastWordCount>2</lastWordCount>
<lastWordCount>4</lastWordCount>
<novelWordCount>1</novelWordCount>
<notesWordCount>1</notesWordCount>
<notesWordCount>3</notesWordCount>
<autoReplace/>
<titleFormat>
<title>%title%</title>
@@ -29,62 +29,62 @@
<section></section>
</titleFormat>
<status>
<entry key="s000008" count="7" red="100" green="100" blue="100">New</entry>
<entry key="s000009" count="0" red="200" green="50" blue="0">Note</entry>
<entry key="s00000a" count="0" red="200" green="150" blue="0">Draft</entry>
<entry key="s00000b" count="0" red="50" green="200" blue="0">Finished</entry>
<entry key="s000000" count="7" red="100" green="100" blue="100">New</entry>
<entry key="s000001" count="0" red="200" green="50" blue="0">Note</entry>
<entry key="s000002" count="0" red="200" green="150" blue="0">Draft</entry>
<entry key="s000003" count="0" red="50" green="200" blue="0">Finished</entry>
</status>
<importance>
<entry key="i00000c" count="4" red="100" green="100" blue="100">New</entry>
<entry key="i00000d" count="0" red="200" green="50" blue="0">Minor</entry>
<entry key="i00000e" count="0" red="200" green="150" blue="0">Major</entry>
<entry key="i00000f" count="0" red="50" green="200" blue="0">Main</entry>
<entry key="i000004" count="4" red="100" green="100" blue="100">New</entry>
<entry key="i000005" count="0" red="200" green="50" blue="0">Minor</entry>
<entry key="i000006" count="0" red="200" green="150" blue="0">Major</entry>
<entry key="i000007" count="0" red="50" green="200" blue="0">Main</entry>
</importance>
</settings>
<content count="11">
<item handle="0000000000010" parent="None" root="0000000000010" order="0" type="ROOT" class="NOVEL">
<item handle="0000000000008" parent="None" root="0000000000008" order="0" type="ROOT" class="NOVEL">
<meta expanded="False"/>
<name status="s000008" import="i00000c">Novel</name>
<name status="s000000" import="i000004">Novel</name>
</item>
<item handle="0000000000011" parent="None" root="0000000000011" order="0" type="ROOT" class="PLOT">
<item handle="0000000000009" parent="None" root="0000000000009" order="0" type="ROOT" class="PLOT">
<meta expanded="False"/>
<name status="s000008" import="i00000c">Plot</name>
<name status="s000000" import="i000004">Plot</name>
</item>
<item handle="0000000000012" parent="None" root="0000000000012" order="0" type="ROOT" class="CHARACTER">
<item handle="000000000000a" parent="None" root="000000000000a" order="0" type="ROOT" class="CHARACTER">
<meta expanded="False"/>
<name status="s000008" import="i00000c">Characters</name>
<name status="s000000" import="i000004">Characters</name>
</item>
<item handle="0000000000013" parent="None" root="0000000000013" order="0" type="ROOT" class="WORLD">
<item handle="000000000000b" parent="None" root="000000000000b" order="0" type="ROOT" class="WORLD">
<meta expanded="False"/>
<name status="s000008" import="i00000c">World</name>
<name status="s000000" import="i000004">World</name>
</item>
<item handle="0000000000014" parent="0000000000010" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
<item handle="000000000000c" parent="0000000000008" root="0000000000008" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
<name status="s000008" import="i00000c" exported="True">Title Page</name>
<name status="s000000" import="i000004" exported="True">Title Page</name>
</item>
<item handle="0000000000015" parent="0000000000010" root="0000000000010" order="0" type="FOLDER" class="NOVEL">
<item handle="000000000000d" parent="0000000000008" root="0000000000008" order="0" type="FOLDER" class="NOVEL">
<meta expanded="False"/>
<name status="s000008" import="i00000c">New Chapter</name>
<name status="s000000" import="i000004">New Chapter</name>
</item>
<item handle="0000000000016" parent="0000000000015" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
<item handle="000000000000e" parent="000000000000d" root="0000000000008" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
<name status="s000008" import="i00000c" exported="True">New Chapter</name>
<name status="s000000" import="i000004" exported="True">New Chapter</name>
</item>
<item handle="0000000000017" parent="0000000000015" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
<item handle="000000000000f" parent="000000000000d" root="0000000000008" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
<name status="s000008" import="i00000c" exported="True">New Scene</name>
<name status="s000000" import="i000004" exported="True">New Scene</name>
</item>
<item handle="0000000000028" parent="0000000000015" root="0000000000010" order="0" type="FOLDER" class="NOVEL">
<item handle="0000000000020" parent="0000000000008" root="0000000000008" order="0" type="FOLDER" class="NOVEL">
<meta expanded="False"/>
<name status="s000008" import="i00000c">Stuff</name>
<name status="s000000" import="i000004">Stuff</name>
</item>
<item handle="0000000000029" parent="0000000000015" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
<item handle="0000000000021" parent="0000000000020" root="0000000000008" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
<meta expanded="False" charCount="5" wordCount="1" paraCount="0" cursorPos="0"/>
<name status="s000008" import="i00000c" exported="True">Hello</name>
<name status="s000000" import="i000004" exported="True">Hello</name>
</item>
<item handle="000000000002a" parent="0000000000012" root="0000000000012" order="0" type="FILE" class="CHARACTER" layout="NOTE">
<meta expanded="False" charCount="4" wordCount="1" paraCount="0" cursorPos="0"/>
<name status="s000008" import="i00000c" exported="True">Jane</name>
<item handle="0000000000022" parent="000000000000a" root="000000000000a" order="0" type="FILE" class="CHARACTER" layout="NOTE">
<meta expanded="False" charCount="11" wordCount="3" paraCount="1" cursorPos="0"/>
<name status="s000000" import="i000004" exported="True">Jane</name>
</item>
</content>
</novelWriterXML>
@@ -1,5 +1,5 @@
<?xml version='1.0' encoding='utf-8'?>
<novelWriterXML appVersion="1.7-beta1" hexVersion="0x010700b1" fileVersion="1.4" timeStamp="2022-07-31 18:40:28">
<novelWriterXML appVersion="2.0-beta1" hexVersion="0x020000b1" fileVersion="1.4" timeStamp="2022-10-11 21:30:35">
<project>
<name>New Project</name>
<title>New Novel</title>
@@ -29,82 +29,82 @@
<section></section>
</titleFormat>
<status>
<entry key="s000008" count="6" red="100" green="100" blue="100">New</entry>
<entry key="s000009" count="0" red="200" green="50" blue="0">Note</entry>
<entry key="s00000a" count="0" red="200" green="150" blue="0">Draft</entry>
<entry key="s00000b" count="0" red="50" green="200" blue="0">Finished</entry>
<entry key="s000000" count="6" red="100" green="100" blue="100">New</entry>
<entry key="s000001" count="0" red="200" green="50" blue="0">Note</entry>
<entry key="s000002" count="0" red="200" green="150" blue="0">Draft</entry>
<entry key="s000003" count="0" red="50" green="200" blue="0">Finished</entry>
</status>
<importance>
<entry key="i00000c" count="10" red="100" green="100" blue="100">New</entry>
<entry key="i00000d" count="0" red="200" green="50" blue="0">Minor</entry>
<entry key="i00000e" count="0" red="200" green="150" blue="0">Major</entry>
<entry key="i00000f" count="0" red="50" green="200" blue="0">Main</entry>
<entry key="i000004" count="10" red="100" green="100" blue="100">New</entry>
<entry key="i000005" count="0" red="200" green="50" blue="0">Minor</entry>
<entry key="i000006" count="0" red="200" green="150" blue="0">Major</entry>
<entry key="i000007" count="0" red="50" green="200" blue="0">Main</entry>
</importance>
</settings>
<content count="16">
<item handle="0000000000010" parent="None" root="0000000000010" order="0" type="ROOT" class="NOVEL">
<item handle="0000000000008" parent="None" root="0000000000008" order="0" type="ROOT" class="NOVEL">
<meta expanded="False"/>
<name status="s000008" import="i00000c">Novel</name>
<name status="s000000" import="i000004">Novel</name>
</item>
<item handle="0000000000011" parent="None" root="0000000000011" order="0" type="ROOT" class="PLOT">
<item handle="0000000000009" parent="None" root="0000000000009" order="0" type="ROOT" class="PLOT">
<meta expanded="False"/>
<name status="s000008" import="i00000c">Plot</name>
<name status="s000000" import="i000004">Plot</name>
</item>
<item handle="0000000000012" parent="None" root="0000000000012" order="0" type="ROOT" class="CHARACTER">
<item handle="000000000000a" parent="None" root="000000000000a" order="0" type="ROOT" class="CHARACTER">
<meta expanded="False"/>
<name status="s000008" import="i00000c">Characters</name>
<name status="s000000" import="i000004">Characters</name>
</item>
<item handle="0000000000013" parent="None" root="0000000000013" order="0" type="ROOT" class="WORLD">
<item handle="000000000000b" parent="None" root="000000000000b" order="0" type="ROOT" class="WORLD">
<meta expanded="False"/>
<name status="s000008" import="i00000c">World</name>
<name status="s000000" import="i000004">World</name>
</item>
<item handle="0000000000014" parent="0000000000010" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
<item handle="000000000000c" parent="0000000000008" root="0000000000008" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
<name status="s000008" import="i00000c" exported="True">Title Page</name>
<name status="s000000" import="i000004" exported="True">Title Page</name>
</item>
<item handle="0000000000015" parent="0000000000010" root="0000000000010" order="0" type="FOLDER" class="NOVEL">
<item handle="000000000000d" parent="0000000000008" root="0000000000008" order="0" type="FOLDER" class="NOVEL">
<meta expanded="False"/>
<name status="s000008" import="i00000c">New Chapter</name>
<name status="s000000" import="i000004">New Chapter</name>
</item>
<item handle="0000000000016" parent="0000000000015" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
<item handle="000000000000e" parent="000000000000d" root="0000000000008" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
<name status="s000008" import="i00000c" exported="True">New Chapter</name>
<name status="s000000" import="i000004" exported="True">New Chapter</name>
</item>
<item handle="0000000000017" parent="0000000000015" root="0000000000010" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
<item handle="000000000000f" parent="000000000000d" root="0000000000008" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
<meta expanded="False" charCount="0" wordCount="0" paraCount="0" cursorPos="0"/>
<name status="s000008" import="i00000c" exported="True">New Scene</name>
<name status="s000000" import="i000004" exported="True">New Scene</name>
</item>
<item handle="0000000000028" parent="None" root="0000000000028" order="0" type="ROOT" class="NOVEL">
<item handle="0000000000020" parent="None" root="0000000000020" order="0" type="ROOT" class="NOVEL">
<meta expanded="False"/>
<name status="s000008" import="i00000c">Novel</name>
<name status="s000000" import="i000004">Novel</name>
</item>
<item handle="0000000000029" parent="None" root="0000000000029" order="0" type="ROOT" class="PLOT">
<item handle="0000000000021" parent="None" root="0000000000021" order="0" type="ROOT" class="PLOT">
<meta expanded="False"/>
<name status="s000008" import="i00000c">Plot</name>
<name status="s000000" import="i000004">Plot</name>
</item>
<item handle="000000000002a" parent="None" root="000000000002a" order="0" type="ROOT" class="CHARACTER">
<item handle="0000000000022" parent="None" root="0000000000022" order="0" type="ROOT" class="CHARACTER">
<meta expanded="False"/>
<name status="s000008" import="i00000c">Characters</name>
<name status="s000000" import="i000004">Characters</name>
</item>
<item handle="000000000002b" parent="None" root="000000000002b" order="0" type="ROOT" class="WORLD">
<item handle="0000000000023" parent="None" root="0000000000023" order="0" type="ROOT" class="WORLD">
<meta expanded="False"/>
<name status="s000008" import="i00000c">Locations</name>
<name status="s000000" import="i000004">Locations</name>
</item>
<item handle="000000000002c" parent="None" root="000000000002c" order="0" type="ROOT" class="TIMELINE">
<item handle="0000000000024" parent="None" root="0000000000024" order="0" type="ROOT" class="TIMELINE">
<meta expanded="False"/>
<name status="s000008" import="i00000c">Timeline</name>
<name status="s000000" import="i000004">Timeline</name>
</item>
<item handle="000000000002d" parent="None" root="000000000002d" order="0" type="ROOT" class="OBJECT">
<item handle="0000000000025" parent="None" root="0000000000025" order="0" type="ROOT" class="OBJECT">
<meta expanded="False"/>
<name status="s000008" import="i00000c">Objects</name>
<name status="s000000" import="i000004">Objects</name>
</item>
<item handle="000000000002e" parent="None" root="000000000002e" order="0" type="ROOT" class="CUSTOM">
<item handle="0000000000026" parent="None" root="0000000000026" order="0" type="ROOT" class="CUSTOM">
<meta expanded="False"/>
<name status="s000008" import="i00000c">Custom</name>
<name status="s000000" import="i000004">Custom</name>
</item>
<item handle="000000000002f" parent="None" root="000000000002f" order="0" type="ROOT" class="CUSTOM">
<item handle="0000000000027" parent="None" root="0000000000027" order="0" type="ROOT" class="CUSTOM">
<meta expanded="False"/>
<name status="s000008" import="i00000c">Custom</name>
<name status="s000000" import="i000004">Custom</name>
</item>
</content>
</novelWriterXML>
+67 -23
View File
@@ -26,7 +26,7 @@ from lxml import etree
from shutil import copyfile
from zipfile import ZipFile
from tools import cmpFiles, writeFile, readFile, buildTestProject, XML_IGNORE
from tools import cmpFiles, writeFile, readFile, buildTestProject, XML_IGNORE, C
from mock import causeOSError
from novelwriter.enum import nwItemClass, nwItemType, nwItemLayout
@@ -256,6 +256,7 @@ def testCoreProject_NewRoot(fncDir, outDir, refDir, mockGUI, mockRnd):
compFile = os.path.join(refDir, "coreProject_NewRoot_nwProject.nwx")
theProject = NWProject(mockGUI)
mockRnd.reset()
buildTestProject(theProject, fncDir)
assert theProject.setProjectPath(fncDir) is True
@@ -263,14 +264,14 @@ def testCoreProject_NewRoot(fncDir, outDir, refDir, mockGUI, mockRnd):
assert theProject.closeProject() is True
assert theProject.openProject(projFile) is True
assert isinstance(theProject.newRoot(nwItemClass.NOVEL), str)
assert isinstance(theProject.newRoot(nwItemClass.PLOT), str)
assert isinstance(theProject.newRoot(nwItemClass.CHARACTER), str)
assert isinstance(theProject.newRoot(nwItemClass.WORLD), str)
assert isinstance(theProject.newRoot(nwItemClass.TIMELINE), str)
assert isinstance(theProject.newRoot(nwItemClass.OBJECT), str)
assert isinstance(theProject.newRoot(nwItemClass.CUSTOM), str)
assert isinstance(theProject.newRoot(nwItemClass.CUSTOM), str)
assert theProject.newRoot(nwItemClass.NOVEL) == "0000000000020"
assert theProject.newRoot(nwItemClass.PLOT) == "0000000000021"
assert theProject.newRoot(nwItemClass.CHARACTER) == "0000000000022"
assert theProject.newRoot(nwItemClass.WORLD) == "0000000000023"
assert theProject.newRoot(nwItemClass.TIMELINE) == "0000000000024"
assert theProject.newRoot(nwItemClass.OBJECT) == "0000000000025"
assert theProject.newRoot(nwItemClass.CUSTOM) == "0000000000026"
assert theProject.newRoot(nwItemClass.CUSTOM) == "0000000000027"
assert theProject.projChanged is True
assert theProject.saveProject() is True
@@ -280,11 +281,30 @@ def testCoreProject_NewRoot(fncDir, outDir, refDir, mockGUI, mockRnd):
assert cmpFiles(testFile, compFile, ignoreStart=XML_IGNORE)
assert theProject.projChanged is False
# Delete the new items
assert theProject.removeItem("0000000000020") is True
assert theProject.removeItem("0000000000021") is True
assert theProject.removeItem("0000000000022") is True
assert theProject.removeItem("0000000000023") is True
assert theProject.removeItem("0000000000024") is True
assert theProject.removeItem("0000000000025") is True
assert theProject.removeItem("0000000000026") is True
assert theProject.removeItem("0000000000027") is True
assert "0000000000020" not in theProject.tree
assert "0000000000021" not in theProject.tree
assert "0000000000022" not in theProject.tree
assert "0000000000023" not in theProject.tree
assert "0000000000024" not in theProject.tree
assert "0000000000025" not in theProject.tree
assert "0000000000026" not in theProject.tree
assert "0000000000027" not in theProject.tree
# END Test testCoreProject_NewRoot
@pytest.mark.core
def testCoreProject_NewFileFolder(fncDir, outDir, refDir, mockGUI, mockRnd):
def testCoreProject_NewFileFolder(monkeypatch, fncDir, outDir, refDir, mockGUI, mockRnd):
"""Check that new files can be added to the project.
"""
projFile = os.path.join(fncDir, "nwProject.nwx")
@@ -292,6 +312,7 @@ def testCoreProject_NewFileFolder(fncDir, outDir, refDir, mockGUI, mockRnd):
compFile = os.path.join(refDir, "coreProject_NewFileFolder_nwProject.nwx")
theProject = NWProject(mockGUI)
mockRnd.reset()
buildTestProject(theProject, fncDir)
assert theProject.setProjectPath(fncDir) is True
@@ -304,35 +325,58 @@ def testCoreProject_NewFileFolder(fncDir, outDir, refDir, mockGUI, mockRnd):
assert theProject.newFile("New File", "1234567890abc") is None
# Add files properly
assert theProject.newFolder("Stuff", "0000000000015") == "0000000000028"
assert theProject.newFile("Hello", "0000000000015") == "0000000000029"
assert theProject.newFile("Jane", "0000000000012") == "000000000002a"
assert theProject.newFolder("Stuff", C.hNovelRoot) == "0000000000020"
assert theProject.newFile("Hello", "0000000000020") == "0000000000021"
assert theProject.newFile("Jane", C.hCharRoot) == "0000000000022"
assert "0000000000028" in theProject.tree
assert "0000000000029" in theProject.tree
assert "000000000002a" in theProject.tree
assert "0000000000020" in theProject.tree
assert "0000000000021" in theProject.tree
assert "0000000000022" in theProject.tree
# Write to file, failed
assert theProject.writeNewFile("blabla", 1, True) is False # Not a handle
assert theProject.writeNewFile("0000000000028", 1, True) is False # Not a file
assert theProject.writeNewFile("0000000000014", 1, True) is False # Already has content
assert theProject.writeNewFile("0000000000020", 1, True) is False # Not a file
assert theProject.writeNewFile(C.hTitlePage, 1, True) is False # Already has content
# Write to file, success
assert theProject.writeNewFile("0000000000029", 2, True) is True
assert NWDoc(theProject, "0000000000029").readDocument() == "## Hello\n\n"
assert theProject.writeNewFile("0000000000021", 2, True) is True
assert NWDoc(theProject, "0000000000021").readDocument() == "## Hello\n\n"
assert theProject.writeNewFile("000000000002a", 1, False) is True
assert NWDoc(theProject, "000000000002a").readDocument() == "# Jane\n\n"
# Write to file with additional text, success
assert theProject.writeNewFile("0000000000022", 1, False, "Hi Jane\n\n") is True
assert NWDoc(theProject, "0000000000022").readDocument() == "# Jane\n\nHi Jane\n\n"
# Save, close and check
assert theProject.projChanged is True
assert theProject.saveProject() is True
assert theProject.closeProject() is True
copyfile(projFile, testFile)
assert cmpFiles(testFile, compFile, ignoreStart=XML_IGNORE)
assert theProject.projChanged is False
# Delete new file, but block access
with monkeypatch.context() as mp:
mp.setattr("os.unlink", causeOSError)
assert theProject.removeItem("0000000000021") is False
assert "0000000000021" in theProject.tree
# Delete new files and folders
assert os.path.isfile(os.path.join(fncDir, "content", "0000000000022.nwd"))
assert os.path.isfile(os.path.join(fncDir, "content", "0000000000021.nwd"))
assert theProject.removeItem("0000000000022") is True
assert theProject.removeItem("0000000000021") is True
assert theProject.removeItem("0000000000020") is True
assert not os.path.isfile(os.path.join(fncDir, "content", "0000000000022.nwd"))
assert not os.path.isfile(os.path.join(fncDir, "content", "0000000000021.nwd"))
assert "0000000000020" not in theProject.tree
assert "0000000000021" not in theProject.tree
assert "0000000000022" not in theProject.tree
assert theProject.closeProject() is True
# END Test testCoreProject_NewFileFolder