Added test to convert older project to new format
This commit is contained in:
+2
-2
@@ -489,7 +489,7 @@ class NWProject():
|
||||
# parser will lose the autoReplace settings if allowed to
|
||||
# read the file. Introduced in version 0.10.
|
||||
|
||||
if fileVersion == "1.0":
|
||||
if fileVersion == "1.0" and self.mainConf.blockGUI:
|
||||
msgBox = QMessageBox()
|
||||
msgRes = msgBox.question(self.theParent, "Old Project Version", (
|
||||
"The project file and data is created by a novelWriter version "
|
||||
@@ -501,7 +501,7 @@ class NWProject():
|
||||
if msgRes != QMessageBox.Yes:
|
||||
return False
|
||||
|
||||
elif fileVersion != "1.1" and fileVersion != "1.2":
|
||||
elif fileVersion != "1.1" and fileVersion != "1.2" and self.mainConf.blockGUI:
|
||||
self.makeAlert((
|
||||
"Unknown or unsupported novelWriter project file format. "
|
||||
"The project cannot be opened by this version of novelWriter. "
|
||||
|
||||
@@ -118,3 +118,16 @@ def nwLipsum(nwTemp):
|
||||
if path.isdir(lipsumDir):
|
||||
shutil.rmtree(lipsumDir)
|
||||
return
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def nwOldProj(nwTemp):
|
||||
testDir = path.dirname(__file__)
|
||||
oldProjStore = path.join(testDir, "oldproj")
|
||||
oldProjDir = path.join(nwTemp, "oldproj")
|
||||
if path.isdir(oldProjDir):
|
||||
shutil.rmtree(oldProjDir)
|
||||
shutil.copytree(oldProjStore, oldProjDir)
|
||||
yield oldProjDir
|
||||
if path.isdir(oldProjDir):
|
||||
shutil.rmtree(oldProjDir)
|
||||
return
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
### Scene Four
|
||||
|
||||
Scene Four
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# Antagonist
|
||||
|
||||
Antagonist
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
### Scene Two
|
||||
|
||||
Scene Two
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# Protagonist
|
||||
|
||||
Protagonist
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
### Scene Three
|
||||
|
||||
Scene Three
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
### Scene Five
|
||||
|
||||
Scene Five
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
### Scene One
|
||||
|
||||
Scene One
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
Start: 2020-09-26 16:13:00 End: 2020-09-26 16:15:54 Words: 24
|
||||
Start: 2020-09-26 16:16:28 End: 2020-09-26 16:16:40 Words: -1
|
||||
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"tagIndex": {},
|
||||
"refIndex": {
|
||||
"f528d831f5b24": [],
|
||||
"88124a4292d8b": [],
|
||||
"91239bf2f8b69": [],
|
||||
"19752e7f9d8af": [],
|
||||
"a764d5acf5a21": [],
|
||||
"9058ae29f0dfd": [],
|
||||
"7ff63b8afc4cd": []
|
||||
},
|
||||
"novelIndex": {
|
||||
"f528d831f5b24": [
|
||||
[
|
||||
1,
|
||||
3,
|
||||
"Scene One",
|
||||
"SCENE"
|
||||
]
|
||||
],
|
||||
"88124a4292d8b": [
|
||||
[
|
||||
1,
|
||||
3,
|
||||
"Scene Two",
|
||||
"SCENE"
|
||||
]
|
||||
],
|
||||
"91239bf2f8b69": [
|
||||
[
|
||||
1,
|
||||
3,
|
||||
"Scene Three",
|
||||
"SCENE"
|
||||
]
|
||||
],
|
||||
"19752e7f9d8af": [
|
||||
[
|
||||
1,
|
||||
3,
|
||||
"Scene Four",
|
||||
"SCENE"
|
||||
]
|
||||
],
|
||||
"a764d5acf5a21": [
|
||||
[
|
||||
1,
|
||||
3,
|
||||
"Scene Five",
|
||||
"SCENE"
|
||||
]
|
||||
]
|
||||
},
|
||||
"noteIndex": {
|
||||
"9058ae29f0dfd": [
|
||||
[
|
||||
1,
|
||||
1,
|
||||
"Protagonist",
|
||||
"NOTE"
|
||||
]
|
||||
],
|
||||
"7ff63b8afc4cd": [
|
||||
[
|
||||
1,
|
||||
1,
|
||||
"Antagonist",
|
||||
"NOTE"
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<novelWriterXML appVersion="0.4.5" fileVersion="1.0" timeStamp="2020-09-26 16:16:39">
|
||||
<project>
|
||||
<name></name>
|
||||
<title></title>
|
||||
<backup>True</backup>
|
||||
</project>
|
||||
<settings>
|
||||
<spellCheck>False</spellCheck>
|
||||
<lastEdited>a764d5acf5a21</lastEdited>
|
||||
<lastViewed>None</lastViewed>
|
||||
<lastWordCount>23</lastWordCount>
|
||||
<autoReplace/>
|
||||
<status>
|
||||
<entry blue="100" green="100" red="100">New</entry>
|
||||
<entry blue="0" green="50" red="200">Note</entry>
|
||||
<entry blue="0" green="150" red="200">Draft</entry>
|
||||
<entry blue="0" green="200" red="50">Finished</entry>
|
||||
</status>
|
||||
<importance>
|
||||
<entry blue="100" green="100" red="100">New</entry>
|
||||
<entry blue="0" green="50" red="200">Minor</entry>
|
||||
<entry blue="0" green="150" red="200">Major</entry>
|
||||
<entry blue="0" green="200" red="50">Main</entry>
|
||||
</importance>
|
||||
</settings>
|
||||
<content count="12">
|
||||
<item handle="095c337ad50c8" order="0" parent="None">
|
||||
<name>Novel</name>
|
||||
<type>ROOT</type>
|
||||
<class>NOVEL</class>
|
||||
<status>New</status>
|
||||
<expanded>True</expanded>
|
||||
</item>
|
||||
<item handle="04d47c4b31af7" order="0" parent="095c337ad50c8">
|
||||
<name>Chapter One</name>
|
||||
<type>FOLDER</type>
|
||||
<class>NOVEL</class>
|
||||
<status>New</status>
|
||||
<expanded>True</expanded>
|
||||
</item>
|
||||
<item handle="f528d831f5b24" order="0" parent="04d47c4b31af7">
|
||||
<name>Scene One</name>
|
||||
<type>FILE</type>
|
||||
<class>NOVEL</class>
|
||||
<status>New</status>
|
||||
<expanded>False</expanded>
|
||||
<layout>SCENE</layout>
|
||||
<charCount>18</charCount>
|
||||
<wordCount>4</wordCount>
|
||||
<paraCount>1</paraCount>
|
||||
<cursorPos>3</cursorPos>
|
||||
</item>
|
||||
<item handle="88124a4292d8b" order="1" parent="04d47c4b31af7">
|
||||
<name>Scene Two</name>
|
||||
<type>FILE</type>
|
||||
<class>NOVEL</class>
|
||||
<status>New</status>
|
||||
<expanded>False</expanded>
|
||||
<layout>SCENE</layout>
|
||||
<charCount>18</charCount>
|
||||
<wordCount>4</wordCount>
|
||||
<paraCount>1</paraCount>
|
||||
<cursorPos>2</cursorPos>
|
||||
</item>
|
||||
<item handle="91239bf2f8b69" order="2" parent="04d47c4b31af7">
|
||||
<name>Scene Three</name>
|
||||
<type>FILE</type>
|
||||
<class>NOVEL</class>
|
||||
<status>New</status>
|
||||
<expanded>False</expanded>
|
||||
<layout>SCENE</layout>
|
||||
<charCount>22</charCount>
|
||||
<wordCount>4</wordCount>
|
||||
<paraCount>1</paraCount>
|
||||
<cursorPos>2</cursorPos>
|
||||
</item>
|
||||
<item handle="19752e7f9d8af" order="3" parent="04d47c4b31af7">
|
||||
<name>Scene Four</name>
|
||||
<type>FILE</type>
|
||||
<class>NOVEL</class>
|
||||
<status>New</status>
|
||||
<expanded>False</expanded>
|
||||
<layout>SCENE</layout>
|
||||
<charCount>20</charCount>
|
||||
<wordCount>4</wordCount>
|
||||
<paraCount>1</paraCount>
|
||||
<cursorPos>2</cursorPos>
|
||||
</item>
|
||||
<item handle="a764d5acf5a21" order="4" parent="04d47c4b31af7">
|
||||
<name>Scene Five</name>
|
||||
<type>FILE</type>
|
||||
<class>NOVEL</class>
|
||||
<status>New</status>
|
||||
<expanded>False</expanded>
|
||||
<layout>SCENE</layout>
|
||||
<charCount>20</charCount>
|
||||
<wordCount>4</wordCount>
|
||||
<paraCount>1</paraCount>
|
||||
<cursorPos>2</cursorPos>
|
||||
</item>
|
||||
<item handle="a11282c943444" order="1" parent="None">
|
||||
<name>Characters</name>
|
||||
<type>ROOT</type>
|
||||
<class>CHARACTER</class>
|
||||
<status>New</status>
|
||||
<expanded>True</expanded>
|
||||
</item>
|
||||
<item handle="9058ae29f0dfd" order="0" parent="a11282c943444">
|
||||
<name>Protagonist</name>
|
||||
<type>FILE</type>
|
||||
<class>CHARACTER</class>
|
||||
<status>New</status>
|
||||
<expanded>False</expanded>
|
||||
<layout>NOTE</layout>
|
||||
<charCount>11</charCount>
|
||||
<wordCount>1</wordCount>
|
||||
<paraCount>0</paraCount>
|
||||
<cursorPos>28</cursorPos>
|
||||
</item>
|
||||
<item handle="7ff63b8afc4cd" order="1" parent="a11282c943444">
|
||||
<name>Antagonist</name>
|
||||
<type>FILE</type>
|
||||
<class>CHARACTER</class>
|
||||
<status>New</status>
|
||||
<expanded>False</expanded>
|
||||
<layout>NOTE</layout>
|
||||
<charCount>13</charCount>
|
||||
<wordCount>2</wordCount>
|
||||
<paraCount>1</paraCount>
|
||||
<cursorPos>26</cursorPos>
|
||||
</item>
|
||||
<item handle="dabb9d158b2b2" order="2" parent="None">
|
||||
<name>Plot</name>
|
||||
<type>ROOT</type>
|
||||
<class>PLOT</class>
|
||||
<status>New</status>
|
||||
<expanded>False</expanded>
|
||||
</item>
|
||||
<item handle="4a817a3a84b42" order="3" parent="None">
|
||||
<name>World</name>
|
||||
<type>ROOT</type>
|
||||
<class>WORLD</class>
|
||||
<status>New</status>
|
||||
<expanded>False</expanded>
|
||||
</item>
|
||||
</content>
|
||||
</novelWriterXML>
|
||||
+85
-1
@@ -3,7 +3,7 @@
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from os import path
|
||||
from os import path, mkdir
|
||||
from shutil import copyfile
|
||||
|
||||
from nwtools import cmpFiles
|
||||
@@ -577,3 +577,87 @@ def testOrphanedFiles(nwDummy, nwLipsum):
|
||||
|
||||
assert theProject.saveProject(nwLipsum)
|
||||
assert theProject.closeProject()
|
||||
|
||||
@pytest.mark.project
|
||||
def testOldProject(nwDummy, nwOldProj):
|
||||
theProject = NWProject(nwDummy)
|
||||
theProject.mainConf.blockGUI = False
|
||||
|
||||
# Create dummy files for known legacy files
|
||||
deleteFiles = [
|
||||
path.join(nwOldProj, "cache", "nwProject.nwx.0"),
|
||||
path.join(nwOldProj, "cache", "nwProject.nwx.1"),
|
||||
path.join(nwOldProj, "cache", "nwProject.nwx.2"),
|
||||
path.join(nwOldProj, "cache", "nwProject.nwx.3"),
|
||||
path.join(nwOldProj, "cache", "nwProject.nwx.4"),
|
||||
path.join(nwOldProj, "cache", "nwProject.nwx.5"),
|
||||
path.join(nwOldProj, "cache", "nwProject.nwx.6"),
|
||||
path.join(nwOldProj, "cache", "nwProject.nwx.7"),
|
||||
path.join(nwOldProj, "cache", "nwProject.nwx.8"),
|
||||
path.join(nwOldProj, "cache", "nwProject.nwx.9"),
|
||||
path.join(nwOldProj, "meta", "mainOptions.json"),
|
||||
path.join(nwOldProj, "meta", "exportOptions.json"),
|
||||
path.join(nwOldProj, "meta", "outlineOptions.json"),
|
||||
path.join(nwOldProj, "meta", "timelineOptions.json"),
|
||||
path.join(nwOldProj, "meta", "docMergeOptions.json"),
|
||||
path.join(nwOldProj, "meta", "sessionLogOptions.json"),
|
||||
]
|
||||
|
||||
# Add some files that shouldn't be there
|
||||
deleteFiles.append(path.join(nwOldProj, "data_f", "whatnow.nwd"))
|
||||
deleteFiles.append(path.join(nwOldProj, "data_f", "whatnow.txt"))
|
||||
|
||||
# Add some folders that shouldn't be there
|
||||
mkdir(path.join(nwOldProj, "stuff"))
|
||||
mkdir(path.join(nwOldProj, "data_1", "stuff"))
|
||||
|
||||
for aFile in deleteFiles:
|
||||
with open(aFile, mode="w+", encoding="utf8") as outFile:
|
||||
outFile.write("Hi")
|
||||
for aFile in deleteFiles:
|
||||
assert path.isfile(aFile)
|
||||
|
||||
# Open project and check that files that are not supposed to be
|
||||
# there have been removed
|
||||
assert theProject.openProject(nwOldProj)
|
||||
for aFile in deleteFiles:
|
||||
assert not path.isfile(aFile)
|
||||
|
||||
assert not path.isdir(path.join(nwOldProj, "data_1", "stuff"))
|
||||
assert not path.isdir(path.join(nwOldProj, "data_1"))
|
||||
assert not path.isdir(path.join(nwOldProj, "data_7"))
|
||||
assert not path.isdir(path.join(nwOldProj, "data_8"))
|
||||
assert not path.isdir(path.join(nwOldProj, "data_9"))
|
||||
assert not path.isdir(path.join(nwOldProj, "data_a"))
|
||||
assert not path.isdir(path.join(nwOldProj, "data_f"))
|
||||
|
||||
# Check stuff that has been moved
|
||||
assert path.isdir(path.join(nwOldProj, "junk"))
|
||||
assert path.isdir(path.join(nwOldProj, "junk", "stuff"))
|
||||
assert path.isfile(path.join(nwOldProj, "junk", "whatnow.nwd"))
|
||||
assert path.isfile(path.join(nwOldProj, "junk", "whatnow.txt"))
|
||||
|
||||
# Check that files we want to keep are in the right place
|
||||
assert path.isdir(path.join(nwOldProj, "cache"))
|
||||
assert path.isdir(path.join(nwOldProj, "content"))
|
||||
assert path.isdir(path.join(nwOldProj, "meta"))
|
||||
|
||||
assert path.isfile(path.join(nwOldProj, "content", "f528d831f5b24.nwd"))
|
||||
assert path.isfile(path.join(nwOldProj, "content", "88124a4292d8b.nwd"))
|
||||
assert path.isfile(path.join(nwOldProj, "content", "91239bf2f8b69.nwd"))
|
||||
assert path.isfile(path.join(nwOldProj, "content", "19752e7f9d8af.nwd"))
|
||||
assert path.isfile(path.join(nwOldProj, "content", "a764d5acf5a21.nwd"))
|
||||
assert path.isfile(path.join(nwOldProj, "content", "9058ae29f0dfd.nwd"))
|
||||
assert path.isfile(path.join(nwOldProj, "content", "7ff63b8afc4cd.nwd"))
|
||||
|
||||
assert path.isfile(path.join(nwOldProj, "meta", "tagsIndex.json"))
|
||||
assert path.isfile(path.join(nwOldProj, "meta", "sessionInfo.log"))
|
||||
|
||||
# Close the project
|
||||
theProject.closeProject()
|
||||
|
||||
# Check that new files have been created
|
||||
assert path.isfile(path.join(nwOldProj, "meta", "guiOptions.json"))
|
||||
assert path.isfile(path.join(nwOldProj, "meta", "sessionStats.log"))
|
||||
assert path.isfile(path.join(nwOldProj, "ToC.json"))
|
||||
assert path.isfile(path.join(nwOldProj, "ToC.txt"))
|
||||
|
||||
Reference in New Issue
Block a user