Add test coverage of template feature
This commit is contained in:
@@ -659,7 +659,10 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
# Set default label and determine if new item is to be added
|
# Set default label and determine if new item is to be added
|
||||||
# as child or sibling to the selected item
|
# as child or sibling to the selected item
|
||||||
if itemType == nwItemType.FILE:
|
if itemType == nwItemType.FILE:
|
||||||
if isNote:
|
if copyDoc and (cItem := SHARED.project.tree[copyDoc]):
|
||||||
|
newLabel = cItem.itemName
|
||||||
|
asChild = sIsParent and pItem.isDocumentLayout()
|
||||||
|
elif isNote:
|
||||||
newLabel = self.tr("New Note")
|
newLabel = self.tr("New Note")
|
||||||
asChild = sIsParent
|
asChild = sIsParent
|
||||||
elif hLevel == 2:
|
elif hLevel == 2:
|
||||||
@@ -804,8 +807,7 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
|
|
||||||
def renameTreeItem(self, tHandle: str, name: str = "") -> None:
|
def renameTreeItem(self, tHandle: str, name: str = "") -> None:
|
||||||
"""Open a dialog to edit the label of an item."""
|
"""Open a dialog to edit the label of an item."""
|
||||||
tItem = SHARED.project.tree[tHandle]
|
if tItem := SHARED.project.tree[tHandle]:
|
||||||
if tItem:
|
|
||||||
newLabel, dlgOk = GuiEditLabel.getLabel(self, text=name or tItem.itemName)
|
newLabel, dlgOk = GuiEditLabel.getLabel(self, text=name or tItem.itemName)
|
||||||
if dlgOk:
|
if dlgOk:
|
||||||
tItem.setName(newLabel)
|
tItem.setName(newLabel)
|
||||||
@@ -1707,7 +1709,7 @@ class _UpdatableMenu(QMenu):
|
|||||||
if action := self._map.pop(tHandle, None):
|
if action := self._map.pop(tHandle, None):
|
||||||
self.removeAction(action)
|
self.removeAction(action)
|
||||||
if not self._map:
|
if not self._map:
|
||||||
self.setActionsVisible(True)
|
self.setActionsVisible(False)
|
||||||
return
|
return
|
||||||
|
|
||||||
def clearMenu(self) -> None:
|
def clearMenu(self) -> None:
|
||||||
|
|||||||
@@ -365,6 +365,7 @@ def testCoreItem_ClassSetter(mockGUI):
|
|||||||
"""
|
"""
|
||||||
project = NWProject()
|
project = NWProject()
|
||||||
item = NWItem(project, "0000000000000")
|
item = NWItem(project, "0000000000000")
|
||||||
|
item.setType(nwItemType.FILE)
|
||||||
|
|
||||||
# Class
|
# Class
|
||||||
item.setClass(None)
|
item.setClass(None)
|
||||||
@@ -377,66 +378,84 @@ def testCoreItem_ClassSetter(mockGUI):
|
|||||||
assert item.isNovelLike() is False
|
assert item.isNovelLike() is False
|
||||||
assert item.documentAllowed() is False
|
assert item.documentAllowed() is False
|
||||||
assert item.isInactiveClass() is True
|
assert item.isInactiveClass() is True
|
||||||
|
assert item.isTemplateFile() is False
|
||||||
|
|
||||||
item.setClass("NOVEL")
|
item.setClass("NOVEL")
|
||||||
assert item.itemClass == nwItemClass.NOVEL
|
assert item.itemClass == nwItemClass.NOVEL
|
||||||
assert item.isNovelLike() is True
|
assert item.isNovelLike() is True
|
||||||
assert item.documentAllowed() is True
|
assert item.documentAllowed() is True
|
||||||
assert item.isInactiveClass() is False
|
assert item.isInactiveClass() is False
|
||||||
|
assert item.isTemplateFile() is False
|
||||||
|
|
||||||
item.setClass("PLOT")
|
item.setClass("PLOT")
|
||||||
assert item.itemClass == nwItemClass.PLOT
|
assert item.itemClass == nwItemClass.PLOT
|
||||||
assert item.isNovelLike() is False
|
assert item.isNovelLike() is False
|
||||||
assert item.documentAllowed() is False
|
assert item.documentAllowed() is False
|
||||||
assert item.isInactiveClass() is False
|
assert item.isInactiveClass() is False
|
||||||
|
assert item.isTemplateFile() is False
|
||||||
|
|
||||||
item.setClass("CHARACTER")
|
item.setClass("CHARACTER")
|
||||||
assert item.itemClass == nwItemClass.CHARACTER
|
assert item.itemClass == nwItemClass.CHARACTER
|
||||||
assert item.isNovelLike() is False
|
assert item.isNovelLike() is False
|
||||||
assert item.documentAllowed() is False
|
assert item.documentAllowed() is False
|
||||||
assert item.isInactiveClass() is False
|
assert item.isInactiveClass() is False
|
||||||
|
assert item.isTemplateFile() is False
|
||||||
|
|
||||||
item.setClass("WORLD")
|
item.setClass("WORLD")
|
||||||
assert item.itemClass == nwItemClass.WORLD
|
assert item.itemClass == nwItemClass.WORLD
|
||||||
assert item.isNovelLike() is False
|
assert item.isNovelLike() is False
|
||||||
assert item.documentAllowed() is False
|
assert item.documentAllowed() is False
|
||||||
assert item.isInactiveClass() is False
|
assert item.isInactiveClass() is False
|
||||||
|
assert item.isTemplateFile() is False
|
||||||
|
|
||||||
item.setClass("TIMELINE")
|
item.setClass("TIMELINE")
|
||||||
assert item.itemClass == nwItemClass.TIMELINE
|
assert item.itemClass == nwItemClass.TIMELINE
|
||||||
assert item.isNovelLike() is False
|
assert item.isNovelLike() is False
|
||||||
assert item.documentAllowed() is False
|
assert item.documentAllowed() is False
|
||||||
assert item.isInactiveClass() is False
|
assert item.isInactiveClass() is False
|
||||||
|
assert item.isTemplateFile() is False
|
||||||
|
|
||||||
item.setClass("OBJECT")
|
item.setClass("OBJECT")
|
||||||
assert item.itemClass == nwItemClass.OBJECT
|
assert item.itemClass == nwItemClass.OBJECT
|
||||||
assert item.isNovelLike() is False
|
assert item.isNovelLike() is False
|
||||||
assert item.documentAllowed() is False
|
assert item.documentAllowed() is False
|
||||||
assert item.isInactiveClass() is False
|
assert item.isInactiveClass() is False
|
||||||
|
assert item.isTemplateFile() is False
|
||||||
|
|
||||||
item.setClass("ENTITY")
|
item.setClass("ENTITY")
|
||||||
assert item.itemClass == nwItemClass.ENTITY
|
assert item.itemClass == nwItemClass.ENTITY
|
||||||
assert item.isNovelLike() is False
|
assert item.isNovelLike() is False
|
||||||
assert item.documentAllowed() is False
|
assert item.documentAllowed() is False
|
||||||
assert item.isInactiveClass() is False
|
assert item.isInactiveClass() is False
|
||||||
|
assert item.isTemplateFile() is False
|
||||||
|
|
||||||
item.setClass("CUSTOM")
|
item.setClass("CUSTOM")
|
||||||
assert item.itemClass == nwItemClass.CUSTOM
|
assert item.itemClass == nwItemClass.CUSTOM
|
||||||
assert item.isNovelLike() is False
|
assert item.isNovelLike() is False
|
||||||
assert item.documentAllowed() is False
|
assert item.documentAllowed() is False
|
||||||
assert item.isInactiveClass() is False
|
assert item.isInactiveClass() is False
|
||||||
|
assert item.isTemplateFile() is False
|
||||||
|
|
||||||
item.setClass("ARCHIVE")
|
item.setClass("ARCHIVE")
|
||||||
assert item.itemClass == nwItemClass.ARCHIVE
|
assert item.itemClass == nwItemClass.ARCHIVE
|
||||||
assert item.isNovelLike() is True
|
assert item.isNovelLike() is True
|
||||||
assert item.documentAllowed() is True
|
assert item.documentAllowed() is True
|
||||||
assert item.isInactiveClass() is True
|
assert item.isInactiveClass() is True
|
||||||
|
assert item.isTemplateFile() is False
|
||||||
|
|
||||||
|
item.setClass("TEMPLATE")
|
||||||
|
assert item.itemClass == nwItemClass.TEMPLATE
|
||||||
|
assert item.isNovelLike() is True
|
||||||
|
assert item.documentAllowed() is True
|
||||||
|
assert item.isInactiveClass() is True
|
||||||
|
assert item.isTemplateFile() is True
|
||||||
|
|
||||||
item.setClass("TRASH")
|
item.setClass("TRASH")
|
||||||
assert item.itemClass == nwItemClass.TRASH
|
assert item.itemClass == nwItemClass.TRASH
|
||||||
assert item.isNovelLike() is False
|
assert item.isNovelLike() is False
|
||||||
assert item.documentAllowed() is True
|
assert item.documentAllowed() is True
|
||||||
assert item.isInactiveClass() is True
|
assert item.isInactiveClass() is True
|
||||||
|
assert item.isTemplateFile() is False
|
||||||
|
|
||||||
# Alternative
|
# Alternative
|
||||||
item.setClass(nwItemClass.NOVEL)
|
item.setClass(nwItemClass.NOVEL)
|
||||||
|
|||||||
@@ -115,15 +115,28 @@ def testGuiProjTree_NewItems(qtbot, caplog, monkeypatch, nwGUI, projPath, mockRn
|
|||||||
assert nwGUI.docEditor.getText() == "### New Scene\n\n"
|
assert nwGUI.docEditor.getText() == "### New Scene\n\n"
|
||||||
assert projTree._getItemWordCount("0000000000014") == 2
|
assert projTree._getItemWordCount("0000000000014") == 2
|
||||||
|
|
||||||
|
# Add a new scene with the content copied from the previous
|
||||||
|
assert nwGUI.openDocument("0000000000014")
|
||||||
|
nwGUI.docEditor.setPlainText("### New Scene\n\nWith Stuff\n\n")
|
||||||
|
nwGUI.saveDocument()
|
||||||
|
projView.setSelectedHandle("0000000000014")
|
||||||
|
assert projTree.newTreeItem(nwItemType.FILE, copyDoc="0000000000014") is True
|
||||||
|
assert project.tree["0000000000015"].itemParent == "0000000000011" # type: ignore
|
||||||
|
assert project.tree["0000000000015"].itemRoot == C.hNovelRoot # type: ignore
|
||||||
|
assert project.tree["0000000000015"].itemClass == nwItemClass.NOVEL # type: ignore
|
||||||
|
assert nwGUI.openDocument("0000000000015")
|
||||||
|
assert nwGUI.docEditor.getText() == "### New Scene\n\nWith Stuff\n\n"
|
||||||
|
assert projTree._getItemWordCount("0000000000015") == 4
|
||||||
|
|
||||||
# Add a new file to the characters folder
|
# Add a new file to the characters folder
|
||||||
projView.setSelectedHandle(C.hCharRoot)
|
projView.setSelectedHandle(C.hCharRoot)
|
||||||
assert projTree.newTreeItem(nwItemType.FILE, hLevel=1, isNote=True) is True
|
assert projTree.newTreeItem(nwItemType.FILE, hLevel=1, isNote=True) is True
|
||||||
assert project.tree["0000000000015"].itemParent == C.hCharRoot # type: ignore
|
assert project.tree["0000000000016"].itemParent == C.hCharRoot # type: ignore
|
||||||
assert project.tree["0000000000015"].itemRoot == C.hCharRoot # type: ignore
|
assert project.tree["0000000000016"].itemRoot == C.hCharRoot # type: ignore
|
||||||
assert project.tree["0000000000015"].itemClass == nwItemClass.CHARACTER # type: ignore
|
assert project.tree["0000000000016"].itemClass == nwItemClass.CHARACTER # type: ignore
|
||||||
assert nwGUI.openDocument("0000000000015")
|
assert nwGUI.openDocument("0000000000016")
|
||||||
assert nwGUI.docEditor.getText() == "# New Note\n\n"
|
assert nwGUI.docEditor.getText() == "# New Note\n\n"
|
||||||
assert projTree._getItemWordCount("0000000000015") == 2
|
assert projTree._getItemWordCount("0000000000016") == 2
|
||||||
|
|
||||||
# Make sure the sibling folder bug trap works
|
# Make sure the sibling folder bug trap works
|
||||||
projView.setSelectedHandle("0000000000013")
|
projView.setSelectedHandle("0000000000013")
|
||||||
@@ -1112,7 +1125,7 @@ def testGuiProjTree_Other(qtbot, monkeypatch, nwGUI: GuiMain, projPath, mockRnd)
|
|||||||
@pytest.mark.gui
|
@pytest.mark.gui
|
||||||
def testGuiProjTree_ContextMenu(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
|
def testGuiProjTree_ContextMenu(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
|
||||||
"""Test the building of the project tree context menu. All this does
|
"""Test the building of the project tree context menu. All this does
|
||||||
is test that the menu builds. It doesn't open the actual menu,
|
is test that the menu builds. It doesn't open the actual menu.
|
||||||
"""
|
"""
|
||||||
monkeypatch.setattr(GuiEditLabel, "getLabel", lambda *a, text: (text, True))
|
monkeypatch.setattr(GuiEditLabel, "getLabel", lambda *a, text: (text, True))
|
||||||
|
|
||||||
@@ -1392,3 +1405,98 @@ def testGuiProjTree_ContextMenu(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
|
|||||||
# qtbot.stop()
|
# qtbot.stop()
|
||||||
|
|
||||||
# END Test testGuiProjTree_ContextMenu
|
# END Test testGuiProjTree_ContextMenu
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.gui
|
||||||
|
def testGuiProjTree_Templates(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
|
||||||
|
"""Test the templates feature of the project tree."""
|
||||||
|
monkeypatch.setattr(GuiEditLabel, "getLabel", lambda *a, text: (text, True))
|
||||||
|
|
||||||
|
# Create a project
|
||||||
|
buildTestProject(nwGUI, projPath)
|
||||||
|
nwGUI.openProject(projPath)
|
||||||
|
nwGUI.switchFocus(nwWidget.TREE)
|
||||||
|
nwGUI.show()
|
||||||
|
|
||||||
|
project = SHARED.project
|
||||||
|
|
||||||
|
projView = nwGUI.projView
|
||||||
|
projTree = projView.projTree
|
||||||
|
projBar = projView.projBar
|
||||||
|
|
||||||
|
# Handles for new objects
|
||||||
|
hTemplatesRoot = "0000000000010"
|
||||||
|
hSceneTemplate = "0000000000011"
|
||||||
|
hNoteTemplate = "0000000000012"
|
||||||
|
hNewScene = "0000000000013"
|
||||||
|
hNewCharacter = "0000000000014"
|
||||||
|
|
||||||
|
# Add template folder
|
||||||
|
projTree.newTreeItem(nwItemType.ROOT, nwItemClass.TEMPLATE)
|
||||||
|
nwTemplateRoot = project.tree[hTemplatesRoot]
|
||||||
|
assert nwTemplateRoot is not None
|
||||||
|
assert nwTemplateRoot.itemName == "Templates"
|
||||||
|
|
||||||
|
# Add a scene template
|
||||||
|
projTree.setSelectedHandle(hTemplatesRoot)
|
||||||
|
projTree.newTreeItem(nwItemType.FILE, hLevel=3, isNote=False)
|
||||||
|
nwSceneTemplate = project.tree[hSceneTemplate]
|
||||||
|
assert nwSceneTemplate is not None
|
||||||
|
assert nwSceneTemplate.itemName == "New Scene"
|
||||||
|
assert projBar.mTemplates.actions()[0].text() == "New Scene"
|
||||||
|
|
||||||
|
# Rename the scene template
|
||||||
|
with qtbot.waitSignal(projTree.itemRefreshed, timeout=1000) as signal:
|
||||||
|
projTree.renameTreeItem(hSceneTemplate, name="Scene")
|
||||||
|
assert signal.args[0] == hSceneTemplate
|
||||||
|
assert signal.args[1].itemName == "Scene"
|
||||||
|
assert projBar.mTemplates.actions()[0].text() == "Scene"
|
||||||
|
|
||||||
|
# Add a note template
|
||||||
|
projTree.setSelectedHandle(hTemplatesRoot)
|
||||||
|
projTree.newTreeItem(nwItemType.FILE, hLevel=1, isNote=True)
|
||||||
|
nwNoteTemplate = project.tree[hNoteTemplate]
|
||||||
|
assert nwNoteTemplate is not None
|
||||||
|
assert nwNoteTemplate.itemName == "New Note"
|
||||||
|
assert projBar.mTemplates.actions()[1].text() == "New Note"
|
||||||
|
|
||||||
|
# Rename the note template
|
||||||
|
with qtbot.waitSignal(projTree.itemRefreshed, timeout=1000) as signal:
|
||||||
|
projTree.renameTreeItem(hNoteTemplate, name="Note")
|
||||||
|
assert signal.args[0] == hNoteTemplate
|
||||||
|
assert signal.args[1].itemName == "Note"
|
||||||
|
assert projBar.mTemplates.actions()[1].text() == "Note"
|
||||||
|
|
||||||
|
# Add new content to template files
|
||||||
|
(projPath / "content" / f"{hSceneTemplate}.nwd").write_text("### Scene\n\n@pov: Jane\n\n")
|
||||||
|
(projPath / "content" / f"{hNoteTemplate}.nwd").write_text("# Jane\n\n@tag: Jane\n\n")
|
||||||
|
|
||||||
|
# Add a new scene using the template
|
||||||
|
projTree.setSelectedHandle(C.hSceneDoc, doScroll=True)
|
||||||
|
projBar.mTemplates.actions()[0].trigger()
|
||||||
|
nwNewScene = project.tree[hNewScene]
|
||||||
|
assert nwNewScene is not None
|
||||||
|
assert nwNewScene.itemName == "Scene"
|
||||||
|
assert project.storage.getDocument(hNewScene).readDocument() == "### Scene\n\n@pov: Jane\n\n"
|
||||||
|
|
||||||
|
# Add a new note using the template
|
||||||
|
projTree.setSelectedHandle(C.hCharRoot, doScroll=True)
|
||||||
|
projBar.mTemplates.actions()[1].trigger()
|
||||||
|
nwNewCharacter = project.tree[hNewCharacter]
|
||||||
|
assert nwNewCharacter is not None
|
||||||
|
assert nwNewCharacter.itemName == "Note"
|
||||||
|
assert project.storage.getDocument(hNewCharacter).readDocument() == "# Jane\n\n@tag: Jane\n\n"
|
||||||
|
|
||||||
|
# Remove the templates
|
||||||
|
with qtbot.waitSignal(projTree.itemRefreshed, timeout=1000) as signal:
|
||||||
|
assert projBar.mTemplates.menuAction().isVisible() is True
|
||||||
|
assert len(projBar.mTemplates.actions()) == 2
|
||||||
|
projTree.moveItemToTrash(hNoteTemplate)
|
||||||
|
assert len(projBar.mTemplates.actions()) == 1
|
||||||
|
projTree.moveItemToTrash(hSceneTemplate)
|
||||||
|
assert len(projBar.mTemplates.actions()) == 0
|
||||||
|
assert projBar.mTemplates.menuAction().isVisible() is False
|
||||||
|
|
||||||
|
# qtbot.stop()
|
||||||
|
|
||||||
|
# END Test testGuiProjTree_Templates
|
||||||
|
|||||||
Reference in New Issue
Block a user