Move new project tool to core tools (resolves #1152)
This commit is contained in:
+2
-2
@@ -1,12 +1,12 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<novelWriterXML appVersion="2.0-rc1" hexVersion="0x020000c1" fileVersion="1.4" timeStamp="2022-11-01 11:53:22">
|
||||
<novelWriterXML appVersion="2.0-rc1" hexVersion="0x020000c1" fileVersion="1.4" timeStamp="2022-11-03 23:38:30">
|
||||
<project>
|
||||
<name>Test Custom</name>
|
||||
<title>Test Novel</title>
|
||||
<author>Jane Doe</author>
|
||||
<author>John Doh</author>
|
||||
<saveCount>1</saveCount>
|
||||
<autoCount>1</autoCount>
|
||||
<autoCount>0</autoCount>
|
||||
<editTime>0</editTime>
|
||||
</project>
|
||||
<settings>
|
||||
+2
-2
@@ -1,12 +1,12 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<novelWriterXML appVersion="2.0-rc1" hexVersion="0x020000c1" fileVersion="1.4" timeStamp="2022-11-01 11:53:22">
|
||||
<novelWriterXML appVersion="2.0-rc1" hexVersion="0x020000c1" fileVersion="1.4" timeStamp="2022-11-03 23:37:43">
|
||||
<project>
|
||||
<name>Test Custom</name>
|
||||
<title>Test Novel</title>
|
||||
<author>Jane Doe</author>
|
||||
<author>John Doh</author>
|
||||
<saveCount>1</saveCount>
|
||||
<autoCount>1</autoCount>
|
||||
<autoCount>0</autoCount>
|
||||
<editTime>0</editTime>
|
||||
</project>
|
||||
<settings>
|
||||
+4
-4
@@ -1,10 +1,10 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<novelWriterXML appVersion="2.0-rc1" hexVersion="0x020000c1" fileVersion="1.4" timeStamp="2022-11-01 11:53:22">
|
||||
<novelWriterXML appVersion="2.0-rc1" hexVersion="0x020000c1" fileVersion="1.4" timeStamp="2022-11-03 23:33:20">
|
||||
<project>
|
||||
<name>New Project</name>
|
||||
<title>None</title>
|
||||
<saveCount>2</saveCount>
|
||||
<autoCount>1</autoCount>
|
||||
<title>New Project</title>
|
||||
<saveCount>1</saveCount>
|
||||
<autoCount>0</autoCount>
|
||||
<editTime>0</editTime>
|
||||
</project>
|
||||
<settings>
|
||||
@@ -23,13 +23,15 @@ import os
|
||||
import pytest
|
||||
|
||||
from shutil import copyfile
|
||||
from zipfile import ZipFile
|
||||
|
||||
from mock import causeOSError
|
||||
from tools import C, buildTestProject, cmpFiles
|
||||
from tools import C, buildTestProject, cmpFiles, XML_IGNORE
|
||||
|
||||
from novelwriter.constants import nwItemClass
|
||||
from novelwriter.core.project import NWProject
|
||||
from novelwriter.core.document import NWDoc
|
||||
from novelwriter.core.coretools import DocMerger, DocSplitter
|
||||
from novelwriter.core.coretools import DocMerger, DocSplitter, ProjectBuilder
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
@@ -259,3 +261,153 @@ def testCoreTools_DocSplitter(monkeypatch, mockGUI, fncDir, outDir, refDir, mock
|
||||
theProject.saveProject()
|
||||
|
||||
# END Test testCoreTools_DocSplitter
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreTools_NewMinimal(fncDir, outDir, refDir, mockGUI, mockRnd):
|
||||
"""Create a new project from a project wizard dictionary. With
|
||||
default setting, creating a Minimal project.
|
||||
"""
|
||||
projFile = os.path.join(fncDir, "nwProject.nwx")
|
||||
testFile = os.path.join(outDir, "coreTools_NewMinimal_nwProject.nwx")
|
||||
compFile = os.path.join(refDir, "coreTools_NewMinimal_nwProject.nwx")
|
||||
|
||||
projBuild = ProjectBuilder(mockGUI)
|
||||
|
||||
# Setting no data should fail
|
||||
assert projBuild.buildProject({}) is False
|
||||
|
||||
# Wrong type should also fail
|
||||
assert projBuild.buildProject("stuff") is False
|
||||
|
||||
# Try again with a proper path
|
||||
assert projBuild.buildProject({"projPath": fncDir}) is True
|
||||
|
||||
# Creating the project once more should fail
|
||||
assert projBuild.buildProject({"projPath": fncDir}) is False
|
||||
|
||||
# Save and close
|
||||
copyfile(projFile, testFile)
|
||||
assert cmpFiles(testFile, compFile, ignoreStart=XML_IGNORE)
|
||||
|
||||
# END Test testCoreTools_NewMinimal
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreTools_NewCustomA(fncDir, outDir, refDir, mockGUI, mockRnd):
|
||||
"""Create a new project from a project wizard dictionary.
|
||||
Custom type with chapters and scenes.
|
||||
"""
|
||||
projFile = os.path.join(fncDir, "nwProject.nwx")
|
||||
testFile = os.path.join(outDir, "coreTools_NewCustomA_nwProject.nwx")
|
||||
compFile = os.path.join(refDir, "coreTools_NewCustomA_nwProject.nwx")
|
||||
|
||||
projData = {
|
||||
"projName": "Test Custom",
|
||||
"projTitle": "Test Novel",
|
||||
"projAuthors": "Jane Doe\nJohn Doh\n",
|
||||
"projPath": fncDir,
|
||||
"popSample": False,
|
||||
"popMinimal": False,
|
||||
"popCustom": True,
|
||||
"addRoots": [
|
||||
nwItemClass.PLOT,
|
||||
nwItemClass.CHARACTER,
|
||||
nwItemClass.WORLD,
|
||||
],
|
||||
"addNotes": True,
|
||||
"numChapters": 3,
|
||||
"numScenes": 3,
|
||||
}
|
||||
|
||||
projBuild = ProjectBuilder(mockGUI)
|
||||
assert projBuild.buildProject(projData) is True
|
||||
|
||||
copyfile(projFile, testFile)
|
||||
assert cmpFiles(testFile, compFile, ignoreStart=XML_IGNORE)
|
||||
|
||||
# END Test testCoreTools_NewCustomA
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreTools_NewCustomB(fncDir, outDir, refDir, mockGUI, mockRnd):
|
||||
"""Create a new project from a project wizard dictionary.
|
||||
Custom type without chapters, but with scenes.
|
||||
"""
|
||||
projFile = os.path.join(fncDir, "nwProject.nwx")
|
||||
testFile = os.path.join(outDir, "coreTools_NewCustomB_nwProject.nwx")
|
||||
compFile = os.path.join(refDir, "coreTools_NewCustomB_nwProject.nwx")
|
||||
|
||||
projData = {
|
||||
"projName": "Test Custom",
|
||||
"projTitle": "Test Novel",
|
||||
"projAuthors": "Jane Doe\nJohn Doh\n",
|
||||
"projPath": fncDir,
|
||||
"popSample": False,
|
||||
"popMinimal": False,
|
||||
"popCustom": True,
|
||||
"addRoots": [
|
||||
nwItemClass.PLOT,
|
||||
nwItemClass.CHARACTER,
|
||||
nwItemClass.WORLD,
|
||||
],
|
||||
"addNotes": True,
|
||||
"numChapters": 0,
|
||||
"numScenes": 6,
|
||||
}
|
||||
|
||||
projBuild = ProjectBuilder(mockGUI)
|
||||
assert projBuild.buildProject(projData) is True
|
||||
|
||||
copyfile(projFile, testFile)
|
||||
assert cmpFiles(testFile, compFile, ignoreStart=XML_IGNORE)
|
||||
|
||||
# END Test testCoreTools_NewCustomB
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreTools_NewSample(fncDir, tmpConf, mockGUI, tmpDir):
|
||||
"""Check that we can create a new project can be created from the
|
||||
provided sample project via a zip file.
|
||||
"""
|
||||
projData = {
|
||||
"projName": "Test Sample",
|
||||
"projTitle": "Test Novel",
|
||||
"projAuthors": "Jane Doe\nJohn Doh\n",
|
||||
"projPath": fncDir,
|
||||
"popSample": True,
|
||||
"popMinimal": False,
|
||||
"popCustom": False,
|
||||
}
|
||||
|
||||
projBuild = ProjectBuilder(mockGUI)
|
||||
|
||||
# No path set
|
||||
assert projBuild.buildProject({"popSample": True}) is False
|
||||
|
||||
# Force the lookup path for assets to our temp folder
|
||||
srcSample = os.path.abspath(os.path.join(tmpConf.appRoot, "sample"))
|
||||
dstSample = os.path.join(tmpDir, "sample.zip")
|
||||
tmpConf.assetPath = tmpDir
|
||||
|
||||
# Cannot extract when the zip does not exist
|
||||
assert projBuild.buildProject(projData) is False
|
||||
|
||||
# Create and open a defective zip file
|
||||
with open(dstSample, mode="w+") as outFile:
|
||||
outFile.write("foo")
|
||||
|
||||
assert projBuild.buildProject(projData) is False
|
||||
os.unlink(dstSample)
|
||||
|
||||
# Create a real zip file, and unpack it
|
||||
with ZipFile(dstSample, "w") as zipObj:
|
||||
zipObj.write(os.path.join(srcSample, "nwProject.nwx"), "nwProject.nwx")
|
||||
for docFile in os.listdir(os.path.join(srcSample, "content")):
|
||||
srcDoc = os.path.join(srcSample, "content", docFile)
|
||||
zipObj.write(srcDoc, "content/"+docFile)
|
||||
|
||||
assert projBuild.buildProject(projData) is True
|
||||
os.unlink(dstSample)
|
||||
|
||||
# END Test testCoreTools_NewSample
|
||||
|
||||
@@ -27,7 +27,7 @@ from shutil import copyfile
|
||||
from zipfile import ZipFile
|
||||
|
||||
from mock import causeOSError
|
||||
from tools import cmpFiles, writeFile, readFile, buildTestProject, XML_IGNORE, C
|
||||
from tools import C, cmpFiles, writeFile, readFile, buildTestProject, XML_IGNORE
|
||||
|
||||
from novelwriter.enum import nwItemClass, nwItemType, nwItemLayout
|
||||
from novelwriter.common import formatTimeStamp
|
||||
@@ -40,214 +40,6 @@ from novelwriter.core.document import NWDoc
|
||||
from novelwriter.core.projectxml import ProjectXMLReader, ProjectXMLWriter, XMLReadState
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreProject_NewMinimal(fncDir, outDir, refDir, mockGUI, mockRnd):
|
||||
"""Create a new project from a project wizard dictionary. With
|
||||
default setting, creating a Minimal project.
|
||||
"""
|
||||
projFile = os.path.join(fncDir, "nwProject.nwx")
|
||||
testFile = os.path.join(outDir, "coreProject_NewMinimal_nwProject.nwx")
|
||||
compFile = os.path.join(refDir, "coreProject_NewMinimal_nwProject.nwx")
|
||||
|
||||
theProject = NWProject(mockGUI)
|
||||
|
||||
# Setting no data should fail
|
||||
assert theProject.newProject({}) is False
|
||||
|
||||
# Wrong type should also fail
|
||||
assert theProject.newProject("stuff") is False
|
||||
|
||||
# Try again with a proper path
|
||||
assert theProject.newProject({"projPath": fncDir}) is True
|
||||
assert theProject.saveProject() is True
|
||||
assert theProject.closeProject() is True
|
||||
|
||||
# Creating the project once more should fail
|
||||
assert theProject.newProject({"projPath": fncDir}) is False
|
||||
|
||||
# Open again
|
||||
assert theProject.openProject(projFile) is True
|
||||
|
||||
# Save and close
|
||||
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
|
||||
|
||||
# Open a second time
|
||||
assert theProject.openProject(projFile) is True
|
||||
assert theProject.openProject(projFile) is False
|
||||
assert theProject.openProject(projFile, overrideLock=True) is True
|
||||
assert theProject.saveProject() is True
|
||||
assert theProject.closeProject() is True
|
||||
copyfile(projFile, testFile)
|
||||
assert cmpFiles(testFile, compFile, ignoreStart=XML_IGNORE)
|
||||
|
||||
# END Test testCoreProject_NewMinimal
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreProject_NewCustomA(fncDir, outDir, refDir, mockGUI, mockRnd):
|
||||
"""Create a new project from a project wizard dictionary.
|
||||
Custom type with chapters and scenes.
|
||||
"""
|
||||
projFile = os.path.join(fncDir, "nwProject.nwx")
|
||||
testFile = os.path.join(outDir, "coreProject_NewCustomA_nwProject.nwx")
|
||||
compFile = os.path.join(refDir, "coreProject_NewCustomA_nwProject.nwx")
|
||||
|
||||
projData = {
|
||||
"projName": "Test Custom",
|
||||
"projTitle": "Test Novel",
|
||||
"projAuthors": "Jane Doe\nJohn Doh\n",
|
||||
"projPath": fncDir,
|
||||
"popSample": False,
|
||||
"popMinimal": False,
|
||||
"popCustom": True,
|
||||
"addRoots": [
|
||||
nwItemClass.PLOT,
|
||||
nwItemClass.CHARACTER,
|
||||
nwItemClass.WORLD,
|
||||
],
|
||||
"addNotes": True,
|
||||
"numChapters": 3,
|
||||
"numScenes": 3,
|
||||
}
|
||||
theProject = NWProject(mockGUI)
|
||||
|
||||
assert theProject.newProject(projData) is True
|
||||
assert theProject.saveProject() is True
|
||||
assert theProject.closeProject() is True
|
||||
|
||||
copyfile(projFile, testFile)
|
||||
assert cmpFiles(testFile, compFile, ignoreStart=XML_IGNORE)
|
||||
|
||||
# END Test testCoreProject_NewCustomA
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreProject_NewCustomB(fncDir, outDir, refDir, mockGUI, mockRnd):
|
||||
"""Create a new project from a project wizard dictionary.
|
||||
Custom type without chapters, but with scenes.
|
||||
"""
|
||||
projFile = os.path.join(fncDir, "nwProject.nwx")
|
||||
testFile = os.path.join(outDir, "coreProject_NewCustomB_nwProject.nwx")
|
||||
compFile = os.path.join(refDir, "coreProject_NewCustomB_nwProject.nwx")
|
||||
|
||||
projData = {
|
||||
"projName": "Test Custom",
|
||||
"projTitle": "Test Novel",
|
||||
"projAuthors": "Jane Doe\nJohn Doh\n",
|
||||
"projPath": fncDir,
|
||||
"popSample": False,
|
||||
"popMinimal": False,
|
||||
"popCustom": True,
|
||||
"addRoots": [
|
||||
nwItemClass.PLOT,
|
||||
nwItemClass.CHARACTER,
|
||||
nwItemClass.WORLD,
|
||||
],
|
||||
"addNotes": True,
|
||||
"numChapters": 0,
|
||||
"numScenes": 6,
|
||||
}
|
||||
theProject = NWProject(mockGUI)
|
||||
|
||||
assert theProject.newProject(projData) is True
|
||||
assert theProject.saveProject() is True
|
||||
assert theProject.closeProject() is True
|
||||
|
||||
copyfile(projFile, testFile)
|
||||
assert cmpFiles(testFile, compFile, ignoreStart=XML_IGNORE)
|
||||
|
||||
# END Test testCoreProject_NewCustomB
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreProject_NewSampleA(fncDir, tmpConf, mockGUI, tmpDir):
|
||||
"""Check that we can create a new project can be created from the
|
||||
provided sample project via a zip file.
|
||||
"""
|
||||
projData = {
|
||||
"projName": "Test Sample",
|
||||
"projTitle": "Test Novel",
|
||||
"projAuthors": "Jane Doe\nJohn Doh\n",
|
||||
"projPath": fncDir,
|
||||
"popSample": True,
|
||||
"popMinimal": False,
|
||||
"popCustom": False,
|
||||
}
|
||||
theProject = NWProject(mockGUI)
|
||||
|
||||
# Sample set, but no path
|
||||
assert not theProject.newProject({"popSample": True})
|
||||
|
||||
# Force the lookup path for assets to our temp folder
|
||||
srcSample = os.path.abspath(os.path.join(tmpConf.appRoot, "sample"))
|
||||
dstSample = os.path.join(tmpDir, "sample.zip")
|
||||
tmpConf.assetPath = tmpDir
|
||||
|
||||
# Create and open a defective zip file
|
||||
with open(dstSample, mode="w+") as outFile:
|
||||
outFile.write("foo")
|
||||
|
||||
assert not theProject.newProject(projData)
|
||||
os.unlink(dstSample)
|
||||
|
||||
# Create a real zip file, and unpack it
|
||||
with ZipFile(dstSample, "w") as zipObj:
|
||||
zipObj.write(os.path.join(srcSample, "nwProject.nwx"), "nwProject.nwx")
|
||||
for docFile in os.listdir(os.path.join(srcSample, "content")):
|
||||
srcDoc = os.path.join(srcSample, "content", docFile)
|
||||
zipObj.write(srcDoc, "content/"+docFile)
|
||||
|
||||
assert theProject.newProject(projData) is True
|
||||
assert theProject.openProject(fncDir) is True
|
||||
assert theProject.data.name == "Sample Project"
|
||||
assert theProject.saveProject() is True
|
||||
assert theProject.closeProject() is True
|
||||
os.unlink(dstSample)
|
||||
|
||||
# END Test testCoreProject_NewSampleA
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreProject_NewSampleB(monkeypatch, fncDir, tmpConf, mockGUI, tmpDir):
|
||||
"""Check that we can create a new project can be created from the
|
||||
provided sample project folder.
|
||||
"""
|
||||
projData = {
|
||||
"projName": "Test Sample",
|
||||
"projTitle": "Test Novel",
|
||||
"projAuthors": "Jane Doe\nJohn Doh\n",
|
||||
"projPath": fncDir,
|
||||
"popSample": True,
|
||||
"popMinimal": False,
|
||||
"popCustom": False,
|
||||
}
|
||||
theProject = NWProject(mockGUI)
|
||||
|
||||
# Make sure we do not pick up the novelwriter/assets/sample.zip file
|
||||
tmpConf.assetPath = tmpDir
|
||||
|
||||
# Set a fake project file name
|
||||
monkeypatch.setattr(nwFiles, "PROJ_FILE", "nothing.nwx")
|
||||
assert not theProject.newProject(projData)
|
||||
|
||||
monkeypatch.setattr(nwFiles, "PROJ_FILE", "nwProject.nwx")
|
||||
assert theProject.newProject(projData) is True
|
||||
assert theProject.openProject(fncDir) is True
|
||||
assert theProject.data.name == "Sample Project"
|
||||
assert theProject.saveProject() is True
|
||||
assert theProject.closeProject() is True
|
||||
|
||||
# Misdirect the appRoot path so neither is possible
|
||||
tmpConf.appRoot = tmpDir
|
||||
assert not theProject.newProject(projData)
|
||||
|
||||
# END Test testCoreProject_NewSampleB
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreProject_NewRoot(fncDir, outDir, refDir, mockGUI, mockRnd):
|
||||
"""Check that new root folders can be added to the project.
|
||||
|
||||
+1
-9
@@ -168,15 +168,7 @@ def buildTestProject(theObject, projPath):
|
||||
theProject.clearProject()
|
||||
theProject.setProjectPath(projPath, newProject=True)
|
||||
theProject.storage.openProjectInPlace(theProject.projPath)
|
||||
|
||||
theProject.data.itemStatus.write(None, "New", (100, 100, 100))
|
||||
theProject.data.itemStatus.write(None, "Note", (200, 50, 0))
|
||||
theProject.data.itemStatus.write(None, "Draft", (200, 150, 0))
|
||||
theProject.data.itemStatus.write(None, "Finished", (50, 200, 0))
|
||||
theProject.data.itemImport.write(None, "New", (100, 100, 100))
|
||||
theProject.data.itemImport.write(None, "Minor", (200, 50, 0))
|
||||
theProject.data.itemImport.write(None, "Major", (200, 150, 0))
|
||||
theProject.data.itemImport.write(None, "Main", (50, 200, 0))
|
||||
theProject.setDefaultStatusImport()
|
||||
|
||||
theProject.data.setName("New Project")
|
||||
theProject.data.setTitle("New Novel")
|
||||
|
||||
Reference in New Issue
Block a user