Add test coverage of the project xml class
This commit is contained in:
@@ -0,0 +1,798 @@
|
||||
"""
|
||||
novelWriter – ProjectXMLReader/Writer Class Tester
|
||||
==================================================
|
||||
|
||||
This file is a part of novelWriter
|
||||
Copyright 2018–2022, Veronica Berglyd Olsen
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import pytest
|
||||
import shutil
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from mock import causeOSError
|
||||
from tools import cmpFiles, writeFile
|
||||
|
||||
from novelwriter.core.item import NWItem
|
||||
from novelwriter.core.project import NWProjectData
|
||||
from novelwriter.core.projectxml import ProjectXMLReader, ProjectXMLWriter, XMLReadState
|
||||
|
||||
|
||||
class MockProject:
|
||||
def setProjectChanged(self, *a):
|
||||
pass
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreProjectXML_ReadCurrent(monkeypatch, filesDir, fncDir, outDir, refDir):
|
||||
"""Test reading the current XML file format.
|
||||
"""
|
||||
refFile = os.path.join(filesDir, "nwProject-1.4.nwx")
|
||||
xmlFile = os.path.join(fncDir, "nwProject-1.4.nwx")
|
||||
bakFile = os.path.join(fncDir, "nwProject-1.4.bak")
|
||||
outFile = os.path.join(fncDir, "nwProject.nwx")
|
||||
|
||||
xmlReader = ProjectXMLReader(xmlFile)
|
||||
assert xmlReader.state == XMLReadState.NO_ACTION
|
||||
|
||||
data = NWProjectData(MockProject())
|
||||
content = []
|
||||
|
||||
# With no valid files, the read should fail
|
||||
writeFile(xmlFile, "")
|
||||
assert xmlReader.read(data, content) is False
|
||||
assert xmlReader.state == XMLReadState.CANNOT_PARSE
|
||||
|
||||
# Also add an invalid backup file
|
||||
writeFile(bakFile, "")
|
||||
assert xmlReader.read(data, content) is False
|
||||
assert xmlReader.state == XMLReadState.CANNOT_PARSE
|
||||
|
||||
# Add a valid backup file, that is not novelWriter
|
||||
writeFile(bakFile, "<xml/>")
|
||||
assert xmlReader.read(data, content) is False
|
||||
assert xmlReader.state == XMLReadState.NOT_NWX_FILE
|
||||
|
||||
# Add a valid project file, that is not novelWriter
|
||||
writeFile(xmlFile, "<xml/>")
|
||||
assert xmlReader.read(data, content) is False
|
||||
assert xmlReader.state == XMLReadState.NOT_NWX_FILE
|
||||
|
||||
# Add a valid novelwriter file without a file version
|
||||
writeFile(xmlFile, "<novelWriterXML/>")
|
||||
assert xmlReader.read(data, content) is False
|
||||
assert xmlReader.state == XMLReadState.UNKNOWN_VERSION
|
||||
|
||||
# Check parsing of unkown sections
|
||||
writeFile(xmlFile, (
|
||||
"<novelWriterXML fileVersion='1.4'>"
|
||||
" <project>"
|
||||
" <stuff></stuff>"
|
||||
" </project>"
|
||||
" <settings>"
|
||||
" <stuff></stuff>"
|
||||
" </settings>"
|
||||
" <content>"
|
||||
" <item>"
|
||||
" <stuff></stuff>"
|
||||
" </item>"
|
||||
" <stuff></stuff>"
|
||||
" </content>"
|
||||
" <stuff></stuff>"
|
||||
"</novelWriterXML>"
|
||||
))
|
||||
assert xmlReader.read(data, content) is True
|
||||
assert xmlReader.state == XMLReadState.PARSED_OK
|
||||
|
||||
writeFile(xmlFile, (
|
||||
"<novelWriterXML fileVersion='1.0'>"
|
||||
" <project>"
|
||||
" <stuff></stuff>"
|
||||
" </project>"
|
||||
" <settings>"
|
||||
" <stuff></stuff>"
|
||||
" </settings>"
|
||||
" <content>"
|
||||
" <item>"
|
||||
" <stuff></stuff>"
|
||||
" </item>"
|
||||
" <stuff></stuff>"
|
||||
" </content>"
|
||||
" <stuff></stuff>"
|
||||
"</novelWriterXML>"
|
||||
))
|
||||
assert xmlReader.read(data, content) is True
|
||||
assert xmlReader.state == XMLReadState.WAS_LEGACY
|
||||
|
||||
# Reset data objects
|
||||
data = NWProjectData(MockProject())
|
||||
content = []
|
||||
|
||||
# Parse a valid, complete file
|
||||
shutil.copy(refFile, xmlFile)
|
||||
assert xmlReader.read(data, content) is True
|
||||
assert xmlReader.state == XMLReadState.PARSED_OK
|
||||
assert xmlReader.xmlRoot == "novelWriterXML"
|
||||
assert xmlReader.xmlVersion == 0x0104
|
||||
assert xmlReader.appVersion == "2.0-rc1"
|
||||
assert xmlReader.hexVersion == "0x020000c1"
|
||||
|
||||
# Check loaded data
|
||||
assert data.name == "Sample Project"
|
||||
assert data.title == "Sample Project"
|
||||
assert data.authors == ["Jane Smith", "Jay Doh"]
|
||||
assert data.saveCount == 5
|
||||
assert data.autoCount == 10
|
||||
assert data.editTime == 1000
|
||||
|
||||
assert data.doBackup is True
|
||||
assert data.language == "en_GB"
|
||||
assert data.spellCheck is True
|
||||
assert data.spellLang == "en_GB"
|
||||
assert data.initCounts == (954, 409)
|
||||
assert data.currCounts == (954, 409)
|
||||
|
||||
assert data.getLastHandle("editor") == "636b6aa9b697b"
|
||||
assert data.getLastHandle("viewer") == "636b6aa9b697b"
|
||||
assert data.getLastHandle("novelTree") == "7031beac91f75"
|
||||
assert data.getLastHandle("outline") == "7031beac91f75"
|
||||
|
||||
assert data.getTitleFormat("title") == "%title%"
|
||||
assert data.getTitleFormat("chapter") == "Chapter %chw%: %title%"
|
||||
assert data.getTitleFormat("unnumbered") == "%title%"
|
||||
assert data.getTitleFormat("scene") == "Scene %ch%.%sc%: %title%"
|
||||
assert data.getTitleFormat("section") == ""
|
||||
|
||||
assert data.itemStatus.name("sf12341") == "New"
|
||||
assert data.itemStatus.name("sf24ce6") == "Notes"
|
||||
assert data.itemStatus.name("sc24b8f") == "Started"
|
||||
assert data.itemStatus.name("s90e6c9") == "1st Draft"
|
||||
assert data.itemStatus.name("sd51c5b") == "2nd Draft"
|
||||
assert data.itemStatus.name("s8ae72a") == "3rd Draft"
|
||||
assert data.itemStatus.name("s78ea90") == "Finished"
|
||||
|
||||
assert data.itemImport.name("ia857f0") == "None"
|
||||
assert data.itemImport.name("icfb3a5") == "Minor"
|
||||
assert data.itemImport.name("i2d7a54") == "Major"
|
||||
assert data.itemImport.name("i56be10") == "Main"
|
||||
|
||||
assert data.itemStatus.cols("sf12341") == (100, 100, 100)
|
||||
assert data.itemStatus.cols("sf24ce6") == (200, 50, 0)
|
||||
assert data.itemStatus.cols("sc24b8f") == (182, 60, 0)
|
||||
assert data.itemStatus.cols("s90e6c9") == (193, 129, 0)
|
||||
assert data.itemStatus.cols("sd51c5b") == (193, 129, 0)
|
||||
assert data.itemStatus.cols("s8ae72a") == (193, 129, 0)
|
||||
assert data.itemStatus.cols("s78ea90") == (58, 180, 58)
|
||||
|
||||
assert data.itemImport.cols("ia857f0") == (100, 100, 100)
|
||||
assert data.itemImport.cols("icfb3a5") == (0, 122, 188)
|
||||
assert data.itemImport.cols("i2d7a54") == (21, 0, 180)
|
||||
assert data.itemImport.cols("i56be10") == (117, 0, 175)
|
||||
|
||||
assert data.itemStatus.count("sf12341") == 4
|
||||
assert data.itemStatus.count("sf24ce6") == 2
|
||||
assert data.itemStatus.count("sc24b8f") == 3
|
||||
assert data.itemStatus.count("s90e6c9") == 7
|
||||
assert data.itemStatus.count("sd51c5b") == 0
|
||||
assert data.itemStatus.count("s8ae72a") == 0
|
||||
assert data.itemStatus.count("s78ea90") == 1
|
||||
|
||||
assert data.itemImport.count("ia857f0") == 5
|
||||
assert data.itemImport.count("icfb3a5") == 2
|
||||
assert data.itemImport.count("i2d7a54") == 2
|
||||
assert data.itemImport.count("i56be10") == 1
|
||||
|
||||
# Compare content
|
||||
dumpFile = os.path.join(outDir, "projectXML_ReadCurrent.json")
|
||||
compFile = os.path.join(refDir, "projectXML_ReadCurrent.json")
|
||||
with open(dumpFile, mode="w", encoding="utf-8") as dump:
|
||||
json.dump(content, dump, indent=2)
|
||||
assert cmpFiles(dumpFile, compFile)
|
||||
|
||||
packedContent = []
|
||||
mockProject = MockProject()
|
||||
mockProject.__setattr__("data", data)
|
||||
for entry in content:
|
||||
item = NWItem(mockProject)
|
||||
item.unpack(entry)
|
||||
packedContent.append(item.pack())
|
||||
|
||||
# Save the project again, which should produce an identical project xml
|
||||
timeStamp = int(datetime.fromisoformat(xmlReader.timeStamp).timestamp())
|
||||
xmlWriter = ProjectXMLWriter(fncDir)
|
||||
|
||||
# Fail saving
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr("builtins.open", causeOSError)
|
||||
assert xmlWriter.write(data, packedContent, timeStamp, 1000) is False
|
||||
assert str(xmlWriter.error) == "Mock OSError"
|
||||
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr("os.replace", causeOSError)
|
||||
assert xmlWriter.write(data, packedContent, timeStamp, 1000) is False
|
||||
assert str(xmlWriter.error) == "Mock OSError"
|
||||
|
||||
# Successful save (should be twice)
|
||||
assert xmlWriter.write(data, packedContent, timeStamp, 1000) is True
|
||||
assert xmlWriter.write(data, packedContent, timeStamp, 1000) is True
|
||||
assert cmpFiles(outFile, xmlFile)
|
||||
|
||||
# END Test testCoreProjectXML_ReadCurrent
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreProjectXML_ReadLegacy10(filesDir, fncDir, outDir, refDir, mockRnd):
|
||||
"""Test reading the version 1.0 XML file format.
|
||||
"""
|
||||
refFile = os.path.join(filesDir, "nwProject-1.0.nwx")
|
||||
xmlFile = os.path.join(fncDir, "nwProject-1.0.nwx")
|
||||
outFile = os.path.join(fncDir, "nwProject.nwx")
|
||||
shutil.copy(refFile, xmlFile)
|
||||
|
||||
xmlReader = ProjectXMLReader(xmlFile)
|
||||
assert xmlReader.state == XMLReadState.NO_ACTION
|
||||
|
||||
data = NWProjectData(MockProject())
|
||||
content = []
|
||||
|
||||
assert xmlReader.read(data, content) is True
|
||||
assert xmlReader.state == XMLReadState.WAS_LEGACY
|
||||
assert xmlReader.xmlRoot == "novelWriterXML"
|
||||
assert xmlReader.xmlVersion == 0x0100
|
||||
assert xmlReader.appVersion == "0.6.1"
|
||||
assert xmlReader.hexVersion == "0x000601f0"
|
||||
|
||||
# Check loaded data
|
||||
assert data.name == "Sample Project"
|
||||
assert data.title == "Sample Project"
|
||||
assert data.authors == ["Jane Smith", "Jay Doh"]
|
||||
assert data.saveCount == 0 # Doesn't exist in 1.0
|
||||
assert data.autoCount == 0 # Doesn't exist in 1.0
|
||||
assert data.editTime == 0 # Doesn't exist in 1.0
|
||||
|
||||
assert data.doBackup is True
|
||||
assert data.language is None # Doesn't exist in 1.0
|
||||
assert data.spellCheck is True
|
||||
assert data.spellLang is None # Doesn't exist in 1.0
|
||||
assert data.initCounts == (0, 0)
|
||||
assert data.currCounts == (0, 0)
|
||||
|
||||
assert data.getLastHandle("editor") is None # Dropped by conversion
|
||||
assert data.getLastHandle("viewer") is None # Dropped by conversion
|
||||
assert data.getLastHandle("novelTree") is None # Doesn't exist in 1.0
|
||||
assert data.getLastHandle("outline") is None # Doesn't exist in 1.0
|
||||
|
||||
assert data.getTitleFormat("title") == "%title%"
|
||||
assert data.getTitleFormat("chapter") == "Chapter %ch%: %title%"
|
||||
assert data.getTitleFormat("unnumbered") == "%title%"
|
||||
assert data.getTitleFormat("scene") == "Scene %ch%.%sc%: %title%"
|
||||
assert data.getTitleFormat("section") == ""
|
||||
|
||||
assert data.itemStatus.name("s000000") == "New"
|
||||
assert data.itemStatus.name("s000001") == "Notes"
|
||||
assert data.itemStatus.name("s000002") == "Started"
|
||||
assert data.itemStatus.name("s000003") == "1st Draft"
|
||||
assert data.itemStatus.name("s000004") == "2nd Draft"
|
||||
assert data.itemStatus.name("s000005") == "3rd Draft"
|
||||
assert data.itemStatus.name("s000006") == "Finished"
|
||||
|
||||
assert data.itemImport.name("i000007") == "None"
|
||||
assert data.itemImport.name("i000008") == "Minor"
|
||||
assert data.itemImport.name("i000009") == "Major"
|
||||
assert data.itemImport.name("i00000a") == "Main"
|
||||
|
||||
assert data.itemStatus.cols("s000000") == (100, 100, 100)
|
||||
assert data.itemStatus.cols("s000001") == (200, 50, 0)
|
||||
assert data.itemStatus.cols("s000002") == (182, 60, 0)
|
||||
assert data.itemStatus.cols("s000003") == (193, 129, 0)
|
||||
assert data.itemStatus.cols("s000004") == (193, 129, 0)
|
||||
assert data.itemStatus.cols("s000005") == (193, 129, 0)
|
||||
assert data.itemStatus.cols("s000006") == (58, 180, 58)
|
||||
|
||||
assert data.itemImport.cols("i000007") == (100, 100, 100)
|
||||
assert data.itemImport.cols("i000008") == (0, 122, 188)
|
||||
assert data.itemImport.cols("i000009") == (21, 0, 180)
|
||||
assert data.itemImport.cols("i00000a") == (117, 0, 175)
|
||||
|
||||
assert data.itemStatus.count("s000000") == 0
|
||||
assert data.itemStatus.count("s000001") == 0
|
||||
assert data.itemStatus.count("s000002") == 0
|
||||
assert data.itemStatus.count("s000003") == 0
|
||||
assert data.itemStatus.count("s000004") == 0
|
||||
assert data.itemStatus.count("s000005") == 0
|
||||
assert data.itemStatus.count("s000006") == 0
|
||||
|
||||
assert data.itemImport.count("i000007") == 0
|
||||
assert data.itemImport.count("i000008") == 0
|
||||
assert data.itemImport.count("i000009") == 0
|
||||
assert data.itemImport.count("i00000a") == 0
|
||||
|
||||
# Compare content
|
||||
dumpFile = os.path.join(outDir, "projectXML_ReadLegacy10.json")
|
||||
compFile = os.path.join(refDir, "projectXML_ReadLegacy10.json")
|
||||
with open(dumpFile, mode="w", encoding="utf-8") as dump:
|
||||
json.dump(content, dump, indent=2)
|
||||
assert cmpFiles(dumpFile, compFile)
|
||||
|
||||
packedContent = []
|
||||
mockProject = MockProject()
|
||||
mockProject.__setattr__("data", data)
|
||||
status = {}
|
||||
for entry in content:
|
||||
item = NWItem(mockProject)
|
||||
item.unpack(entry)
|
||||
status[item.itemHandle] = item.getImportStatus(incIcon=False)[0]
|
||||
packedContent.append(item.pack())
|
||||
|
||||
assert status == {
|
||||
"7031beac91f75": "Started",
|
||||
"53b69b83cdafc": "Started",
|
||||
"974e400180a99": "New",
|
||||
"edca4be2fcaf8": "New",
|
||||
"e7ded148d6e4a": "1st Draft",
|
||||
"6a2d6d5f4f401": "Notes",
|
||||
"636b6aa9b697b": "1st Draft",
|
||||
"bc0cbd2a407f3": "1st Draft",
|
||||
"ba8a28a246524": "Finished",
|
||||
"96b68994dfa3d": "2nd Draft",
|
||||
"88706ddc78b1b": "1st Draft",
|
||||
"ae7339df26ded": "1st Draft",
|
||||
"f6622b4617424": "None",
|
||||
"f7e2d9f330615": "None",
|
||||
"14298de4d9524": "Minor",
|
||||
"bb2c23b3c42cc": "Major",
|
||||
"15c4492bd5107": "None",
|
||||
"b3e74dbc1f584": "Main",
|
||||
"f1471bef9f2ae": "Minor",
|
||||
"5eaea4e8cdee8": "Major",
|
||||
"98acd8c76c93a": "None",
|
||||
"b8136a5a774a0": "New",
|
||||
}
|
||||
|
||||
# Save the project again, which should produce an identical project xml
|
||||
timeStamp = int(datetime.fromisoformat(xmlReader.timeStamp).timestamp())
|
||||
xmlWriter = ProjectXMLWriter(fncDir)
|
||||
assert xmlWriter.write(data, packedContent, timeStamp, 1000) is True
|
||||
compFile = os.path.join(refDir, "projectXML_ReadLegacy10.nwx")
|
||||
assert cmpFiles(outFile, compFile)
|
||||
|
||||
# END Test testCoreProjectXML_ReadLegacy10
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreProjectXML_ReadLegacy11(filesDir, fncDir, outDir, refDir, mockRnd):
|
||||
"""Test reading the version 1.1 XML file format.
|
||||
"""
|
||||
refFile = os.path.join(filesDir, "nwProject-1.1.nwx")
|
||||
xmlFile = os.path.join(fncDir, "nwProject-1.1.nwx")
|
||||
outFile = os.path.join(fncDir, "nwProject.nwx")
|
||||
shutil.copy(refFile, xmlFile)
|
||||
|
||||
xmlReader = ProjectXMLReader(xmlFile)
|
||||
assert xmlReader.state == XMLReadState.NO_ACTION
|
||||
|
||||
data = NWProjectData(MockProject())
|
||||
content = []
|
||||
|
||||
assert xmlReader.read(data, content) is True
|
||||
assert xmlReader.state == XMLReadState.WAS_LEGACY
|
||||
assert xmlReader.xmlRoot == "novelWriterXML"
|
||||
assert xmlReader.xmlVersion == 0x0101
|
||||
assert xmlReader.appVersion == "0.9.2"
|
||||
assert xmlReader.hexVersion == "0x000902f0"
|
||||
|
||||
# Check loaded data
|
||||
assert data.name == "Sample Project"
|
||||
assert data.title == "Sample Project"
|
||||
assert data.authors == ["Jane Smith", "Jay Doh"]
|
||||
assert data.saveCount == 5
|
||||
assert data.autoCount == 10
|
||||
assert data.editTime == 1000
|
||||
|
||||
assert data.doBackup is True
|
||||
assert data.language is None # Doesn't exist in 1.1
|
||||
assert data.spellCheck is True
|
||||
assert data.spellLang is None # Doesn't exist in 1.1
|
||||
assert data.initCounts == (0, 0)
|
||||
assert data.currCounts == (0, 0)
|
||||
|
||||
assert data.getLastHandle("editor") is None # Dropped by conversion
|
||||
assert data.getLastHandle("viewer") is None # Dropped by conversion
|
||||
assert data.getLastHandle("novelTree") is None # Doesn't exist in 1.1
|
||||
assert data.getLastHandle("outline") is None # Doesn't exist in 1.1
|
||||
|
||||
assert data.getTitleFormat("title") == "%title%"
|
||||
assert data.getTitleFormat("chapter") == "Chapter %ch%: %title%"
|
||||
assert data.getTitleFormat("unnumbered") == "%title%"
|
||||
assert data.getTitleFormat("scene") == "Scene %ch%.%sc%: %title%"
|
||||
assert data.getTitleFormat("section") == ""
|
||||
|
||||
assert data.itemStatus.name("s000000") == "New"
|
||||
assert data.itemStatus.name("s000001") == "Notes"
|
||||
assert data.itemStatus.name("s000002") == "Started"
|
||||
assert data.itemStatus.name("s000003") == "1st Draft"
|
||||
assert data.itemStatus.name("s000004") == "2nd Draft"
|
||||
assert data.itemStatus.name("s000005") == "3rd Draft"
|
||||
assert data.itemStatus.name("s000006") == "Finished"
|
||||
|
||||
assert data.itemImport.name("i000007") == "None"
|
||||
assert data.itemImport.name("i000008") == "Minor"
|
||||
assert data.itemImport.name("i000009") == "Major"
|
||||
assert data.itemImport.name("i00000a") == "Main"
|
||||
|
||||
assert data.itemStatus.cols("s000000") == (100, 100, 100)
|
||||
assert data.itemStatus.cols("s000001") == (200, 50, 0)
|
||||
assert data.itemStatus.cols("s000002") == (182, 60, 0)
|
||||
assert data.itemStatus.cols("s000003") == (193, 129, 0)
|
||||
assert data.itemStatus.cols("s000004") == (193, 129, 0)
|
||||
assert data.itemStatus.cols("s000005") == (193, 129, 0)
|
||||
assert data.itemStatus.cols("s000006") == (58, 180, 58)
|
||||
|
||||
assert data.itemImport.cols("i000007") == (100, 100, 100)
|
||||
assert data.itemImport.cols("i000008") == (0, 122, 188)
|
||||
assert data.itemImport.cols("i000009") == (21, 0, 180)
|
||||
assert data.itemImport.cols("i00000a") == (117, 0, 175)
|
||||
|
||||
assert data.itemStatus.count("s000000") == 0
|
||||
assert data.itemStatus.count("s000001") == 0
|
||||
assert data.itemStatus.count("s000002") == 0
|
||||
assert data.itemStatus.count("s000003") == 0
|
||||
assert data.itemStatus.count("s000004") == 0
|
||||
assert data.itemStatus.count("s000005") == 0
|
||||
assert data.itemStatus.count("s000006") == 0
|
||||
|
||||
assert data.itemImport.count("i000007") == 0
|
||||
assert data.itemImport.count("i000008") == 0
|
||||
assert data.itemImport.count("i000009") == 0
|
||||
assert data.itemImport.count("i00000a") == 0
|
||||
|
||||
# Compare content
|
||||
dumpFile = os.path.join(outDir, "projectXML_ReadLegacy11.json")
|
||||
compFile = os.path.join(refDir, "projectXML_ReadLegacy11.json")
|
||||
with open(dumpFile, mode="w", encoding="utf-8") as dump:
|
||||
json.dump(content, dump, indent=2)
|
||||
assert cmpFiles(dumpFile, compFile)
|
||||
|
||||
packedContent = []
|
||||
mockProject = MockProject()
|
||||
mockProject.__setattr__("data", data)
|
||||
status = {}
|
||||
for entry in content:
|
||||
item = NWItem(mockProject)
|
||||
item.unpack(entry)
|
||||
status[item.itemHandle] = item.getImportStatus(incIcon=False)[0]
|
||||
packedContent.append(item.pack())
|
||||
|
||||
assert status == {
|
||||
"7031beac91f75": "Started",
|
||||
"53b69b83cdafc": "Started",
|
||||
"974e400180a99": "New",
|
||||
"edca4be2fcaf8": "New",
|
||||
"e7ded148d6e4a": "1st Draft",
|
||||
"6a2d6d5f4f401": "Notes",
|
||||
"636b6aa9b697b": "1st Draft",
|
||||
"bc0cbd2a407f3": "1st Draft",
|
||||
"ba8a28a246524": "Finished",
|
||||
"96b68994dfa3d": "2nd Draft",
|
||||
"88706ddc78b1b": "1st Draft",
|
||||
"ae7339df26ded": "1st Draft",
|
||||
"f6622b4617424": "None",
|
||||
"f7e2d9f330615": "None",
|
||||
"14298de4d9524": "Minor",
|
||||
"bb2c23b3c42cc": "Major",
|
||||
"15c4492bd5107": "None",
|
||||
"b3e74dbc1f584": "Main",
|
||||
"f1471bef9f2ae": "Minor",
|
||||
"5eaea4e8cdee8": "Major",
|
||||
"98acd8c76c93a": "None",
|
||||
"b8136a5a774a0": "New",
|
||||
}
|
||||
|
||||
# Save the project again, which should produce an identical project xml
|
||||
timeStamp = int(datetime.fromisoformat(xmlReader.timeStamp).timestamp())
|
||||
xmlWriter = ProjectXMLWriter(fncDir)
|
||||
assert xmlWriter.write(data, packedContent, timeStamp, 1000) is True
|
||||
compFile = os.path.join(refDir, "projectXML_ReadLegacy11.nwx")
|
||||
assert cmpFiles(outFile, compFile)
|
||||
|
||||
# END Test testCoreProjectXML_ReadLegacy11
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreProjectXML_ReadLegacy12(filesDir, fncDir, outDir, refDir, mockRnd):
|
||||
"""Test reading the version 1.2 XML file format.
|
||||
"""
|
||||
refFile = os.path.join(filesDir, "nwProject-1.2.nwx")
|
||||
xmlFile = os.path.join(fncDir, "nwProject-1.2.nwx")
|
||||
outFile = os.path.join(fncDir, "nwProject.nwx")
|
||||
shutil.copy(refFile, xmlFile)
|
||||
|
||||
xmlReader = ProjectXMLReader(xmlFile)
|
||||
assert xmlReader.state == XMLReadState.NO_ACTION
|
||||
|
||||
data = NWProjectData(MockProject())
|
||||
content = []
|
||||
|
||||
assert xmlReader.read(data, content) is True
|
||||
assert xmlReader.state == XMLReadState.WAS_LEGACY
|
||||
assert xmlReader.xmlRoot == "novelWriterXML"
|
||||
assert xmlReader.xmlVersion == 0x0102
|
||||
assert xmlReader.appVersion == "1.4.2"
|
||||
assert xmlReader.hexVersion == "0x010402f0"
|
||||
|
||||
# Check loaded data
|
||||
assert data.name == "Sample Project"
|
||||
assert data.title == "Sample Project"
|
||||
assert data.authors == ["Jane Smith", "Jay Doh"]
|
||||
assert data.saveCount == 5
|
||||
assert data.autoCount == 10
|
||||
assert data.editTime == 1000
|
||||
|
||||
assert data.doBackup is True
|
||||
assert data.language == "en_GB"
|
||||
assert data.spellCheck is True
|
||||
assert data.spellLang == "en_GB"
|
||||
assert data.initCounts == (840, 376)
|
||||
assert data.currCounts == (840, 376)
|
||||
|
||||
assert data.getLastHandle("editor") is None # Dropped by conversion
|
||||
assert data.getLastHandle("viewer") is None # Dropped by conversion
|
||||
assert data.getLastHandle("novelTree") is None # Doesn't exist in 1.2
|
||||
assert data.getLastHandle("outline") is None # Doesn't exist in 1.2
|
||||
|
||||
assert data.getTitleFormat("title") == "%title%"
|
||||
assert data.getTitleFormat("chapter") == "Chapter %chw%: %title%"
|
||||
assert data.getTitleFormat("unnumbered") == "%title%"
|
||||
assert data.getTitleFormat("scene") == "Scene %ch%.%sc%: %title%"
|
||||
assert data.getTitleFormat("section") == ""
|
||||
|
||||
assert data.itemStatus.name("s000000") == "New"
|
||||
assert data.itemStatus.name("s000001") == "Notes"
|
||||
assert data.itemStatus.name("s000002") == "Started"
|
||||
assert data.itemStatus.name("s000003") == "1st Draft"
|
||||
assert data.itemStatus.name("s000004") == "2nd Draft"
|
||||
assert data.itemStatus.name("s000005") == "3rd Draft"
|
||||
assert data.itemStatus.name("s000006") == "Finished"
|
||||
|
||||
assert data.itemImport.name("i000007") == "None"
|
||||
assert data.itemImport.name("i000008") == "Minor"
|
||||
assert data.itemImport.name("i000009") == "Major"
|
||||
assert data.itemImport.name("i00000a") == "Main"
|
||||
|
||||
assert data.itemStatus.cols("s000000") == (100, 100, 100)
|
||||
assert data.itemStatus.cols("s000001") == (200, 50, 0)
|
||||
assert data.itemStatus.cols("s000002") == (182, 60, 0)
|
||||
assert data.itemStatus.cols("s000003") == (193, 129, 0)
|
||||
assert data.itemStatus.cols("s000004") == (193, 129, 0)
|
||||
assert data.itemStatus.cols("s000005") == (193, 129, 0)
|
||||
assert data.itemStatus.cols("s000006") == (58, 180, 58)
|
||||
|
||||
assert data.itemImport.cols("i000007") == (100, 100, 100)
|
||||
assert data.itemImport.cols("i000008") == (0, 122, 188)
|
||||
assert data.itemImport.cols("i000009") == (21, 0, 180)
|
||||
assert data.itemImport.cols("i00000a") == (117, 0, 175)
|
||||
|
||||
assert data.itemStatus.count("s000000") == 0
|
||||
assert data.itemStatus.count("s000001") == 0
|
||||
assert data.itemStatus.count("s000002") == 0
|
||||
assert data.itemStatus.count("s000003") == 0
|
||||
assert data.itemStatus.count("s000004") == 0
|
||||
assert data.itemStatus.count("s000005") == 0
|
||||
assert data.itemStatus.count("s000006") == 0
|
||||
|
||||
assert data.itemImport.count("i000007") == 0
|
||||
assert data.itemImport.count("i000008") == 0
|
||||
assert data.itemImport.count("i000009") == 0
|
||||
assert data.itemImport.count("i00000a") == 0
|
||||
|
||||
# Compare content
|
||||
dumpFile = os.path.join(outDir, "projectXML_ReadLegacy12.json")
|
||||
compFile = os.path.join(refDir, "projectXML_ReadLegacy12.json")
|
||||
with open(dumpFile, mode="w", encoding="utf-8") as dump:
|
||||
json.dump(content, dump, indent=2)
|
||||
assert cmpFiles(dumpFile, compFile)
|
||||
|
||||
packedContent = []
|
||||
mockProject = MockProject()
|
||||
mockProject.__setattr__("data", data)
|
||||
status = {}
|
||||
for entry in content:
|
||||
item = NWItem(mockProject)
|
||||
item.unpack(entry)
|
||||
status[item.itemHandle] = item.getImportStatus(incIcon=False)[0]
|
||||
packedContent.append(item.pack())
|
||||
|
||||
assert status == {
|
||||
"7031beac91f75": "Started",
|
||||
"53b69b83cdafc": "Started",
|
||||
"974e400180a99": "New",
|
||||
"edca4be2fcaf8": "New",
|
||||
"e7ded148d6e4a": "1st Draft",
|
||||
"6a2d6d5f4f401": "Notes",
|
||||
"636b6aa9b697b": "1st Draft",
|
||||
"bc0cbd2a407f3": "1st Draft",
|
||||
"ba8a28a246524": "New",
|
||||
"96b68994dfa3d": "2nd Draft",
|
||||
"88706ddc78b1b": "1st Draft",
|
||||
"ae7339df26ded": "1st Draft",
|
||||
"f6622b4617424": "None",
|
||||
"f7e2d9f330615": "None",
|
||||
"14298de4d9524": "Minor",
|
||||
"bb2c23b3c42cc": "Major",
|
||||
"15c4492bd5107": "None",
|
||||
"b3e74dbc1f584": "Main",
|
||||
"f1471bef9f2ae": "Minor",
|
||||
"5eaea4e8cdee8": "Major",
|
||||
"6827118336ac1": "New", # Is now treated as novel-like
|
||||
"ae9bf3c3ea159": "New", # Is now treated as novel-like
|
||||
"8a5deb88c0e97": "1st Draft",
|
||||
"98acd8c76c93a": "None",
|
||||
"b8136a5a774a0": "New",
|
||||
}
|
||||
|
||||
# Save the project again, which should produce an identical project xml
|
||||
timeStamp = int(datetime.fromisoformat(xmlReader.timeStamp).timestamp())
|
||||
xmlWriter = ProjectXMLWriter(fncDir)
|
||||
assert xmlWriter.write(data, packedContent, timeStamp, 1000) is True
|
||||
compFile = os.path.join(refDir, "projectXML_ReadLegacy12.nwx")
|
||||
assert cmpFiles(outFile, compFile)
|
||||
|
||||
# END Test testCoreProjectXML_ReadLegacy12
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreProjectXML_ReadLegacy13(filesDir, fncDir, outDir, refDir, mockRnd):
|
||||
"""Test reading the version 1.3 XML file format.
|
||||
"""
|
||||
refFile = os.path.join(filesDir, "nwProject-1.3.nwx")
|
||||
xmlFile = os.path.join(fncDir, "nwProject-1.3.nwx")
|
||||
outFile = os.path.join(fncDir, "nwProject.nwx")
|
||||
shutil.copy(refFile, xmlFile)
|
||||
|
||||
xmlReader = ProjectXMLReader(xmlFile)
|
||||
assert xmlReader.state == XMLReadState.NO_ACTION
|
||||
|
||||
data = NWProjectData(MockProject())
|
||||
content = []
|
||||
|
||||
assert xmlReader.read(data, content) is True
|
||||
assert xmlReader.state == XMLReadState.WAS_LEGACY
|
||||
assert xmlReader.xmlRoot == "novelWriterXML"
|
||||
assert xmlReader.xmlVersion == 0x0103
|
||||
assert xmlReader.appVersion == "1.6.6"
|
||||
assert xmlReader.hexVersion == "0x010606f0"
|
||||
|
||||
# Check loaded data
|
||||
assert data.name == "Sample Project"
|
||||
assert data.title == "Sample Project"
|
||||
assert data.authors == ["Jane Smith", "Jay Doh"]
|
||||
assert data.saveCount == 5
|
||||
assert data.autoCount == 10
|
||||
assert data.editTime == 1000
|
||||
|
||||
assert data.doBackup is True
|
||||
assert data.language == "en_GB"
|
||||
assert data.spellCheck is True
|
||||
assert data.spellLang == "en_GB"
|
||||
assert data.initCounts == (830, 376)
|
||||
assert data.currCounts == (830, 376)
|
||||
|
||||
assert data.getLastHandle("editor") is None # Dropped by conversion
|
||||
assert data.getLastHandle("viewer") is None # Dropped by conversion
|
||||
assert data.getLastHandle("novelTree") is None # Doesn't exist in 1.3
|
||||
assert data.getLastHandle("outline") is None # Doesn't exist in 1.3
|
||||
|
||||
assert data.getTitleFormat("title") == "%title%"
|
||||
assert data.getTitleFormat("chapter") == "Chapter %chw%: %title%"
|
||||
assert data.getTitleFormat("unnumbered") == "%title%"
|
||||
assert data.getTitleFormat("scene") == "Scene %ch%.%sc%: %title%"
|
||||
assert data.getTitleFormat("section") == ""
|
||||
|
||||
assert data.itemStatus.name("s000000") == "New"
|
||||
assert data.itemStatus.name("s000001") == "Notes"
|
||||
assert data.itemStatus.name("s000002") == "Started"
|
||||
assert data.itemStatus.name("s000003") == "1st Draft"
|
||||
assert data.itemStatus.name("s000004") == "2nd Draft"
|
||||
assert data.itemStatus.name("s000005") == "3rd Draft"
|
||||
assert data.itemStatus.name("s000006") == "Finished"
|
||||
|
||||
assert data.itemImport.name("i000007") == "None"
|
||||
assert data.itemImport.name("i000008") == "Minor"
|
||||
assert data.itemImport.name("i000009") == "Major"
|
||||
assert data.itemImport.name("i00000a") == "Main"
|
||||
|
||||
assert data.itemStatus.cols("s000000") == (100, 100, 100)
|
||||
assert data.itemStatus.cols("s000001") == (200, 50, 0)
|
||||
assert data.itemStatus.cols("s000002") == (182, 60, 0)
|
||||
assert data.itemStatus.cols("s000003") == (193, 129, 0)
|
||||
assert data.itemStatus.cols("s000004") == (193, 129, 0)
|
||||
assert data.itemStatus.cols("s000005") == (193, 129, 0)
|
||||
assert data.itemStatus.cols("s000006") == (58, 180, 58)
|
||||
|
||||
assert data.itemImport.cols("i000007") == (100, 100, 100)
|
||||
assert data.itemImport.cols("i000008") == (0, 122, 188)
|
||||
assert data.itemImport.cols("i000009") == (21, 0, 180)
|
||||
assert data.itemImport.cols("i00000a") == (117, 0, 175)
|
||||
|
||||
assert data.itemStatus.count("s000000") == 0
|
||||
assert data.itemStatus.count("s000001") == 0
|
||||
assert data.itemStatus.count("s000002") == 0
|
||||
assert data.itemStatus.count("s000003") == 0
|
||||
assert data.itemStatus.count("s000004") == 0
|
||||
assert data.itemStatus.count("s000005") == 0
|
||||
assert data.itemStatus.count("s000006") == 0
|
||||
|
||||
assert data.itemImport.count("i000007") == 0
|
||||
assert data.itemImport.count("i000008") == 0
|
||||
assert data.itemImport.count("i000009") == 0
|
||||
assert data.itemImport.count("i00000a") == 0
|
||||
|
||||
# Compare content
|
||||
dumpFile = os.path.join(outDir, "projectXML_ReadLegacy13.json")
|
||||
compFile = os.path.join(refDir, "projectXML_ReadLegacy13.json")
|
||||
with open(dumpFile, mode="w", encoding="utf-8") as dump:
|
||||
json.dump(content, dump, indent=2)
|
||||
assert cmpFiles(dumpFile, compFile)
|
||||
|
||||
packedContent = []
|
||||
mockProject = MockProject()
|
||||
mockProject.__setattr__("data", data)
|
||||
status = {}
|
||||
for entry in content:
|
||||
item = NWItem(mockProject)
|
||||
item.unpack(entry)
|
||||
status[item.itemHandle] = item.getImportStatus(incIcon=False)[0]
|
||||
packedContent.append(item.pack())
|
||||
|
||||
assert status == {
|
||||
"7031beac91f75": "Started",
|
||||
"53b69b83cdafc": "Started",
|
||||
"974e400180a99": "New",
|
||||
"edca4be2fcaf8": "New",
|
||||
"e7ded148d6e4a": "1st Draft",
|
||||
"6a2d6d5f4f401": "Notes",
|
||||
"636b6aa9b697b": "1st Draft",
|
||||
"bc0cbd2a407f3": "1st Draft",
|
||||
"ba8a28a246524": "New",
|
||||
"96b68994dfa3d": "2nd Draft",
|
||||
"88706ddc78b1b": "1st Draft",
|
||||
"ae7339df26ded": "1st Draft",
|
||||
"f6622b4617424": "None",
|
||||
"f7e2d9f330615": "None",
|
||||
"14298de4d9524": "Minor",
|
||||
"bb2c23b3c42cc": "Major",
|
||||
"15c4492bd5107": "None",
|
||||
"b3e74dbc1f584": "Main",
|
||||
"f1471bef9f2ae": "Minor",
|
||||
"5eaea4e8cdee8": "Major",
|
||||
"6827118336ac1": "New", # Is now treated as novel-like
|
||||
"ae9bf3c3ea159": "New", # Is now treated as novel-like
|
||||
"8a5deb88c0e97": "1st Draft",
|
||||
"98acd8c76c93a": "None",
|
||||
"b8136a5a774a0": "New",
|
||||
}
|
||||
|
||||
# Save the project again, which should produce an identical project xml
|
||||
timeStamp = int(datetime.fromisoformat(xmlReader.timeStamp).timestamp())
|
||||
xmlWriter = ProjectXMLWriter(fncDir)
|
||||
assert xmlWriter.write(data, packedContent, timeStamp, 1000) is True
|
||||
compFile = os.path.join(refDir, "projectXML_ReadLegacy13.nwx")
|
||||
assert cmpFiles(outFile, compFile)
|
||||
|
||||
# END Test testCoreProjectXML_ReadLegacy13
|
||||
Reference in New Issue
Block a user