Merge pull request #620 from vkbo/item_layouts

Automatic Item Layouts
This commit is contained in:
Veronica K. Berglyd Olsen
2021-01-30 14:16:14 +00:00
committed by GitHub
8 changed files with 364 additions and 41 deletions
+36 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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>
+66 -17
View File
@@ -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
+139 -14
View File
@@ -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")