+36
-3
@@ -59,6 +59,7 @@ class NWIndex():
|
|||||||
self._novelIndex = {}
|
self._novelIndex = {}
|
||||||
self._noteIndex = {}
|
self._noteIndex = {}
|
||||||
self._textCounts = {}
|
self._textCounts = {}
|
||||||
|
self._firstTitle = {}
|
||||||
|
|
||||||
# TimeStamps
|
# TimeStamps
|
||||||
self._timeNovel = 0
|
self._timeNovel = 0
|
||||||
@@ -79,6 +80,7 @@ class NWIndex():
|
|||||||
self._novelIndex = {}
|
self._novelIndex = {}
|
||||||
self._noteIndex = {}
|
self._noteIndex = {}
|
||||||
self._textCounts = {}
|
self._textCounts = {}
|
||||||
|
self._firstTitle = {}
|
||||||
self._timeNovel = 0
|
self._timeNovel = 0
|
||||||
self._timeNotes = 0
|
self._timeNotes = 0
|
||||||
self._timeIndex = 0
|
self._timeIndex = 0
|
||||||
@@ -101,6 +103,7 @@ class NWIndex():
|
|||||||
self._novelIndex.pop(tHandle, None)
|
self._novelIndex.pop(tHandle, None)
|
||||||
self._noteIndex.pop(tHandle, None)
|
self._noteIndex.pop(tHandle, None)
|
||||||
self._textCounts.pop(tHandle, None)
|
self._textCounts.pop(tHandle, None)
|
||||||
|
self._firstTitle.pop(tHandle, None)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -169,6 +172,7 @@ class NWIndex():
|
|||||||
self._novelIndex = theData.get("novelIndex", {})
|
self._novelIndex = theData.get("novelIndex", {})
|
||||||
self._noteIndex = theData.get("noteIndex", {})
|
self._noteIndex = theData.get("noteIndex", {})
|
||||||
self._textCounts = theData.get("textCounts", {})
|
self._textCounts = theData.get("textCounts", {})
|
||||||
|
self._firstTitle = theData.get("firstTitle", {})
|
||||||
|
|
||||||
nowTime = round(time())
|
nowTime = round(time())
|
||||||
self._timeNovel = nowTime
|
self._timeNovel = nowTime
|
||||||
@@ -194,6 +198,7 @@ class NWIndex():
|
|||||||
"novelIndex" : self._novelIndex,
|
"novelIndex" : self._novelIndex,
|
||||||
"noteIndex" : self._noteIndex,
|
"noteIndex" : self._noteIndex,
|
||||||
"textCounts" : self._textCounts,
|
"textCounts" : self._textCounts,
|
||||||
|
"firstTitle" : self._firstTitle,
|
||||||
}, outFile, indent=2)
|
}, outFile, indent=2)
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.error("Failed to save index file")
|
logger.error("Failed to save index file")
|
||||||
@@ -215,6 +220,7 @@ class NWIndex():
|
|||||||
self._checkNovelNoteIndex("novelIndex")
|
self._checkNovelNoteIndex("novelIndex")
|
||||||
self._checkNovelNoteIndex("noteIndex")
|
self._checkNovelNoteIndex("noteIndex")
|
||||||
self._checkTextCounts()
|
self._checkTextCounts()
|
||||||
|
self._checkFirstTitles()
|
||||||
self.indexBroken = False
|
self.indexBroken = False
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
@@ -285,6 +291,7 @@ class NWIndex():
|
|||||||
"tags" : [],
|
"tags" : [],
|
||||||
"updated" : round(time()),
|
"updated" : round(time()),
|
||||||
}
|
}
|
||||||
|
self._firstTitle[tHandle] = ["H0", "T000000"]
|
||||||
if itemLayout == nwItemLayout.NOTE:
|
if itemLayout == nwItemLayout.NOTE:
|
||||||
self._novelIndex.pop(tHandle, None)
|
self._novelIndex.pop(tHandle, None)
|
||||||
self._noteIndex[tHandle] = {}
|
self._noteIndex[tHandle] = {}
|
||||||
@@ -312,7 +319,7 @@ class NWIndex():
|
|||||||
if nChar == 0:
|
if nChar == 0:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if aLine.startswith(r"#"):
|
if aLine.startswith("#"):
|
||||||
isTitle = self._indexTitle(tHandle, isNovel, aLine, nLine, itemLayout)
|
isTitle = self._indexTitle(tHandle, isNovel, aLine, nLine, itemLayout)
|
||||||
if isTitle and nLine > 0:
|
if isTitle and nLine > 0:
|
||||||
if nTitle > 0:
|
if nTitle > 0:
|
||||||
@@ -320,11 +327,11 @@ class NWIndex():
|
|||||||
self._indexWordCounts(tHandle, isNovel, lastText, nTitle)
|
self._indexWordCounts(tHandle, isNovel, lastText, nTitle)
|
||||||
nTitle = nLine
|
nTitle = nLine
|
||||||
|
|
||||||
elif aLine.startswith(r"@"):
|
elif aLine.startswith("@"):
|
||||||
self._indexNoteRef(tHandle, aLine, nLine, nTitle)
|
self._indexNoteRef(tHandle, aLine, nLine, nTitle)
|
||||||
self._indexTag(tHandle, aLine, nLine, nTitle, itemClass)
|
self._indexTag(tHandle, aLine, nLine, nTitle, itemClass)
|
||||||
|
|
||||||
elif aLine.startswith(r"%"):
|
elif aLine.startswith("%"):
|
||||||
if nTitle > 0:
|
if nTitle > 0:
|
||||||
toCheck = aLine[1:].lstrip()
|
toCheck = aLine[1:].lstrip()
|
||||||
synTag = toCheck[:9].lower()
|
synTag = toCheck[:9].lower()
|
||||||
@@ -393,6 +400,9 @@ class NWIndex():
|
|||||||
"updated" : round(time()),
|
"updated" : round(time()),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self._firstTitle[tHandle][0] == "H0":
|
||||||
|
self._firstTitle[tHandle] = [hDepth, sTitle]
|
||||||
|
|
||||||
if hText != "":
|
if hText != "":
|
||||||
if isNovel:
|
if isNovel:
|
||||||
if tHandle in self._novelIndex:
|
if tHandle in self._novelIndex:
|
||||||
@@ -638,6 +648,11 @@ class NWIndex():
|
|||||||
|
|
||||||
return theToC
|
return theToC
|
||||||
|
|
||||||
|
def getFirstTitle(self, tHandle):
|
||||||
|
"""Return the level and location of the first title of a handle.
|
||||||
|
"""
|
||||||
|
return self._firstTitle.get(tHandle, ["H0", "T000000"])
|
||||||
|
|
||||||
def getCounts(self, tHandle, sTitle=None):
|
def getCounts(self, tHandle, sTitle=None):
|
||||||
"""Returns the counts for a file, or a section of a file
|
"""Returns the counts for a file, or a section of a file
|
||||||
starting at title sTitle if it is provided.
|
starting at title sTitle if it is provided.
|
||||||
@@ -879,4 +894,22 @@ class NWIndex():
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def _checkFirstTitles(self):
|
||||||
|
"""Scan the first titles index for errors.
|
||||||
|
Waring: This function raises exceptions.
|
||||||
|
"""
|
||||||
|
for tHandle in self._firstTitle:
|
||||||
|
if not isHandle(tHandle):
|
||||||
|
raise KeyError("firstTitle key is not a handle")
|
||||||
|
|
||||||
|
tEntry = self._firstTitle[tHandle]
|
||||||
|
if len(tEntry) != 2:
|
||||||
|
raise IndexError("firstTitle[a] expected 2 values")
|
||||||
|
if not tEntry[0] in self.H_VALID:
|
||||||
|
raise ValueError("firstTitle[a][0] is not a header level")
|
||||||
|
if not isTitleTag(tEntry[1]):
|
||||||
|
raise ValueError("firstTitle[a][1] is not a title tag")
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
# END Class NWIndex
|
# END Class NWIndex
|
||||||
|
|||||||
+49
-1
@@ -34,10 +34,35 @@ from time import time
|
|||||||
|
|
||||||
from nw.core.item import NWItem
|
from nw.core.item import NWItem
|
||||||
from nw.common import checkHandle
|
from nw.common import checkHandle
|
||||||
from nw.constants import nwFiles, nwItemType, nwItemClass, nwItemLayout, nwConst
|
from nw.constants import (
|
||||||
|
nwFiles, nwItemType, nwItemClass, nwItemLayout, nwConst, nwLists
|
||||||
|
)
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
# Layout Translation Map
|
||||||
|
LAYOUT_MAP = {
|
||||||
|
nwItemLayout.SCENE: {
|
||||||
|
"H1": nwItemLayout.BOOK,
|
||||||
|
"H2": nwItemLayout.CHAPTER,
|
||||||
|
},
|
||||||
|
nwItemLayout.CHAPTER: {
|
||||||
|
"H1": nwItemLayout.BOOK,
|
||||||
|
"H3": nwItemLayout.SCENE,
|
||||||
|
"H4": nwItemLayout.SCENE,
|
||||||
|
},
|
||||||
|
nwItemLayout.UNNUMBERED: {
|
||||||
|
"H1": nwItemLayout.BOOK,
|
||||||
|
"H3": nwItemLayout.SCENE,
|
||||||
|
"H4": nwItemLayout.SCENE,
|
||||||
|
},
|
||||||
|
nwItemLayout.PARTITION: {
|
||||||
|
"H2": nwItemLayout.CHAPTER,
|
||||||
|
"H3": nwItemLayout.SCENE,
|
||||||
|
"H4": nwItemLayout.SCENE,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
class NWTree():
|
class NWTree():
|
||||||
|
|
||||||
def __init__(self, theProject):
|
def __init__(self, theProject):
|
||||||
@@ -204,6 +229,29 @@ class NWTree():
|
|||||||
novelWords += tItem.wordCount
|
novelWords += tItem.wordCount
|
||||||
return novelWords, noteWords
|
return novelWords, noteWords
|
||||||
|
|
||||||
|
def updateItemLayout(self, tHandle, hLevel):
|
||||||
|
"""Check if the item layout needs updating based on the header
|
||||||
|
given level.
|
||||||
|
"""
|
||||||
|
tItem = self.__getitem__(tHandle)
|
||||||
|
if tItem is None:
|
||||||
|
return False
|
||||||
|
if tItem.itemClass not in nwLists.CLS_NOVEL:
|
||||||
|
return False
|
||||||
|
if hLevel not in ("H1", "H2", "H3", "H4"):
|
||||||
|
return False
|
||||||
|
|
||||||
|
iLayout = tItem.itemLayout
|
||||||
|
if iLayout in LAYOUT_MAP:
|
||||||
|
if hLevel in LAYOUT_MAP[iLayout]:
|
||||||
|
tItem.itemLayout = LAYOUT_MAP[iLayout][hLevel]
|
||||||
|
logger.debug("Changed layout for %s from %s to %s" % (
|
||||||
|
tHandle, iLayout.name, tItem.itemLayout.name
|
||||||
|
))
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
##
|
##
|
||||||
# Tree Structure Methods
|
# Tree Structure Methods
|
||||||
##
|
##
|
||||||
|
|||||||
+7
-1
@@ -398,6 +398,7 @@ class GuiDocEditor(QTextEdit):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
docText = self.getText()
|
docText = self.getText()
|
||||||
|
tHandle = theItem.itemHandle
|
||||||
|
|
||||||
cC, wC, pC = countWords(docText)
|
cC, wC, pC = countWords(docText)
|
||||||
self._updateCounts(cC, wC, pC)
|
self._updateCounts(cC, wC, pC)
|
||||||
@@ -410,7 +411,12 @@ class GuiDocEditor(QTextEdit):
|
|||||||
self.nwDocument.saveDocument(docText)
|
self.nwDocument.saveDocument(docText)
|
||||||
self.setDocumentChanged(False)
|
self.setDocumentChanged(False)
|
||||||
|
|
||||||
self.theParent.theIndex.scanText(theItem.itemHandle, docText)
|
self.theParent.theIndex.scanText(tHandle, docText)
|
||||||
|
|
||||||
|
hLevel, _ = self.theParent.theIndex.getFirstTitle(tHandle)
|
||||||
|
if self.theProject.projTree.updateItemLayout(tHandle, hLevel):
|
||||||
|
self.theParent.treeView.setTreeItemValues(tHandle)
|
||||||
|
self.nwDocument.saveDocument(docText)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|||||||
@@ -567,5 +567,67 @@
|
|||||||
259,
|
259,
|
||||||
3
|
3
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"firstTitle": {
|
||||||
|
"7a992350f3eb6": [
|
||||||
|
"H1",
|
||||||
|
"T000001"
|
||||||
|
],
|
||||||
|
"8c58a65414c23": [
|
||||||
|
"H0",
|
||||||
|
"T000000"
|
||||||
|
],
|
||||||
|
"88d59a277361b": [
|
||||||
|
"H2",
|
||||||
|
"T000001"
|
||||||
|
],
|
||||||
|
"db7e733775d4d": [
|
||||||
|
"H1",
|
||||||
|
"T000001"
|
||||||
|
],
|
||||||
|
"fb609cd8319dc": [
|
||||||
|
"H2",
|
||||||
|
"T000001"
|
||||||
|
],
|
||||||
|
"88243afbe5ed8": [
|
||||||
|
"H3",
|
||||||
|
"T000001"
|
||||||
|
],
|
||||||
|
"f96ec11c6a3da": [
|
||||||
|
"H3",
|
||||||
|
"T000001"
|
||||||
|
],
|
||||||
|
"846352075de7d": [
|
||||||
|
"H2",
|
||||||
|
"T000001"
|
||||||
|
],
|
||||||
|
"441420a886d82": [
|
||||||
|
"H2",
|
||||||
|
"T000001"
|
||||||
|
],
|
||||||
|
"eb103bc70c90c": [
|
||||||
|
"H3",
|
||||||
|
"T000001"
|
||||||
|
],
|
||||||
|
"f8c0562e50f1b": [
|
||||||
|
"H3",
|
||||||
|
"T000001"
|
||||||
|
],
|
||||||
|
"47666c91c7ccf": [
|
||||||
|
"H3",
|
||||||
|
"T000001"
|
||||||
|
],
|
||||||
|
"4c4f28287af27": [
|
||||||
|
"H1",
|
||||||
|
"T000001"
|
||||||
|
],
|
||||||
|
"2426c6f0ca922": [
|
||||||
|
"H1",
|
||||||
|
"T000001"
|
||||||
|
],
|
||||||
|
"04468803b92e1": [
|
||||||
|
"H1",
|
||||||
|
"T000001"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
%%~name: New Scene
|
%%~name: New Scene
|
||||||
%%~path: 31489056e0916/0e17daca5f3e1
|
%%~path: 31489056e0916/0e17daca5f3e1
|
||||||
%%~kind: NOVEL/SCENE
|
%%~kind: NOVEL/BOOK
|
||||||
# Novel
|
# Novel
|
||||||
|
|
||||||
## Chapter
|
## Chapter
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
<?xml version='1.0' encoding='utf-8'?>
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
<novelWriterXML appVersion="1.0b3" hexVersion="0x010000b3" fileVersion="1.2" timeStamp="2020-09-21 19:58:53">
|
<novelWriterXML appVersion="1.2a0" hexVersion="0x010200a0" fileVersion="1.2" timeStamp="2021-01-29 01:10:23">
|
||||||
<project>
|
<project>
|
||||||
<name>New Project</name>
|
<name>New Project</name>
|
||||||
<title></title>
|
<title></title>
|
||||||
<saveCount>4</saveCount>
|
<saveCount>4</saveCount>
|
||||||
<autoCount>1</autoCount>
|
<autoCount>2</autoCount>
|
||||||
<editTime>11</editTime>
|
<editTime>8</editTime>
|
||||||
</project>
|
</project>
|
||||||
<settings>
|
<settings>
|
||||||
<doBackup>True</doBackup>
|
<doBackup>True</doBackup>
|
||||||
@@ -83,7 +83,7 @@
|
|||||||
<class>NOVEL</class>
|
<class>NOVEL</class>
|
||||||
<status>New</status>
|
<status>New</status>
|
||||||
<exported>True</exported>
|
<exported>True</exported>
|
||||||
<layout>SCENE</layout>
|
<layout>BOOK</layout>
|
||||||
<charCount>466</charCount>
|
<charCount>466</charCount>
|
||||||
<wordCount>83</wordCount>
|
<wordCount>83</wordCount>
|
||||||
<paraCount>4</paraCount>
|
<paraCount>4</paraCount>
|
||||||
|
|||||||
@@ -492,9 +492,8 @@ def testCoreIndex_ExtractData(nwMinimal, dummyGUI):
|
|||||||
assert wC == 12 # Words in text and title only
|
assert wC == 12 # Words in text and title only
|
||||||
assert pC == 2 # Paragraphs in text only
|
assert pC == 2 # Paragraphs in text only
|
||||||
|
|
||||||
##
|
# getReferences
|
||||||
# getReferences
|
# =============
|
||||||
##
|
|
||||||
|
|
||||||
# Look up an ivalid handle
|
# Look up an ivalid handle
|
||||||
theRefs = theIndex.getReferences("Not a handle")
|
theRefs = theIndex.getReferences("Not a handle")
|
||||||
@@ -506,9 +505,8 @@ def testCoreIndex_ExtractData(nwMinimal, dummyGUI):
|
|||||||
assert theRefs["@pov"] == ["Jane"]
|
assert theRefs["@pov"] == ["Jane"]
|
||||||
assert theRefs["@char"] == ["Jane"]
|
assert theRefs["@char"] == ["Jane"]
|
||||||
|
|
||||||
##
|
# getBackReferenceList
|
||||||
# getBackReferenceList
|
# ====================
|
||||||
##
|
|
||||||
|
|
||||||
# None handle should return an empty dict
|
# None handle should return an empty dict
|
||||||
assert theIndex.getBackReferenceList(None) == {}
|
assert theIndex.getBackReferenceList(None) == {}
|
||||||
@@ -517,16 +515,15 @@ def testCoreIndex_ExtractData(nwMinimal, dummyGUI):
|
|||||||
theRefs = theIndex.getBackReferenceList(cHandle)
|
theRefs = theIndex.getBackReferenceList(cHandle)
|
||||||
assert theRefs == {nHandle: "T000001"}
|
assert theRefs == {nHandle: "T000001"}
|
||||||
|
|
||||||
##
|
# getTagSource
|
||||||
# getTagSource
|
# ============
|
||||||
##
|
|
||||||
|
|
||||||
assert theIndex.getTagSource("Jane") == (cHandle, 2, "T000001")
|
assert theIndex.getTagSource("Jane") == (cHandle, 2, "T000001")
|
||||||
assert theIndex.getTagSource("John") == (None, 0, "T000000")
|
assert theIndex.getTagSource("John") == (None, 0, "T000000")
|
||||||
|
|
||||||
##
|
# getCounts
|
||||||
# getCounts for whole text and sections
|
# =========
|
||||||
##
|
# For whole text and sections
|
||||||
|
|
||||||
# Get section counts for a novel file
|
# Get section counts for a novel file
|
||||||
assert theIndex.scanText(nHandle, (
|
assert theIndex.scanText(nHandle, (
|
||||||
@@ -555,7 +552,7 @@ def testCoreIndex_ExtractData(nwMinimal, dummyGUI):
|
|||||||
assert wC == 12
|
assert wC == 12
|
||||||
assert pC == 2
|
assert pC == 2
|
||||||
|
|
||||||
# First part
|
# Second part
|
||||||
cC, wC, pC = theIndex.getCounts(nHandle, "T000011")
|
cC, wC, pC = theIndex.getCounts(nHandle, "T000011")
|
||||||
assert cC == 62
|
assert cC == 62
|
||||||
assert wC == 12
|
assert wC == 12
|
||||||
@@ -588,15 +585,19 @@ def testCoreIndex_ExtractData(nwMinimal, dummyGUI):
|
|||||||
assert wC == 12
|
assert wC == 12
|
||||||
assert pC == 2
|
assert pC == 2
|
||||||
|
|
||||||
# First part
|
# Second part
|
||||||
cC, wC, pC = theIndex.getCounts(cHandle, "T000011")
|
cC, wC, pC = theIndex.getCounts(cHandle, "T000011")
|
||||||
assert cC == 62
|
assert cC == 62
|
||||||
assert wC == 12
|
assert wC == 12
|
||||||
assert pC == 2
|
assert pC == 2
|
||||||
|
|
||||||
##
|
# getFirstTitle
|
||||||
# Novel Stats
|
# =============
|
||||||
##
|
|
||||||
|
assert theIndex.getFirstTitle(cHandle) == ["H1", "T000001"]
|
||||||
|
|
||||||
|
# Novel Stats
|
||||||
|
# ===========
|
||||||
|
|
||||||
hHandle = theProject.newFile("Chapter", nwItemClass.NOVEL, "a508bb932959c")
|
hHandle = theProject.newFile("Chapter", nwItemClass.NOVEL, "a508bb932959c")
|
||||||
sHandle = theProject.newFile("Scene One", nwItemClass.NOVEL, "a508bb932959c")
|
sHandle = theProject.newFile("Scene One", nwItemClass.NOVEL, "a508bb932959c")
|
||||||
@@ -1145,3 +1146,51 @@ def testCoreIndex_CheckTextCounts(dummyGUI):
|
|||||||
theIndex._checkTextCounts()
|
theIndex._checkTextCounts()
|
||||||
|
|
||||||
# END Test testCoreIndex_CheckTextCounts
|
# END Test testCoreIndex_CheckTextCounts
|
||||||
|
|
||||||
|
@pytest.mark.core
|
||||||
|
def testCoreIndex_CheckFirstTitle(dummyGUI):
|
||||||
|
"""Test the first title checker.
|
||||||
|
"""
|
||||||
|
theProject = NWProject(dummyGUI)
|
||||||
|
theIndex = NWIndex(theProject, dummyGUI)
|
||||||
|
|
||||||
|
# Valid Index
|
||||||
|
theIndex._firstTitle = {
|
||||||
|
"53b69b83cdafc": ["H1", "T000001"],
|
||||||
|
"974e400180a99": ["H0", "T000000"],
|
||||||
|
}
|
||||||
|
assert theIndex._checkFirstTitles() is None
|
||||||
|
|
||||||
|
# Invalid Handle
|
||||||
|
theIndex._firstTitle = {
|
||||||
|
"53b69b83cdafc": ["H1", "T000001"],
|
||||||
|
"h74e400180a99": ["H0", "T000000"],
|
||||||
|
}
|
||||||
|
with pytest.raises(KeyError):
|
||||||
|
theIndex._checkFirstTitles()
|
||||||
|
|
||||||
|
# Wrong Length
|
||||||
|
theIndex._firstTitle = {
|
||||||
|
"53b69b83cdafc": ["H1", "T000001"],
|
||||||
|
"974e400180a99": ["H0", "T000000", "stuff"],
|
||||||
|
}
|
||||||
|
with pytest.raises(IndexError):
|
||||||
|
theIndex._checkFirstTitles()
|
||||||
|
|
||||||
|
# Wrong Header
|
||||||
|
theIndex._firstTitle = {
|
||||||
|
"53b69b83cdafc": ["H1", "T000001"],
|
||||||
|
"974e400180a99": ["XX", "T000000"],
|
||||||
|
}
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
theIndex._checkFirstTitles()
|
||||||
|
|
||||||
|
# Wrong Title
|
||||||
|
theIndex._firstTitle = {
|
||||||
|
"53b69b83cdafc": ["H1", "T000001"],
|
||||||
|
"974e400180a99": ["H0", "INVALID"],
|
||||||
|
}
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
theIndex._checkFirstTitles()
|
||||||
|
|
||||||
|
# END Test testCoreIndex_CheckFirstTitle
|
||||||
|
|||||||
@@ -123,9 +123,9 @@ def testCoreTree_BuildTree(dummyGUI, dummyItems):
|
|||||||
assert not theTree.isTrashRoot("a000000000003")
|
assert not theTree.isTrashRoot("a000000000003")
|
||||||
|
|
||||||
aHandles = []
|
aHandles = []
|
||||||
for tHandle, pHande, nwItem in dummyItems:
|
for tHandle, pHandle, nwItem in dummyItems:
|
||||||
aHandles.append(tHandle)
|
aHandles.append(tHandle)
|
||||||
assert theTree.append(tHandle, pHande, nwItem)
|
assert theTree.append(tHandle, pHandle, nwItem)
|
||||||
|
|
||||||
assert theTree._treeChanged
|
assert theTree._treeChanged
|
||||||
|
|
||||||
@@ -202,13 +202,13 @@ def testCoreTree_BuildTree(dummyGUI, dummyItems):
|
|||||||
|
|
||||||
@pytest.mark.core
|
@pytest.mark.core
|
||||||
def testCoreTree_Methods(dummyGUI, dummyItems):
|
def testCoreTree_Methods(dummyGUI, dummyItems):
|
||||||
"""Test building a project tree from a list of items.
|
"""Test bvarious class methods.
|
||||||
"""
|
"""
|
||||||
theProject = NWProject(dummyGUI)
|
theProject = NWProject(dummyGUI)
|
||||||
theTree = NWTree(theProject)
|
theTree = NWTree(theProject)
|
||||||
|
|
||||||
for tHandle, pHande, nwItem in dummyItems:
|
for tHandle, pHandle, nwItem in dummyItems:
|
||||||
theTree.append(tHandle, pHande, nwItem)
|
theTree.append(tHandle, pHandle, nwItem)
|
||||||
|
|
||||||
assert len(theTree) == len(dummyItems)
|
assert len(theTree) == len(dummyItems)
|
||||||
|
|
||||||
@@ -256,6 +256,131 @@ def testCoreTree_Methods(dummyGUI, dummyItems):
|
|||||||
|
|
||||||
# END Test testCoreTree_Methods
|
# END Test testCoreTree_Methods
|
||||||
|
|
||||||
|
@pytest.mark.core
|
||||||
|
def testCoreTree_UpdateItemLayout(dummyGUI, dummyItems):
|
||||||
|
"""Test building a project tree from a list of items.
|
||||||
|
"""
|
||||||
|
theProject = NWProject(dummyGUI)
|
||||||
|
theTree = NWTree(theProject)
|
||||||
|
|
||||||
|
for tHandle, pHandle, nwItem in dummyItems:
|
||||||
|
theTree.append(tHandle, pHandle, nwItem)
|
||||||
|
|
||||||
|
assert len(theTree) == len(dummyItems)
|
||||||
|
|
||||||
|
# Check rejected items
|
||||||
|
assert not theTree.updateItemLayout("0000000000000", "H1") # Non-existent handle
|
||||||
|
assert not theTree.updateItemLayout("a000000000004", "H2") # Character file
|
||||||
|
assert not theTree.updateItemLayout("c000000000002", "H0") # Wrong header level
|
||||||
|
|
||||||
|
cHandle = "c000000000002"
|
||||||
|
|
||||||
|
# Check layouts we won't change
|
||||||
|
theTree[cHandle].setLayout(nwItemLayout.NO_LAYOUT)
|
||||||
|
assert not theTree.updateItemLayout("c000000000002", "H1")
|
||||||
|
|
||||||
|
theTree[cHandle].setLayout(nwItemLayout.TITLE)
|
||||||
|
assert not theTree.updateItemLayout("c000000000002", "H1")
|
||||||
|
|
||||||
|
theTree[cHandle].setLayout(nwItemLayout.PAGE)
|
||||||
|
assert not theTree.updateItemLayout("c000000000002", "H1")
|
||||||
|
|
||||||
|
theTree[cHandle].setLayout(nwItemLayout.NOTE)
|
||||||
|
assert not theTree.updateItemLayout("c000000000002", "H1")
|
||||||
|
|
||||||
|
# BOOK is also a layout we change to, but never from
|
||||||
|
theTree[cHandle].setLayout(nwItemLayout.BOOK)
|
||||||
|
assert not theTree.updateItemLayout("c000000000002", "H1")
|
||||||
|
|
||||||
|
# Test SCENE Changes
|
||||||
|
# ==================
|
||||||
|
|
||||||
|
# H1 -> BOOK
|
||||||
|
theTree[cHandle].setLayout(nwItemLayout.SCENE)
|
||||||
|
assert theTree.updateItemLayout("c000000000002", "H1")
|
||||||
|
assert theTree[cHandle].itemLayout == nwItemLayout.BOOK
|
||||||
|
|
||||||
|
# H2 -> CHAPTER
|
||||||
|
theTree[cHandle].setLayout(nwItemLayout.SCENE)
|
||||||
|
assert theTree.updateItemLayout("c000000000002", "H2")
|
||||||
|
assert theTree[cHandle].itemLayout == nwItemLayout.CHAPTER
|
||||||
|
|
||||||
|
# H3 -> No CHange
|
||||||
|
theTree[cHandle].setLayout(nwItemLayout.SCENE)
|
||||||
|
assert not theTree.updateItemLayout("c000000000002", "H3")
|
||||||
|
|
||||||
|
# H4 -> No CHange
|
||||||
|
theTree[cHandle].setLayout(nwItemLayout.SCENE)
|
||||||
|
assert not theTree.updateItemLayout("c000000000002", "H4")
|
||||||
|
|
||||||
|
# Test CHAPTER Changes
|
||||||
|
# ====================
|
||||||
|
|
||||||
|
# H1 -> BOOK
|
||||||
|
theTree[cHandle].setLayout(nwItemLayout.CHAPTER)
|
||||||
|
assert theTree.updateItemLayout("c000000000002", "H1")
|
||||||
|
assert theTree[cHandle].itemLayout == nwItemLayout.BOOK
|
||||||
|
|
||||||
|
# H2 -> No Change
|
||||||
|
theTree[cHandle].setLayout(nwItemLayout.CHAPTER)
|
||||||
|
assert not theTree.updateItemLayout("c000000000002", "H2")
|
||||||
|
|
||||||
|
# H3 -> SCENE
|
||||||
|
theTree[cHandle].setLayout(nwItemLayout.CHAPTER)
|
||||||
|
assert theTree.updateItemLayout("c000000000002", "H3")
|
||||||
|
assert theTree[cHandle].itemLayout == nwItemLayout.SCENE
|
||||||
|
|
||||||
|
# H4 -> SCENE
|
||||||
|
theTree[cHandle].setLayout(nwItemLayout.CHAPTER)
|
||||||
|
assert theTree.updateItemLayout("c000000000002", "H4")
|
||||||
|
assert theTree[cHandle].itemLayout == nwItemLayout.SCENE
|
||||||
|
|
||||||
|
# Test UNNUMBERED Changes
|
||||||
|
# =======================
|
||||||
|
|
||||||
|
# H1 -> BOOK
|
||||||
|
theTree[cHandle].setLayout(nwItemLayout.UNNUMBERED)
|
||||||
|
assert theTree.updateItemLayout("c000000000002", "H1")
|
||||||
|
assert theTree[cHandle].itemLayout == nwItemLayout.BOOK
|
||||||
|
|
||||||
|
# H2 -> No Change
|
||||||
|
theTree[cHandle].setLayout(nwItemLayout.UNNUMBERED)
|
||||||
|
assert not theTree.updateItemLayout("c000000000002", "H2")
|
||||||
|
|
||||||
|
# H3 -> SCENE
|
||||||
|
theTree[cHandle].setLayout(nwItemLayout.UNNUMBERED)
|
||||||
|
assert theTree.updateItemLayout("c000000000002", "H3")
|
||||||
|
assert theTree[cHandle].itemLayout == nwItemLayout.SCENE
|
||||||
|
|
||||||
|
# H4 -> SCENE
|
||||||
|
theTree[cHandle].setLayout(nwItemLayout.UNNUMBERED)
|
||||||
|
assert theTree.updateItemLayout("c000000000002", "H4")
|
||||||
|
assert theTree[cHandle].itemLayout == nwItemLayout.SCENE
|
||||||
|
|
||||||
|
# Test PARTITION Changes
|
||||||
|
# ======================
|
||||||
|
|
||||||
|
# H1 -> BOOK
|
||||||
|
theTree[cHandle].setLayout(nwItemLayout.PARTITION)
|
||||||
|
assert not theTree.updateItemLayout("c000000000002", "H1")
|
||||||
|
|
||||||
|
# H2 -> No Change
|
||||||
|
theTree[cHandle].setLayout(nwItemLayout.PARTITION)
|
||||||
|
assert theTree.updateItemLayout("c000000000002", "H2")
|
||||||
|
assert theTree[cHandle].itemLayout == nwItemLayout.CHAPTER
|
||||||
|
|
||||||
|
# H3 -> SCENE
|
||||||
|
theTree[cHandle].setLayout(nwItemLayout.PARTITION)
|
||||||
|
assert theTree.updateItemLayout("c000000000002", "H3")
|
||||||
|
assert theTree[cHandle].itemLayout == nwItemLayout.SCENE
|
||||||
|
|
||||||
|
# H4 -> SCENE
|
||||||
|
theTree[cHandle].setLayout(nwItemLayout.PARTITION)
|
||||||
|
assert theTree.updateItemLayout("c000000000002", "H4")
|
||||||
|
assert theTree[cHandle].itemLayout == nwItemLayout.SCENE
|
||||||
|
|
||||||
|
# END Test testCoreTree_UpdateItemLayout
|
||||||
|
|
||||||
@pytest.mark.core
|
@pytest.mark.core
|
||||||
def testCoreTree_MakeHandles(monkeypatch, dummyGUI):
|
def testCoreTree_MakeHandles(monkeypatch, dummyGUI):
|
||||||
"""Test generating item handles.
|
"""Test generating item handles.
|
||||||
@@ -296,8 +421,8 @@ def testCoreTree_Stats(dummyGUI, dummyItems):
|
|||||||
theProject = NWProject(dummyGUI)
|
theProject = NWProject(dummyGUI)
|
||||||
theTree = NWTree(theProject)
|
theTree = NWTree(theProject)
|
||||||
|
|
||||||
for tHandle, pHande, nwItem in dummyItems:
|
for tHandle, pHandle, nwItem in dummyItems:
|
||||||
theTree.append(tHandle, pHande, nwItem)
|
theTree.append(tHandle, pHandle, nwItem)
|
||||||
|
|
||||||
assert len(theTree) == len(dummyItems)
|
assert len(theTree) == len(dummyItems)
|
||||||
theTree._treeOrder.append("dummy")
|
theTree._treeOrder.append("dummy")
|
||||||
@@ -323,9 +448,9 @@ def testCoreTree_Reorder(dummyGUI, dummyItems):
|
|||||||
theTree = NWTree(theProject)
|
theTree = NWTree(theProject)
|
||||||
|
|
||||||
aHandle = []
|
aHandle = []
|
||||||
for tHandle, pHande, nwItem in dummyItems:
|
for tHandle, pHandle, nwItem in dummyItems:
|
||||||
aHandle.append(tHandle)
|
aHandle.append(tHandle)
|
||||||
theTree.append(tHandle, pHande, nwItem)
|
theTree.append(tHandle, pHandle, nwItem)
|
||||||
|
|
||||||
assert len(theTree) == len(dummyItems)
|
assert len(theTree) == len(dummyItems)
|
||||||
|
|
||||||
@@ -348,13 +473,13 @@ def testCoreTree_Reorder(dummyGUI, dummyItems):
|
|||||||
|
|
||||||
@pytest.mark.core
|
@pytest.mark.core
|
||||||
def testCoreTree_XMLPackUnpack(dummyGUI, dummyItems):
|
def testCoreTree_XMLPackUnpack(dummyGUI, dummyItems):
|
||||||
"""Test changing tree order.
|
"""Test packing and unpacking the tree to and from XML.
|
||||||
"""
|
"""
|
||||||
theProject = NWProject(dummyGUI)
|
theProject = NWProject(dummyGUI)
|
||||||
theTree = NWTree(theProject)
|
theTree = NWTree(theProject)
|
||||||
|
|
||||||
for tHandle, pHande, nwItem in dummyItems:
|
for tHandle, pHandle, nwItem in dummyItems:
|
||||||
theTree.append(tHandle, pHande, nwItem)
|
theTree.append(tHandle, pHandle, nwItem)
|
||||||
|
|
||||||
assert len(theTree) == len(dummyItems)
|
assert len(theTree) == len(dummyItems)
|
||||||
|
|
||||||
@@ -408,8 +533,8 @@ def testCoreTree_ToCFile(monkeypatch, dummyGUI, dummyItems, tmpDir):
|
|||||||
theProject = NWProject(dummyGUI)
|
theProject = NWProject(dummyGUI)
|
||||||
theTree = NWTree(theProject)
|
theTree = NWTree(theProject)
|
||||||
|
|
||||||
for tHandle, pHande, nwItem in dummyItems:
|
for tHandle, pHandle, nwItem in dummyItems:
|
||||||
theTree.append(tHandle, pHande, nwItem)
|
theTree.append(tHandle, pHandle, nwItem)
|
||||||
|
|
||||||
assert len(theTree) == len(dummyItems)
|
assert len(theTree) == len(dummyItems)
|
||||||
theTree._treeOrder.append("dummy")
|
theTree._treeOrder.append("dummy")
|
||||||
|
|||||||
Reference in New Issue
Block a user