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
|
||||
# as child or sibling to the selected item
|
||||
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")
|
||||
asChild = sIsParent
|
||||
elif hLevel == 2:
|
||||
@@ -804,8 +807,7 @@ class GuiProjectTree(QTreeWidget):
|
||||
|
||||
def renameTreeItem(self, tHandle: str, name: str = "") -> None:
|
||||
"""Open a dialog to edit the label of an item."""
|
||||
tItem = SHARED.project.tree[tHandle]
|
||||
if tItem:
|
||||
if tItem := SHARED.project.tree[tHandle]:
|
||||
newLabel, dlgOk = GuiEditLabel.getLabel(self, text=name or tItem.itemName)
|
||||
if dlgOk:
|
||||
tItem.setName(newLabel)
|
||||
@@ -1707,7 +1709,7 @@ class _UpdatableMenu(QMenu):
|
||||
if action := self._map.pop(tHandle, None):
|
||||
self.removeAction(action)
|
||||
if not self._map:
|
||||
self.setActionsVisible(True)
|
||||
self.setActionsVisible(False)
|
||||
return
|
||||
|
||||
def clearMenu(self) -> None:
|
||||
|
||||
@@ -365,6 +365,7 @@ def testCoreItem_ClassSetter(mockGUI):
|
||||
"""
|
||||
project = NWProject()
|
||||
item = NWItem(project, "0000000000000")
|
||||
item.setType(nwItemType.FILE)
|
||||
|
||||
# Class
|
||||
item.setClass(None)
|
||||
@@ -377,66 +378,84 @@ def testCoreItem_ClassSetter(mockGUI):
|
||||
assert item.isNovelLike() is False
|
||||
assert item.documentAllowed() is False
|
||||
assert item.isInactiveClass() is True
|
||||
assert item.isTemplateFile() is False
|
||||
|
||||
item.setClass("NOVEL")
|
||||
assert item.itemClass == nwItemClass.NOVEL
|
||||
assert item.isNovelLike() is True
|
||||
assert item.documentAllowed() is True
|
||||
assert item.isInactiveClass() is False
|
||||
assert item.isTemplateFile() is False
|
||||
|
||||
item.setClass("PLOT")
|
||||
assert item.itemClass == nwItemClass.PLOT
|
||||
assert item.isNovelLike() is False
|
||||
assert item.documentAllowed() is False
|
||||
assert item.isInactiveClass() is False
|
||||
assert item.isTemplateFile() is False
|
||||
|
||||
item.setClass("CHARACTER")
|
||||
assert item.itemClass == nwItemClass.CHARACTER
|
||||
assert item.isNovelLike() is False
|
||||
assert item.documentAllowed() is False
|
||||
assert item.isInactiveClass() is False
|
||||
assert item.isTemplateFile() is False
|
||||
|
||||
item.setClass("WORLD")
|
||||
assert item.itemClass == nwItemClass.WORLD
|
||||
assert item.isNovelLike() is False
|
||||
assert item.documentAllowed() is False
|
||||
assert item.isInactiveClass() is False
|
||||
assert item.isTemplateFile() is False
|
||||
|
||||
item.setClass("TIMELINE")
|
||||
assert item.itemClass == nwItemClass.TIMELINE
|
||||
assert item.isNovelLike() is False
|
||||
assert item.documentAllowed() is False
|
||||
assert item.isInactiveClass() is False
|
||||
assert item.isTemplateFile() is False
|
||||
|
||||
item.setClass("OBJECT")
|
||||
assert item.itemClass == nwItemClass.OBJECT
|
||||
assert item.isNovelLike() is False
|
||||
assert item.documentAllowed() is False
|
||||
assert item.isInactiveClass() is False
|
||||
assert item.isTemplateFile() is False
|
||||
|
||||
item.setClass("ENTITY")
|
||||
assert item.itemClass == nwItemClass.ENTITY
|
||||
assert item.isNovelLike() is False
|
||||
assert item.documentAllowed() is False
|
||||
assert item.isInactiveClass() is False
|
||||
assert item.isTemplateFile() is False
|
||||
|
||||
item.setClass("CUSTOM")
|
||||
assert item.itemClass == nwItemClass.CUSTOM
|
||||
assert item.isNovelLike() is False
|
||||
assert item.documentAllowed() is False
|
||||
assert item.isInactiveClass() is False
|
||||
assert item.isTemplateFile() is False
|
||||
|
||||
item.setClass("ARCHIVE")
|
||||
assert item.itemClass == nwItemClass.ARCHIVE
|
||||
assert item.isNovelLike() is True
|
||||
assert item.documentAllowed() 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")
|
||||
assert item.itemClass == nwItemClass.TRASH
|
||||
assert item.isNovelLike() is False
|
||||
assert item.documentAllowed() is True
|
||||
assert item.isInactiveClass() is True
|
||||
assert item.isTemplateFile() is False
|
||||
|
||||
# Alternative
|
||||
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 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
|
||||
projView.setSelectedHandle(C.hCharRoot)
|
||||
assert projTree.newTreeItem(nwItemType.FILE, hLevel=1, isNote=True) is True
|
||||
assert project.tree["0000000000015"].itemParent == C.hCharRoot # type: ignore
|
||||
assert project.tree["0000000000015"].itemRoot == C.hCharRoot # type: ignore
|
||||
assert project.tree["0000000000015"].itemClass == nwItemClass.CHARACTER # type: ignore
|
||||
assert nwGUI.openDocument("0000000000015")
|
||||
assert project.tree["0000000000016"].itemParent == C.hCharRoot # type: ignore
|
||||
assert project.tree["0000000000016"].itemRoot == C.hCharRoot # type: ignore
|
||||
assert project.tree["0000000000016"].itemClass == nwItemClass.CHARACTER # type: ignore
|
||||
assert nwGUI.openDocument("0000000000016")
|
||||
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
|
||||
projView.setSelectedHandle("0000000000013")
|
||||
@@ -1112,7 +1125,7 @@ def testGuiProjTree_Other(qtbot, monkeypatch, nwGUI: GuiMain, projPath, mockRnd)
|
||||
@pytest.mark.gui
|
||||
def testGuiProjTree_ContextMenu(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
|
||||
"""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))
|
||||
|
||||
@@ -1392,3 +1405,98 @@ def testGuiProjTree_ContextMenu(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
|
||||
# qtbot.stop()
|
||||
|
||||
# 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