Tighten up the item class (#937)
* Protect the attributes of the NWItem class * Fix test coverage * Add a type checker function to the tree class
This commit is contained in:
committed by
GitHub
parent
af3d0d2eb0
commit
6ac9e1aec4
@@ -107,11 +107,7 @@ class NWIndex():
|
||||
project.
|
||||
"""
|
||||
logger.debug("Re-indexing item '%s'", tHandle)
|
||||
|
||||
tItem = self.theProject.projTree[tHandle]
|
||||
if tItem is None:
|
||||
return False
|
||||
if tItem.itemType != nwItemType.FILE:
|
||||
if not self.theProject.projTree.checkType(tHandle, nwItemType.FILE):
|
||||
return False
|
||||
|
||||
theDoc = NWDoc(self.theProject, tHandle)
|
||||
|
||||
+135
-65
@@ -42,26 +42,96 @@ class NWItem():
|
||||
|
||||
self.theProject = theProject
|
||||
|
||||
self.itemName = ""
|
||||
self.itemHandle = None
|
||||
self.itemParent = None
|
||||
self.itemOrder = 0
|
||||
self.itemType = nwItemType.NO_TYPE
|
||||
self.itemClass = nwItemClass.NO_CLASS
|
||||
self.itemLayout = nwItemLayout.NO_LAYOUT
|
||||
self.itemStatus = None
|
||||
self.isExpanded = False
|
||||
self.isExported = True
|
||||
self._name = ""
|
||||
self._handle = None
|
||||
self._parent = None
|
||||
self._order = 0
|
||||
self._type = nwItemType.NO_TYPE
|
||||
self._class = nwItemClass.NO_CLASS
|
||||
self._layout = nwItemLayout.NO_LAYOUT
|
||||
self._status = None
|
||||
self._expanded = False
|
||||
self._exported = True
|
||||
|
||||
# Document Meta Data
|
||||
self.charCount = 0 # Current character count
|
||||
self.wordCount = 0 # Current word count
|
||||
self.paraCount = 0 # Current paragraph count
|
||||
self.initCount = 0 # Initial word count
|
||||
self.cursorPos = 0 # Last cursor position
|
||||
self._charCount = 0 # Current character count
|
||||
self._wordCount = 0 # Current word count
|
||||
self._paraCount = 0 # Current paragraph count
|
||||
self._cursorPos = 0 # Last cursor position
|
||||
self._initCount = 0 # Initial word count
|
||||
|
||||
return
|
||||
|
||||
def __repr__(self):
|
||||
return f"<NWItem handle={self._handle}, parent={self._parent}, name='{self._name}'>"
|
||||
|
||||
def __bool__(self):
|
||||
return self._handle is not None
|
||||
|
||||
##
|
||||
# Properties
|
||||
##
|
||||
|
||||
@property
|
||||
def itemName(self):
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def itemHandle(self):
|
||||
return self._handle
|
||||
|
||||
@property
|
||||
def itemParent(self):
|
||||
return self._parent
|
||||
|
||||
@property
|
||||
def itemOrder(self):
|
||||
return self._order
|
||||
|
||||
@property
|
||||
def itemType(self):
|
||||
return self._type
|
||||
|
||||
@property
|
||||
def itemClass(self):
|
||||
return self._class
|
||||
|
||||
@property
|
||||
def itemLayout(self):
|
||||
return self._layout
|
||||
|
||||
@property
|
||||
def itemStatus(self):
|
||||
return self._status
|
||||
|
||||
@property
|
||||
def isExpanded(self):
|
||||
return self._expanded
|
||||
|
||||
@property
|
||||
def isExported(self):
|
||||
return self._exported
|
||||
|
||||
@property
|
||||
def charCount(self):
|
||||
return self._charCount
|
||||
|
||||
@property
|
||||
def wordCount(self):
|
||||
return self._wordCount
|
||||
|
||||
@property
|
||||
def paraCount(self):
|
||||
return self._paraCount
|
||||
|
||||
@property
|
||||
def initCount(self):
|
||||
return self._initCount
|
||||
|
||||
@property
|
||||
def cursorPos(self):
|
||||
return self._cursorPos
|
||||
|
||||
##
|
||||
# XML Pack/Unpack
|
||||
##
|
||||
@@ -70,23 +140,23 @@ class NWItem():
|
||||
"""Pack all the data in the class instance into an XML object.
|
||||
"""
|
||||
xPack = etree.SubElement(xParent, "item", attrib={
|
||||
"handle": str(self.itemHandle),
|
||||
"order": str(self.itemOrder),
|
||||
"parent": str(self.itemParent),
|
||||
"handle": str(self._handle),
|
||||
"order": str(self._order),
|
||||
"parent": str(self._parent),
|
||||
})
|
||||
self._subPack(xPack, "name", text=str(self.itemName))
|
||||
self._subPack(xPack, "type", text=str(self.itemType.name))
|
||||
self._subPack(xPack, "class", text=str(self.itemClass.name))
|
||||
self._subPack(xPack, "status", text=str(self.itemStatus))
|
||||
if self.itemType == nwItemType.FILE:
|
||||
self._subPack(xPack, "exported", text=str(self.isExported))
|
||||
self._subPack(xPack, "layout", text=str(self.itemLayout.name))
|
||||
self._subPack(xPack, "charCount", text=str(self.charCount), none=False)
|
||||
self._subPack(xPack, "wordCount", text=str(self.wordCount), none=False)
|
||||
self._subPack(xPack, "paraCount", text=str(self.paraCount), none=False)
|
||||
self._subPack(xPack, "cursorPos", text=str(self.cursorPos), none=False)
|
||||
self._subPack(xPack, "name", text=str(self._name))
|
||||
self._subPack(xPack, "type", text=str(self._type.name))
|
||||
self._subPack(xPack, "class", text=str(self._class.name))
|
||||
self._subPack(xPack, "status", text=str(self._status))
|
||||
if self._type == nwItemType.FILE:
|
||||
self._subPack(xPack, "exported", text=str(self._exported))
|
||||
self._subPack(xPack, "layout", text=str(self._layout.name))
|
||||
self._subPack(xPack, "charCount", text=str(self._charCount), none=False)
|
||||
self._subPack(xPack, "wordCount", text=str(self._wordCount), none=False)
|
||||
self._subPack(xPack, "paraCount", text=str(self._paraCount), none=False)
|
||||
self._subPack(xPack, "cursorPos", text=str(self._cursorPos), none=False)
|
||||
else:
|
||||
self._subPack(xPack, "expanded", text=str(self.isExpanded))
|
||||
self._subPack(xPack, "expanded", text=str(self._expanded))
|
||||
|
||||
return
|
||||
|
||||
@@ -162,12 +232,12 @@ class NWItem():
|
||||
"""Return a string description of the item.
|
||||
"""
|
||||
descKey = "none"
|
||||
if self.itemType == nwItemType.ROOT:
|
||||
if self._type == nwItemType.ROOT:
|
||||
descKey = "root"
|
||||
elif self.itemType == nwItemType.FOLDER:
|
||||
elif self._type == nwItemType.FOLDER:
|
||||
descKey = "folder"
|
||||
elif self.itemType == nwItemType.FILE:
|
||||
if self.itemLayout == nwItemLayout.DOCUMENT:
|
||||
elif self._type == nwItemType.FILE:
|
||||
if self._layout == nwItemLayout.DOCUMENT:
|
||||
if hLevel == "H1":
|
||||
descKey = "doc_h1"
|
||||
elif hLevel == "H2":
|
||||
@@ -176,7 +246,7 @@ class NWItem():
|
||||
descKey = "doc_h3"
|
||||
else:
|
||||
descKey = "document"
|
||||
elif self.itemLayout == nwItemLayout.NOTE:
|
||||
elif self._layout == nwItemLayout.NOTE:
|
||||
descKey = "note"
|
||||
|
||||
return trConst(nwLabels.ITEM_DESCRIPTION.get(descKey, ""))
|
||||
@@ -189,29 +259,29 @@ class NWItem():
|
||||
"""Set the item name.
|
||||
"""
|
||||
if isinstance(theName, str):
|
||||
self.itemName = theName.strip()
|
||||
self._name = theName.strip()
|
||||
else:
|
||||
self.itemName = ""
|
||||
self._name = ""
|
||||
return
|
||||
|
||||
def setHandle(self, theHandle):
|
||||
"""Set the item handle, and ensure it is valid.
|
||||
"""
|
||||
if isHandle(theHandle):
|
||||
self.itemHandle = theHandle
|
||||
self._handle = theHandle
|
||||
else:
|
||||
self.itemHandle = None
|
||||
self._handle = None
|
||||
return
|
||||
|
||||
def setParent(self, theParent):
|
||||
"""Set the parent handle, and ensure it is valid.
|
||||
"""
|
||||
if theParent is None:
|
||||
self.itemParent = None
|
||||
self._parent = None
|
||||
elif isHandle(theParent):
|
||||
self.itemParent = theParent
|
||||
self._parent = theParent
|
||||
else:
|
||||
self.itemParent = None
|
||||
self._parent = None
|
||||
return
|
||||
|
||||
def setOrder(self, theOrder):
|
||||
@@ -219,7 +289,7 @@ class NWItem():
|
||||
is purely a meta value, and not actually used by novelWriter at
|
||||
the moment.
|
||||
"""
|
||||
self.itemOrder = checkInt(theOrder, 0)
|
||||
self._order = checkInt(theOrder, 0)
|
||||
return
|
||||
|
||||
def setType(self, theType):
|
||||
@@ -227,12 +297,12 @@ class NWItem():
|
||||
from a string representing an nwItemType.
|
||||
"""
|
||||
if isinstance(theType, nwItemType):
|
||||
self.itemType = theType
|
||||
self._type = theType
|
||||
elif isItemType(theType):
|
||||
self.itemType = nwItemType[theType]
|
||||
self._type = nwItemType[theType]
|
||||
else:
|
||||
logger.error("Unrecognised item type '%s'", theType)
|
||||
self.itemType = nwItemType.NO_TYPE
|
||||
self._type = nwItemType.NO_TYPE
|
||||
return
|
||||
|
||||
def setClass(self, theClass):
|
||||
@@ -240,12 +310,12 @@ class NWItem():
|
||||
it from a string representing an nwItemClass.
|
||||
"""
|
||||
if isinstance(theClass, nwItemClass):
|
||||
self.itemClass = theClass
|
||||
self._class = theClass
|
||||
elif isItemClass(theClass):
|
||||
self.itemClass = nwItemClass[theClass]
|
||||
self._class = nwItemClass[theClass]
|
||||
else:
|
||||
logger.error("Unrecognised item class '%s'", theClass)
|
||||
self.itemClass = nwItemClass.NO_CLASS
|
||||
self._class = nwItemClass.NO_CLASS
|
||||
return
|
||||
|
||||
def setLayout(self, theLayout):
|
||||
@@ -253,42 +323,42 @@ class NWItem():
|
||||
it from a string representing an nwItemLayout.
|
||||
"""
|
||||
if isinstance(theLayout, nwItemLayout):
|
||||
self.itemLayout = theLayout
|
||||
self._layout = theLayout
|
||||
elif isItemLayout(theLayout):
|
||||
self.itemLayout = nwItemLayout[theLayout]
|
||||
self._layout = nwItemLayout[theLayout]
|
||||
elif theLayout in nwLists.DEP_LAYOUT:
|
||||
self.itemLayout = nwItemLayout.DOCUMENT
|
||||
self._layout = nwItemLayout.DOCUMENT
|
||||
else:
|
||||
logger.error("Unrecognised item layout '%s'", theLayout)
|
||||
self.itemLayout = nwItemLayout.NO_LAYOUT
|
||||
self._layout = nwItemLayout.NO_LAYOUT
|
||||
return
|
||||
|
||||
def setStatus(self, theStatus):
|
||||
"""Set the item status by looking it up in the valid status
|
||||
items of the current project.
|
||||
"""
|
||||
if self.itemClass in nwLists.CLS_NOVEL:
|
||||
self.itemStatus = self.theProject.statusItems.checkEntry(theStatus)
|
||||
if self._class in nwLists.CLS_NOVEL:
|
||||
self._status = self.theProject.statusItems.checkEntry(theStatus)
|
||||
else:
|
||||
self.itemStatus = self.theProject.importItems.checkEntry(theStatus)
|
||||
self._status = self.theProject.importItems.checkEntry(theStatus)
|
||||
return
|
||||
|
||||
def setExpanded(self, expState):
|
||||
"""Set the expanded status of an item in the project tree.
|
||||
"""
|
||||
if isinstance(expState, str):
|
||||
self.isExpanded = (expState == str(True))
|
||||
self._expanded = (expState == str(True))
|
||||
else:
|
||||
self.isExpanded = (expState is True)
|
||||
self._expanded = (expState is True)
|
||||
return
|
||||
|
||||
def setExported(self, expState):
|
||||
"""Set the export flag.
|
||||
"""
|
||||
if isinstance(expState, str):
|
||||
self.isExported = (expState == str(True))
|
||||
self._exported = (expState == str(True))
|
||||
else:
|
||||
self.isExported = (expState is True)
|
||||
self._exported = (expState is True)
|
||||
return
|
||||
|
||||
##
|
||||
@@ -298,31 +368,31 @@ class NWItem():
|
||||
def setCharCount(self, theCount):
|
||||
"""Set the character count, and ensure that it is an integer.
|
||||
"""
|
||||
self.charCount = max(0, checkInt(theCount, 0))
|
||||
self._charCount = max(0, checkInt(theCount, 0))
|
||||
return
|
||||
|
||||
def setWordCount(self, theCount):
|
||||
"""Set the word count, and ensure that it is an integer.
|
||||
"""
|
||||
self.wordCount = max(0, checkInt(theCount, 0))
|
||||
self._wordCount = max(0, checkInt(theCount, 0))
|
||||
return
|
||||
|
||||
def setParaCount(self, theCount):
|
||||
"""Set the paragraph count, and ensure that it is an integer.
|
||||
"""
|
||||
self.paraCount = max(0, checkInt(theCount, 0))
|
||||
self._paraCount = max(0, checkInt(theCount, 0))
|
||||
return
|
||||
|
||||
def setCursorPos(self, thePosition):
|
||||
"""Set the cursor position, and ensure that it is an integer.
|
||||
"""
|
||||
self.cursorPos = max(0, checkInt(thePosition, 0))
|
||||
self._cursorPos = max(0, checkInt(thePosition, 0))
|
||||
return
|
||||
|
||||
def saveInitialCount(self):
|
||||
"""Save the initial word count.
|
||||
"""
|
||||
self.initCount = self.wordCount
|
||||
self._initCount = self._wordCount
|
||||
return
|
||||
|
||||
# END Class NWItem
|
||||
|
||||
@@ -1166,7 +1166,7 @@ class NWProject():
|
||||
nMax = min(len(iterItems), 10000)
|
||||
while n < nMax:
|
||||
tHandle = iterItems[n]
|
||||
tItem = self.projTree[tHandle]
|
||||
tItem = self.projTree[tHandle]
|
||||
n += 1
|
||||
if tItem is None:
|
||||
# Technically a bug since treeOrder is built from the
|
||||
|
||||
@@ -270,11 +270,7 @@ class Tokenizer():
|
||||
def addRootHeading(self, theHandle):
|
||||
"""Add a heading at the start of a new root folder.
|
||||
"""
|
||||
theItem = self.theProject.projTree[theHandle]
|
||||
if theItem is None:
|
||||
return False
|
||||
|
||||
if theItem.itemType != nwItemType.ROOT:
|
||||
if not self.theProject.projTree.checkType(theHandle, nwItemType.ROOT):
|
||||
return False
|
||||
|
||||
if self._isFirst:
|
||||
@@ -283,6 +279,7 @@ class Tokenizer():
|
||||
else:
|
||||
textAlign = self.A_PBB | self.A_CENTRE
|
||||
|
||||
theItem = self.theProject.projTree[theHandle]
|
||||
locNotes = self._localLookup("Notes")
|
||||
theTitle = f"{locNotes}: {theItem.itemName}"
|
||||
self._theTokens = []
|
||||
@@ -299,7 +296,7 @@ class Tokenizer():
|
||||
not set, load it from the file.
|
||||
"""
|
||||
self._theHandle = theHandle
|
||||
self._theItem = self.theProject.projTree[theHandle]
|
||||
self._theItem = self.theProject.projTree[theHandle]
|
||||
if self._theItem is None:
|
||||
return False
|
||||
|
||||
|
||||
@@ -210,6 +210,14 @@ class NWTree():
|
||||
# Tree Structure Methods
|
||||
##
|
||||
|
||||
def checkType(self, tHandle, itemType):
|
||||
"""Return true of item exists and is of the specified item type.
|
||||
"""
|
||||
tItem = self.__getitem__(tHandle)
|
||||
if not tItem:
|
||||
return False
|
||||
return tItem.itemType == itemType
|
||||
|
||||
def trashRoot(self):
|
||||
"""Returns the handle of the trash folder, or None if there
|
||||
isn't one.
|
||||
|
||||
@@ -159,14 +159,10 @@ class GuiDocViewer(QTextBrowser):
|
||||
def loadText(self, tHandle, updateHistory=True):
|
||||
"""Load text into the viewer from an item handle.
|
||||
"""
|
||||
tItem = self.theProject.projTree[tHandle]
|
||||
if tItem is None:
|
||||
if not self.theProject.projTree.checkType(tHandle, nwItemType.FILE):
|
||||
logger.warning("Item not found")
|
||||
return False
|
||||
|
||||
if tItem.itemType != nwItemType.FILE:
|
||||
return False
|
||||
|
||||
logger.debug("Generating preview for item '%s'", tHandle)
|
||||
qApp.setOverrideCursor(QCursor(Qt.WaitCursor))
|
||||
|
||||
|
||||
@@ -1051,16 +1051,12 @@ class GuiProjectTree(QTreeWidget):
|
||||
def _emitItemChange(self, tHandle):
|
||||
"""Emit an item change signal for a given handle.
|
||||
"""
|
||||
nwItem = self.theProject.projTree[tHandle]
|
||||
if nwItem is None:
|
||||
return
|
||||
|
||||
if nwItem.itemType == nwItemType.FILE:
|
||||
if self.theProject.projTree.checkType(tHandle, nwItemType.FILE):
|
||||
nwItem = self.theProject.projTree[tHandle]
|
||||
if nwItem.itemClass == nwItemClass.NOVEL:
|
||||
self.novelItemChanged.emit()
|
||||
else:
|
||||
self.noteItemChanged.emit()
|
||||
|
||||
return
|
||||
|
||||
def _recordLastMove(self, srcItem, parItem, parIndex):
|
||||
|
||||
+10
-21
@@ -623,9 +623,7 @@ class GuiMain(QMainWindow):
|
||||
fHandle = None # The first file handle we encounter
|
||||
foundIt = False # We've found tHandle, pick the next we see
|
||||
for tItem in self.theProject.projTree:
|
||||
if tItem is None:
|
||||
continue
|
||||
if tItem.itemType != nwItemType.FILE:
|
||||
if not self.theProject.projTree.checkType(tItem.itemHandle, nwItemType.FILE):
|
||||
continue
|
||||
if fHandle is None:
|
||||
fHandle = tItem.itemHandle
|
||||
@@ -812,9 +810,7 @@ class GuiMain(QMainWindow):
|
||||
return False
|
||||
|
||||
logger.verbose("Opening item '%s'", tHandle)
|
||||
nwItem = self.theProject.projTree[tHandle]
|
||||
if nwItem.itemType == nwItemType.FILE:
|
||||
logger.verbose("Requested item '%s' is a file", tHandle)
|
||||
if self.theProject.projTree.checkType(tHandle, nwItemType.FILE):
|
||||
self.openDocument(tHandle, doScroll=False)
|
||||
else:
|
||||
logger.verbose("Requested item '%s' is not a file", tHandle)
|
||||
@@ -1572,13 +1568,10 @@ class GuiMain(QMainWindow):
|
||||
tHandle = tItem.data(self.treeView.C_NAME, Qt.UserRole)
|
||||
logger.verbose("User double clicked tree item with handle '%s'", tHandle)
|
||||
|
||||
nwItem = self.theProject.projTree[tHandle]
|
||||
if nwItem is not None:
|
||||
if nwItem.itemType == nwItemType.FILE:
|
||||
logger.verbose("Requested item '%s' is a file", tHandle)
|
||||
self.openDocument(tHandle, changeFocus=False, doScroll=False)
|
||||
else:
|
||||
logger.verbose("Requested item '%s' is a folder", tHandle)
|
||||
if self.theProject.projTree.checkType(tHandle, nwItemType.FILE):
|
||||
self.openDocument(tHandle, changeFocus=False, doScroll=False)
|
||||
else:
|
||||
logger.verbose("Requested item '%s' is a folder", tHandle)
|
||||
|
||||
return
|
||||
|
||||
@@ -1603,14 +1596,10 @@ class GuiMain(QMainWindow):
|
||||
"""
|
||||
tHandle = self.treeView.getSelectedHandle()
|
||||
logger.verbose("User pressed return on tree item with handle '%s'", tHandle)
|
||||
|
||||
nwItem = self.theProject.projTree[tHandle]
|
||||
if nwItem is not None:
|
||||
if nwItem.itemType == nwItemType.FILE:
|
||||
logger.verbose("Requested item '%s' is a file", tHandle)
|
||||
self.openDocument(tHandle, changeFocus=False, doScroll=False)
|
||||
else:
|
||||
logger.verbose("Requested item '%s' is a folder", tHandle)
|
||||
if self.theProject.projTree.checkType(tHandle, nwItemType.FILE):
|
||||
self.openDocument(tHandle, changeFocus=False, doScroll=False)
|
||||
else:
|
||||
logger.verbose("Requested item '%s' is a folder", tHandle)
|
||||
|
||||
return
|
||||
|
||||
|
||||
@@ -433,7 +433,7 @@ def testCoreIndex_ScanText(nwMinimal, mockGUI):
|
||||
# Page wo/Title
|
||||
# =============
|
||||
|
||||
theProject.projTree[pHandle].itemLayout = nwItemLayout.DOCUMENT
|
||||
theProject.projTree[pHandle]._layout = nwItemLayout.DOCUMENT
|
||||
assert theIndex.scanText(pHandle, (
|
||||
"This is a page with some text on it.\n\n"
|
||||
))
|
||||
@@ -446,7 +446,7 @@ def testCoreIndex_ScanText(nwMinimal, mockGUI):
|
||||
assert theIndex._fileIndex[pHandle]["T000000"]["pCount"] == 1
|
||||
assert theIndex._fileIndex[pHandle]["T000000"]["synopsis"] == ""
|
||||
|
||||
theProject.projTree[pHandle].itemLayout = nwItemLayout.NOTE
|
||||
theProject.projTree[pHandle]._layout = nwItemLayout.NOTE
|
||||
assert theIndex.scanText(pHandle, (
|
||||
"This is a page with some text on it.\n\n"
|
||||
))
|
||||
|
||||
@@ -86,7 +86,7 @@ def testCoreItem_Setters(mockGUI):
|
||||
assert theItem.itemStatus == "Main"
|
||||
|
||||
# Status
|
||||
theItem.itemClass = nwItemClass.NOVEL
|
||||
theItem._class = nwItemClass.NOVEL
|
||||
theItem.setStatus("Nonsense")
|
||||
assert theItem.itemStatus == "New"
|
||||
theItem.setStatus("New")
|
||||
@@ -100,31 +100,31 @@ def testCoreItem_Setters(mockGUI):
|
||||
|
||||
# Expanded
|
||||
theItem.setExpanded(8)
|
||||
assert not theItem.isExpanded
|
||||
assert theItem.isExpanded is False
|
||||
theItem.setExpanded(None)
|
||||
assert not theItem.isExpanded
|
||||
assert theItem.isExpanded is False
|
||||
theItem.setExpanded("None")
|
||||
assert not theItem.isExpanded
|
||||
assert theItem.isExpanded is False
|
||||
theItem.setExpanded("What?")
|
||||
assert not theItem.isExpanded
|
||||
assert theItem.isExpanded is False
|
||||
theItem.setExpanded("True")
|
||||
assert theItem.isExpanded
|
||||
assert theItem.isExpanded is True
|
||||
theItem.setExpanded(True)
|
||||
assert theItem.isExpanded
|
||||
assert theItem.isExpanded is True
|
||||
|
||||
# Exported
|
||||
theItem.setExported(8)
|
||||
assert not theItem.isExported
|
||||
assert theItem.isExported is False
|
||||
theItem.setExported(None)
|
||||
assert not theItem.isExported
|
||||
assert theItem.isExported is False
|
||||
theItem.setExported("None")
|
||||
assert not theItem.isExported
|
||||
assert theItem.isExported is False
|
||||
theItem.setExported("What?")
|
||||
assert not theItem.isExported
|
||||
assert theItem.isExported is False
|
||||
theItem.setExported("True")
|
||||
assert theItem.isExported
|
||||
assert theItem.isExported is True
|
||||
theItem.setExported(True)
|
||||
assert theItem.isExported
|
||||
assert theItem.isExported is True
|
||||
|
||||
# CharCount
|
||||
theItem.setCharCount(None)
|
||||
@@ -196,6 +196,21 @@ def testCoreItem_Methods(mockGUI):
|
||||
theItem.setLayout("NOTE")
|
||||
assert theItem.describeMe() == "Project Note"
|
||||
|
||||
# Representation
|
||||
# ==============
|
||||
|
||||
theItem.setName("New Item")
|
||||
theItem.setHandle("1234567890abc")
|
||||
theItem.setParent("4567890abcdef")
|
||||
assert repr(theItem) == "<NWItem handle=1234567890abc, parent=4567890abcdef, name='New Item'>"
|
||||
|
||||
# Truthiness
|
||||
# ==========
|
||||
|
||||
assert bool(theItem) is True
|
||||
theItem.setHandle(None)
|
||||
assert bool(theItem) is False
|
||||
|
||||
# END Test testCoreItem_Methods
|
||||
|
||||
|
||||
|
||||
@@ -39,61 +39,61 @@ def mockItems(mockGUI):
|
||||
theProject = NWProject(mockGUI)
|
||||
|
||||
itemA = NWItem(theProject)
|
||||
itemA.itemName = "Novel"
|
||||
itemA.itemType = nwItemType.ROOT
|
||||
itemA.itemClass = nwItemClass.NOVEL
|
||||
itemA.isExpanded = True
|
||||
itemA._name = "Novel"
|
||||
itemA._type = nwItemType.ROOT
|
||||
itemA._class = nwItemClass.NOVEL
|
||||
itemA._expanded = True
|
||||
|
||||
itemB = NWItem(theProject)
|
||||
itemB.itemName = "Act One"
|
||||
itemB.itemType = nwItemType.FOLDER
|
||||
itemB.itemClass = nwItemClass.NOVEL
|
||||
itemB.isExpanded = True
|
||||
itemB._name = "Act One"
|
||||
itemB._type = nwItemType.FOLDER
|
||||
itemB._class = nwItemClass.NOVEL
|
||||
itemB._expanded = True
|
||||
|
||||
itemC = NWItem(theProject)
|
||||
itemC.itemName = "Chapter One"
|
||||
itemC.itemType = nwItemType.FILE
|
||||
itemC.itemClass = nwItemClass.NOVEL
|
||||
itemC.itemLayout = nwItemLayout.DOCUMENT
|
||||
itemC.charCount = 300
|
||||
itemC.wordCount = 50
|
||||
itemC.paraCount = 2
|
||||
itemC._name = "Chapter One"
|
||||
itemC._type = nwItemType.FILE
|
||||
itemC._class = nwItemClass.NOVEL
|
||||
itemC._layout = nwItemLayout.DOCUMENT
|
||||
itemC._charCount = 300
|
||||
itemC._wordCount = 50
|
||||
itemC._paraCount = 2
|
||||
|
||||
itemD = NWItem(theProject)
|
||||
itemD.itemName = "Scene One"
|
||||
itemD.itemType = nwItemType.FILE
|
||||
itemD.itemClass = nwItemClass.NOVEL
|
||||
itemD.itemLayout = nwItemLayout.DOCUMENT
|
||||
itemD.charCount = 3000
|
||||
itemD.wordCount = 500
|
||||
itemD.paraCount = 20
|
||||
itemD._name = "Scene One"
|
||||
itemD._type = nwItemType.FILE
|
||||
itemD._class = nwItemClass.NOVEL
|
||||
itemD._layout = nwItemLayout.DOCUMENT
|
||||
itemD._charCount = 3000
|
||||
itemD._wordCount = 500
|
||||
itemD._paraCount = 20
|
||||
|
||||
itemE = NWItem(theProject)
|
||||
itemE.itemName = "Outtakes"
|
||||
itemE.itemType = nwItemType.ROOT
|
||||
itemE.itemClass = nwItemClass.ARCHIVE
|
||||
itemE.isExpanded = False
|
||||
itemE._name = "Outtakes"
|
||||
itemE._type = nwItemType.ROOT
|
||||
itemE._class = nwItemClass.ARCHIVE
|
||||
itemE._expanded = False
|
||||
|
||||
itemF = NWItem(theProject)
|
||||
itemF.itemName = "Trash"
|
||||
itemF.itemType = nwItemType.TRASH
|
||||
itemF.itemClass = nwItemClass.TRASH
|
||||
itemF.isExpanded = False
|
||||
itemF._name = "Trash"
|
||||
itemF._type = nwItemType.TRASH
|
||||
itemF._class = nwItemClass.TRASH
|
||||
itemF._expanded = False
|
||||
|
||||
itemG = NWItem(theProject)
|
||||
itemG.itemName = "Characters"
|
||||
itemG.itemType = nwItemType.ROOT
|
||||
itemG.itemClass = nwItemClass.CHARACTER
|
||||
itemG.isExpanded = True
|
||||
itemG._name = "Characters"
|
||||
itemG._type = nwItemType.ROOT
|
||||
itemG._class = nwItemClass.CHARACTER
|
||||
itemG._expanded = True
|
||||
|
||||
itemH = NWItem(theProject)
|
||||
itemH.itemName = "Jane Doe"
|
||||
itemH.itemType = nwItemType.FILE
|
||||
itemH.itemClass = nwItemClass.CHARACTER
|
||||
itemH.itemLayout = nwItemLayout.NOTE
|
||||
itemH.charCount = 2000
|
||||
itemH.wordCount = 400
|
||||
itemH.paraCount = 16
|
||||
itemH._name = "Jane Doe"
|
||||
itemH._type = nwItemType.FILE
|
||||
itemH._class = nwItemClass.CHARACTER
|
||||
itemH._layout = nwItemLayout.NOTE
|
||||
itemH._charCount = 2000
|
||||
itemH._wordCount = 400
|
||||
itemH._paraCount = 16
|
||||
|
||||
theItems = [
|
||||
("a000000000001", None, itemA),
|
||||
@@ -154,20 +154,20 @@ def testCoreTree_BuildTree(mockGUI, mockItems):
|
||||
|
||||
# Try to add another trash folder
|
||||
itemT = NWItem(theProject)
|
||||
itemT.itemName = "Trash"
|
||||
itemT.itemType = nwItemType.TRASH
|
||||
itemT.itemClass = nwItemClass.TRASH
|
||||
itemT.isExpanded = False
|
||||
itemT._name = "Trash"
|
||||
itemT._type = nwItemType.TRASH
|
||||
itemT._class = nwItemClass.TRASH
|
||||
itemT._expanded = False
|
||||
|
||||
assert not theTree.append("1234567890abc", None, itemT)
|
||||
assert len(theTree) == len(mockItems)
|
||||
|
||||
# Generate handle automatically
|
||||
itemT = NWItem(theProject)
|
||||
itemT.itemName = "New File"
|
||||
itemT.itemType = nwItemType.FILE
|
||||
itemT.itemClass = nwItemClass.NOVEL
|
||||
itemT.itemLayout = nwItemLayout.DOCUMENT
|
||||
itemT._name = "New File"
|
||||
itemT._type = nwItemType.FILE
|
||||
itemT._class = nwItemClass.NOVEL
|
||||
itemT._layout = nwItemLayout.DOCUMENT
|
||||
|
||||
assert theTree.append(None, None, itemT)
|
||||
assert len(theTree) == len(mockItems) + 1
|
||||
@@ -218,6 +218,11 @@ def testCoreTree_Methods(mockGUI, mockItems):
|
||||
|
||||
assert len(theTree) == len(mockItems)
|
||||
|
||||
# Chech type
|
||||
assert theTree.checkType("blabla", nwItemType.FILE) is False
|
||||
assert theTree.checkType("b000000000001", nwItemType.FILE) is False
|
||||
assert theTree.checkType("c000000000001", nwItemType.FILE) is True
|
||||
|
||||
# Root item lookup
|
||||
theTree._treeRoots.append("stuff")
|
||||
assert theTree.findRoot(nwItemClass.WORLD) is None
|
||||
@@ -243,12 +248,12 @@ def testCoreTree_Methods(mockGUI, mockItems):
|
||||
]
|
||||
|
||||
# Break the folder parent handle
|
||||
theTree["b000000000001"].itemParent = "stuff"
|
||||
theTree["b000000000001"]._parent = "stuff"
|
||||
assert theTree.getItemPath("c000000000001") == [
|
||||
"c000000000001", "b000000000001"
|
||||
]
|
||||
|
||||
theTree["b000000000001"].itemParent = "a000000000001"
|
||||
theTree["b000000000001"]._parent = "a000000000001"
|
||||
assert theTree.getItemPath("c000000000001") == [
|
||||
"c000000000001", "b000000000001", "a000000000001"
|
||||
]
|
||||
|
||||
@@ -62,9 +62,9 @@ def testDlgItemEditor_Dialog(qtbot, monkeypatch, nwGUI, fncProj):
|
||||
assert nwGUI.editItem() is False
|
||||
|
||||
# Invalid Type
|
||||
nwGUI.theProject.projTree["0e17daca5f3e1"].itemType = nwItemType.NO_TYPE
|
||||
nwGUI.theProject.projTree["0e17daca5f3e1"]._type = nwItemType.NO_TYPE
|
||||
assert nwGUI.editItem() is False
|
||||
nwGUI.theProject.projTree["0e17daca5f3e1"].itemType = nwItemType.FILE
|
||||
nwGUI.theProject.projTree["0e17daca5f3e1"]._type = nwItemType.FILE
|
||||
|
||||
# Open Properly
|
||||
assert nwGUI.editItem() is True
|
||||
|
||||
@@ -1225,8 +1225,8 @@ def testGuiEditor_WordCounters(qtbot, monkeypatch, caplog, nwGUI, nwMinimal, ips
|
||||
|
||||
# Open a document and populate it
|
||||
sHandle = "8c659a11cd429"
|
||||
nwGUI.theProject.projTree[sHandle].initCount = 0 # Clear item's count
|
||||
nwGUI.theProject.projTree[sHandle].wordCount = 0 # Clear item's count
|
||||
nwGUI.theProject.projTree[sHandle]._initCount = 0 # Clear item's count
|
||||
nwGUI.theProject.projTree[sHandle]._wordCount = 0 # Clear item's count
|
||||
assert nwGUI.openDocument(sHandle) is True
|
||||
qtbot.wait(stepDelay)
|
||||
|
||||
@@ -1252,9 +1252,9 @@ def testGuiEditor_WordCounters(qtbot, monkeypatch, caplog, nwGUI, nwMinimal, ips
|
||||
nwGUI.docEditor.wCounterDoc.run()
|
||||
# nwGUI.docEditor._updateDocCounts(cC, wC, pC)
|
||||
qtbot.wait(stepDelay)
|
||||
assert nwGUI.theProject.projTree[sHandle].charCount == cC
|
||||
assert nwGUI.theProject.projTree[sHandle].wordCount == wC
|
||||
assert nwGUI.theProject.projTree[sHandle].paraCount == pC
|
||||
assert nwGUI.theProject.projTree[sHandle]._charCount == cC
|
||||
assert nwGUI.theProject.projTree[sHandle]._wordCount == wC
|
||||
assert nwGUI.theProject.projTree[sHandle]._paraCount == pC
|
||||
assert nwGUI.docEditor.docFooter.wordsText.text() == f"Words: {wC} (+{wC})"
|
||||
|
||||
# Select all text
|
||||
|
||||
@@ -223,7 +223,7 @@ def testGuiProjTree_TreeItems(qtbot, caplog, monkeypatch, nwGUI, nwMinimal):
|
||||
# Add new file after one that has no parent handle
|
||||
chItem = nwTree._getTreeItem("44cb730c42048")
|
||||
nwTree.setCurrentItem(chItem, QItemSelectionModel.Current)
|
||||
nwTree.theProject.projTree["44cb730c42048"].itemParent = None
|
||||
nwTree.theProject.projTree["44cb730c42048"]._parent = None
|
||||
assert not nwTree.newTreeItem(nwItemType.FILE, nwItemClass.NOVEL)
|
||||
nwTree.clearSelection()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user