From 59cfb14a1961d2fbcd59be5f138ec796f75bd8ec Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Fri, 29 Jan 2021 00:57:34 +0100 Subject: [PATCH 1/7] Add a first title index that tracks the level and location of the first title of a file --- nw/core/index.py | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/nw/core/index.py b/nw/core/index.py index ba2e06f3..a4c013a1 100644 --- a/nw/core/index.py +++ b/nw/core/index.py @@ -57,6 +57,7 @@ class NWIndex(): self._novelIndex = {} self._noteIndex = {} self._textCounts = {} + self._firstTitle = {} # TimeStamps self._timeNovel = 0 @@ -77,6 +78,7 @@ class NWIndex(): self._novelIndex = {} self._noteIndex = {} self._textCounts = {} + self._firstTitle = {} self._timeNovel = 0 self._timeNotes = 0 self._timeIndex = 0 @@ -99,6 +101,7 @@ class NWIndex(): self._novelIndex.pop(tHandle, None) self._noteIndex.pop(tHandle, None) self._textCounts.pop(tHandle, None) + self._firstTitle.pop(tHandle, None) return @@ -162,6 +165,7 @@ class NWIndex(): self._novelIndex = theData.get("novelIndex", {}) self._noteIndex = theData.get("noteIndex", {}) self._textCounts = theData.get("textCounts", {}) + self._firstTitle = theData.get("firstTitle", {}) nowTime = round(time()) self._timeNovel = nowTime @@ -187,6 +191,7 @@ class NWIndex(): "novelIndex" : self._novelIndex, "noteIndex" : self._noteIndex, "textCounts" : self._textCounts, + "firstTitle" : self._firstTitle, }, outFile, indent=2) except Exception as e: logger.error("Failed to save index file") @@ -227,7 +232,13 @@ class NWIndex(): if len(self._textCounts[tHandle]) != 3: self.indexBroken = True - except Exception: + for tHandle in self._firstTitle: + if len(self._firstTitle[tHandle]) != 2: + self.indexBroken = True + + except Exception as e: + logger.error("Error while checking index") + logger.error(str(e)) self.indexBroken = True logger.debug("Index check complete") @@ -290,6 +301,7 @@ class NWIndex(): "tags" : [], "updated" : round(time()), } + self._firstTitle[tHandle] = ["H0", "T000000"] if itemLayout == nwItemLayout.NOTE: self._novelIndex.pop(tHandle, None) self._noteIndex[tHandle] = {} @@ -317,7 +329,7 @@ class NWIndex(): if nChar == 0: continue - if aLine.startswith(r"#"): + if aLine.startswith("#"): isTitle = self._indexTitle(tHandle, isNovel, aLine, nLine, itemLayout) if isTitle and nLine > 0: if nTitle > 0: @@ -325,11 +337,11 @@ class NWIndex(): self._indexWordCounts(tHandle, isNovel, lastText, nTitle) nTitle = nLine - elif aLine.startswith(r"@"): + elif aLine.startswith("@"): self._indexNoteRef(tHandle, aLine, nLine, nTitle) self._indexTag(tHandle, aLine, nLine, nTitle, itemClass) - elif aLine.startswith(r"%"): + elif aLine.startswith("%"): if nTitle > 0: toCheck = aLine[1:].lstrip() synTag = toCheck[:9].lower() @@ -398,6 +410,9 @@ class NWIndex(): "updated" : round(time()), } + if self._firstTitle[tHandle][0] == "H0": + self._firstTitle[tHandle] = [hDepth, sTitle] + if hText != "": if isNovel: if tHandle in self._novelIndex: @@ -643,6 +658,11 @@ class NWIndex(): 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): """Returns the counts for a file, or a section of a file starting at title sTitle if it is provided. From 4c27d2600aa1598e32b4fc77d8423d959c0df80d Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Fri, 29 Jan 2021 01:09:04 +0100 Subject: [PATCH 2/7] Update document layout during editor save process --- nw/core/tree.py | 48 ++++++++++++++++++++++++++++++++++++++++++++- nw/gui/doceditor.py | 8 +++++++- 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/nw/core/tree.py b/nw/core/tree.py index 36a56e5c..786ba89f 100644 --- a/nw/core/tree.py +++ b/nw/core/tree.py @@ -33,10 +33,36 @@ from time import time from nw.core.item import NWItem 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__) +# Translation map for item layouts +NOVEL_MAP = { + nwItemLayout.SCENE: { + "H1": nwItemLayout.PARTITION, + "H2": nwItemLayout.CHAPTER, + "H4": nwItemLayout.SCENE, + }, + nwItemLayout.CHAPTER: { + "H1": nwItemLayout.PARTITION, + "H3": nwItemLayout.SCENE, + "H4": nwItemLayout.SCENE, + }, + nwItemLayout.UNNUMBERED: { + "H1": nwItemLayout.PARTITION, + "H3": nwItemLayout.SCENE, + "H4": nwItemLayout.SCENE, + }, + nwItemLayout.PARTITION: { + "H2": nwItemLayout.CHAPTER, + "H3": nwItemLayout.SCENE, + "H4": nwItemLayout.SCENE, + }, +} + class NWTree(): def __init__(self, theProject): @@ -202,6 +228,26 @@ class NWTree(): novelWords += tItem.wordCount 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 NOVEL_MAP: + if hLevel in NOVEL_MAP[iLayout]: + tItem.itemLayout = NOVEL_MAP[iLayout][hLevel] + return True + + return False + ## # Tree Structure Methods ## diff --git a/nw/gui/doceditor.py b/nw/gui/doceditor.py index b3709420..9990988a 100644 --- a/nw/gui/doceditor.py +++ b/nw/gui/doceditor.py @@ -393,6 +393,7 @@ class GuiDocEditor(QTextEdit): return False docText = self.getText() + tHandle = theItem.itemHandle cC, wC, pC = countWords(docText) self._updateCounts(cC, wC, pC) @@ -405,7 +406,12 @@ class GuiDocEditor(QTextEdit): self.nwDocument.saveDocument(docText) 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 From 8de0c55b6849a369b1dc1914430bd026aa0f23ab Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Fri, 29 Jan 2021 01:14:58 +0100 Subject: [PATCH 3/7] Fix broken tests --- nw/core/tree.py | 8 +-- .../coreIndex_LoadSave_tagsIndex.json | 62 +++++++++++++++++++ .../guiEditor_Main_Final_0e17daca5f3e1.nwd | 2 +- .../guiEditor_Main_Final_nwProject.nwx | 8 +-- 4 files changed, 71 insertions(+), 9 deletions(-) diff --git a/nw/core/tree.py b/nw/core/tree.py index 786ba89f..85791f42 100644 --- a/nw/core/tree.py +++ b/nw/core/tree.py @@ -42,21 +42,21 @@ logger = logging.getLogger(__name__) # Translation map for item layouts NOVEL_MAP = { nwItemLayout.SCENE: { - "H1": nwItemLayout.PARTITION, + "H1": nwItemLayout.BOOK, "H2": nwItemLayout.CHAPTER, "H4": nwItemLayout.SCENE, }, nwItemLayout.CHAPTER: { - "H1": nwItemLayout.PARTITION, + "H1": nwItemLayout.BOOK, "H3": nwItemLayout.SCENE, "H4": nwItemLayout.SCENE, }, nwItemLayout.UNNUMBERED: { - "H1": nwItemLayout.PARTITION, + "H1": nwItemLayout.BOOK, "H3": nwItemLayout.SCENE, "H4": nwItemLayout.SCENE, }, - nwItemLayout.PARTITION: { + nwItemLayout.BOOK: { "H2": nwItemLayout.CHAPTER, "H3": nwItemLayout.SCENE, "H4": nwItemLayout.SCENE, diff --git a/tests/reference/coreIndex_LoadSave_tagsIndex.json b/tests/reference/coreIndex_LoadSave_tagsIndex.json index 2aa3df3c..993b4e26 100644 --- a/tests/reference/coreIndex_LoadSave_tagsIndex.json +++ b/tests/reference/coreIndex_LoadSave_tagsIndex.json @@ -567,5 +567,67 @@ 259, 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" + ] } } \ No newline at end of file diff --git a/tests/reference/guiEditor_Main_Final_0e17daca5f3e1.nwd b/tests/reference/guiEditor_Main_Final_0e17daca5f3e1.nwd index 54fef623..c77c3cd6 100644 --- a/tests/reference/guiEditor_Main_Final_0e17daca5f3e1.nwd +++ b/tests/reference/guiEditor_Main_Final_0e17daca5f3e1.nwd @@ -1,6 +1,6 @@ %%~name: New Scene %%~path: 31489056e0916/0e17daca5f3e1 -%%~kind: NOVEL/SCENE +%%~kind: NOVEL/BOOK # Novel ## Chapter diff --git a/tests/reference/guiEditor_Main_Final_nwProject.nwx b/tests/reference/guiEditor_Main_Final_nwProject.nwx index 21011e03..764c4610 100644 --- a/tests/reference/guiEditor_Main_Final_nwProject.nwx +++ b/tests/reference/guiEditor_Main_Final_nwProject.nwx @@ -1,11 +1,11 @@ - + New Project 4 - 1 - 11 + 2 + 8 True @@ -83,7 +83,7 @@ NOVEL New True - SCENE + BOOK 466 83 4 From 8e3fa892e1d6d141b1c06e099c0413635434191f Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Fri, 29 Jan 2021 11:55:36 +0100 Subject: [PATCH 4/7] Modify conditions according to #618 --- nw/core/tree.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/nw/core/tree.py b/nw/core/tree.py index 85791f42..f739a940 100644 --- a/nw/core/tree.py +++ b/nw/core/tree.py @@ -39,12 +39,11 @@ from nw.constants import ( logger = logging.getLogger(__name__) -# Translation map for item layouts -NOVEL_MAP = { +# Layout Translation Map +LAYOUT_MAP = { nwItemLayout.SCENE: { "H1": nwItemLayout.BOOK, "H2": nwItemLayout.CHAPTER, - "H4": nwItemLayout.SCENE, }, nwItemLayout.CHAPTER: { "H1": nwItemLayout.BOOK, @@ -56,7 +55,7 @@ NOVEL_MAP = { "H3": nwItemLayout.SCENE, "H4": nwItemLayout.SCENE, }, - nwItemLayout.BOOK: { + nwItemLayout.PARTITION: { "H2": nwItemLayout.CHAPTER, "H3": nwItemLayout.SCENE, "H4": nwItemLayout.SCENE, @@ -241,9 +240,9 @@ class NWTree(): return False iLayout = tItem.itemLayout - if iLayout in NOVEL_MAP: - if hLevel in NOVEL_MAP[iLayout]: - tItem.itemLayout = NOVEL_MAP[iLayout][hLevel] + if iLayout in LAYOUT_MAP: + if hLevel in LAYOUT_MAP[iLayout]: + tItem.itemLayout = LAYOUT_MAP[iLayout][hLevel] return True return False From b7766946d801dbd64461a1322c4c3eadbe9181a4 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Fri, 29 Jan 2021 20:43:04 +0100 Subject: [PATCH 5/7] Update index check and test --- nw/core/index.py | 23 +++++++-- tests/test_core/test_core_index.py | 83 ++++++++++++++++++++++++------ 2 files changed, 85 insertions(+), 21 deletions(-) diff --git a/nw/core/index.py b/nw/core/index.py index 15b4c955..85ec8791 100644 --- a/nw/core/index.py +++ b/nw/core/index.py @@ -220,12 +220,9 @@ class NWIndex(): self._checkNovelNoteIndex("novelIndex") self._checkNovelNoteIndex("noteIndex") self._checkTextCounts() + self._checkFirstTitles() self.indexBroken = False - for tHandle in self._firstTitle: - if len(self._firstTitle[tHandle]) != 2: - self.indexBroken = True - except Exception: logger.error("Error while checking index") nw.logException() @@ -897,4 +894,22 @@ class NWIndex(): 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 diff --git a/tests/test_core/test_core_index.py b/tests/test_core/test_core_index.py index 5e1e9223..bd2f6b3f 100644 --- a/tests/test_core/test_core_index.py +++ b/tests/test_core/test_core_index.py @@ -492,9 +492,8 @@ def testCoreIndex_ExtractData(nwMinimal, dummyGUI): assert wC == 12 # Words in text and title only assert pC == 2 # Paragraphs in text only - ## - # getReferences - ## + # getReferences + # ============= # Look up an ivalid handle theRefs = theIndex.getReferences("Not a handle") @@ -506,9 +505,8 @@ def testCoreIndex_ExtractData(nwMinimal, dummyGUI): assert theRefs["@pov"] == ["Jane"] assert theRefs["@char"] == ["Jane"] - ## - # getBackReferenceList - ## + # getBackReferenceList + # ==================== # None handle should return an empty dict assert theIndex.getBackReferenceList(None) == {} @@ -517,16 +515,15 @@ def testCoreIndex_ExtractData(nwMinimal, dummyGUI): theRefs = theIndex.getBackReferenceList(cHandle) assert theRefs == {nHandle: "T000001"} - ## - # getTagSource - ## + # getTagSource + # ============ assert theIndex.getTagSource("Jane") == (cHandle, 2, "T000001") assert theIndex.getTagSource("John") == (None, 0, "T000000") - ## - # getCounts for whole text and sections - ## + # getCounts + # ========= + # For whole text and sections # Get section counts for a novel file assert theIndex.scanText(nHandle, ( @@ -555,7 +552,7 @@ def testCoreIndex_ExtractData(nwMinimal, dummyGUI): assert wC == 12 assert pC == 2 - # First part + # Second part cC, wC, pC = theIndex.getCounts(nHandle, "T000011") assert cC == 62 assert wC == 12 @@ -588,15 +585,19 @@ def testCoreIndex_ExtractData(nwMinimal, dummyGUI): assert wC == 12 assert pC == 2 - # First part + # Second part cC, wC, pC = theIndex.getCounts(cHandle, "T000011") assert cC == 62 assert wC == 12 assert pC == 2 - ## - # Novel Stats - ## + # getFirstTitle + # ============= + + assert theIndex.getFirstTitle(cHandle) == ["H1", "T000001"] + + # Novel Stats + # =========== hHandle = theProject.newFile("Chapter", nwItemClass.NOVEL, "a508bb932959c") sHandle = theProject.newFile("Scene One", nwItemClass.NOVEL, "a508bb932959c") @@ -1145,3 +1146,51 @@ def testCoreIndex_CheckTextCounts(dummyGUI): theIndex._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 From cab1530afc775f8a96cea2db281e35144d1e0bcf Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Sat, 30 Jan 2021 01:03:54 +0100 Subject: [PATCH 6/7] Add debug log output for layout change --- nw/core/tree.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nw/core/tree.py b/nw/core/tree.py index dd72c3ff..5fdc55ba 100644 --- a/nw/core/tree.py +++ b/nw/core/tree.py @@ -245,6 +245,9 @@ class NWTree(): 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 From 0624f9103f229fc940ce0a3a53e1db61616248ba Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Sat, 30 Jan 2021 01:28:05 +0100 Subject: [PATCH 7/7] Get test coverage of NWTree back to 100% --- tests/test_core/test_core_tree.py | 153 +++++++++++++++++++++++++++--- 1 file changed, 139 insertions(+), 14 deletions(-) diff --git a/tests/test_core/test_core_tree.py b/tests/test_core/test_core_tree.py index 62803830..d4588b37 100644 --- a/tests/test_core/test_core_tree.py +++ b/tests/test_core/test_core_tree.py @@ -123,9 +123,9 @@ def testCoreTree_BuildTree(dummyGUI, dummyItems): assert not theTree.isTrashRoot("a000000000003") aHandles = [] - for tHandle, pHande, nwItem in dummyItems: + for tHandle, pHandle, nwItem in dummyItems: aHandles.append(tHandle) - assert theTree.append(tHandle, pHande, nwItem) + assert theTree.append(tHandle, pHandle, nwItem) assert theTree._treeChanged @@ -202,13 +202,13 @@ def testCoreTree_BuildTree(dummyGUI, dummyItems): @pytest.mark.core def testCoreTree_Methods(dummyGUI, dummyItems): - """Test building a project tree from a list of items. + """Test bvarious class methods. """ theProject = NWProject(dummyGUI) theTree = NWTree(theProject) - for tHandle, pHande, nwItem in dummyItems: - theTree.append(tHandle, pHande, nwItem) + for tHandle, pHandle, nwItem in dummyItems: + theTree.append(tHandle, pHandle, nwItem) assert len(theTree) == len(dummyItems) @@ -256,6 +256,131 @@ def testCoreTree_Methods(dummyGUI, dummyItems): # 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 def testCoreTree_MakeHandles(monkeypatch, dummyGUI): """Test generating item handles. @@ -296,8 +421,8 @@ def testCoreTree_Stats(dummyGUI, dummyItems): theProject = NWProject(dummyGUI) theTree = NWTree(theProject) - for tHandle, pHande, nwItem in dummyItems: - theTree.append(tHandle, pHande, nwItem) + for tHandle, pHandle, nwItem in dummyItems: + theTree.append(tHandle, pHandle, nwItem) assert len(theTree) == len(dummyItems) theTree._treeOrder.append("dummy") @@ -323,9 +448,9 @@ def testCoreTree_Reorder(dummyGUI, dummyItems): theTree = NWTree(theProject) aHandle = [] - for tHandle, pHande, nwItem in dummyItems: + for tHandle, pHandle, nwItem in dummyItems: aHandle.append(tHandle) - theTree.append(tHandle, pHande, nwItem) + theTree.append(tHandle, pHandle, nwItem) assert len(theTree) == len(dummyItems) @@ -348,13 +473,13 @@ def testCoreTree_Reorder(dummyGUI, dummyItems): @pytest.mark.core def testCoreTree_XMLPackUnpack(dummyGUI, dummyItems): - """Test changing tree order. + """Test packing and unpacking the tree to and from XML. """ theProject = NWProject(dummyGUI) theTree = NWTree(theProject) - for tHandle, pHande, nwItem in dummyItems: - theTree.append(tHandle, pHande, nwItem) + for tHandle, pHandle, nwItem in dummyItems: + theTree.append(tHandle, pHandle, nwItem) assert len(theTree) == len(dummyItems) @@ -408,8 +533,8 @@ def testCoreTree_ToCFile(monkeypatch, dummyGUI, dummyItems, tmpDir): theProject = NWProject(dummyGUI) theTree = NWTree(theProject) - for tHandle, pHande, nwItem in dummyItems: - theTree.append(tHandle, pHande, nwItem) + for tHandle, pHandle, nwItem in dummyItems: + theTree.append(tHandle, pHandle, nwItem) assert len(theTree) == len(dummyItems) theTree._treeOrder.append("dummy")