Clean up variables and formatting
This commit is contained in:
+16
-16
@@ -213,17 +213,17 @@ def formatInt(value: int) -> str:
|
|||||||
if not isinstance(value, int):
|
if not isinstance(value, int):
|
||||||
return "ERR"
|
return "ERR"
|
||||||
|
|
||||||
theVal = float(value)
|
fVal = float(value)
|
||||||
if theVal > 1000.0:
|
if fVal > 1000.0:
|
||||||
for pF in ["k", "M", "G", "T", "P", "E"]:
|
for pF in ["k", "M", "G", "T", "P", "E"]:
|
||||||
theVal /= 1000.0
|
fVal /= 1000.0
|
||||||
if theVal < 1000.0:
|
if fVal < 1000.0:
|
||||||
if theVal < 10.0:
|
if fVal < 10.0:
|
||||||
return f"{theVal:4.2f}{nwUnicode.U_THSP}{pF}"
|
return f"{fVal:4.2f}{nwUnicode.U_THSP}{pF}"
|
||||||
elif theVal < 100.0:
|
elif fVal < 100.0:
|
||||||
return f"{theVal:4.1f}{nwUnicode.U_THSP}{pF}"
|
return f"{fVal:4.1f}{nwUnicode.U_THSP}{pF}"
|
||||||
else:
|
else:
|
||||||
return f"{theVal:3.0f}{nwUnicode.U_THSP}{pF}"
|
return f"{fVal:3.0f}{nwUnicode.U_THSP}{pF}"
|
||||||
|
|
||||||
return str(value)
|
return str(value)
|
||||||
|
|
||||||
@@ -275,22 +275,22 @@ def transferCase(source: str, target: str) -> str:
|
|||||||
"""Transfers the case of the source word to the target word. This
|
"""Transfers the case of the source word to the target word. This
|
||||||
will consider all upper or lower, and first char capitalisation.
|
will consider all upper or lower, and first char capitalisation.
|
||||||
"""
|
"""
|
||||||
theResult = target
|
result = target
|
||||||
|
|
||||||
if not isinstance(source, str) or not isinstance(target, str):
|
if not isinstance(source, str) or not isinstance(target, str):
|
||||||
return theResult
|
return result
|
||||||
if len(target) < 1 or len(source) < 1:
|
if len(target) < 1 or len(source) < 1:
|
||||||
return theResult
|
return result
|
||||||
|
|
||||||
if source.istitle():
|
if source.istitle():
|
||||||
theResult = target.title()
|
result = target.title()
|
||||||
|
|
||||||
if source.isupper():
|
if source.isupper():
|
||||||
theResult = target.upper()
|
result = target.upper()
|
||||||
elif source.islower():
|
elif source.islower():
|
||||||
theResult = target.lower()
|
result = target.lower()
|
||||||
|
|
||||||
return theResult
|
return result
|
||||||
|
|
||||||
|
|
||||||
def fuzzyTime(seconds: int) -> str:
|
def fuzzyTime(seconds: int) -> str:
|
||||||
|
|||||||
@@ -235,16 +235,12 @@ class BuildSettings:
|
|||||||
def getInt(self, key: str) -> int:
|
def getInt(self, key: str) -> int:
|
||||||
"""Type safe value access for integers."""
|
"""Type safe value access for integers."""
|
||||||
value = self._settings.get(key, SETTINGS_TEMPLATE.get(key, (None, None))[1])
|
value = self._settings.get(key, SETTINGS_TEMPLATE.get(key, (None, None))[1])
|
||||||
if isinstance(value, (int, float)):
|
return int(value) if isinstance(value, (int, float)) else 0
|
||||||
return int(value)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def getFloat(self, key: str) -> float:
|
def getFloat(self, key: str) -> float:
|
||||||
"""Type safe value access for floats."""
|
"""Type safe value access for floats."""
|
||||||
value = self._settings.get(key, SETTINGS_TEMPLATE.get(key, (None, None))[1])
|
value = self._settings.get(key, SETTINGS_TEMPLATE.get(key, (None, None))[1])
|
||||||
if isinstance(value, (int, float)):
|
return float(value) if isinstance(value, (int, float)) else 0.0
|
||||||
return float(value)
|
|
||||||
return 0.0
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Setters
|
# Setters
|
||||||
|
|||||||
@@ -279,28 +279,25 @@ class DocDuplicator:
|
|||||||
"""Run through a list of items, duplicate them, and copy the
|
"""Run through a list of items, duplicate them, and copy the
|
||||||
text content if they are documents.
|
text content if they are documents.
|
||||||
"""
|
"""
|
||||||
if not items:
|
if items:
|
||||||
return
|
nHandle = items[0]
|
||||||
|
hMap: dict[str, str | None] = {t: None for t in items}
|
||||||
nHandle = items[0]
|
for tHandle in items:
|
||||||
hMap: dict[str, str | None] = {t: None for t in items}
|
newItem = self._project.tree.duplicate(tHandle)
|
||||||
for tHandle in items:
|
if newItem is None:
|
||||||
newItem = self._project.tree.duplicate(tHandle)
|
|
||||||
if newItem is None:
|
|
||||||
return
|
|
||||||
hMap[tHandle] = newItem.itemHandle
|
|
||||||
if newItem.itemParent in hMap:
|
|
||||||
newItem.setParent(hMap[newItem.itemParent])
|
|
||||||
self._project.tree.updateItemData(newItem.itemHandle)
|
|
||||||
if newItem.isFileType():
|
|
||||||
oldDoc = self._project.storage.getDocument(tHandle)
|
|
||||||
newDoc = self._project.storage.getDocument(newItem.itemHandle)
|
|
||||||
if newDoc.fileExists():
|
|
||||||
return
|
return
|
||||||
newDoc.writeDocument(oldDoc.readDocument() or "")
|
hMap[tHandle] = newItem.itemHandle
|
||||||
yield newItem.itemHandle, nHandle
|
if newItem.itemParent in hMap:
|
||||||
nHandle = None
|
newItem.setParent(hMap[newItem.itemParent])
|
||||||
|
self._project.tree.updateItemData(newItem.itemHandle)
|
||||||
|
if newItem.isFileType():
|
||||||
|
oldDoc = self._project.storage.getDocument(tHandle)
|
||||||
|
newDoc = self._project.storage.getDocument(newItem.itemHandle)
|
||||||
|
if newDoc.fileExists():
|
||||||
|
return
|
||||||
|
newDoc.writeDocument(oldDoc.readDocument() or "")
|
||||||
|
yield newItem.itemHandle, nHandle
|
||||||
|
nHandle = None
|
||||||
return
|
return
|
||||||
|
|
||||||
# END Class DocDuplicator
|
# END Class DocDuplicator
|
||||||
@@ -313,7 +310,7 @@ class ProjectBuilder:
|
|||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self._path = None
|
self._path = None
|
||||||
self.tr = partial(QCoreApplication.translate, "NWProject")
|
self.tr = partial(QCoreApplication.translate, "ProjectBuilder")
|
||||||
return
|
return
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|||||||
@@ -248,8 +248,8 @@ class NWBuildDocument:
|
|||||||
def _setupBuild(self, bldObj: Tokenizer) -> dict:
|
def _setupBuild(self, bldObj: Tokenizer) -> dict:
|
||||||
"""Configure the build object."""
|
"""Configure the build object."""
|
||||||
# Get Settings
|
# Get Settings
|
||||||
textFont = self._build.getStr("format.textFont")
|
textFont = self._build.getStr("format.textFont")
|
||||||
textSize = self._build.getInt("format.textSize")
|
textSize = self._build.getInt("format.textSize")
|
||||||
|
|
||||||
fontFamily = textFont or CONFIG.textFont
|
fontFamily = textFont or CONFIG.textFont
|
||||||
bldFont = QFont(fontFamily, textSize)
|
bldFont = QFont(fontFamily, textSize)
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ class NWDocument:
|
|||||||
|
|
||||||
def __init__(self, project: NWProject, tHandle: str | None) -> None:
|
def __init__(self, project: NWProject, tHandle: str | None) -> None:
|
||||||
|
|
||||||
self._project = project
|
self._project = project
|
||||||
|
|
||||||
self._item = None # The currently open item
|
self._item = None # The currently open item
|
||||||
self._handle = None # The handle of the currently open item
|
self._handle = None # The handle of the currently open item
|
||||||
@@ -284,12 +284,12 @@ class NWDocument:
|
|||||||
"""Parse the document meta tag and return the name, parent,
|
"""Parse the document meta tag and return the name, parent,
|
||||||
class and layout meta values.
|
class and layout meta values.
|
||||||
"""
|
"""
|
||||||
theName = self._docMeta.get("name", "")
|
name = self._docMeta.get("name", "")
|
||||||
theParent = self._docMeta.get("parent", None)
|
parent = self._docMeta.get("parent", None)
|
||||||
theClass = self._docMeta.get("class", None)
|
itemClass = self._docMeta.get("class", None)
|
||||||
theLayout = self._docMeta.get("layout", None)
|
itemLayout = self._docMeta.get("layout", None)
|
||||||
|
|
||||||
return theName, theParent, theClass, theLayout
|
return name, parent, itemClass, itemLayout
|
||||||
|
|
||||||
def getError(self) -> str:
|
def getError(self) -> str:
|
||||||
"""Return the last recorded exception."""
|
"""Return the last recorded exception."""
|
||||||
|
|||||||
@@ -122,8 +122,8 @@ class NWIndex:
|
|||||||
for nwItem in self._project.tree:
|
for nwItem in self._project.tree:
|
||||||
if nwItem.isFileType():
|
if nwItem.isFileType():
|
||||||
tHandle = nwItem.itemHandle
|
tHandle = nwItem.itemHandle
|
||||||
theDoc = self._project.storage.getDocument(tHandle)
|
doc = self._project.storage.getDocument(tHandle)
|
||||||
self.scanText(tHandle, theDoc.readDocument() or "", blockSignal=True)
|
self.scanText(tHandle, doc.readDocument() or "", blockSignal=True)
|
||||||
self._indexBroken = False
|
self._indexBroken = False
|
||||||
SHARED.indexSignalProxy({"event": "buildIndex"})
|
SHARED.indexSignalProxy({"event": "buildIndex"})
|
||||||
return
|
return
|
||||||
@@ -148,8 +148,8 @@ class NWIndex:
|
|||||||
"""
|
"""
|
||||||
if tHandle and self._project.tree.checkType(tHandle, nwItemType.FILE):
|
if tHandle and self._project.tree.checkType(tHandle, nwItemType.FILE):
|
||||||
logger.debug("Re-indexing item '%s'", tHandle)
|
logger.debug("Re-indexing item '%s'", tHandle)
|
||||||
theDoc = self._project.storage.getDocument(tHandle)
|
doc = self._project.storage.getDocument(tHandle)
|
||||||
self.scanText(tHandle, theDoc.readDocument() or "")
|
self.scanText(tHandle, doc.readDocument() or "")
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|||||||
@@ -194,12 +194,12 @@ class Tokenizer(ABC):
|
|||||||
##
|
##
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def theResult(self) -> str:
|
def result(self) -> str:
|
||||||
"""The result of the build process."""
|
"""The result of the build process."""
|
||||||
return self._result
|
return self._result
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def theMarkdown(self) -> list:
|
def allMarkdown(self) -> list:
|
||||||
"""The combined novelWriter Markdown text."""
|
"""The combined novelWriter Markdown text."""
|
||||||
return self._allMarkdown
|
return self._allMarkdown
|
||||||
|
|
||||||
@@ -358,8 +358,8 @@ class Tokenizer(ABC):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def setText(self, tHandle: str, text: str | None = None) -> bool:
|
def setText(self, tHandle: str, text: str | None = None) -> bool:
|
||||||
"""Set the text for the tokenizer from a handle. If theText is
|
"""Set the text for the tokenizer from a handle. If text is not
|
||||||
not set, load it from the file.
|
set, load it from the file.
|
||||||
"""
|
"""
|
||||||
self._nwItem = self._project.tree[tHandle]
|
self._nwItem = self._project.tree[tHandle]
|
||||||
if self._nwItem is None:
|
if self._nwItem is None:
|
||||||
|
|||||||
@@ -682,12 +682,12 @@ class ToOdt(Tokenizer):
|
|||||||
return parName
|
return parName
|
||||||
|
|
||||||
oStyle.setParentStyleName(parName)
|
oStyle.setParentStyleName(parName)
|
||||||
theID = oStyle.getID()
|
pID = oStyle.getID()
|
||||||
if theID in self._autoPara:
|
if pID in self._autoPara:
|
||||||
return self._autoPara[theID][0]
|
return self._autoPara[pID][0]
|
||||||
|
|
||||||
newName = "P%d" % (len(self._autoPara) + 1)
|
newName = "P%d" % (len(self._autoPara) + 1)
|
||||||
self._autoPara[theID] = (newName, oStyle)
|
self._autoPara[pID] = (newName, oStyle)
|
||||||
|
|
||||||
return newName
|
return newName
|
||||||
|
|
||||||
|
|||||||
@@ -500,7 +500,7 @@ class NWTree:
|
|||||||
##
|
##
|
||||||
|
|
||||||
def _setTreeChanged(self, state: bool) -> None:
|
def _setTreeChanged(self, state: bool) -> None:
|
||||||
"""Set the changed flag to theState, and if being set to True,
|
"""Set the changed flag to state, and if being set to True,
|
||||||
propagate that state change to the parent NWProject class.
|
propagate that state change to the parent NWProject class.
|
||||||
"""
|
"""
|
||||||
self._changed = state
|
self._changed = state
|
||||||
|
|||||||
@@ -77,9 +77,9 @@ class GuiQuoteSelect(QDialog):
|
|||||||
|
|
||||||
minSize = 100
|
minSize = 100
|
||||||
for sKey, sLabel in nwQuotes.SYMBOLS.items():
|
for sKey, sLabel in nwQuotes.SYMBOLS.items():
|
||||||
theText = "[ %s ] %s" % (sKey, trConst(sLabel))
|
text = "[ %s ] %s" % (sKey, trConst(sLabel))
|
||||||
minSize = max(minSize, qMetrics.boundingRect(theText).width())
|
minSize = max(minSize, qMetrics.boundingRect(text).width())
|
||||||
qtItem = QListWidgetItem(theText)
|
qtItem = QListWidgetItem(text)
|
||||||
qtItem.setData(self.D_KEY, sKey)
|
qtItem.setData(self.D_KEY, sKey)
|
||||||
self.listBox.addItem(qtItem)
|
self.listBox.addItem(qtItem)
|
||||||
if sKey == current:
|
if sKey == current:
|
||||||
|
|||||||
@@ -256,9 +256,9 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
|||||||
nBlocks = qDoc.blockCount()
|
nBlocks = qDoc.blockCount()
|
||||||
tStart = time()
|
tStart = time()
|
||||||
for i in range(nBlocks):
|
for i in range(nBlocks):
|
||||||
theBlock = qDoc.findBlockByNumber(i)
|
block = qDoc.findBlockByNumber(i)
|
||||||
if theBlock.userState() & cType > 0:
|
if block.userState() & cType > 0:
|
||||||
self.rehighlightBlock(theBlock)
|
self.rehighlightBlock(block)
|
||||||
logger.debug("Document highlighted in %.3f ms" % (1000*(time() - tStart)))
|
logger.debug("Document highlighted in %.3f ms" % (1000*(time() - tStart)))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@@ -229,7 +229,7 @@ class GuiDocViewer(QTextBrowser):
|
|||||||
self.setDocumentTitle(tHandle)
|
self.setDocumentTitle(tHandle)
|
||||||
|
|
||||||
# Replace tabs before setting the HTML, and then put them back in
|
# Replace tabs before setting the HTML, and then put them back in
|
||||||
self.setHtml(aDoc.theResult.replace("\t", "!!tab!!"))
|
self.setHtml(aDoc.result.replace("\t", "!!tab!!"))
|
||||||
while self.find("!!tab!!"):
|
while self.find("!!tab!!"):
|
||||||
self.textCursor().insertText("\t")
|
self.textCursor().insertText("\t")
|
||||||
|
|
||||||
@@ -367,9 +367,9 @@ class GuiDocViewer(QTextBrowser):
|
|||||||
link = url.url()
|
link = url.url()
|
||||||
logger.debug("Clicked link: '%s'", link)
|
logger.debug("Clicked link: '%s'", link)
|
||||||
if len(link) > 0:
|
if len(link) > 0:
|
||||||
theBits = link.split("=")
|
bits = link.split("=")
|
||||||
if len(theBits) == 2:
|
if len(bits) == 2:
|
||||||
self.loadDocumentTagRequest.emit(theBits[1], nwDocMode.VIEW)
|
self.loadDocumentTagRequest.emit(bits[1], nwDocMode.VIEW)
|
||||||
return
|
return
|
||||||
|
|
||||||
@pyqtSlot("QPoint")
|
@pyqtSlot("QPoint")
|
||||||
|
|||||||
@@ -239,9 +239,9 @@ class GuiItemDetails(QWidget):
|
|||||||
# Label
|
# Label
|
||||||
# =====
|
# =====
|
||||||
|
|
||||||
theLabel = nwItem.itemName
|
label = nwItem.itemName
|
||||||
if len(theLabel) > 100:
|
if len(label) > 100:
|
||||||
theLabel = theLabel[:96].rstrip()+" ..."
|
label = label[:96].rstrip()+" ..."
|
||||||
|
|
||||||
if nwItem.isFileType():
|
if nwItem.isFileType():
|
||||||
if nwItem.isActive:
|
if nwItem.isActive:
|
||||||
@@ -251,14 +251,14 @@ class GuiItemDetails(QWidget):
|
|||||||
else:
|
else:
|
||||||
self.labelIcon.setPixmap(SHARED.theme.getPixmap("noncheckable", (iPx, iPx)))
|
self.labelIcon.setPixmap(SHARED.theme.getPixmap("noncheckable", (iPx, iPx)))
|
||||||
|
|
||||||
self.labelData.setText(theLabel)
|
self.labelData.setText(label)
|
||||||
|
|
||||||
# Status
|
# Status
|
||||||
# ======
|
# ======
|
||||||
|
|
||||||
theStatus, theIcon = nwItem.getImportStatus(incIcon=True)
|
status, icon = nwItem.getImportStatus(incIcon=True)
|
||||||
self.statusIcon.setPixmap(theIcon.pixmap(iPx, iPx))
|
self.statusIcon.setPixmap(icon.pixmap(iPx, iPx))
|
||||||
self.statusData.setText(theStatus)
|
self.statusData.setText(status)
|
||||||
|
|
||||||
# Class
|
# Class
|
||||||
# =====
|
# =====
|
||||||
|
|||||||
@@ -726,17 +726,17 @@ class GuiNovelTree(QTreeWidget):
|
|||||||
|
|
||||||
refData = []
|
refData = []
|
||||||
refName = ""
|
refName = ""
|
||||||
theRefs = SHARED.project.index.getReferences(tHandle, sTitle)
|
refs = SHARED.project.index.getReferences(tHandle, sTitle)
|
||||||
if self._lastCol == NovelTreeColumn.POV:
|
if self._lastCol == NovelTreeColumn.POV:
|
||||||
refData = theRefs[nwKeyWords.POV_KEY]
|
refData = refs[nwKeyWords.POV_KEY]
|
||||||
refName = self._povLabel
|
refName = self._povLabel
|
||||||
|
|
||||||
elif self._lastCol == NovelTreeColumn.FOCUS:
|
elif self._lastCol == NovelTreeColumn.FOCUS:
|
||||||
refData = theRefs[nwKeyWords.FOCUS_KEY]
|
refData = refs[nwKeyWords.FOCUS_KEY]
|
||||||
refName = self._focLabel
|
refName = self._focLabel
|
||||||
|
|
||||||
elif self._lastCol == NovelTreeColumn.PLOT:
|
elif self._lastCol == NovelTreeColumn.PLOT:
|
||||||
refData = theRefs[nwKeyWords.PLOT_KEY]
|
refData = refs[nwKeyWords.PLOT_KEY]
|
||||||
refName = self._pltLabel
|
refName = self._pltLabel
|
||||||
|
|
||||||
if refData:
|
if refData:
|
||||||
|
|||||||
+13
-13
@@ -625,12 +625,12 @@ class GuiOutlineTree(QTreeWidget):
|
|||||||
self.clear()
|
self.clear()
|
||||||
|
|
||||||
if self._firstView:
|
if self._firstView:
|
||||||
theLabels = []
|
labels = []
|
||||||
for i, hItem in enumerate(self._treeOrder):
|
for i, hItem in enumerate(self._treeOrder):
|
||||||
theLabels.append(trConst(nwLabels.OUTLINE_COLS[hItem]))
|
labels.append(trConst(nwLabels.OUTLINE_COLS[hItem]))
|
||||||
self._colIdx[hItem] = i
|
self._colIdx[hItem] = i
|
||||||
|
|
||||||
self.setHeaderLabels(theLabels)
|
self.setHeaderLabels(labels)
|
||||||
for hItem in self._treeOrder:
|
for hItem in self._treeOrder:
|
||||||
self.setColumnWidth(self._colIdx[hItem], self._colWidth[hItem])
|
self.setColumnWidth(self._colIdx[hItem], self._colWidth[hItem])
|
||||||
self.setColumnHidden(self._colIdx[hItem], self._colHidden[hItem])
|
self.setColumnHidden(self._colIdx[hItem], self._colHidden[hItem])
|
||||||
@@ -990,7 +990,7 @@ class GuiOutlineDetails(QScrollArea):
|
|||||||
pIndex = SHARED.project.index
|
pIndex = SHARED.project.index
|
||||||
nwItem = SHARED.project.tree[tHandle]
|
nwItem = SHARED.project.tree[tHandle]
|
||||||
novIdx = pIndex.getItemHeader(tHandle, sTitle)
|
novIdx = pIndex.getItemHeader(tHandle, sTitle)
|
||||||
theRefs = pIndex.getReferences(tHandle, sTitle)
|
novRefs = pIndex.getReferences(tHandle, sTitle)
|
||||||
if nwItem is None or novIdx is None:
|
if nwItem is None or novIdx is None:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -1015,15 +1015,15 @@ class GuiOutlineDetails(QScrollArea):
|
|||||||
|
|
||||||
self.synopValue.setText(novIdx.synopsis)
|
self.synopValue.setText(novIdx.synopsis)
|
||||||
|
|
||||||
self.povKeyValue.setText(self._formatTags(theRefs, nwKeyWords.POV_KEY))
|
self.povKeyValue.setText(self._formatTags(novRefs, nwKeyWords.POV_KEY))
|
||||||
self.focKeyValue.setText(self._formatTags(theRefs, nwKeyWords.FOCUS_KEY))
|
self.focKeyValue.setText(self._formatTags(novRefs, nwKeyWords.FOCUS_KEY))
|
||||||
self.chrKeyValue.setText(self._formatTags(theRefs, nwKeyWords.CHAR_KEY))
|
self.chrKeyValue.setText(self._formatTags(novRefs, nwKeyWords.CHAR_KEY))
|
||||||
self.pltKeyValue.setText(self._formatTags(theRefs, nwKeyWords.PLOT_KEY))
|
self.pltKeyValue.setText(self._formatTags(novRefs, nwKeyWords.PLOT_KEY))
|
||||||
self.timKeyValue.setText(self._formatTags(theRefs, nwKeyWords.TIME_KEY))
|
self.timKeyValue.setText(self._formatTags(novRefs, nwKeyWords.TIME_KEY))
|
||||||
self.wldKeyValue.setText(self._formatTags(theRefs, nwKeyWords.WORLD_KEY))
|
self.wldKeyValue.setText(self._formatTags(novRefs, nwKeyWords.WORLD_KEY))
|
||||||
self.objKeyValue.setText(self._formatTags(theRefs, nwKeyWords.OBJECT_KEY))
|
self.objKeyValue.setText(self._formatTags(novRefs, nwKeyWords.OBJECT_KEY))
|
||||||
self.entKeyValue.setText(self._formatTags(theRefs, nwKeyWords.ENTITY_KEY))
|
self.entKeyValue.setText(self._formatTags(novRefs, nwKeyWords.ENTITY_KEY))
|
||||||
self.cstKeyValue.setText(self._formatTags(theRefs, nwKeyWords.CUSTOM_KEY))
|
self.cstKeyValue.setText(self._formatTags(novRefs, nwKeyWords.CUSTOM_KEY))
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|||||||
+12
-12
@@ -785,24 +785,24 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
project structure, and must be called before any code that
|
project structure, and must be called before any code that
|
||||||
depends on this order to be up to date.
|
depends on this order to be up to date.
|
||||||
"""
|
"""
|
||||||
theList = []
|
items = []
|
||||||
for i in range(self.topLevelItemCount()):
|
for i in range(self.topLevelItemCount()):
|
||||||
item = self.topLevelItem(i)
|
item = self.topLevelItem(i)
|
||||||
if isinstance(item, QTreeWidgetItem):
|
if isinstance(item, QTreeWidgetItem):
|
||||||
theList = self._scanChildren(theList, item, i)
|
items = self._scanChildren(items, item, i)
|
||||||
logger.debug("Saving project tree item order")
|
logger.debug("Saving project tree item order")
|
||||||
SHARED.project.setTreeOrder(theList)
|
SHARED.project.setTreeOrder(items)
|
||||||
return
|
return
|
||||||
|
|
||||||
def getTreeFromHandle(self, tHandle: str) -> list[str]:
|
def getTreeFromHandle(self, tHandle: str) -> list[str]:
|
||||||
"""Recursively return all the child items starting from a given
|
"""Recursively return all the child items starting from a given
|
||||||
item handle.
|
item handle.
|
||||||
"""
|
"""
|
||||||
theList = []
|
result = []
|
||||||
theItem = self._getTreeItem(tHandle)
|
tIten = self._getTreeItem(tHandle)
|
||||||
if theItem is not None:
|
if tIten is not None:
|
||||||
theList = self._scanChildren(theList, theItem, 0)
|
result = self._scanChildren(result, tIten, 0)
|
||||||
return theList
|
return result
|
||||||
|
|
||||||
def requestDeleteItem(self, tHandle: str | None = None) -> bool:
|
def requestDeleteItem(self, tHandle: str | None = None) -> bool:
|
||||||
"""Request an item deleted from the project tree. This function
|
"""Request an item deleted from the project tree. This function
|
||||||
@@ -857,11 +857,11 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
SHARED.info(self.tr("There is currently no Trash folder in this project."))
|
SHARED.info(self.tr("There is currently no Trash folder in this project."))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
theTrash = self.getTreeFromHandle(trashHandle)
|
trashItems = self.getTreeFromHandle(trashHandle)
|
||||||
if trashHandle in theTrash:
|
if trashHandle in trashItems:
|
||||||
theTrash.remove(trashHandle)
|
trashItems.remove(trashHandle)
|
||||||
|
|
||||||
nTrash = len(theTrash)
|
nTrash = len(trashItems)
|
||||||
if nTrash == 0:
|
if nTrash == 0:
|
||||||
SHARED.info(self.tr("The Trash folder is already empty."))
|
SHARED.info(self.tr("The Trash folder is already empty."))
|
||||||
return False
|
return False
|
||||||
|
|||||||
@@ -368,22 +368,22 @@ class GuiTheme:
|
|||||||
|
|
||||||
def _setGuiFont(self) -> None:
|
def _setGuiFont(self) -> None:
|
||||||
"""Update the GUI's font style from settings."""
|
"""Update the GUI's font style from settings."""
|
||||||
theFont = QFont()
|
font = QFont()
|
||||||
fontDB = QFontDatabase()
|
fontDB = QFontDatabase()
|
||||||
if CONFIG.guiFont not in fontDB.families():
|
if CONFIG.guiFont not in fontDB.families():
|
||||||
if CONFIG.osWindows and "Arial" in fontDB.families():
|
if CONFIG.osWindows and "Arial" in fontDB.families():
|
||||||
# On Windows we default to Arial if possible
|
# On Windows we default to Arial if possible
|
||||||
theFont.setFamily("Arial")
|
font.setFamily("Arial")
|
||||||
theFont.setPointSize(10)
|
font.setPointSize(10)
|
||||||
else:
|
else:
|
||||||
theFont = fontDB.systemFont(QFontDatabase.GeneralFont)
|
font = fontDB.systemFont(QFontDatabase.GeneralFont)
|
||||||
CONFIG.guiFont = theFont.family()
|
CONFIG.guiFont = font.family()
|
||||||
CONFIG.guiFontSize = theFont.pointSize()
|
CONFIG.guiFontSize = font.pointSize()
|
||||||
else:
|
else:
|
||||||
theFont.setFamily(CONFIG.guiFont)
|
font.setFamily(CONFIG.guiFont)
|
||||||
theFont.setPointSize(CONFIG.guiFontSize)
|
font.setPointSize(CONFIG.guiFontSize)
|
||||||
|
|
||||||
qApp.setFont(theFont)
|
qApp.setFont(font)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@@ -679,10 +679,10 @@ class GuiMain(QMainWindow):
|
|||||||
if loadFile.strip() == "":
|
if loadFile.strip() == "":
|
||||||
return False
|
return False
|
||||||
|
|
||||||
theText = None
|
text = None
|
||||||
try:
|
try:
|
||||||
with open(loadFile, mode="rt", encoding="utf-8") as inFile:
|
with open(loadFile, mode="rt", encoding="utf-8") as inFile:
|
||||||
theText = inFile.read()
|
text = inFile.read()
|
||||||
CONFIG.setLastPath(loadFile)
|
CONFIG.setLastPath(loadFile)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
SHARED.error(self.tr(
|
SHARED.error(self.tr(
|
||||||
@@ -704,7 +704,7 @@ class GuiMain(QMainWindow):
|
|||||||
if not msgYes:
|
if not msgYes:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
self.docEditor.replaceText(theText)
|
self.docEditor.replaceText(text)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|||||||
@@ -375,9 +375,9 @@ class GuiManuscript(QDialog):
|
|||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def _printDocument(self) -> None:
|
def _printDocument(self) -> None:
|
||||||
"""Open the print preview dialog."""
|
"""Open the print preview dialog."""
|
||||||
thePreview = QPrintPreviewDialog(self)
|
preview = QPrintPreviewDialog(self)
|
||||||
thePreview.paintRequested.connect(self.docPreview.printPreview)
|
preview.paintRequested.connect(self.docPreview.printPreview)
|
||||||
thePreview.exec_()
|
preview.exec_()
|
||||||
return
|
return
|
||||||
|
|
||||||
##
|
##
|
||||||
@@ -771,8 +771,8 @@ class _PreviewWidget(QTextBrowser):
|
|||||||
self.setHtml(html)
|
self.setHtml(html)
|
||||||
qApp.processEvents()
|
qApp.processEvents()
|
||||||
while self.find("!!tab!!"):
|
while self.find("!!tab!!"):
|
||||||
theCursor = self.textCursor()
|
cursor = self.textCursor()
|
||||||
theCursor.insertText("\t")
|
cursor.insertText("\t")
|
||||||
|
|
||||||
self.verticalScrollBar().setValue(sPos)
|
self.verticalScrollBar().setValue(sPos)
|
||||||
self._docTime = checkInt(data.get("time"), 0)
|
self._docTime = checkInt(data.get("time"), 0)
|
||||||
|
|||||||
@@ -1112,10 +1112,10 @@ class _FormatTab(NScrollableForm):
|
|||||||
currFont = QFont()
|
currFont = QFont()
|
||||||
currFont.setFamily(self.textFont.text())
|
currFont.setFamily(self.textFont.text())
|
||||||
currFont.setPointSize(self.textSize.value())
|
currFont.setPointSize(self.textSize.value())
|
||||||
theFont, theStatus = QFontDialog.getFont(currFont, self)
|
newFont, status = QFontDialog.getFont(currFont, self)
|
||||||
if theStatus:
|
if status:
|
||||||
self.textFont.setText(theFont.family())
|
self.textFont.setText(newFont.family())
|
||||||
self.textSize.setValue(theFont.pointSize())
|
self.textSize.setValue(newFont.pointSize())
|
||||||
return
|
return
|
||||||
|
|
||||||
@pyqtSlot(int)
|
@pyqtSlot(int)
|
||||||
|
|||||||
@@ -455,19 +455,19 @@ class _ContentsPage(NFixedPage):
|
|||||||
pTotal = 0
|
pTotal = 0
|
||||||
tPages = 1
|
tPages = 1
|
||||||
|
|
||||||
theList = []
|
entries = []
|
||||||
for _, tLevel, tTitle, wCount in self._data:
|
for _, tLevel, tTitle, wCount in self._data:
|
||||||
pCount = math.ceil(wCount/wpPage)
|
pCount = math.ceil(wCount/wpPage)
|
||||||
if dblPages:
|
if dblPages:
|
||||||
pCount += pCount%2
|
pCount += pCount%2
|
||||||
|
|
||||||
pTotal += pCount
|
pTotal += pCount
|
||||||
theList.append((tLevel, tTitle, wCount, pCount))
|
entries.append((tLevel, tTitle, wCount, pCount))
|
||||||
|
|
||||||
pMax = pTotal - fstPage
|
pMax = pTotal - fstPage
|
||||||
|
|
||||||
self.tocTree.clear()
|
self.tocTree.clear()
|
||||||
for tLevel, tTitle, wCount, pCount in theList:
|
for tLevel, tTitle, wCount, pCount in entries:
|
||||||
newItem = QTreeWidgetItem()
|
newItem = QTreeWidgetItem()
|
||||||
|
|
||||||
if tPages <= fstPage:
|
if tPages <= fstPage:
|
||||||
|
|||||||
@@ -585,13 +585,13 @@ class GuiWritingStats(QDialog):
|
|||||||
newItem.setText(self.C_COUNT, f"{nWords:n}")
|
newItem.setText(self.C_COUNT, f"{nWords:n}")
|
||||||
|
|
||||||
if nWords > 0 and listMax > 0:
|
if nWords > 0 and listMax > 0:
|
||||||
theBar = self.barImage.scaled(
|
wBar = self.barImage.scaled(
|
||||||
int(200*min(nWords, histMax)/listMax),
|
int(200*min(nWords, histMax)/listMax),
|
||||||
self.barHeight,
|
self.barHeight,
|
||||||
Qt.IgnoreAspectRatio,
|
Qt.IgnoreAspectRatio,
|
||||||
Qt.FastTransformation
|
Qt.FastTransformation
|
||||||
)
|
)
|
||||||
newItem.setData(self.C_BAR, Qt.DecorationRole, theBar)
|
newItem.setData(self.C_BAR, Qt.DecorationRole, wBar)
|
||||||
|
|
||||||
newItem.setTextAlignment(self.C_LENGTH, Qt.AlignRight)
|
newItem.setTextAlignment(self.C_LENGTH, Qt.AlignRight)
|
||||||
newItem.setTextAlignment(self.C_IDLE, Qt.AlignRight)
|
newItem.setTextAlignment(self.C_IDLE, Qt.AlignRight)
|
||||||
|
|||||||
+5
-5
@@ -47,9 +47,9 @@ def extractVersion(beQuiet: bool = False) -> tuple[str, str, str]:
|
|||||||
"""Extract the novelWriter version number without having to import
|
"""Extract the novelWriter version number without having to import
|
||||||
anything else from the main package.
|
anything else from the main package.
|
||||||
"""
|
"""
|
||||||
def getValue(theString):
|
def getValue(text):
|
||||||
theBits = theString.partition("=")
|
bits = text.partition("=")
|
||||||
return theBits[2].strip().strip('"')
|
return bits[2].strip().strip('"')
|
||||||
|
|
||||||
numVers = "0"
|
numVers = "0"
|
||||||
hexVers = "0x0"
|
hexVers = "0x0"
|
||||||
@@ -1744,7 +1744,7 @@ def winUninstall() -> None:
|
|||||||
print("")
|
print("")
|
||||||
print("Removing registry keys ...")
|
print("Removing registry keys ...")
|
||||||
|
|
||||||
theKeys = [
|
keys = [
|
||||||
r"Software\Classes\novelWriterProject.nwx\shell\open\command",
|
r"Software\Classes\novelWriterProject.nwx\shell\open\command",
|
||||||
r"Software\Classes\novelWriterProject.nwx\shell\open",
|
r"Software\Classes\novelWriterProject.nwx\shell\open",
|
||||||
r"Software\Classes\novelWriterProject.nwx\shell",
|
r"Software\Classes\novelWriterProject.nwx\shell",
|
||||||
@@ -1756,7 +1756,7 @@ def winUninstall() -> None:
|
|||||||
r"Software\Classes\Applications\novelWriter.pyw",
|
r"Software\Classes\Applications\novelWriter.pyw",
|
||||||
]
|
]
|
||||||
|
|
||||||
for aKey in theKeys:
|
for aKey in keys:
|
||||||
try:
|
try:
|
||||||
winreg.DeleteKey(winreg.HKEY_CURRENT_USER, aKey)
|
winreg.DeleteKey(winreg.HKEY_CURRENT_USER, aKey)
|
||||||
print("Deleted: HKEY_CURRENT_USER\\%s" % aKey)
|
print("Deleted: HKEY_CURRENT_USER\\%s" % aKey)
|
||||||
|
|||||||
+4
-4
@@ -39,7 +39,7 @@ class MockGuiMain(QWidget):
|
|||||||
def postLaunchTasks(self, cmdOpen):
|
def postLaunchTasks(self, cmdOpen):
|
||||||
return
|
return
|
||||||
|
|
||||||
def setStatus(self, theMessage):
|
def setStatus(self, message):
|
||||||
return
|
return
|
||||||
|
|
||||||
def openProject(self, projPath):
|
def openProject(self, projPath):
|
||||||
@@ -63,10 +63,10 @@ class MockStatusBar:
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
return
|
return
|
||||||
|
|
||||||
def setStatus(self, theText):
|
def setStatus(self, text):
|
||||||
return
|
return
|
||||||
|
|
||||||
def updateProjectStatus(self, theStatus):
|
def updateProjectStatus(self, status):
|
||||||
return
|
return
|
||||||
|
|
||||||
# END Class MockStatusBar
|
# END Class MockStatusBar
|
||||||
@@ -89,7 +89,7 @@ class MockApp:
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
return
|
return
|
||||||
|
|
||||||
def installTranslator(self, theLang):
|
def installTranslator(self, language):
|
||||||
return
|
return
|
||||||
|
|
||||||
# END Class MockApp
|
# END Class MockApp
|
||||||
|
|||||||
@@ -177,19 +177,19 @@ def testBaseConfig_Localisation(fncPath, tstPaths):
|
|||||||
tstConf.initLocalisation(tstApp) # type: ignore
|
tstConf.initLocalisation(tstApp) # type: ignore
|
||||||
|
|
||||||
# Check Lists
|
# Check Lists
|
||||||
theList = tstConf.listLanguages(tstConf.LANG_NW)
|
languages = tstConf.listLanguages(tstConf.LANG_NW)
|
||||||
assert theList == [("en_GB", "British English")]
|
assert languages == [("en_GB", "British English")]
|
||||||
theList = tstConf.listLanguages(tstConf.LANG_PROJ)
|
languages = tstConf.listLanguages(tstConf.LANG_PROJ)
|
||||||
assert theList == [("en_GB", "British English")]
|
assert languages == [("en_GB", "British English")]
|
||||||
theList = tstConf.listLanguages(None) # type: ignore
|
languages = tstConf.listLanguages(None) # type: ignore
|
||||||
assert theList == []
|
assert languages == []
|
||||||
|
|
||||||
# Add Language
|
# Add Language
|
||||||
copyfile(tstPaths.filesDir / "nw_en_GB.qm", i18nDir / "nw_fr.qm")
|
copyfile(tstPaths.filesDir / "nw_en_GB.qm", i18nDir / "nw_fr.qm")
|
||||||
writeFile(i18nDir / "nw_fr.ts", "")
|
writeFile(i18nDir / "nw_fr.ts", "")
|
||||||
|
|
||||||
theList = tstConf.listLanguages(tstConf.LANG_NW)
|
languages = tstConf.listLanguages(tstConf.LANG_NW)
|
||||||
assert theList == [("en_GB", "British English"), ("fr", "Français")]
|
assert languages == [("en_GB", "British English"), ("fr", "Français")]
|
||||||
|
|
||||||
# END Test testBaseConfig_Localisation
|
# END Test testBaseConfig_Localisation
|
||||||
|
|
||||||
|
|||||||
@@ -43,19 +43,19 @@ def testBaseError_Dialog(qtbot, monkeypatch, nwGUI):
|
|||||||
with monkeypatch.context() as mp:
|
with monkeypatch.context() as mp:
|
||||||
mp.setattr("PyQt5.QtCore.QSysInfo.kernelVersion", lambda: "1.2.3")
|
mp.setattr("PyQt5.QtCore.QSysInfo.kernelVersion", lambda: "1.2.3")
|
||||||
nwErr.setMessage(Exception, "Fine Error", None)
|
nwErr.setMessage(Exception, "Fine Error", None)
|
||||||
theMessage = nwErr.msgBody.toPlainText()
|
message = nwErr.msgBody.toPlainText()
|
||||||
assert theMessage != ""
|
assert message != ""
|
||||||
assert "Fine Error" in theMessage
|
assert "Fine Error" in message
|
||||||
assert "Exception" in theMessage
|
assert "Exception" in message
|
||||||
assert "(1.2.3)" in theMessage
|
assert "(1.2.3)" in message
|
||||||
|
|
||||||
# No kernel version retrieved
|
# No kernel version retrieved
|
||||||
with monkeypatch.context() as mp:
|
with monkeypatch.context() as mp:
|
||||||
mp.setattr("PyQt5.QtCore.QSysInfo.kernelVersion", causeException)
|
mp.setattr("PyQt5.QtCore.QSysInfo.kernelVersion", causeException)
|
||||||
nwErr.setMessage(Exception, "Almost Fine Error", None)
|
nwErr.setMessage(Exception, "Almost Fine Error", None)
|
||||||
theMessage = nwErr.msgBody.toPlainText()
|
message = nwErr.msgBody.toPlainText()
|
||||||
assert theMessage != ""
|
assert message != ""
|
||||||
assert "(Unknown)" in theMessage
|
assert "(Unknown)" in message
|
||||||
|
|
||||||
nwErr._doClose()
|
nwErr._doClose()
|
||||||
nwErr.close()
|
nwErr.close()
|
||||||
|
|||||||
@@ -35,51 +35,51 @@ def testCoreDocument_LoadSave(monkeypatch, mockGUI, fncPath, mockRnd):
|
|||||||
"""Test loading and saving a document with the NWDocument class."""
|
"""Test loading and saving a document with the NWDocument class."""
|
||||||
monkeypatch.setattr("novelwriter.core.document.time", lambda: MOCK_TIME)
|
monkeypatch.setattr("novelwriter.core.document.time", lambda: MOCK_TIME)
|
||||||
|
|
||||||
theProject = NWProject()
|
project = NWProject()
|
||||||
mockRnd.reset()
|
mockRnd.reset()
|
||||||
buildTestProject(theProject, fncPath)
|
buildTestProject(project, fncPath)
|
||||||
|
|
||||||
# Read Document
|
# Read Document
|
||||||
# =============
|
# =============
|
||||||
|
|
||||||
# Not a valid handle
|
# Not a valid handle
|
||||||
theDoc = NWDocument(theProject, "stuff")
|
doc = NWDocument(project, "stuff")
|
||||||
assert bool(theDoc) is False
|
assert bool(doc) is False
|
||||||
assert theDoc.readDocument() is None
|
assert doc.readDocument() is None
|
||||||
assert theDoc.fileExists() is False
|
assert doc.fileExists() is False
|
||||||
|
|
||||||
# Non-existent handle
|
# Non-existent handle
|
||||||
theDoc = NWDocument(theProject, C.hInvalid)
|
doc = NWDocument(project, C.hInvalid)
|
||||||
assert theDoc.readDocument() is None
|
assert doc.readDocument() is None
|
||||||
assert theDoc._lastHash == ""
|
assert doc._lastHash == ""
|
||||||
assert theDoc.fileExists() is False
|
assert doc.fileExists() is False
|
||||||
|
|
||||||
# No content path
|
# No content path
|
||||||
with monkeypatch.context() as mp:
|
with monkeypatch.context() as mp:
|
||||||
mp.setattr("novelwriter.core.storage.NWStorage.contentPath", property(lambda *a: None))
|
mp.setattr("novelwriter.core.storage.NWStorage.contentPath", property(lambda *a: None))
|
||||||
theDoc = NWDocument(theProject, C.hSceneDoc)
|
doc = NWDocument(project, C.hSceneDoc)
|
||||||
assert theDoc.readDocument() is None
|
assert doc.readDocument() is None
|
||||||
assert theDoc.fileExists() is False
|
assert doc.fileExists() is False
|
||||||
|
|
||||||
# Cause open() to fail while loading
|
# Cause open() to fail while loading
|
||||||
with monkeypatch.context() as mp:
|
with monkeypatch.context() as mp:
|
||||||
mp.setattr("builtins.open", causeOSError)
|
mp.setattr("builtins.open", causeOSError)
|
||||||
theDoc = NWDocument(theProject, C.hSceneDoc)
|
doc = NWDocument(project, C.hSceneDoc)
|
||||||
assert theDoc.fileExists() is True
|
assert doc.fileExists() is True
|
||||||
assert theDoc.readDocument() is None
|
assert doc.readDocument() is None
|
||||||
assert theDoc.getError() == "OSError: Mock OSError"
|
assert doc.getError() == "OSError: Mock OSError"
|
||||||
|
|
||||||
# Load the text
|
# Load the text
|
||||||
theDoc = NWDocument(theProject, C.hSceneDoc)
|
doc = NWDocument(project, C.hSceneDoc)
|
||||||
assert theDoc.fileExists() is True
|
assert doc.fileExists() is True
|
||||||
assert theDoc.readDocument() == "### New Scene\n\n"
|
assert doc.readDocument() == "### New Scene\n\n"
|
||||||
|
|
||||||
# Try to open a new (non-existent) file
|
# Try to open a new (non-existent) file
|
||||||
xHandle = theProject.newFile("New File", C.hNovelRoot)
|
xHandle = project.newFile("New File", C.hNovelRoot)
|
||||||
theDoc = NWDocument(theProject, xHandle)
|
doc = NWDocument(project, xHandle)
|
||||||
assert bool(theDoc) is True
|
assert bool(doc) is True
|
||||||
assert repr(theDoc) == f"<NWDocument handle={xHandle}>"
|
assert repr(doc) == f"<NWDocument handle={xHandle}>"
|
||||||
assert theDoc.readDocument() == ""
|
assert doc.readDocument() == ""
|
||||||
|
|
||||||
# Write Document
|
# Write Document
|
||||||
# ==============
|
# ==============
|
||||||
@@ -87,17 +87,17 @@ def testCoreDocument_LoadSave(monkeypatch, mockGUI, fncPath, mockRnd):
|
|||||||
# No content path
|
# No content path
|
||||||
with monkeypatch.context() as mp:
|
with monkeypatch.context() as mp:
|
||||||
mp.setattr("novelwriter.core.storage.NWStorage.contentPath", property(lambda *a: None))
|
mp.setattr("novelwriter.core.storage.NWStorage.contentPath", property(lambda *a: None))
|
||||||
theDoc = NWDocument(theProject, xHandle)
|
doc = NWDocument(project, xHandle)
|
||||||
assert theDoc.writeDocument("") is False
|
assert doc.writeDocument("") is False
|
||||||
|
|
||||||
# Set handle and save
|
# Set handle and save
|
||||||
theText = "### Test File\n\nText ...\n\n"
|
text = "### Test File\n\nText ...\n\n"
|
||||||
theDoc = NWDocument(theProject, xHandle)
|
doc = NWDocument(project, xHandle)
|
||||||
assert theDoc.readDocument(xHandle) == "" # type: ignore
|
assert doc.readDocument(xHandle) == "" # type: ignore
|
||||||
assert theDoc.writeDocument(theText) is True
|
assert doc.writeDocument(text) is True
|
||||||
|
|
||||||
# Save again to ensure temp file and previous file is handled
|
# Save again to ensure temp file and previous file is handled
|
||||||
assert theDoc.writeDocument(theText) is True
|
assert doc.writeDocument(text) is True
|
||||||
|
|
||||||
# Check file content
|
# Check file content
|
||||||
docPath = fncPath / "content" / f"{xHandle}.nwd"
|
docPath = fncPath / "content" / f"{xHandle}.nwd"
|
||||||
@@ -113,62 +113,62 @@ def testCoreDocument_LoadSave(monkeypatch, mockGUI, fncPath, mockRnd):
|
|||||||
|
|
||||||
# Alter the document on disk and save again
|
# Alter the document on disk and save again
|
||||||
writeFile(docPath, "blablabla")
|
writeFile(docPath, "blablabla")
|
||||||
assert theDoc.writeDocument(theText) is False
|
assert doc.writeDocument(text) is False
|
||||||
|
|
||||||
# Force the overwrite
|
# Force the overwrite
|
||||||
assert theDoc.writeDocument(theText, forceWrite=True) is True
|
assert doc.writeDocument(text, forceWrite=True) is True
|
||||||
|
|
||||||
# Force no meta data
|
# Force no meta data
|
||||||
theDoc._item = None
|
doc._item = None
|
||||||
assert theDoc.writeDocument(theText) is True
|
assert doc.writeDocument(text) is True
|
||||||
assert readFile(docPath) == theText
|
assert readFile(docPath) == text
|
||||||
|
|
||||||
# Cause open() to fail while saving
|
# Cause open() to fail while saving
|
||||||
with monkeypatch.context() as mp:
|
with monkeypatch.context() as mp:
|
||||||
mp.setattr("builtins.open", causeOSError)
|
mp.setattr("builtins.open", causeOSError)
|
||||||
assert theDoc.writeDocument(theText) is False
|
assert doc.writeDocument(text) is False
|
||||||
assert theDoc.getError() == "OSError: Mock OSError"
|
assert doc.getError() == "OSError: Mock OSError"
|
||||||
|
|
||||||
theDoc._docError = ""
|
doc._docError = ""
|
||||||
assert theDoc.getError() == ""
|
assert doc.getError() == ""
|
||||||
|
|
||||||
# Cause os.replace() to fail while saving
|
# Cause os.replace() to fail while saving
|
||||||
with monkeypatch.context() as mp:
|
with monkeypatch.context() as mp:
|
||||||
mp.setattr("pathlib.Path.replace", causeOSError)
|
mp.setattr("pathlib.Path.replace", causeOSError)
|
||||||
assert theDoc.writeDocument(theText) is False
|
assert doc.writeDocument(text) is False
|
||||||
assert theDoc.getError() == "OSError: Mock OSError"
|
assert doc.getError() == "OSError: Mock OSError"
|
||||||
|
|
||||||
theDoc._docError = ""
|
doc._docError = ""
|
||||||
assert theDoc.getError() == ""
|
assert doc.getError() == ""
|
||||||
|
|
||||||
# Saving with no handle
|
# Saving with no handle
|
||||||
theDoc._handle = None
|
doc._handle = None
|
||||||
assert theDoc.writeDocument(theText) is False
|
assert doc.writeDocument(text) is False
|
||||||
|
|
||||||
# Delete Document
|
# Delete Document
|
||||||
# ===============
|
# ===============
|
||||||
|
|
||||||
# Delete a non-existing document
|
# Delete a non-existing document
|
||||||
theDoc = NWDocument(theProject, "stuff")
|
doc = NWDocument(project, "stuff")
|
||||||
assert theDoc.deleteDocument() is False
|
assert doc.deleteDocument() is False
|
||||||
assert docPath.exists()
|
assert docPath.exists()
|
||||||
|
|
||||||
# No content path
|
# No content path
|
||||||
with monkeypatch.context() as mp:
|
with monkeypatch.context() as mp:
|
||||||
mp.setattr("novelwriter.core.storage.NWStorage.contentPath", property(lambda *a: None))
|
mp.setattr("novelwriter.core.storage.NWStorage.contentPath", property(lambda *a: None))
|
||||||
theDoc = NWDocument(theProject, xHandle)
|
doc = NWDocument(project, xHandle)
|
||||||
assert theDoc.deleteDocument() is False
|
assert doc.deleteDocument() is False
|
||||||
|
|
||||||
# Cause the delete to fail
|
# Cause the delete to fail
|
||||||
with monkeypatch.context() as mp:
|
with monkeypatch.context() as mp:
|
||||||
mp.setattr("pathlib.Path.unlink", causeOSError)
|
mp.setattr("pathlib.Path.unlink", causeOSError)
|
||||||
theDoc = NWDocument(theProject, xHandle)
|
doc = NWDocument(project, xHandle)
|
||||||
assert theDoc.deleteDocument() is False
|
assert doc.deleteDocument() is False
|
||||||
assert theDoc.getError() == "OSError: Mock OSError"
|
assert doc.getError() == "OSError: Mock OSError"
|
||||||
|
|
||||||
# Make the delete pass
|
# Make the delete pass
|
||||||
theDoc = NWDocument(theProject, xHandle)
|
doc = NWDocument(project, xHandle)
|
||||||
assert theDoc.deleteDocument() is True
|
assert doc.deleteDocument() is True
|
||||||
assert not docPath.exists()
|
assert not docPath.exists()
|
||||||
|
|
||||||
# END Test testCoreDocument_Load
|
# END Test testCoreDocument_Load
|
||||||
@@ -179,31 +179,31 @@ def testCoreDocument_Methods(monkeypatch, mockGUI, fncPath, mockRnd):
|
|||||||
"""Test other methods of the NWDocument class."""
|
"""Test other methods of the NWDocument class."""
|
||||||
monkeypatch.setattr("novelwriter.core.document.time", lambda: MOCK_TIME)
|
monkeypatch.setattr("novelwriter.core.document.time", lambda: MOCK_TIME)
|
||||||
|
|
||||||
theProject = NWProject()
|
project = NWProject()
|
||||||
mockRnd.reset()
|
mockRnd.reset()
|
||||||
buildTestProject(theProject, fncPath)
|
buildTestProject(project, fncPath)
|
||||||
|
|
||||||
theDoc = NWDocument(theProject, C.hSceneDoc)
|
doc = NWDocument(project, C.hSceneDoc)
|
||||||
docPath = fncPath / "content" / f"{C.hSceneDoc}.nwd"
|
docPath = fncPath / "content" / f"{C.hSceneDoc}.nwd"
|
||||||
|
|
||||||
assert theDoc.readDocument() == "### New Scene\n\n"
|
assert doc.readDocument() == "### New Scene\n\n"
|
||||||
|
|
||||||
# Check location
|
# Check location
|
||||||
assert theDoc.fileLocation == str(docPath)
|
assert doc.fileLocation == str(docPath)
|
||||||
|
|
||||||
# Check the item
|
# Check the item
|
||||||
assert theDoc.nwItem is not None
|
assert doc.nwItem is not None
|
||||||
assert theDoc.nwItem.itemHandle == C.hSceneDoc # type: ignore
|
assert doc.nwItem.itemHandle == C.hSceneDoc # type: ignore
|
||||||
|
|
||||||
# Check the meta
|
# Check the meta
|
||||||
theName, theParent, theClass, theLayout = theDoc.getMeta()
|
name, parent, itemClass, itemLayout = doc.getMeta()
|
||||||
assert theName == "New Scene"
|
assert name == "New Scene"
|
||||||
assert theParent == C.hChapterDir
|
assert parent == C.hChapterDir
|
||||||
assert theClass == nwItemClass.NOVEL
|
assert itemClass == nwItemClass.NOVEL
|
||||||
assert theLayout == nwItemLayout.DOCUMENT
|
assert itemLayout == nwItemLayout.DOCUMENT
|
||||||
|
|
||||||
# Add meta data garbage
|
# Add meta data garbage
|
||||||
assert theDoc.writeDocument("%%~ stuff\n### Test File\n\nText ...\n\n")
|
assert doc.writeDocument("%%~ stuff\n### Test File\n\nText ...\n\n")
|
||||||
assert readFile(docPath) == (
|
assert readFile(docPath) == (
|
||||||
"%%~name: New Scene\n"
|
"%%~name: New Scene\n"
|
||||||
f"%%~path: {C.hChapterDir}/{C.hSceneDoc}\n"
|
f"%%~path: {C.hChapterDir}/{C.hSceneDoc}\n"
|
||||||
@@ -215,6 +215,6 @@ def testCoreDocument_Methods(monkeypatch, mockGUI, fncPath, mockRnd):
|
|||||||
"Text ...\n\n"
|
"Text ...\n\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
assert theDoc.readDocument() == "### Test File\n\nText ...\n\n"
|
assert doc.readDocument() == "### Test File\n\nText ...\n\n"
|
||||||
|
|
||||||
# END Test testCoreDocument_Methods
|
# END Test testCoreDocument_Methods
|
||||||
|
|||||||
@@ -160,52 +160,52 @@ def testCoreIndex_ScanThis(mockGUI):
|
|||||||
project = NWProject()
|
project = NWProject()
|
||||||
index = project.index
|
index = project.index
|
||||||
|
|
||||||
isValid, theBits, thePos = index.scanThis("tag: this, and this")
|
isValid, bits, pos = index.scanThis("tag: this, and this")
|
||||||
assert isValid is False
|
assert isValid is False
|
||||||
|
|
||||||
isValid, theBits, thePos = index.scanThis("@")
|
isValid, bits, pos = index.scanThis("@")
|
||||||
assert isValid is False
|
assert isValid is False
|
||||||
|
|
||||||
isValid, theBits, thePos = index.scanThis("@:")
|
isValid, bits, pos = index.scanThis("@:")
|
||||||
assert isValid is False
|
assert isValid is False
|
||||||
|
|
||||||
isValid, theBits, thePos = index.scanThis(" @a: b")
|
isValid, bits, pos = index.scanThis(" @a: b")
|
||||||
assert isValid is False
|
assert isValid is False
|
||||||
|
|
||||||
isValid, theBits, thePos = index.scanThis("@a:")
|
isValid, bits, pos = index.scanThis("@a:")
|
||||||
assert isValid is True
|
assert isValid is True
|
||||||
assert theBits == ["@a"]
|
assert bits == ["@a"]
|
||||||
assert thePos == [0]
|
assert pos == [0]
|
||||||
|
|
||||||
isValid, theBits, thePos = index.scanThis("@a:b")
|
isValid, bits, pos = index.scanThis("@a:b")
|
||||||
assert isValid is True
|
assert isValid is True
|
||||||
assert theBits == ["@a", "b"]
|
assert bits == ["@a", "b"]
|
||||||
assert thePos == [0, 3]
|
assert pos == [0, 3]
|
||||||
|
|
||||||
isValid, theBits, thePos = index.scanThis("@a:b,c,d")
|
isValid, bits, pos = index.scanThis("@a:b,c,d")
|
||||||
assert isValid is True
|
assert isValid is True
|
||||||
assert theBits == ["@a", "b", "c", "d"]
|
assert bits == ["@a", "b", "c", "d"]
|
||||||
assert thePos == [0, 3, 5, 7]
|
assert pos == [0, 3, 5, 7]
|
||||||
|
|
||||||
isValid, theBits, thePos = index.scanThis("@a : b , c , d")
|
isValid, bits, pos = index.scanThis("@a : b , c , d")
|
||||||
assert isValid is True
|
assert isValid is True
|
||||||
assert theBits == ["@a", "b", "c", "d"]
|
assert bits == ["@a", "b", "c", "d"]
|
||||||
assert thePos == [0, 5, 9, 13]
|
assert pos == [0, 5, 9, 13]
|
||||||
|
|
||||||
isValid, theBits, thePos = index.scanThis("@tag: this, and this")
|
isValid, bits, pos = index.scanThis("@tag: this, and this")
|
||||||
assert isValid is True
|
assert isValid is True
|
||||||
assert theBits == ["@tag", "this", "and this"]
|
assert bits == ["@tag", "this", "and this"]
|
||||||
assert thePos == [0, 6, 12]
|
assert pos == [0, 6, 12]
|
||||||
|
|
||||||
isValid, theBits, thePos = index.scanThis("@tag: this,, and this")
|
isValid, bits, pos = index.scanThis("@tag: this,, and this")
|
||||||
assert isValid is True
|
assert isValid is True
|
||||||
assert theBits == ["@tag", "this", "", "and this"]
|
assert bits == ["@tag", "this", "", "and this"]
|
||||||
assert thePos == [0, 6, 11, 13]
|
assert pos == [0, 6, 11, 13]
|
||||||
|
|
||||||
isValid, theBits, thePos = index.scanThis("@tag: this, , and this")
|
isValid, bits, pos = index.scanThis("@tag: this, , and this")
|
||||||
assert isValid is True
|
assert isValid is True
|
||||||
assert theBits == ["@tag", "this", "", "and this"]
|
assert bits == ["@tag", "this", "", "and this"]
|
||||||
assert thePos == [0, 6, 12, 14]
|
assert pos == [0, 6, 12, 14]
|
||||||
|
|
||||||
project.closeProject()
|
project.closeProject()
|
||||||
|
|
||||||
|
|||||||
+349
-349
@@ -35,150 +35,150 @@ from novelwriter.core.project import NWProject
|
|||||||
@pytest.mark.core
|
@pytest.mark.core
|
||||||
def testCoreItem_Setters(mockGUI, mockRnd, fncPath):
|
def testCoreItem_Setters(mockGUI, mockRnd, fncPath):
|
||||||
"""Test all the simple setters for the NWItem class."""
|
"""Test all the simple setters for the NWItem class."""
|
||||||
theProject = NWProject()
|
project = NWProject()
|
||||||
mockRnd.reset()
|
mockRnd.reset()
|
||||||
buildTestProject(theProject, fncPath)
|
buildTestProject(project, fncPath)
|
||||||
theItem = NWItem(theProject, "0000000000000")
|
item = NWItem(project, "0000000000000")
|
||||||
assert theItem.itemHandle == "0000000000000"
|
assert item.itemHandle == "0000000000000"
|
||||||
|
|
||||||
statusKeys = ["s000000", "s000001", "s000002", "s000003"]
|
statusKeys = ["s000000", "s000001", "s000002", "s000003"]
|
||||||
importKeys = ["i000004", "i000005", "i000006", "i000007"]
|
importKeys = ["i000004", "i000005", "i000006", "i000007"]
|
||||||
|
|
||||||
# Name
|
# Name
|
||||||
theItem.setName("A Name")
|
item.setName("A Name")
|
||||||
assert theItem.itemName == "A Name"
|
assert item.itemName == "A Name"
|
||||||
theItem.setName("\t A Name ")
|
item.setName("\t A Name ")
|
||||||
assert theItem.itemName == "A Name"
|
assert item.itemName == "A Name"
|
||||||
theItem.setName("\t A\t\u2009\u202f\u2002\u2003\u2028\u2029Name ")
|
item.setName("\t A\t\u2009\u202f\u2002\u2003\u2028\u2029Name ")
|
||||||
assert theItem.itemName == "A Name"
|
assert item.itemName == "A Name"
|
||||||
theItem.setName(123)
|
item.setName(123)
|
||||||
assert theItem.itemName == ""
|
assert item.itemName == ""
|
||||||
|
|
||||||
# Parent
|
# Parent
|
||||||
theItem.setParent(None)
|
item.setParent(None)
|
||||||
assert theItem.itemParent is None
|
assert item.itemParent is None
|
||||||
theItem.setParent(123)
|
item.setParent(123)
|
||||||
assert theItem.itemParent is None
|
assert item.itemParent is None
|
||||||
theItem.setParent("0123456789abcdef")
|
item.setParent("0123456789abcdef")
|
||||||
assert theItem.itemParent is None
|
assert item.itemParent is None
|
||||||
theItem.setParent("0123456789abg")
|
item.setParent("0123456789abg")
|
||||||
assert theItem.itemParent is None
|
assert item.itemParent is None
|
||||||
theItem.setParent("0123456789abc")
|
item.setParent("0123456789abc")
|
||||||
assert theItem.itemParent == "0123456789abc"
|
assert item.itemParent == "0123456789abc"
|
||||||
|
|
||||||
# Root
|
# Root
|
||||||
theItem.setRoot(None)
|
item.setRoot(None)
|
||||||
assert theItem.itemRoot is None
|
assert item.itemRoot is None
|
||||||
theItem.setRoot(123)
|
item.setRoot(123)
|
||||||
assert theItem.itemRoot is None
|
assert item.itemRoot is None
|
||||||
theItem.setRoot("0123456789abcdef")
|
item.setRoot("0123456789abcdef")
|
||||||
assert theItem.itemRoot is None
|
assert item.itemRoot is None
|
||||||
theItem.setRoot("0123456789abg")
|
item.setRoot("0123456789abg")
|
||||||
assert theItem.itemRoot is None
|
assert item.itemRoot is None
|
||||||
theItem.setRoot("0123456789abc")
|
item.setRoot("0123456789abc")
|
||||||
assert theItem.itemRoot == "0123456789abc"
|
assert item.itemRoot == "0123456789abc"
|
||||||
|
|
||||||
# Order
|
# Order
|
||||||
theItem.setOrder(None)
|
item.setOrder(None)
|
||||||
assert theItem.itemOrder == 0
|
assert item.itemOrder == 0
|
||||||
theItem.setOrder("1")
|
item.setOrder("1")
|
||||||
assert theItem.itemOrder == 1
|
assert item.itemOrder == 1
|
||||||
theItem.setOrder(1)
|
item.setOrder(1)
|
||||||
assert theItem.itemOrder == 1
|
assert item.itemOrder == 1
|
||||||
|
|
||||||
# Importance
|
# Importance
|
||||||
theItem._class = nwItemClass.CHARACTER
|
item._class = nwItemClass.CHARACTER
|
||||||
theItem.setImport("Word")
|
item.setImport("Word")
|
||||||
assert theItem.itemImport == importKeys[0] # Default
|
assert item.itemImport == importKeys[0] # Default
|
||||||
for key in importKeys:
|
for key in importKeys:
|
||||||
theItem.setImport(key)
|
item.setImport(key)
|
||||||
assert theItem.itemImport == key
|
assert item.itemImport == key
|
||||||
|
|
||||||
# Status
|
# Status
|
||||||
theItem._class = nwItemClass.NOVEL
|
item._class = nwItemClass.NOVEL
|
||||||
theItem.setStatus("Word")
|
item.setStatus("Word")
|
||||||
assert theItem.itemStatus == statusKeys[0] # Default
|
assert item.itemStatus == statusKeys[0] # Default
|
||||||
for key in statusKeys:
|
for key in statusKeys:
|
||||||
theItem.setStatus(key)
|
item.setStatus(key)
|
||||||
assert theItem.itemStatus == key
|
assert item.itemStatus == key
|
||||||
|
|
||||||
# Status/Importance Wrapper
|
# Status/Importance Wrapper
|
||||||
theItem._class = nwItemClass.CHARACTER
|
item._class = nwItemClass.CHARACTER
|
||||||
for key in importKeys:
|
for key in importKeys:
|
||||||
theItem.setImport(key)
|
item.setImport(key)
|
||||||
assert theItem.itemImport == key
|
assert item.itemImport == key
|
||||||
assert theItem.itemStatus == statusKeys[3] # Should not change
|
assert item.itemStatus == statusKeys[3] # Should not change
|
||||||
|
|
||||||
theItem._class = nwItemClass.NOVEL
|
item._class = nwItemClass.NOVEL
|
||||||
for key in statusKeys:
|
for key in statusKeys:
|
||||||
theItem.setStatus(key)
|
item.setStatus(key)
|
||||||
assert theItem.itemImport == importKeys[3] # Should not change
|
assert item.itemImport == importKeys[3] # Should not change
|
||||||
assert theItem.itemStatus == key
|
assert item.itemStatus == key
|
||||||
|
|
||||||
# Expanded
|
# Expanded
|
||||||
theItem.setExpanded(8)
|
item.setExpanded(8)
|
||||||
assert theItem.isExpanded is False
|
assert item.isExpanded is False
|
||||||
theItem.setExpanded(None)
|
item.setExpanded(None)
|
||||||
assert theItem.isExpanded is False
|
assert item.isExpanded is False
|
||||||
theItem.setExpanded("None")
|
item.setExpanded("None")
|
||||||
assert theItem.isExpanded is False
|
assert item.isExpanded is False
|
||||||
theItem.setExpanded("What?")
|
item.setExpanded("What?")
|
||||||
assert theItem.isExpanded is False
|
assert item.isExpanded is False
|
||||||
theItem.setExpanded("True")
|
item.setExpanded("True")
|
||||||
assert theItem.isExpanded is False
|
assert item.isExpanded is False
|
||||||
theItem.setExpanded(True)
|
item.setExpanded(True)
|
||||||
assert theItem.isExpanded is True
|
assert item.isExpanded is True
|
||||||
|
|
||||||
# Active
|
# Active
|
||||||
theItem.setActive(8)
|
item.setActive(8)
|
||||||
assert theItem.isActive is False
|
assert item.isActive is False
|
||||||
theItem.setActive(None)
|
item.setActive(None)
|
||||||
assert theItem.isActive is False
|
assert item.isActive is False
|
||||||
theItem.setActive("None")
|
item.setActive("None")
|
||||||
assert theItem.isActive is False
|
assert item.isActive is False
|
||||||
theItem.setActive("What?")
|
item.setActive("What?")
|
||||||
assert theItem.isActive is False
|
assert item.isActive is False
|
||||||
theItem.setActive("True")
|
item.setActive("True")
|
||||||
assert theItem.isActive is False
|
assert item.isActive is False
|
||||||
theItem.setActive(True)
|
item.setActive(True)
|
||||||
assert theItem.isActive is True
|
assert item.isActive is True
|
||||||
|
|
||||||
# CharCount
|
# CharCount
|
||||||
theItem.setCharCount(None)
|
item.setCharCount(None)
|
||||||
assert theItem.charCount == 0
|
assert item.charCount == 0
|
||||||
theItem.setCharCount("1")
|
item.setCharCount("1")
|
||||||
assert theItem.charCount == 0
|
assert item.charCount == 0
|
||||||
theItem.setCharCount(1)
|
item.setCharCount(1)
|
||||||
assert theItem.charCount == 1
|
assert item.charCount == 1
|
||||||
|
|
||||||
# WordCount
|
# WordCount
|
||||||
theItem.setWordCount(None)
|
item.setWordCount(None)
|
||||||
assert theItem.wordCount == 0
|
assert item.wordCount == 0
|
||||||
theItem.setWordCount("1")
|
item.setWordCount("1")
|
||||||
assert theItem.wordCount == 0
|
assert item.wordCount == 0
|
||||||
theItem.setWordCount(1)
|
item.setWordCount(1)
|
||||||
assert theItem.wordCount == 1
|
assert item.wordCount == 1
|
||||||
|
|
||||||
# ParaCount
|
# ParaCount
|
||||||
theItem.setParaCount(None)
|
item.setParaCount(None)
|
||||||
assert theItem.paraCount == 0
|
assert item.paraCount == 0
|
||||||
theItem.setParaCount("1")
|
item.setParaCount("1")
|
||||||
assert theItem.paraCount == 0
|
assert item.paraCount == 0
|
||||||
theItem.setParaCount(1)
|
item.setParaCount(1)
|
||||||
assert theItem.paraCount == 1
|
assert item.paraCount == 1
|
||||||
|
|
||||||
# CursorPos
|
# CursorPos
|
||||||
theItem.setCursorPos(None)
|
item.setCursorPos(None)
|
||||||
assert theItem.cursorPos == 0
|
assert item.cursorPos == 0
|
||||||
theItem.setCursorPos("1")
|
item.setCursorPos("1")
|
||||||
assert theItem.cursorPos == 0
|
assert item.cursorPos == 0
|
||||||
theItem.setCursorPos(1)
|
item.setCursorPos(1)
|
||||||
assert theItem.cursorPos == 1
|
assert item.cursorPos == 1
|
||||||
|
|
||||||
# Initial Count
|
# Initial Count
|
||||||
theItem.setWordCount(234)
|
item.setWordCount(234)
|
||||||
theItem.saveInitialCount()
|
item.saveInitialCount()
|
||||||
assert theItem.initCount == 234
|
assert item.initCount == 234
|
||||||
|
|
||||||
# END Test testCoreItem_Setters
|
# END Test testCoreItem_Setters
|
||||||
|
|
||||||
@@ -186,91 +186,91 @@ def testCoreItem_Setters(mockGUI, mockRnd, fncPath):
|
|||||||
@pytest.mark.core
|
@pytest.mark.core
|
||||||
def testCoreItem_Methods(mockGUI, mockRnd, fncPath):
|
def testCoreItem_Methods(mockGUI, mockRnd, fncPath):
|
||||||
"""Test the simple methods of the NWItem class."""
|
"""Test the simple methods of the NWItem class."""
|
||||||
theProject = NWProject()
|
project = NWProject()
|
||||||
mockRnd.reset()
|
mockRnd.reset()
|
||||||
buildTestProject(theProject, fncPath)
|
buildTestProject(project, fncPath)
|
||||||
theItem = NWItem(theProject, "0000000000000")
|
item = NWItem(project, "0000000000000")
|
||||||
|
|
||||||
# Describe Me
|
# Describe Me
|
||||||
# ===========
|
# ===========
|
||||||
|
|
||||||
assert theItem.describeMe() == "None"
|
assert item.describeMe() == "None"
|
||||||
|
|
||||||
theItem.setType("ROOT")
|
item.setType("ROOT")
|
||||||
assert theItem.describeMe() == "Root Folder"
|
assert item.describeMe() == "Root Folder"
|
||||||
assert theItem.isRootType() is True
|
assert item.isRootType() is True
|
||||||
|
|
||||||
theItem.setType("FOLDER")
|
item.setType("FOLDER")
|
||||||
assert theItem.describeMe() == "Folder"
|
assert item.describeMe() == "Folder"
|
||||||
assert theItem.isFolderType() is True
|
assert item.isFolderType() is True
|
||||||
|
|
||||||
theItem.setType("FILE")
|
item.setType("FILE")
|
||||||
theItem.setLayout("DOCUMENT")
|
item.setLayout("DOCUMENT")
|
||||||
assert theItem.isFileType() is True
|
assert item.isFileType() is True
|
||||||
assert theItem.isDocumentLayout() is True
|
assert item.isDocumentLayout() is True
|
||||||
|
|
||||||
theItem.setMainHeading("HH")
|
item.setMainHeading("HH")
|
||||||
assert theItem.mainHeading == "H0"
|
assert item.mainHeading == "H0"
|
||||||
assert theItem.describeMe() == "Novel Document"
|
assert item.describeMe() == "Novel Document"
|
||||||
|
|
||||||
theItem.setMainHeading("H0")
|
item.setMainHeading("H0")
|
||||||
assert theItem.mainHeading == "H0"
|
assert item.mainHeading == "H0"
|
||||||
assert theItem.describeMe() == "Novel Document"
|
assert item.describeMe() == "Novel Document"
|
||||||
|
|
||||||
theItem.setMainHeading("H1")
|
item.setMainHeading("H1")
|
||||||
assert theItem.mainHeading == "H1"
|
assert item.mainHeading == "H1"
|
||||||
assert theItem.describeMe() == "Novel Title Page"
|
assert item.describeMe() == "Novel Title Page"
|
||||||
|
|
||||||
theItem.setMainHeading("H2")
|
item.setMainHeading("H2")
|
||||||
assert theItem.mainHeading == "H2"
|
assert item.mainHeading == "H2"
|
||||||
assert theItem.describeMe() == "Novel Chapter"
|
assert item.describeMe() == "Novel Chapter"
|
||||||
|
|
||||||
theItem.setMainHeading("H3")
|
item.setMainHeading("H3")
|
||||||
assert theItem.mainHeading == "H3"
|
assert item.mainHeading == "H3"
|
||||||
assert theItem.describeMe() == "Novel Scene"
|
assert item.describeMe() == "Novel Scene"
|
||||||
|
|
||||||
theItem.setMainHeading("H4")
|
item.setMainHeading("H4")
|
||||||
assert theItem.mainHeading == "H4"
|
assert item.mainHeading == "H4"
|
||||||
assert theItem.describeMe() == "Novel Section"
|
assert item.describeMe() == "Novel Section"
|
||||||
|
|
||||||
theItem.setMainHeading("H5")
|
item.setMainHeading("H5")
|
||||||
assert theItem.mainHeading == "H4"
|
assert item.mainHeading == "H4"
|
||||||
assert theItem.describeMe() == "Novel Section"
|
assert item.describeMe() == "Novel Section"
|
||||||
|
|
||||||
theItem.setLayout("NOTE")
|
item.setLayout("NOTE")
|
||||||
assert theItem.isNoteLayout() is True
|
assert item.isNoteLayout() is True
|
||||||
assert theItem.describeMe() == "Project Note"
|
assert item.describeMe() == "Project Note"
|
||||||
|
|
||||||
# Status + Icon
|
# Status + Icon
|
||||||
# =============
|
# =============
|
||||||
|
|
||||||
theItem.setType("FILE")
|
item.setType("FILE")
|
||||||
theItem.setStatus(C.sNote)
|
item.setStatus(C.sNote)
|
||||||
theItem.setImport(C.iMinor)
|
item.setImport(C.iMinor)
|
||||||
|
|
||||||
theItem.setClass("NOVEL")
|
item.setClass("NOVEL")
|
||||||
stT, stI = theItem.getImportStatus()
|
stT, stI = item.getImportStatus()
|
||||||
assert stT == "Note"
|
assert stT == "Note"
|
||||||
assert isinstance(stI, QIcon)
|
assert isinstance(stI, QIcon)
|
||||||
|
|
||||||
theItem.setClass("CHARACTER")
|
item.setClass("CHARACTER")
|
||||||
stT, stI = theItem.getImportStatus()
|
stT, stI = item.getImportStatus()
|
||||||
assert stT == "Minor"
|
assert stT == "Minor"
|
||||||
assert isinstance(stI, QIcon)
|
assert isinstance(stI, QIcon)
|
||||||
|
|
||||||
# Representation
|
# Representation
|
||||||
# ==============
|
# ==============
|
||||||
|
|
||||||
theItem.setName("New Item")
|
item.setName("New Item")
|
||||||
theItem.setParent("1111111111111")
|
item.setParent("1111111111111")
|
||||||
assert repr(theItem) == "<NWItem handle=0000000000000, parent=1111111111111, name='New Item'>"
|
assert repr(item) == "<NWItem handle=0000000000000, parent=1111111111111, name='New Item'>"
|
||||||
|
|
||||||
# Truthiness
|
# Truthiness
|
||||||
# ==========
|
# ==========
|
||||||
|
|
||||||
# Is True if the handle evaluates to True
|
# Is True if the handle evaluates to True
|
||||||
assert bool(NWItem(theProject, "0000000000000")) is True
|
assert bool(NWItem(project, "0000000000000")) is True
|
||||||
assert bool(NWItem(theProject, "")) is False
|
assert bool(NWItem(project, "")) is False
|
||||||
|
|
||||||
# Copy an Item
|
# Copy an Item
|
||||||
# ============
|
# ============
|
||||||
@@ -302,11 +302,11 @@ def testCoreItem_Methods(mockGUI, mockRnd, fncPath):
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Get the scene item
|
# Get the scene item
|
||||||
scItem = theProject.tree[C.hSceneDoc]
|
scItem = project.tree[C.hSceneDoc]
|
||||||
assert isinstance(scItem, NWItem)
|
assert isinstance(scItem, NWItem)
|
||||||
|
|
||||||
# Duplicate and update the expected content with a new handle
|
# Duplicate and update the expected content with a new handle
|
||||||
cpHandle = theProject.tree._makeHandle()
|
cpHandle = project.tree._makeHandle()
|
||||||
cpData = copy.deepcopy(scData)
|
cpData = copy.deepcopy(scData)
|
||||||
cpData["itemAttr"]["handle"] = cpHandle
|
cpData["itemAttr"]["handle"] = cpHandle
|
||||||
|
|
||||||
@@ -334,26 +334,26 @@ def testCoreItem_TypeSetter(mockGUI):
|
|||||||
"""Test the setter for all the nwItemType values for the NWItem
|
"""Test the setter for all the nwItemType values for the NWItem
|
||||||
class.
|
class.
|
||||||
"""
|
"""
|
||||||
theProject = NWProject()
|
project = NWProject()
|
||||||
theItem = NWItem(theProject, "0000000000000")
|
item = NWItem(project, "0000000000000")
|
||||||
|
|
||||||
# Type
|
# Type
|
||||||
theItem.setType(None)
|
item.setType(None)
|
||||||
assert theItem.itemType == nwItemType.NO_TYPE
|
assert item.itemType == nwItemType.NO_TYPE
|
||||||
theItem.setType("NONSENSE")
|
item.setType("NONSENSE")
|
||||||
assert theItem.itemType == nwItemType.NO_TYPE
|
assert item.itemType == nwItemType.NO_TYPE
|
||||||
theItem.setType("NO_TYPE")
|
item.setType("NO_TYPE")
|
||||||
assert theItem.itemType == nwItemType.NO_TYPE
|
assert item.itemType == nwItemType.NO_TYPE
|
||||||
theItem.setType("ROOT")
|
item.setType("ROOT")
|
||||||
assert theItem.itemType == nwItemType.ROOT
|
assert item.itemType == nwItemType.ROOT
|
||||||
theItem.setType("FOLDER")
|
item.setType("FOLDER")
|
||||||
assert theItem.itemType == nwItemType.FOLDER
|
assert item.itemType == nwItemType.FOLDER
|
||||||
theItem.setType("FILE")
|
item.setType("FILE")
|
||||||
assert theItem.itemType == nwItemType.FILE
|
assert item.itemType == nwItemType.FILE
|
||||||
|
|
||||||
# Alternative
|
# Alternative
|
||||||
theItem.setType(nwItemType.ROOT)
|
item.setType(nwItemType.ROOT)
|
||||||
assert theItem.itemType == nwItemType.ROOT
|
assert item.itemType == nwItemType.ROOT
|
||||||
|
|
||||||
# END Test testCoreItem_TypeSetter
|
# END Test testCoreItem_TypeSetter
|
||||||
|
|
||||||
@@ -363,84 +363,84 @@ def testCoreItem_ClassSetter(mockGUI):
|
|||||||
"""Test the setter for all the nwItemClass values for the NWItem
|
"""Test the setter for all the nwItemClass values for the NWItem
|
||||||
class.
|
class.
|
||||||
"""
|
"""
|
||||||
theProject = NWProject()
|
project = NWProject()
|
||||||
theItem = NWItem(theProject, "0000000000000")
|
item = NWItem(project, "0000000000000")
|
||||||
|
|
||||||
# Class
|
# Class
|
||||||
theItem.setClass(None)
|
item.setClass(None)
|
||||||
assert theItem.itemClass == nwItemClass.NO_CLASS
|
assert item.itemClass == nwItemClass.NO_CLASS
|
||||||
theItem.setClass("NONSENSE")
|
item.setClass("NONSENSE")
|
||||||
assert theItem.itemClass == nwItemClass.NO_CLASS
|
assert item.itemClass == nwItemClass.NO_CLASS
|
||||||
|
|
||||||
theItem.setClass("NO_CLASS")
|
item.setClass("NO_CLASS")
|
||||||
assert theItem.itemClass == nwItemClass.NO_CLASS
|
assert item.itemClass == nwItemClass.NO_CLASS
|
||||||
assert theItem.isNovelLike() is False
|
assert item.isNovelLike() is False
|
||||||
assert theItem.documentAllowed() is False
|
assert item.documentAllowed() is False
|
||||||
assert theItem.isInactiveClass() is True
|
assert item.isInactiveClass() is True
|
||||||
|
|
||||||
theItem.setClass("NOVEL")
|
item.setClass("NOVEL")
|
||||||
assert theItem.itemClass == nwItemClass.NOVEL
|
assert item.itemClass == nwItemClass.NOVEL
|
||||||
assert theItem.isNovelLike() is True
|
assert item.isNovelLike() is True
|
||||||
assert theItem.documentAllowed() is True
|
assert item.documentAllowed() is True
|
||||||
assert theItem.isInactiveClass() is False
|
assert item.isInactiveClass() is False
|
||||||
|
|
||||||
theItem.setClass("PLOT")
|
item.setClass("PLOT")
|
||||||
assert theItem.itemClass == nwItemClass.PLOT
|
assert item.itemClass == nwItemClass.PLOT
|
||||||
assert theItem.isNovelLike() is False
|
assert item.isNovelLike() is False
|
||||||
assert theItem.documentAllowed() is False
|
assert item.documentAllowed() is False
|
||||||
assert theItem.isInactiveClass() is False
|
assert item.isInactiveClass() is False
|
||||||
|
|
||||||
theItem.setClass("CHARACTER")
|
item.setClass("CHARACTER")
|
||||||
assert theItem.itemClass == nwItemClass.CHARACTER
|
assert item.itemClass == nwItemClass.CHARACTER
|
||||||
assert theItem.isNovelLike() is False
|
assert item.isNovelLike() is False
|
||||||
assert theItem.documentAllowed() is False
|
assert item.documentAllowed() is False
|
||||||
assert theItem.isInactiveClass() is False
|
assert item.isInactiveClass() is False
|
||||||
|
|
||||||
theItem.setClass("WORLD")
|
item.setClass("WORLD")
|
||||||
assert theItem.itemClass == nwItemClass.WORLD
|
assert item.itemClass == nwItemClass.WORLD
|
||||||
assert theItem.isNovelLike() is False
|
assert item.isNovelLike() is False
|
||||||
assert theItem.documentAllowed() is False
|
assert item.documentAllowed() is False
|
||||||
assert theItem.isInactiveClass() is False
|
assert item.isInactiveClass() is False
|
||||||
|
|
||||||
theItem.setClass("TIMELINE")
|
item.setClass("TIMELINE")
|
||||||
assert theItem.itemClass == nwItemClass.TIMELINE
|
assert item.itemClass == nwItemClass.TIMELINE
|
||||||
assert theItem.isNovelLike() is False
|
assert item.isNovelLike() is False
|
||||||
assert theItem.documentAllowed() is False
|
assert item.documentAllowed() is False
|
||||||
assert theItem.isInactiveClass() is False
|
assert item.isInactiveClass() is False
|
||||||
|
|
||||||
theItem.setClass("OBJECT")
|
item.setClass("OBJECT")
|
||||||
assert theItem.itemClass == nwItemClass.OBJECT
|
assert item.itemClass == nwItemClass.OBJECT
|
||||||
assert theItem.isNovelLike() is False
|
assert item.isNovelLike() is False
|
||||||
assert theItem.documentAllowed() is False
|
assert item.documentAllowed() is False
|
||||||
assert theItem.isInactiveClass() is False
|
assert item.isInactiveClass() is False
|
||||||
|
|
||||||
theItem.setClass("ENTITY")
|
item.setClass("ENTITY")
|
||||||
assert theItem.itemClass == nwItemClass.ENTITY
|
assert item.itemClass == nwItemClass.ENTITY
|
||||||
assert theItem.isNovelLike() is False
|
assert item.isNovelLike() is False
|
||||||
assert theItem.documentAllowed() is False
|
assert item.documentAllowed() is False
|
||||||
assert theItem.isInactiveClass() is False
|
assert item.isInactiveClass() is False
|
||||||
|
|
||||||
theItem.setClass("CUSTOM")
|
item.setClass("CUSTOM")
|
||||||
assert theItem.itemClass == nwItemClass.CUSTOM
|
assert item.itemClass == nwItemClass.CUSTOM
|
||||||
assert theItem.isNovelLike() is False
|
assert item.isNovelLike() is False
|
||||||
assert theItem.documentAllowed() is False
|
assert item.documentAllowed() is False
|
||||||
assert theItem.isInactiveClass() is False
|
assert item.isInactiveClass() is False
|
||||||
|
|
||||||
theItem.setClass("ARCHIVE")
|
item.setClass("ARCHIVE")
|
||||||
assert theItem.itemClass == nwItemClass.ARCHIVE
|
assert item.itemClass == nwItemClass.ARCHIVE
|
||||||
assert theItem.isNovelLike() is True
|
assert item.isNovelLike() is True
|
||||||
assert theItem.documentAllowed() is True
|
assert item.documentAllowed() is True
|
||||||
assert theItem.isInactiveClass() is True
|
assert item.isInactiveClass() is True
|
||||||
|
|
||||||
theItem.setClass("TRASH")
|
item.setClass("TRASH")
|
||||||
assert theItem.itemClass == nwItemClass.TRASH
|
assert item.itemClass == nwItemClass.TRASH
|
||||||
assert theItem.isNovelLike() is False
|
assert item.isNovelLike() is False
|
||||||
assert theItem.documentAllowed() is True
|
assert item.documentAllowed() is True
|
||||||
assert theItem.isInactiveClass() is True
|
assert item.isInactiveClass() is True
|
||||||
|
|
||||||
# Alternative
|
# Alternative
|
||||||
theItem.setClass(nwItemClass.NOVEL)
|
item.setClass(nwItemClass.NOVEL)
|
||||||
assert theItem.itemClass == nwItemClass.NOVEL
|
assert item.itemClass == nwItemClass.NOVEL
|
||||||
|
|
||||||
# END Test testCoreItem_ClassSetter
|
# END Test testCoreItem_ClassSetter
|
||||||
|
|
||||||
@@ -450,26 +450,26 @@ def testCoreItem_LayoutSetter(mockGUI):
|
|||||||
"""Test the setter for all the nwItemLayout values for the NWItem
|
"""Test the setter for all the nwItemLayout values for the NWItem
|
||||||
class.
|
class.
|
||||||
"""
|
"""
|
||||||
theProject = NWProject()
|
project = NWProject()
|
||||||
theItem = NWItem(theProject, "0000000000000")
|
item = NWItem(project, "0000000000000")
|
||||||
|
|
||||||
# Faulty Layouts
|
# Faulty Layouts
|
||||||
theItem.setLayout(None)
|
item.setLayout(None)
|
||||||
assert theItem.itemLayout == nwItemLayout.NO_LAYOUT
|
assert item.itemLayout == nwItemLayout.NO_LAYOUT
|
||||||
theItem.setLayout("NONSENSE")
|
item.setLayout("NONSENSE")
|
||||||
assert theItem.itemLayout == nwItemLayout.NO_LAYOUT
|
assert item.itemLayout == nwItemLayout.NO_LAYOUT
|
||||||
|
|
||||||
# Current Layouts
|
# Current Layouts
|
||||||
theItem.setLayout("NO_LAYOUT")
|
item.setLayout("NO_LAYOUT")
|
||||||
assert theItem.itemLayout == nwItemLayout.NO_LAYOUT
|
assert item.itemLayout == nwItemLayout.NO_LAYOUT
|
||||||
theItem.setLayout("DOCUMENT")
|
item.setLayout("DOCUMENT")
|
||||||
assert theItem.itemLayout == nwItemLayout.DOCUMENT
|
assert item.itemLayout == nwItemLayout.DOCUMENT
|
||||||
theItem.setLayout("NOTE")
|
item.setLayout("NOTE")
|
||||||
assert theItem.itemLayout == nwItemLayout.NOTE
|
assert item.itemLayout == nwItemLayout.NOTE
|
||||||
|
|
||||||
# Alternative
|
# Alternative
|
||||||
theItem.setLayout(nwItemLayout.NOTE)
|
item.setLayout(nwItemLayout.NOTE)
|
||||||
assert theItem.itemLayout == nwItemLayout.NOTE
|
assert item.itemLayout == nwItemLayout.NOTE
|
||||||
|
|
||||||
# END Test testCoreItem_LayoutSetter
|
# END Test testCoreItem_LayoutSetter
|
||||||
|
|
||||||
@@ -478,54 +478,54 @@ def testCoreItem_LayoutSetter(mockGUI):
|
|||||||
def testCoreItem_ClassDefaults(mockGUI):
|
def testCoreItem_ClassDefaults(mockGUI):
|
||||||
"""Test the setter for the default values.
|
"""Test the setter for the default values.
|
||||||
"""
|
"""
|
||||||
theProject = NWProject()
|
project = NWProject()
|
||||||
theItem = NWItem(theProject, "0000000000000")
|
item = NWItem(project, "0000000000000")
|
||||||
|
|
||||||
# Root items should not have their class updated
|
# Root items should not have their class updated
|
||||||
theItem.setParent(None)
|
item.setParent(None)
|
||||||
theItem.setClass(nwItemClass.NO_CLASS)
|
item.setClass(nwItemClass.NO_CLASS)
|
||||||
assert theItem.itemClass == nwItemClass.NO_CLASS
|
assert item.itemClass == nwItemClass.NO_CLASS
|
||||||
|
|
||||||
theItem.setClassDefaults(nwItemClass.NOVEL)
|
item.setClassDefaults(nwItemClass.NOVEL)
|
||||||
assert theItem.itemClass == nwItemClass.NO_CLASS
|
assert item.itemClass == nwItemClass.NO_CLASS
|
||||||
|
|
||||||
# Non-root items should have their class updated
|
# Non-root items should have their class updated
|
||||||
theItem.setParent("0123456789abc")
|
item.setParent("0123456789abc")
|
||||||
theItem.setClass(nwItemClass.NO_CLASS)
|
item.setClass(nwItemClass.NO_CLASS)
|
||||||
assert theItem.itemClass == nwItemClass.NO_CLASS
|
assert item.itemClass == nwItemClass.NO_CLASS
|
||||||
|
|
||||||
theItem.setClassDefaults(nwItemClass.NOVEL)
|
item.setClassDefaults(nwItemClass.NOVEL)
|
||||||
assert theItem.itemClass == nwItemClass.NOVEL
|
assert item.itemClass == nwItemClass.NOVEL
|
||||||
|
|
||||||
# Non-layout items should have their layout set based on class
|
# Non-layout items should have their layout set based on class
|
||||||
theItem.setParent("0123456789abc")
|
item.setParent("0123456789abc")
|
||||||
theItem.setClass(nwItemClass.NO_CLASS)
|
item.setClass(nwItemClass.NO_CLASS)
|
||||||
theItem.setLayout(nwItemLayout.NO_LAYOUT)
|
item.setLayout(nwItemLayout.NO_LAYOUT)
|
||||||
assert theItem.itemLayout == nwItemLayout.NO_LAYOUT
|
assert item.itemLayout == nwItemLayout.NO_LAYOUT
|
||||||
|
|
||||||
theItem.setClassDefaults(nwItemClass.NOVEL)
|
item.setClassDefaults(nwItemClass.NOVEL)
|
||||||
assert theItem.itemLayout == nwItemLayout.DOCUMENT
|
assert item.itemLayout == nwItemLayout.DOCUMENT
|
||||||
|
|
||||||
theItem.setParent("0123456789abc")
|
item.setParent("0123456789abc")
|
||||||
theItem.setClass(nwItemClass.NO_CLASS)
|
item.setClass(nwItemClass.NO_CLASS)
|
||||||
theItem.setLayout(nwItemLayout.NO_LAYOUT)
|
item.setLayout(nwItemLayout.NO_LAYOUT)
|
||||||
assert theItem.itemLayout == nwItemLayout.NO_LAYOUT
|
assert item.itemLayout == nwItemLayout.NO_LAYOUT
|
||||||
|
|
||||||
theItem.setClassDefaults(nwItemClass.PLOT)
|
item.setClassDefaults(nwItemClass.PLOT)
|
||||||
assert theItem.itemLayout == nwItemLayout.NOTE
|
assert item.itemLayout == nwItemLayout.NOTE
|
||||||
|
|
||||||
# If documents are not allowed in that class, the layout should be changed
|
# If documents are not allowed in that class, the layout should be changed
|
||||||
theItem.setParent("0123456789abc")
|
item.setParent("0123456789abc")
|
||||||
theItem.setClass(nwItemClass.NO_CLASS)
|
item.setClass(nwItemClass.NO_CLASS)
|
||||||
theItem.setLayout(nwItemLayout.DOCUMENT)
|
item.setLayout(nwItemLayout.DOCUMENT)
|
||||||
assert theItem.itemLayout == nwItemLayout.DOCUMENT
|
assert item.itemLayout == nwItemLayout.DOCUMENT
|
||||||
|
|
||||||
theItem.setClassDefaults(nwItemClass.PLOT)
|
item.setClassDefaults(nwItemClass.PLOT)
|
||||||
assert theItem.itemLayout == nwItemLayout.NOTE
|
assert item.itemLayout == nwItemLayout.NOTE
|
||||||
|
|
||||||
# In all cases, status and importance should no longer be None
|
# In all cases, status and importance should no longer be None
|
||||||
assert theItem.itemStatus is not None
|
assert item.itemStatus is not None
|
||||||
assert theItem.itemImport is not None
|
assert item.itemImport is not None
|
||||||
|
|
||||||
# END Test testCoreItem_ClassDefaults
|
# END Test testCoreItem_ClassDefaults
|
||||||
|
|
||||||
@@ -533,17 +533,17 @@ def testCoreItem_ClassDefaults(mockGUI):
|
|||||||
@pytest.mark.core
|
@pytest.mark.core
|
||||||
def testCoreItem_PackUnpack(mockGUI, caplog, mockRnd):
|
def testCoreItem_PackUnpack(mockGUI, caplog, mockRnd):
|
||||||
"""Test packing and unpacking entries for the NWItem class."""
|
"""Test packing and unpacking entries for the NWItem class."""
|
||||||
theProject = NWProject()
|
project = NWProject()
|
||||||
theProject.data.itemStatus.write(None, "New", (100, 100, 100))
|
project.data.itemStatus.write(None, "New", (100, 100, 100))
|
||||||
theProject.data.itemImport.write(None, "New", (100, 100, 100))
|
project.data.itemImport.write(None, "New", (100, 100, 100))
|
||||||
|
|
||||||
# Invalid
|
# Invalid
|
||||||
theItem = NWItem(theProject, "0000000000000")
|
item = NWItem(project, "0000000000000")
|
||||||
assert theItem.unpack({}) is False
|
assert item.unpack({}) is False
|
||||||
|
|
||||||
# File
|
# File
|
||||||
theItem = NWItem(theProject, "")
|
item = NWItem(project, "")
|
||||||
assert theItem.unpack({
|
assert item.unpack({
|
||||||
"name": "A File",
|
"name": "A File",
|
||||||
"itemAttr": {
|
"itemAttr": {
|
||||||
"handle": "0000000000003",
|
"handle": "0000000000003",
|
||||||
@@ -569,25 +569,25 @@ def testCoreItem_PackUnpack(mockGUI, caplog, mockRnd):
|
|||||||
},
|
},
|
||||||
}) is True
|
}) is True
|
||||||
|
|
||||||
assert theItem.itemName == "A File"
|
assert item.itemName == "A File"
|
||||||
assert theItem.itemHandle == "0000000000003"
|
assert item.itemHandle == "0000000000003"
|
||||||
assert theItem.itemParent == "0000000000002"
|
assert item.itemParent == "0000000000002"
|
||||||
assert theItem.itemRoot == "0000000000001"
|
assert item.itemRoot == "0000000000001"
|
||||||
assert theItem.itemOrder == 1
|
assert item.itemOrder == 1
|
||||||
assert theItem.itemType == nwItemType.FILE
|
assert item.itemType == nwItemType.FILE
|
||||||
assert theItem.itemClass == nwItemClass.NOVEL
|
assert item.itemClass == nwItemClass.NOVEL
|
||||||
assert theItem.itemLayout == nwItemLayout.DOCUMENT
|
assert item.itemLayout == nwItemLayout.DOCUMENT
|
||||||
assert theItem.itemStatus == "s000000"
|
assert item.itemStatus == "s000000"
|
||||||
assert theItem.itemImport == "i000001"
|
assert item.itemImport == "i000001"
|
||||||
assert theItem.isActive is False
|
assert item.isActive is False
|
||||||
assert theItem.isExpanded is True
|
assert item.isExpanded is True
|
||||||
assert theItem.mainHeading == "H1"
|
assert item.mainHeading == "H1"
|
||||||
assert theItem.charCount == 100
|
assert item.charCount == 100
|
||||||
assert theItem.wordCount == 20
|
assert item.wordCount == 20
|
||||||
assert theItem.paraCount == 2
|
assert item.paraCount == 2
|
||||||
assert theItem.cursorPos == 50
|
assert item.cursorPos == 50
|
||||||
|
|
||||||
assert theItem.pack() == {
|
assert item.pack() == {
|
||||||
"name": "A File",
|
"name": "A File",
|
||||||
"itemAttr": {
|
"itemAttr": {
|
||||||
"handle": "0000000000003",
|
"handle": "0000000000003",
|
||||||
@@ -614,8 +614,8 @@ def testCoreItem_PackUnpack(mockGUI, caplog, mockRnd):
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Folder
|
# Folder
|
||||||
theItem = NWItem(theProject, "")
|
item = NWItem(project, "")
|
||||||
assert theItem.unpack({
|
assert item.unpack({
|
||||||
"name": "A Folder",
|
"name": "A Folder",
|
||||||
"itemAttr": {
|
"itemAttr": {
|
||||||
"handle": "0000000000003",
|
"handle": "0000000000003",
|
||||||
@@ -641,25 +641,25 @@ def testCoreItem_PackUnpack(mockGUI, caplog, mockRnd):
|
|||||||
}
|
}
|
||||||
}) is True
|
}) is True
|
||||||
|
|
||||||
assert theItem.itemName == "A Folder"
|
assert item.itemName == "A Folder"
|
||||||
assert theItem.itemHandle == "0000000000003"
|
assert item.itemHandle == "0000000000003"
|
||||||
assert theItem.itemParent == "0000000000002"
|
assert item.itemParent == "0000000000002"
|
||||||
assert theItem.itemRoot == "0000000000001"
|
assert item.itemRoot == "0000000000001"
|
||||||
assert theItem.itemOrder == 1
|
assert item.itemOrder == 1
|
||||||
assert theItem.itemType == nwItemType.FOLDER
|
assert item.itemType == nwItemType.FOLDER
|
||||||
assert theItem.itemClass == nwItemClass.NOVEL
|
assert item.itemClass == nwItemClass.NOVEL
|
||||||
assert theItem.itemLayout == nwItemLayout.NO_LAYOUT
|
assert item.itemLayout == nwItemLayout.NO_LAYOUT
|
||||||
assert theItem.itemStatus == "s000000"
|
assert item.itemStatus == "s000000"
|
||||||
assert theItem.itemImport == "i000001"
|
assert item.itemImport == "i000001"
|
||||||
assert theItem.isActive is False
|
assert item.isActive is False
|
||||||
assert theItem.isExpanded is True
|
assert item.isExpanded is True
|
||||||
assert theItem.mainHeading == "H0"
|
assert item.mainHeading == "H0"
|
||||||
assert theItem.charCount == 0
|
assert item.charCount == 0
|
||||||
assert theItem.wordCount == 0
|
assert item.wordCount == 0
|
||||||
assert theItem.paraCount == 0
|
assert item.paraCount == 0
|
||||||
assert theItem.cursorPos == 0
|
assert item.cursorPos == 0
|
||||||
|
|
||||||
assert theItem.pack() == {
|
assert item.pack() == {
|
||||||
"name": "A Folder",
|
"name": "A Folder",
|
||||||
"itemAttr": {
|
"itemAttr": {
|
||||||
"handle": "0000000000003",
|
"handle": "0000000000003",
|
||||||
@@ -679,8 +679,8 @@ def testCoreItem_PackUnpack(mockGUI, caplog, mockRnd):
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Root
|
# Root
|
||||||
theItem = NWItem(theProject, "")
|
item = NWItem(project, "")
|
||||||
assert theItem.unpack({
|
assert item.unpack({
|
||||||
"name": "A Novel",
|
"name": "A Novel",
|
||||||
"itemAttr": {
|
"itemAttr": {
|
||||||
"handle": "0000000000003",
|
"handle": "0000000000003",
|
||||||
@@ -706,25 +706,25 @@ def testCoreItem_PackUnpack(mockGUI, caplog, mockRnd):
|
|||||||
},
|
},
|
||||||
}) is True
|
}) is True
|
||||||
|
|
||||||
assert theItem.itemName == "A Novel"
|
assert item.itemName == "A Novel"
|
||||||
assert theItem.itemHandle == "0000000000003"
|
assert item.itemHandle == "0000000000003"
|
||||||
assert theItem.itemParent is None
|
assert item.itemParent is None
|
||||||
assert theItem.itemRoot == "0000000000003"
|
assert item.itemRoot == "0000000000003"
|
||||||
assert theItem.itemOrder == 1
|
assert item.itemOrder == 1
|
||||||
assert theItem.itemType == nwItemType.ROOT
|
assert item.itemType == nwItemType.ROOT
|
||||||
assert theItem.itemClass == nwItemClass.NOVEL
|
assert item.itemClass == nwItemClass.NOVEL
|
||||||
assert theItem.itemLayout == nwItemLayout.NO_LAYOUT
|
assert item.itemLayout == nwItemLayout.NO_LAYOUT
|
||||||
assert theItem.itemStatus == "s000000"
|
assert item.itemStatus == "s000000"
|
||||||
assert theItem.itemImport == "i000001"
|
assert item.itemImport == "i000001"
|
||||||
assert theItem.isActive is False
|
assert item.isActive is False
|
||||||
assert theItem.isExpanded is True
|
assert item.isExpanded is True
|
||||||
assert theItem.mainHeading == "H0"
|
assert item.mainHeading == "H0"
|
||||||
assert theItem.charCount == 0
|
assert item.charCount == 0
|
||||||
assert theItem.wordCount == 0
|
assert item.wordCount == 0
|
||||||
assert theItem.paraCount == 0
|
assert item.paraCount == 0
|
||||||
assert theItem.cursorPos == 0
|
assert item.cursorPos == 0
|
||||||
|
|
||||||
assert theItem.pack() == {
|
assert item.pack() == {
|
||||||
"name": "A Novel",
|
"name": "A Novel",
|
||||||
"itemAttr": {
|
"itemAttr": {
|
||||||
"handle": "0000000000003",
|
"handle": "0000000000003",
|
||||||
|
|||||||
@@ -622,15 +622,15 @@ def testCoreProject_Backup(monkeypatch, mockGUI, fncPath, tstPaths):
|
|||||||
# Test correct settings
|
# Test correct settings
|
||||||
assert project.backupProject(doNotify=True) is True
|
assert project.backupProject(doNotify=True) is True
|
||||||
|
|
||||||
theFiles = sorted((tstPaths.tmpDir / "Test Minimal").iterdir())
|
files = sorted((tstPaths.tmpDir / "Test Minimal").iterdir())
|
||||||
assert len(theFiles) in (1, 2) # Sometimes 2 due to clock tick
|
assert len(files) in (1, 2) # Sometimes 2 due to clock tick
|
||||||
|
|
||||||
theZip = theFiles[0]
|
zipFile = files[0]
|
||||||
assert theZip.name.startswith("Test Minimal")
|
assert zipFile.name.startswith("Test Minimal")
|
||||||
assert theZip.suffix == ".zip"
|
assert zipFile.suffix == ".zip"
|
||||||
|
|
||||||
# Extract the archive
|
# Extract the archive
|
||||||
with ZipFile(tstPaths.tmpDir / "Test Minimal" / theZip.name, mode="r") as inZip:
|
with ZipFile(tstPaths.tmpDir / "Test Minimal" / zipFile.name, mode="r") as inZip:
|
||||||
inZip.extractall(tstPaths.tmpDir / "extract")
|
inZip.extractall(tstPaths.tmpDir / "extract")
|
||||||
|
|
||||||
# Check that the main project file was restored
|
# Check that the main project file was restored
|
||||||
|
|||||||
+136
-136
@@ -36,8 +36,8 @@ importKeys = [C.iNew, C.iMinor, C.iMajor, C.iMain]
|
|||||||
def testCoreStatus_Internal(mockRnd):
|
def testCoreStatus_Internal(mockRnd):
|
||||||
"""Test all the internal functions of the NWStatus class.
|
"""Test all the internal functions of the NWStatus class.
|
||||||
"""
|
"""
|
||||||
theStatus = NWStatus(NWStatus.STATUS)
|
nStatus = NWStatus(NWStatus.STATUS)
|
||||||
theImport = NWStatus(NWStatus.IMPORT)
|
nImport = NWStatus(NWStatus.IMPORT)
|
||||||
|
|
||||||
with pytest.raises(Exception):
|
with pytest.raises(Exception):
|
||||||
NWStatus(999)
|
NWStatus(999)
|
||||||
@@ -45,42 +45,42 @@ def testCoreStatus_Internal(mockRnd):
|
|||||||
# Generate Key
|
# Generate Key
|
||||||
# ============
|
# ============
|
||||||
|
|
||||||
assert theStatus._newKey() == statusKeys[0]
|
assert nStatus._newKey() == statusKeys[0]
|
||||||
assert theStatus._newKey() == statusKeys[1]
|
assert nStatus._newKey() == statusKeys[1]
|
||||||
|
|
||||||
# Key collision, should move to key 3
|
# Key collision, should move to key 3
|
||||||
theStatus.write(statusKeys[2], "Crash", (0, 0, 0))
|
nStatus.write(statusKeys[2], "Crash", (0, 0, 0))
|
||||||
assert theStatus._newKey() == statusKeys[3]
|
assert nStatus._newKey() == statusKeys[3]
|
||||||
|
|
||||||
assert theImport._newKey() == importKeys[0]
|
assert nImport._newKey() == importKeys[0]
|
||||||
assert theImport._newKey() == importKeys[1]
|
assert nImport._newKey() == importKeys[1]
|
||||||
|
|
||||||
# Key collision, should move to key 3
|
# Key collision, should move to key 3
|
||||||
theImport.write(importKeys[2], "Crash", (0, 0, 0))
|
nImport.write(importKeys[2], "Crash", (0, 0, 0))
|
||||||
assert theImport._newKey() == importKeys[3]
|
assert nImport._newKey() == importKeys[3]
|
||||||
|
|
||||||
# Check Key
|
# Check Key
|
||||||
# =========
|
# =========
|
||||||
|
|
||||||
assert theStatus._isKey(None) is False # Not a string
|
assert nStatus._isKey(None) is False # Not a string
|
||||||
assert theStatus._isKey("s00000") is False # Too short
|
assert nStatus._isKey("s00000") is False # Too short
|
||||||
assert theStatus._isKey("s000000") is True # Correct length
|
assert nStatus._isKey("s000000") is True # Correct length
|
||||||
assert theStatus._isKey("s0000000") is False # Too long
|
assert nStatus._isKey("s0000000") is False # Too long
|
||||||
assert theStatus._isKey("i000000") is False # Wrong type
|
assert nStatus._isKey("i000000") is False # Wrong type
|
||||||
assert theStatus._isKey("q000000") is False # Wrong type
|
assert nStatus._isKey("q000000") is False # Wrong type
|
||||||
assert theStatus._isKey("s12345H") is False # Not a hex value
|
assert nStatus._isKey("s12345H") is False # Not a hex value
|
||||||
assert theStatus._isKey("s12345F") is False # Not a lower case hex value
|
assert nStatus._isKey("s12345F") is False # Not a lower case hex value
|
||||||
assert theStatus._isKey("s12345f") is True # Valid hex value
|
assert nStatus._isKey("s12345f") is True # Valid hex value
|
||||||
|
|
||||||
assert theImport._isKey(None) is False # Not a string
|
assert nImport._isKey(None) is False # Not a string
|
||||||
assert theImport._isKey("i00000") is False # Too short
|
assert nImport._isKey("i00000") is False # Too short
|
||||||
assert theImport._isKey("i000000") is True # Correct length
|
assert nImport._isKey("i000000") is True # Correct length
|
||||||
assert theImport._isKey("i0000000") is False # Too long
|
assert nImport._isKey("i0000000") is False # Too long
|
||||||
assert theImport._isKey("s000000") is False # Wrong type
|
assert nImport._isKey("s000000") is False # Wrong type
|
||||||
assert theImport._isKey("q000000") is False # Wrong type
|
assert nImport._isKey("q000000") is False # Wrong type
|
||||||
assert theImport._isKey("i12345H") is False # Not a hex value
|
assert nImport._isKey("i12345H") is False # Not a hex value
|
||||||
assert theImport._isKey("i12345F") is False # Not a lower case hex value
|
assert nImport._isKey("i12345F") is False # Not a lower case hex value
|
||||||
assert theImport._isKey("i12345f") is True # Valid hex value
|
assert nImport._isKey("i12345f") is True # Valid hex value
|
||||||
|
|
||||||
# END Test testCoreStatus_Internal
|
# END Test testCoreStatus_Internal
|
||||||
|
|
||||||
@@ -89,30 +89,30 @@ def testCoreStatus_Internal(mockRnd):
|
|||||||
def testCoreStatus_Iterator(mockRnd):
|
def testCoreStatus_Iterator(mockRnd):
|
||||||
"""Test the iterator functions of the NWStatus class.
|
"""Test the iterator functions of the NWStatus class.
|
||||||
"""
|
"""
|
||||||
theStatus = NWStatus(NWStatus.STATUS)
|
nStatus = NWStatus(NWStatus.STATUS)
|
||||||
|
|
||||||
theStatus.write(None, "New", (100, 100, 100))
|
nStatus.write(None, "New", (100, 100, 100))
|
||||||
theStatus.write(None, "Note", (200, 50, 0))
|
nStatus.write(None, "Note", (200, 50, 0))
|
||||||
theStatus.write(None, "Draft", (200, 150, 0))
|
nStatus.write(None, "Draft", (200, 150, 0))
|
||||||
theStatus.write(None, "Finished", (50, 200, 0))
|
nStatus.write(None, "Finished", (50, 200, 0))
|
||||||
|
|
||||||
# Direct access
|
# Direct access
|
||||||
entry = theStatus[statusKeys[0]]
|
entry = nStatus[statusKeys[0]]
|
||||||
assert entry["cols"] == (100, 100, 100)
|
assert entry["cols"] == (100, 100, 100)
|
||||||
assert entry["name"] == "New"
|
assert entry["name"] == "New"
|
||||||
assert entry["count"] == 0
|
assert entry["count"] == 0
|
||||||
assert isinstance(entry["icon"], QIcon)
|
assert isinstance(entry["icon"], QIcon)
|
||||||
|
|
||||||
# Iterate
|
# Iterate
|
||||||
entries = list(theStatus)
|
entries = list(nStatus)
|
||||||
assert len(entries) == 4
|
assert len(entries) == 4
|
||||||
assert len(theStatus) == 4
|
assert len(nStatus) == 4
|
||||||
|
|
||||||
# Keys
|
# Keys
|
||||||
assert list(theStatus.keys()) == statusKeys
|
assert list(nStatus.keys()) == statusKeys
|
||||||
|
|
||||||
# Items
|
# Items
|
||||||
for index, (key, entry) in enumerate(theStatus.items()):
|
for index, (key, entry) in enumerate(nStatus.items()):
|
||||||
assert key == statusKeys[index]
|
assert key == statusKeys[index]
|
||||||
assert "cols" in entry
|
assert "cols" in entry
|
||||||
assert "name" in entry
|
assert "name" in entry
|
||||||
@@ -120,7 +120,7 @@ def testCoreStatus_Iterator(mockRnd):
|
|||||||
assert "icon" in entry
|
assert "icon" in entry
|
||||||
|
|
||||||
# Valuse
|
# Valuse
|
||||||
for entry in theStatus.values():
|
for entry in nStatus.values():
|
||||||
assert "cols" in entry
|
assert "cols" in entry
|
||||||
assert "name" in entry
|
assert "name" in entry
|
||||||
assert "count" in entry
|
assert "count" in entry
|
||||||
@@ -133,67 +133,67 @@ def testCoreStatus_Iterator(mockRnd):
|
|||||||
def testCoreStatus_Entries(mockRnd):
|
def testCoreStatus_Entries(mockRnd):
|
||||||
"""Test all the simple setters for the NWStatus class.
|
"""Test all the simple setters for the NWStatus class.
|
||||||
"""
|
"""
|
||||||
theStatus = NWStatus(NWStatus.STATUS)
|
nStatus = NWStatus(NWStatus.STATUS)
|
||||||
|
|
||||||
# Write
|
# Write
|
||||||
# =====
|
# =====
|
||||||
|
|
||||||
# Have a key
|
# Have a key
|
||||||
theStatus.write(statusKeys[0], "Entry 1", (200, 100, 50))
|
nStatus.write(statusKeys[0], "Entry 1", (200, 100, 50))
|
||||||
assert theStatus[statusKeys[0]]["name"] == "Entry 1"
|
assert nStatus[statusKeys[0]]["name"] == "Entry 1"
|
||||||
assert theStatus[statusKeys[0]]["cols"] == (200, 100, 50)
|
assert nStatus[statusKeys[0]]["cols"] == (200, 100, 50)
|
||||||
|
|
||||||
# Don't have a key
|
# Don't have a key
|
||||||
theStatus.write(None, "Entry 2", (210, 110, 60))
|
nStatus.write(None, "Entry 2", (210, 110, 60))
|
||||||
assert theStatus[statusKeys[1]]["name"] == "Entry 2"
|
assert nStatus[statusKeys[1]]["name"] == "Entry 2"
|
||||||
assert theStatus[statusKeys[1]]["cols"] == (210, 110, 60)
|
assert nStatus[statusKeys[1]]["cols"] == (210, 110, 60)
|
||||||
|
|
||||||
# Wrong colour spec
|
# Wrong colour spec
|
||||||
theStatus.write(None, "Entry 3", "what?")
|
nStatus.write(None, "Entry 3", "what?")
|
||||||
assert theStatus[statusKeys[2]]["name"] == "Entry 3"
|
assert nStatus[statusKeys[2]]["name"] == "Entry 3"
|
||||||
assert theStatus[statusKeys[2]]["cols"] == (100, 100, 100)
|
assert nStatus[statusKeys[2]]["cols"] == (100, 100, 100)
|
||||||
|
|
||||||
# Wrong colour count
|
# Wrong colour count
|
||||||
theStatus.write(None, "Entry 4", (10, 20))
|
nStatus.write(None, "Entry 4", (10, 20))
|
||||||
assert theStatus[statusKeys[3]]["name"] == "Entry 4"
|
assert nStatus[statusKeys[3]]["name"] == "Entry 4"
|
||||||
assert theStatus[statusKeys[3]]["cols"] == (100, 100, 100)
|
assert nStatus[statusKeys[3]]["cols"] == (100, 100, 100)
|
||||||
|
|
||||||
# Check
|
# Check
|
||||||
# =====
|
# =====
|
||||||
|
|
||||||
# Normal lookup
|
# Normal lookup
|
||||||
for key in statusKeys:
|
for key in statusKeys:
|
||||||
assert theStatus.check(key) == key
|
assert nStatus.check(key) == key
|
||||||
|
|
||||||
# Non-existing name
|
# Non-existing name
|
||||||
assert theStatus.check("s987654") == statusKeys[0]
|
assert nStatus.check("s987654") == statusKeys[0]
|
||||||
|
|
||||||
# Name Access
|
# Name Access
|
||||||
# ===========
|
# ===========
|
||||||
|
|
||||||
assert theStatus.name(statusKeys[0]) == "Entry 1"
|
assert nStatus.name(statusKeys[0]) == "Entry 1"
|
||||||
assert theStatus.name(statusKeys[1]) == "Entry 2"
|
assert nStatus.name(statusKeys[1]) == "Entry 2"
|
||||||
assert theStatus.name(statusKeys[2]) == "Entry 3"
|
assert nStatus.name(statusKeys[2]) == "Entry 3"
|
||||||
assert theStatus.name(statusKeys[3]) == "Entry 4"
|
assert nStatus.name(statusKeys[3]) == "Entry 4"
|
||||||
assert theStatus.name("blablabla") == "Entry 1"
|
assert nStatus.name("blablabla") == "Entry 1"
|
||||||
|
|
||||||
# Colour Access
|
# Colour Access
|
||||||
# =============
|
# =============
|
||||||
|
|
||||||
assert theStatus.cols(statusKeys[0]) == (200, 100, 50)
|
assert nStatus.cols(statusKeys[0]) == (200, 100, 50)
|
||||||
assert theStatus.cols(statusKeys[1]) == (210, 110, 60)
|
assert nStatus.cols(statusKeys[1]) == (210, 110, 60)
|
||||||
assert theStatus.cols(statusKeys[2]) == (100, 100, 100)
|
assert nStatus.cols(statusKeys[2]) == (100, 100, 100)
|
||||||
assert theStatus.cols(statusKeys[3]) == (100, 100, 100)
|
assert nStatus.cols(statusKeys[3]) == (100, 100, 100)
|
||||||
assert theStatus.cols("blablabla") == (200, 100, 50)
|
assert nStatus.cols("blablabla") == (200, 100, 50)
|
||||||
|
|
||||||
# Icon Access
|
# Icon Access
|
||||||
# ===========
|
# ===========
|
||||||
|
|
||||||
assert isinstance(theStatus.icon(statusKeys[0]), QIcon)
|
assert isinstance(nStatus.icon(statusKeys[0]), QIcon)
|
||||||
assert isinstance(theStatus.icon(statusKeys[1]), QIcon)
|
assert isinstance(nStatus.icon(statusKeys[1]), QIcon)
|
||||||
assert isinstance(theStatus.icon(statusKeys[2]), QIcon)
|
assert isinstance(nStatus.icon(statusKeys[2]), QIcon)
|
||||||
assert isinstance(theStatus.icon(statusKeys[3]), QIcon)
|
assert isinstance(nStatus.icon(statusKeys[3]), QIcon)
|
||||||
assert isinstance(theStatus.icon("blablabla"), QIcon)
|
assert isinstance(nStatus.icon("blablabla"), QIcon)
|
||||||
|
|
||||||
# Increment and Count Access
|
# Increment and Count Access
|
||||||
# ==========================
|
# ==========================
|
||||||
@@ -201,32 +201,32 @@ def testCoreStatus_Entries(mockRnd):
|
|||||||
countTo = [3, 5, 7, 9]
|
countTo = [3, 5, 7, 9]
|
||||||
for i, n in enumerate(countTo):
|
for i, n in enumerate(countTo):
|
||||||
for _ in range(n):
|
for _ in range(n):
|
||||||
theStatus.increment(statusKeys[i])
|
nStatus.increment(statusKeys[i])
|
||||||
|
|
||||||
assert theStatus.count(statusKeys[0]) == countTo[0]
|
assert nStatus.count(statusKeys[0]) == countTo[0]
|
||||||
assert theStatus.count(statusKeys[1]) == countTo[1]
|
assert nStatus.count(statusKeys[1]) == countTo[1]
|
||||||
assert theStatus.count(statusKeys[2]) == countTo[2]
|
assert nStatus.count(statusKeys[2]) == countTo[2]
|
||||||
assert theStatus.count(statusKeys[3]) == countTo[3]
|
assert nStatus.count(statusKeys[3]) == countTo[3]
|
||||||
assert theStatus.count("blablabla") == countTo[0]
|
assert nStatus.count("blablabla") == countTo[0]
|
||||||
|
|
||||||
theStatus.resetCounts()
|
nStatus.resetCounts()
|
||||||
|
|
||||||
assert theStatus.count(statusKeys[0]) == 0
|
assert nStatus.count(statusKeys[0]) == 0
|
||||||
assert theStatus.count(statusKeys[1]) == 0
|
assert nStatus.count(statusKeys[1]) == 0
|
||||||
assert theStatus.count(statusKeys[2]) == 0
|
assert nStatus.count(statusKeys[2]) == 0
|
||||||
assert theStatus.count(statusKeys[3]) == 0
|
assert nStatus.count(statusKeys[3]) == 0
|
||||||
|
|
||||||
# Reorder
|
# Reorder
|
||||||
# =======
|
# =======
|
||||||
|
|
||||||
cOrder = list(theStatus.keys())
|
cOrder = list(nStatus.keys())
|
||||||
assert cOrder == statusKeys
|
assert cOrder == statusKeys
|
||||||
|
|
||||||
# Wrong length
|
# Wrong length
|
||||||
assert theStatus.reorder([]) is False
|
assert nStatus.reorder([]) is False
|
||||||
|
|
||||||
# No change
|
# No change
|
||||||
assert theStatus.reorder(cOrder) is False
|
assert nStatus.reorder(cOrder) is False
|
||||||
|
|
||||||
# Actual reaorder
|
# Actual reaorder
|
||||||
nOrder = [
|
nOrder = [
|
||||||
@@ -235,63 +235,63 @@ def testCoreStatus_Entries(mockRnd):
|
|||||||
statusKeys[1],
|
statusKeys[1],
|
||||||
statusKeys[3],
|
statusKeys[3],
|
||||||
]
|
]
|
||||||
assert theStatus.reorder(nOrder) is True
|
assert nStatus.reorder(nOrder) is True
|
||||||
assert list(theStatus.keys()) == nOrder
|
assert list(nStatus.keys()) == nOrder
|
||||||
|
|
||||||
# Add an unknown key
|
# Add an unknown key
|
||||||
wOrder = nOrder.copy()
|
wOrder = nOrder.copy()
|
||||||
wOrder[3] = theStatus._newKey()
|
wOrder[3] = nStatus._newKey()
|
||||||
assert theStatus.reorder(wOrder) is False
|
assert nStatus.reorder(wOrder) is False
|
||||||
assert list(theStatus.keys()) == nOrder
|
assert list(nStatus.keys()) == nOrder
|
||||||
|
|
||||||
# Put it back
|
# Put it back
|
||||||
assert theStatus.reorder(cOrder) is True
|
assert nStatus.reorder(cOrder) is True
|
||||||
assert list(theStatus.keys()) == cOrder
|
assert list(nStatus.keys()) == cOrder
|
||||||
|
|
||||||
# Default
|
# Default
|
||||||
# =======
|
# =======
|
||||||
|
|
||||||
default = theStatus._default
|
default = nStatus._default
|
||||||
theStatus._default = None
|
nStatus._default = None
|
||||||
|
|
||||||
assert theStatus.check("Entry 5") == ""
|
assert nStatus.check("Entry 5") == ""
|
||||||
assert theStatus.name("blablabla") == ""
|
assert nStatus.name("blablabla") == ""
|
||||||
assert theStatus.cols("blablabla") == (100, 100, 100)
|
assert nStatus.cols("blablabla") == (100, 100, 100)
|
||||||
assert theStatus.count("blablabla") == 0
|
assert nStatus.count("blablabla") == 0
|
||||||
assert isinstance(theStatus.icon("blablabla"), QIcon)
|
assert isinstance(nStatus.icon("blablabla"), QIcon)
|
||||||
|
|
||||||
theStatus._default = default
|
nStatus._default = default
|
||||||
|
|
||||||
# Remove
|
# Remove
|
||||||
# ======
|
# ======
|
||||||
|
|
||||||
# Non-existing entry
|
# Non-existing entry
|
||||||
assert theStatus.remove("blablabla") is False
|
assert nStatus.remove("blablabla") is False
|
||||||
|
|
||||||
# Non-zero entry
|
# Non-zero entry
|
||||||
theStatus.increment(statusKeys[3])
|
nStatus.increment(statusKeys[3])
|
||||||
assert theStatus.remove(statusKeys[3]) is False
|
assert nStatus.remove(statusKeys[3]) is False
|
||||||
|
|
||||||
# Delete last entry
|
# Delete last entry
|
||||||
theStatus.resetCounts()
|
nStatus.resetCounts()
|
||||||
lastName = theStatus.name(statusKeys[3])
|
lastName = nStatus.name(statusKeys[3])
|
||||||
assert lastName == "Entry 4"
|
assert lastName == "Entry 4"
|
||||||
assert theStatus.remove(statusKeys[3]) is True
|
assert nStatus.remove(statusKeys[3]) is True
|
||||||
assert theStatus.check(statusKeys[3]) == theStatus._default
|
assert nStatus.check(statusKeys[3]) == nStatus._default
|
||||||
assert theStatus.check(lastName) == theStatus._default
|
assert nStatus.check(lastName) == nStatus._default
|
||||||
|
|
||||||
# Delete default entry, Entry 2 is new default
|
# Delete default entry, Entry 2 is new default
|
||||||
firstName = theStatus.name(theStatus._default)
|
firstName = nStatus.name(nStatus._default)
|
||||||
assert firstName == "Entry 1"
|
assert firstName == "Entry 1"
|
||||||
assert theStatus.remove(theStatus._default) is True
|
assert nStatus.remove(nStatus._default) is True
|
||||||
assert theStatus.name(firstName) == "Entry 2"
|
assert nStatus.name(firstName) == "Entry 2"
|
||||||
|
|
||||||
# Remove remaining entries
|
# Remove remaining entries
|
||||||
assert theStatus.remove(statusKeys[1]) is True
|
assert nStatus.remove(statusKeys[1]) is True
|
||||||
assert theStatus.remove(statusKeys[2]) is True
|
assert nStatus.remove(statusKeys[2]) is True
|
||||||
|
|
||||||
assert len(theStatus) == 0
|
assert len(nStatus) == 0
|
||||||
assert theStatus._default is None
|
assert nStatus._default is None
|
||||||
|
|
||||||
# END Test testCoreStatus_Entries
|
# END Test testCoreStatus_Entries
|
||||||
|
|
||||||
@@ -300,19 +300,19 @@ def testCoreStatus_Entries(mockRnd):
|
|||||||
def testCoreStatus_PackUnpack(mockRnd):
|
def testCoreStatus_PackUnpack(mockRnd):
|
||||||
"""Test all the pack/unpack of the NWStatus class.
|
"""Test all the pack/unpack of the NWStatus class.
|
||||||
"""
|
"""
|
||||||
theStatus = NWStatus(NWStatus.STATUS)
|
nStatus = NWStatus(NWStatus.STATUS)
|
||||||
theStatus.write(None, "New", (100, 100, 100))
|
nStatus.write(None, "New", (100, 100, 100))
|
||||||
theStatus.write(None, "Note", (200, 50, 0))
|
nStatus.write(None, "Note", (200, 50, 0))
|
||||||
theStatus.write(None, "Draft", (200, 150, 0))
|
nStatus.write(None, "Draft", (200, 150, 0))
|
||||||
theStatus.write(None, "Finished", (50, 200, 0))
|
nStatus.write(None, "Finished", (50, 200, 0))
|
||||||
|
|
||||||
countTo = [3, 5, 7, 9]
|
countTo = [3, 5, 7, 9]
|
||||||
for i, n in enumerate(countTo):
|
for i, n in enumerate(countTo):
|
||||||
for _ in range(n):
|
for _ in range(n):
|
||||||
theStatus.increment(statusKeys[i])
|
nStatus.increment(statusKeys[i])
|
||||||
|
|
||||||
# Pack
|
# Pack
|
||||||
assert list(theStatus.pack()) == [
|
assert list(nStatus.pack()) == [
|
||||||
("New", {
|
("New", {
|
||||||
"key": statusKeys[0],
|
"key": statusKeys[0],
|
||||||
"count": "3",
|
"count": "3",
|
||||||
@@ -344,26 +344,26 @@ def testCoreStatus_PackUnpack(mockRnd):
|
|||||||
]
|
]
|
||||||
|
|
||||||
# Unpack
|
# Unpack
|
||||||
theStatus = NWStatus(NWStatus.STATUS)
|
nStatus = NWStatus(NWStatus.STATUS)
|
||||||
theStatus.unpack({
|
nStatus.unpack({
|
||||||
statusKeys[0]: {"label": "New0", "colour": (100, 100, 100), "count": countTo[0]},
|
statusKeys[0]: {"label": "New0", "colour": (100, 100, 100), "count": countTo[0]},
|
||||||
statusKeys[1]: {"label": "New1", "colour": (150, 150, 150), "count": countTo[1]},
|
statusKeys[1]: {"label": "New1", "colour": (150, 150, 150), "count": countTo[1]},
|
||||||
statusKeys[2]: {"label": "New2", "colour": (200, 200, 200), "count": countTo[2]},
|
statusKeys[2]: {"label": "New2", "colour": (200, 200, 200), "count": countTo[2]},
|
||||||
statusKeys[3]: {"label": "New3", "colour": (250, 250, 250), "count": countTo[3]},
|
statusKeys[3]: {"label": "New3", "colour": (250, 250, 250), "count": countTo[3]},
|
||||||
})
|
})
|
||||||
assert len(theStatus._store) == 4
|
assert len(nStatus._store) == 4
|
||||||
assert list(theStatus._store.keys()) == statusKeys
|
assert list(nStatus._store.keys()) == statusKeys
|
||||||
assert theStatus._store[statusKeys[0]]["name"] == "New0"
|
assert nStatus._store[statusKeys[0]]["name"] == "New0"
|
||||||
assert theStatus._store[statusKeys[1]]["name"] == "New1"
|
assert nStatus._store[statusKeys[1]]["name"] == "New1"
|
||||||
assert theStatus._store[statusKeys[2]]["name"] == "New2"
|
assert nStatus._store[statusKeys[2]]["name"] == "New2"
|
||||||
assert theStatus._store[statusKeys[3]]["name"] == "New3"
|
assert nStatus._store[statusKeys[3]]["name"] == "New3"
|
||||||
assert theStatus._store[statusKeys[0]]["cols"] == (100, 100, 100)
|
assert nStatus._store[statusKeys[0]]["cols"] == (100, 100, 100)
|
||||||
assert theStatus._store[statusKeys[1]]["cols"] == (150, 150, 150)
|
assert nStatus._store[statusKeys[1]]["cols"] == (150, 150, 150)
|
||||||
assert theStatus._store[statusKeys[2]]["cols"] == (200, 200, 200)
|
assert nStatus._store[statusKeys[2]]["cols"] == (200, 200, 200)
|
||||||
assert theStatus._store[statusKeys[3]]["cols"] == (250, 250, 250)
|
assert nStatus._store[statusKeys[3]]["cols"] == (250, 250, 250)
|
||||||
assert theStatus._store[statusKeys[0]]["count"] == countTo[0]
|
assert nStatus._store[statusKeys[0]]["count"] == countTo[0]
|
||||||
assert theStatus._store[statusKeys[1]]["count"] == countTo[1]
|
assert nStatus._store[statusKeys[1]]["count"] == countTo[1]
|
||||||
assert theStatus._store[statusKeys[2]]["count"] == countTo[2]
|
assert nStatus._store[statusKeys[2]]["count"] == countTo[2]
|
||||||
assert theStatus._store[statusKeys[3]]["count"] == countTo[3]
|
assert nStatus._store[statusKeys[3]]["count"] == countTo[3]
|
||||||
|
|
||||||
# END Test testCoreStatus_PackUnpack
|
# END Test testCoreStatus_PackUnpack
|
||||||
|
|||||||
@@ -266,13 +266,13 @@ def testCoreStorage_ZipIt(monkeypatch, mockGUI, fncPath, tstPaths, mockRnd):
|
|||||||
"""Test making a zip archive of a project."""
|
"""Test making a zip archive of a project."""
|
||||||
zipFile = tstPaths.tmpDir / "project.zip"
|
zipFile = tstPaths.tmpDir / "project.zip"
|
||||||
|
|
||||||
theProject = NWProject()
|
project = NWProject()
|
||||||
storage = theProject.storage
|
storage = project.storage
|
||||||
assert storage.zipIt(zipFile) is False
|
assert storage.zipIt(zipFile) is False
|
||||||
|
|
||||||
# Make a project
|
# Make a project
|
||||||
mockRnd.reset()
|
mockRnd.reset()
|
||||||
buildTestProject(theProject, fncPath)
|
buildTestProject(project, fncPath)
|
||||||
|
|
||||||
# Fail to create archive
|
# Fail to create archive
|
||||||
with monkeypatch.context() as mp:
|
with monkeypatch.context() as mp:
|
||||||
@@ -292,7 +292,7 @@ def testCoreStorage_ZipIt(monkeypatch, mockGUI, fncPath, tstPaths, mockRnd):
|
|||||||
assert f"content/{C.hChapterDoc}.nwd" in names
|
assert f"content/{C.hChapterDoc}.nwd" in names
|
||||||
assert f"content/{C.hSceneDoc}.nwd" in names
|
assert f"content/{C.hSceneDoc}.nwd" in names
|
||||||
|
|
||||||
theProject.closeProject()
|
project.closeProject()
|
||||||
|
|
||||||
# END Test testCoreStorage_ZipIt
|
# END Test testCoreStorage_ZipIt
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ def testCoreToHtml_ConvertFormat(mockGUI):
|
|||||||
html._text = "# Partition\n"
|
html._text = "# Partition\n"
|
||||||
html.tokenizeText()
|
html.tokenizeText()
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == (
|
assert html.result == (
|
||||||
"<h1 class='title' style='text-align: center;'>Partition</h1>\n"
|
"<h1 class='title' style='text-align: center;'>Partition</h1>\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ def testCoreToHtml_ConvertFormat(mockGUI):
|
|||||||
html._text = "## Chapter Title\n"
|
html._text = "## Chapter Title\n"
|
||||||
html.tokenizeText()
|
html.tokenizeText()
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == (
|
assert html.result == (
|
||||||
"<h1 style='page-break-before: always;'>Chapter Title</h1>\n"
|
"<h1 style='page-break-before: always;'>Chapter Title</h1>\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -61,19 +61,19 @@ def testCoreToHtml_ConvertFormat(mockGUI):
|
|||||||
html._text = "### Scene Title\n"
|
html._text = "### Scene Title\n"
|
||||||
html.tokenizeText()
|
html.tokenizeText()
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == "<h2>Scene Title</h2>\n"
|
assert html.result == "<h2>Scene Title</h2>\n"
|
||||||
|
|
||||||
# Header 4
|
# Header 4
|
||||||
html._text = "#### Section Title\n"
|
html._text = "#### Section Title\n"
|
||||||
html.tokenizeText()
|
html.tokenizeText()
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == "<h3>Section Title</h3>\n"
|
assert html.result == "<h3>Section Title</h3>\n"
|
||||||
|
|
||||||
# Title
|
# Title
|
||||||
html._text = "#! Title\n"
|
html._text = "#! Title\n"
|
||||||
html.tokenizeText()
|
html.tokenizeText()
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == (
|
assert html.result == (
|
||||||
"<h1 class='title' style='text-align: center;'>Title</h1>\n"
|
"<h1 class='title' style='text-align: center;'>Title</h1>\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -81,7 +81,7 @@ def testCoreToHtml_ConvertFormat(mockGUI):
|
|||||||
html._text = "##! Prologue\n"
|
html._text = "##! Prologue\n"
|
||||||
html.tokenizeText()
|
html.tokenizeText()
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == "<h1 style='page-break-before: always;'>Prologue</h1>\n"
|
assert html.result == "<h1 style='page-break-before: always;'>Prologue</h1>\n"
|
||||||
|
|
||||||
# Note Files Headers
|
# Note Files Headers
|
||||||
# ==================
|
# ==================
|
||||||
@@ -95,31 +95,31 @@ def testCoreToHtml_ConvertFormat(mockGUI):
|
|||||||
html._text = "# Heading One\n"
|
html._text = "# Heading One\n"
|
||||||
html.tokenizeText()
|
html.tokenizeText()
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == "<h1><a name='T0001'></a>Heading One</h1>\n"
|
assert html.result == "<h1><a name='T0001'></a>Heading One</h1>\n"
|
||||||
|
|
||||||
# Header 2
|
# Header 2
|
||||||
html._text = "## Heading Two\n"
|
html._text = "## Heading Two\n"
|
||||||
html.tokenizeText()
|
html.tokenizeText()
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == "<h2><a name='T0001'></a>Heading Two</h2>\n"
|
assert html.result == "<h2><a name='T0001'></a>Heading Two</h2>\n"
|
||||||
|
|
||||||
# Header 3
|
# Header 3
|
||||||
html._text = "### Heading Three\n"
|
html._text = "### Heading Three\n"
|
||||||
html.tokenizeText()
|
html.tokenizeText()
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == "<h3><a name='T0001'></a>Heading Three</h3>\n"
|
assert html.result == "<h3><a name='T0001'></a>Heading Three</h3>\n"
|
||||||
|
|
||||||
# Header 4
|
# Header 4
|
||||||
html._text = "#### Heading Four\n"
|
html._text = "#### Heading Four\n"
|
||||||
html.tokenizeText()
|
html.tokenizeText()
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == "<h4><a name='T0001'></a>Heading Four</h4>\n"
|
assert html.result == "<h4><a name='T0001'></a>Heading Four</h4>\n"
|
||||||
|
|
||||||
# Title
|
# Title
|
||||||
html._text = "#! Heading One\n"
|
html._text = "#! Heading One\n"
|
||||||
html.tokenizeText()
|
html.tokenizeText()
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == (
|
assert html.result == (
|
||||||
"<h1 style='text-align: center;'><a name='T0001'></a>Heading One</h1>\n"
|
"<h1 style='text-align: center;'><a name='T0001'></a>Heading One</h1>\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -127,7 +127,7 @@ def testCoreToHtml_ConvertFormat(mockGUI):
|
|||||||
html._text = "##! Heading Two\n"
|
html._text = "##! Heading Two\n"
|
||||||
html.tokenizeText()
|
html.tokenizeText()
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == "<h2><a name='T0001'></a>Heading Two</h2>\n"
|
assert html.result == "<h2><a name='T0001'></a>Heading Two</h2>\n"
|
||||||
|
|
||||||
# Paragraphs
|
# Paragraphs
|
||||||
# ==========
|
# ==========
|
||||||
@@ -136,7 +136,7 @@ def testCoreToHtml_ConvertFormat(mockGUI):
|
|||||||
html._text = "Some **nested bold and _italic_ and ~~strikethrough~~ text** here\n"
|
html._text = "Some **nested bold and _italic_ and ~~strikethrough~~ text** here\n"
|
||||||
html.tokenizeText()
|
html.tokenizeText()
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == (
|
assert html.result == (
|
||||||
"<p>Some <strong>nested bold and <em>italic</em> and "
|
"<p>Some <strong>nested bold and <em>italic</em> and "
|
||||||
"<del>strikethrough</del> text</strong> here</p>\n"
|
"<del>strikethrough</del> text</strong> here</p>\n"
|
||||||
)
|
)
|
||||||
@@ -145,7 +145,7 @@ def testCoreToHtml_ConvertFormat(mockGUI):
|
|||||||
html._text = "Line one \nLine two \nLine three\n"
|
html._text = "Line one \nLine two \nLine three\n"
|
||||||
html.tokenizeText()
|
html.tokenizeText()
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == (
|
assert html.result == (
|
||||||
"<p class='break'>Line one<br/>Line two<br/>Line three</p>\n"
|
"<p class='break'>Line one<br/>Line two<br/>Line three</p>\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -153,13 +153,13 @@ def testCoreToHtml_ConvertFormat(mockGUI):
|
|||||||
html._text = "%synopsis: The synopsis ...\n"
|
html._text = "%synopsis: The synopsis ...\n"
|
||||||
html.tokenizeText()
|
html.tokenizeText()
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == ""
|
assert html.result == ""
|
||||||
|
|
||||||
html.setSynopsis(True)
|
html.setSynopsis(True)
|
||||||
html._text = "%synopsis: The synopsis ...\n"
|
html._text = "%synopsis: The synopsis ...\n"
|
||||||
html.tokenizeText()
|
html.tokenizeText()
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == (
|
assert html.result == (
|
||||||
"<p class='synopsis'><strong>Synopsis:</strong> The synopsis ...</p>\n"
|
"<p class='synopsis'><strong>Synopsis:</strong> The synopsis ...</p>\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -167,7 +167,7 @@ def testCoreToHtml_ConvertFormat(mockGUI):
|
|||||||
html._text = "%short: A short description ...\n"
|
html._text = "%short: A short description ...\n"
|
||||||
html.tokenizeText()
|
html.tokenizeText()
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == (
|
assert html.result == (
|
||||||
"<p class='synopsis'><strong>Short Description:</strong> A short description ...</p>\n"
|
"<p class='synopsis'><strong>Short Description:</strong> A short description ...</p>\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -175,13 +175,13 @@ def testCoreToHtml_ConvertFormat(mockGUI):
|
|||||||
html._text = "% A comment ...\n"
|
html._text = "% A comment ...\n"
|
||||||
html.tokenizeText()
|
html.tokenizeText()
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == ""
|
assert html.result == ""
|
||||||
|
|
||||||
html.setComments(True)
|
html.setComments(True)
|
||||||
html._text = "% A comment ...\n"
|
html._text = "% A comment ...\n"
|
||||||
html.tokenizeText()
|
html.tokenizeText()
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == (
|
assert html.result == (
|
||||||
"<p class='comment'><strong>Comment:</strong> A comment ...</p>\n"
|
"<p class='comment'><strong>Comment:</strong> A comment ...</p>\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -189,13 +189,13 @@ def testCoreToHtml_ConvertFormat(mockGUI):
|
|||||||
html._text = "@char: Bod, Jane\n"
|
html._text = "@char: Bod, Jane\n"
|
||||||
html.tokenizeText()
|
html.tokenizeText()
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == ""
|
assert html.result == ""
|
||||||
|
|
||||||
html.setKeywords(True)
|
html.setKeywords(True)
|
||||||
html._text = "@char: Bod, Jane\n"
|
html._text = "@char: Bod, Jane\n"
|
||||||
html.tokenizeText()
|
html.tokenizeText()
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == (
|
assert html.result == (
|
||||||
"<p><span class='tags'>Characters:</span> "
|
"<p><span class='tags'>Characters:</span> "
|
||||||
"<a href='#tag_Bod'>Bod</a>, <a href='#tag_Jane'>Jane</a></p>\n"
|
"<a href='#tag_Bod'>Bod</a>, <a href='#tag_Jane'>Jane</a></p>\n"
|
||||||
)
|
)
|
||||||
@@ -205,7 +205,7 @@ def testCoreToHtml_ConvertFormat(mockGUI):
|
|||||||
html._text = "## Chapter\n\n@pov: Bod\n@plot: Main\n@location: Europe\n\n"
|
html._text = "## Chapter\n\n@pov: Bod\n@plot: Main\n@location: Europe\n\n"
|
||||||
html.tokenizeText()
|
html.tokenizeText()
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == (
|
assert html.result == (
|
||||||
"<h2>"
|
"<h2>"
|
||||||
"<a name='T0001'></a>Chapter</h2>\n"
|
"<a name='T0001'></a>Chapter</h2>\n"
|
||||||
"<p style='margin-bottom: 0;'>"
|
"<p style='margin-bottom: 0;'>"
|
||||||
@@ -228,7 +228,7 @@ def testCoreToHtml_ConvertFormat(mockGUI):
|
|||||||
html._text = "Some **nested bold and _italic_ and ~~strikethrough~~ text** here\n"
|
html._text = "Some **nested bold and _italic_ and ~~strikethrough~~ text** here\n"
|
||||||
html.tokenizeText()
|
html.tokenizeText()
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == (
|
assert html.result == (
|
||||||
"<p>Some <b>nested bold and <i>italic</i> and "
|
"<p>Some <b>nested bold and <i>italic</i> and "
|
||||||
"<span style='text-decoration: line-through;'>strikethrough</span> "
|
"<span style='text-decoration: line-through;'>strikethrough</span> "
|
||||||
"text</b> here</p>\n"
|
"text</b> here</p>\n"
|
||||||
@@ -256,7 +256,7 @@ def testCoreToHtml_ConvertDirect(mockGUI):
|
|||||||
(html.T_EMPTY, 1, "", None, html.A_NONE),
|
(html.T_EMPTY, 1, "", None, html.A_NONE),
|
||||||
]
|
]
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == (
|
assert html.result == (
|
||||||
"<h1 class='title' style='text-align: center; page-break-before: always;'>"
|
"<h1 class='title' style='text-align: center; page-break-before: always;'>"
|
||||||
"<a name='T0001'></a>A Title</h1>\n"
|
"<a name='T0001'></a>A Title</h1>\n"
|
||||||
)
|
)
|
||||||
@@ -267,7 +267,7 @@ def testCoreToHtml_ConvertDirect(mockGUI):
|
|||||||
(html.T_EMPTY, 1, "", None, html.A_NONE),
|
(html.T_EMPTY, 1, "", None, html.A_NONE),
|
||||||
]
|
]
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == (
|
assert html.result == (
|
||||||
"<h1 style='page-break-before: always;'>"
|
"<h1 style='page-break-before: always;'>"
|
||||||
"<a name='T0001'></a>Prologue</h1>\n"
|
"<a name='T0001'></a>Prologue</h1>\n"
|
||||||
)
|
)
|
||||||
@@ -281,7 +281,7 @@ def testCoreToHtml_ConvertDirect(mockGUI):
|
|||||||
(html.T_EMPTY, 1, "", None, html.A_NONE),
|
(html.T_EMPTY, 1, "", None, html.A_NONE),
|
||||||
]
|
]
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == "<p class='sep' style='text-align: center;'>* * *</p>\n"
|
assert html.result == "<p class='sep' style='text-align: center;'>* * *</p>\n"
|
||||||
|
|
||||||
# Skip
|
# Skip
|
||||||
html._tokens = [
|
html._tokens = [
|
||||||
@@ -289,7 +289,7 @@ def testCoreToHtml_ConvertDirect(mockGUI):
|
|||||||
(html.T_EMPTY, 1, "", None, html.A_NONE),
|
(html.T_EMPTY, 1, "", None, html.A_NONE),
|
||||||
]
|
]
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == "<p class='skip'> </p>\n"
|
assert html.result == "<p class='skip'> </p>\n"
|
||||||
|
|
||||||
# Alignment
|
# Alignment
|
||||||
# =========
|
# =========
|
||||||
@@ -302,7 +302,7 @@ def testCoreToHtml_ConvertDirect(mockGUI):
|
|||||||
(html.T_HEAD1, 1, "A Title", None, html.A_LEFT),
|
(html.T_HEAD1, 1, "A Title", None, html.A_LEFT),
|
||||||
]
|
]
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == (
|
assert html.result == (
|
||||||
"<h1 class='title'>A Title</h1>\n"
|
"<h1 class='title'>A Title</h1>\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -313,7 +313,7 @@ def testCoreToHtml_ConvertDirect(mockGUI):
|
|||||||
(html.T_HEAD1, 1, "A Title", None, html.A_LEFT),
|
(html.T_HEAD1, 1, "A Title", None, html.A_LEFT),
|
||||||
]
|
]
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == (
|
assert html.result == (
|
||||||
"<h1 class='title' style='text-align: left;'>A Title</h1>\n"
|
"<h1 class='title' style='text-align: left;'>A Title</h1>\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -322,7 +322,7 @@ def testCoreToHtml_ConvertDirect(mockGUI):
|
|||||||
(html.T_HEAD1, 1, "A Title", None, html.A_RIGHT),
|
(html.T_HEAD1, 1, "A Title", None, html.A_RIGHT),
|
||||||
]
|
]
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == (
|
assert html.result == (
|
||||||
"<h1 class='title' style='text-align: right;'>A Title</h1>\n"
|
"<h1 class='title' style='text-align: right;'>A Title</h1>\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -331,7 +331,7 @@ def testCoreToHtml_ConvertDirect(mockGUI):
|
|||||||
(html.T_HEAD1, 1, "A Title", None, html.A_CENTRE),
|
(html.T_HEAD1, 1, "A Title", None, html.A_CENTRE),
|
||||||
]
|
]
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == (
|
assert html.result == (
|
||||||
"<h1 class='title' style='text-align: center;'>A Title</h1>\n"
|
"<h1 class='title' style='text-align: center;'>A Title</h1>\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -340,7 +340,7 @@ def testCoreToHtml_ConvertDirect(mockGUI):
|
|||||||
(html.T_HEAD1, 1, "A Title", None, html.A_JUSTIFY),
|
(html.T_HEAD1, 1, "A Title", None, html.A_JUSTIFY),
|
||||||
]
|
]
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == (
|
assert html.result == (
|
||||||
"<h1 class='title' style='text-align: justify;'>A Title</h1>\n"
|
"<h1 class='title' style='text-align: justify;'>A Title</h1>\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -352,7 +352,7 @@ def testCoreToHtml_ConvertDirect(mockGUI):
|
|||||||
(html.T_HEAD1, 1, "A Title", None, html.A_PBB | html.A_PBA),
|
(html.T_HEAD1, 1, "A Title", None, html.A_PBB | html.A_PBA),
|
||||||
]
|
]
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == (
|
assert html.result == (
|
||||||
"<h1 class='title' "
|
"<h1 class='title' "
|
||||||
"style='page-break-before: always; page-break-after: always;'>A Title</h1>\n"
|
"style='page-break-before: always; page-break-after: always;'>A Title</h1>\n"
|
||||||
)
|
)
|
||||||
@@ -366,7 +366,7 @@ def testCoreToHtml_ConvertDirect(mockGUI):
|
|||||||
(html.T_EMPTY, 2, "", None, html.A_NONE),
|
(html.T_EMPTY, 2, "", None, html.A_NONE),
|
||||||
]
|
]
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == (
|
assert html.result == (
|
||||||
"<p style='margin-left: 40px;'>Some text ...</p>\n"
|
"<p style='margin-left: 40px;'>Some text ...</p>\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -376,7 +376,7 @@ def testCoreToHtml_ConvertDirect(mockGUI):
|
|||||||
(html.T_EMPTY, 2, "", None, html.A_NONE),
|
(html.T_EMPTY, 2, "", None, html.A_NONE),
|
||||||
]
|
]
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == (
|
assert html.result == (
|
||||||
"<p style='margin-right: 40px;'>Some text ...</p>\n"
|
"<p style='margin-right: 40px;'>Some text ...</p>\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -396,28 +396,28 @@ def testCoreToHtml_SpecialCases(mockGUI):
|
|||||||
html._text = "Text with > and < with some **bold text** in it.\n"
|
html._text = "Text with > and < with some **bold text** in it.\n"
|
||||||
html.tokenizeText()
|
html.tokenizeText()
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == (
|
assert html.result == (
|
||||||
"<p>Text with > and < with some <strong>bold text</strong> in it.</p>\n"
|
"<p>Text with > and < with some <strong>bold text</strong> in it.</p>\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
html._text = "Text with some <**bold text**> in it.\n"
|
html._text = "Text with some <**bold text**> in it.\n"
|
||||||
html.tokenizeText()
|
html.tokenizeText()
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == (
|
assert html.result == (
|
||||||
"<p>Text with some <<strong>bold text</strong>> in it.</p>\n"
|
"<p>Text with some <<strong>bold text</strong>> in it.</p>\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
html._text = "Let's > be > _difficult **shall** > we_?\n"
|
html._text = "Let's > be > _difficult **shall** > we_?\n"
|
||||||
html.tokenizeText()
|
html.tokenizeText()
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == (
|
assert html.result == (
|
||||||
"<p>Let's > be > <em>difficult <strong>shall</strong> > we</em>?</p>\n"
|
"<p>Let's > be > <em>difficult <strong>shall</strong> > we</em>?</p>\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
html._text = "Test > text _<**bold**>_ and more.\n"
|
html._text = "Test > text _<**bold**>_ and more.\n"
|
||||||
html.tokenizeText()
|
html.tokenizeText()
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == (
|
assert html.result == (
|
||||||
"<p>Test > text <em><<strong>bold</strong>></em> and more.</p>\n"
|
"<p>Test > text <em><<strong>bold</strong>></em> and more.</p>\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -429,7 +429,7 @@ def testCoreToHtml_SpecialCases(mockGUI):
|
|||||||
html._text = "% Test > text _<**bold**>_ and more.\n"
|
html._text = "% Test > text _<**bold**>_ and more.\n"
|
||||||
html.tokenizeText()
|
html.tokenizeText()
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == (
|
assert html.result == (
|
||||||
"<p class='comment'>"
|
"<p class='comment'>"
|
||||||
"<strong>Comment:</strong> Test > text _<**bold**>_ and more."
|
"<strong>Comment:</strong> Test > text _<**bold**>_ and more."
|
||||||
"</p>\n"
|
"</p>\n"
|
||||||
@@ -438,7 +438,7 @@ def testCoreToHtml_SpecialCases(mockGUI):
|
|||||||
html._text = "## Heading <1>\n"
|
html._text = "## Heading <1>\n"
|
||||||
html.tokenizeText()
|
html.tokenizeText()
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == (
|
assert html.result == (
|
||||||
"<h1 style='page-break-before: always;'>Heading <1></h1>\n"
|
"<h1 style='page-break-before: always;'>Heading <1></h1>\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -449,7 +449,7 @@ def testCoreToHtml_SpecialCases(mockGUI):
|
|||||||
html._text = "Test text \\**_bold_** and more.\n"
|
html._text = "Test text \\**_bold_** and more.\n"
|
||||||
html.tokenizeText()
|
html.tokenizeText()
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == (
|
assert html.result == (
|
||||||
"<p>Test text **<em>bold</em>** and more.</p>\n"
|
"<p>Test text **<em>bold</em>** and more.</p>\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -511,7 +511,7 @@ def testCoreToHtml_Complex(mockGUI, fncPath):
|
|||||||
html.doPreProcessing()
|
html.doPreProcessing()
|
||||||
html.tokenizeText()
|
html.tokenizeText()
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == resText[i]
|
assert html.result == resText[i]
|
||||||
|
|
||||||
assert html.fullHTML == resText
|
assert html.fullHTML == resText
|
||||||
|
|
||||||
@@ -521,7 +521,7 @@ def testCoreToHtml_Complex(mockGUI, fncPath):
|
|||||||
# Check File
|
# Check File
|
||||||
# ==========
|
# ==========
|
||||||
|
|
||||||
theStyle = html.getStyleSheet()
|
hStyle = html.getStyleSheet()
|
||||||
htmlDoc = (
|
htmlDoc = (
|
||||||
"<!DOCTYPE html>\n"
|
"<!DOCTYPE html>\n"
|
||||||
"<html>\n"
|
"<html>\n"
|
||||||
@@ -539,7 +539,7 @@ def testCoreToHtml_Complex(mockGUI, fncPath):
|
|||||||
"</body>\n"
|
"</body>\n"
|
||||||
"</html>\n"
|
"</html>\n"
|
||||||
).format(
|
).format(
|
||||||
htmlStyle="\n".join(theStyle),
|
htmlStyle="\n".join(hStyle),
|
||||||
bodyText="".join(resText).rstrip()
|
bodyText="".join(resText).rstrip()
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -564,7 +564,7 @@ def testCoreToHtml_Methods(mockGUI):
|
|||||||
html.doPreProcessing()
|
html.doPreProcessing()
|
||||||
html.tokenizeText()
|
html.tokenizeText()
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == (
|
assert html.result == (
|
||||||
"<p>Text with <brackets> & short–dash, long—dash …</p>\n"
|
"<p>Text with <brackets> & short–dash, long—dash …</p>\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -575,7 +575,7 @@ def testCoreToHtml_Methods(mockGUI):
|
|||||||
html.doPreProcessing()
|
html.doPreProcessing()
|
||||||
html.tokenizeText()
|
html.tokenizeText()
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theResult == (
|
assert html.result == (
|
||||||
"<p>Text with <brackets> & short–dash, long—dash …</p>\n"
|
"<p>Text with <brackets> & short–dash, long—dash …</p>\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -585,7 +585,7 @@ def testCoreToHtml_Methods(mockGUI):
|
|||||||
html.doPreProcessing()
|
html.doPreProcessing()
|
||||||
html.tokenizeText()
|
html.tokenizeText()
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.theMarkdown[-1] == (
|
assert html.allMarkdown[-1] == (
|
||||||
"Text with <brackets> & short–dash, long—dash …\n\n"
|
"Text with <brackets> & short–dash, long—dash …\n\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -168,14 +168,14 @@ def testCoreToken_TextOps(monkeypatch, mockGUI, mockRnd, fncPath):
|
|||||||
|
|
||||||
# First Page
|
# First Page
|
||||||
assert tokens.addRootHeading(C.hPlotRoot) is True
|
assert tokens.addRootHeading(C.hPlotRoot) is True
|
||||||
assert tokens.theMarkdown[-1] == "# Notes: Plot\n\n"
|
assert tokens.allMarkdown[-1] == "# Notes: Plot\n\n"
|
||||||
assert tokens._tokens[-1] == (
|
assert tokens._tokens[-1] == (
|
||||||
Tokenizer.T_TITLE, 0, "Notes: Plot", None, Tokenizer.A_CENTRE
|
Tokenizer.T_TITLE, 0, "Notes: Plot", None, Tokenizer.A_CENTRE
|
||||||
)
|
)
|
||||||
|
|
||||||
# Not First Page
|
# Not First Page
|
||||||
assert tokens.addRootHeading(C.hPlotRoot) is True
|
assert tokens.addRootHeading(C.hPlotRoot) is True
|
||||||
assert tokens.theMarkdown[-1] == "# Notes: Plot\n\n"
|
assert tokens.allMarkdown[-1] == "# Notes: Plot\n\n"
|
||||||
assert tokens._tokens[-1] == (
|
assert tokens._tokens[-1] == (
|
||||||
Tokenizer.T_TITLE, 0, "Notes: Plot", None, Tokenizer.A_CENTRE | Tokenizer.A_PBB
|
Tokenizer.T_TITLE, 0, "Notes: Plot", None, Tokenizer.A_CENTRE | Tokenizer.A_PBB
|
||||||
)
|
)
|
||||||
@@ -250,7 +250,7 @@ def testCoreToken_HeaderFormat(mockGUI):
|
|||||||
(Tokenizer.T_TITLE, 1, "Novel Title", None, Tokenizer.A_CENTRE),
|
(Tokenizer.T_TITLE, 1, "Novel Title", None, Tokenizer.A_CENTRE),
|
||||||
(Tokenizer.T_EMPTY, 1, "", None, Tokenizer.A_NONE),
|
(Tokenizer.T_EMPTY, 1, "", None, Tokenizer.A_NONE),
|
||||||
]
|
]
|
||||||
assert tokens.theMarkdown[-1] == "#! Novel Title\n\n"
|
assert tokens.allMarkdown[-1] == "#! Novel Title\n\n"
|
||||||
|
|
||||||
# Note File
|
# Note File
|
||||||
tokens._isNovel = False
|
tokens._isNovel = False
|
||||||
@@ -263,7 +263,7 @@ def testCoreToken_HeaderFormat(mockGUI):
|
|||||||
(Tokenizer.T_HEAD1, 1, "Note Title", None, Tokenizer.A_CENTRE),
|
(Tokenizer.T_HEAD1, 1, "Note Title", None, Tokenizer.A_CENTRE),
|
||||||
(Tokenizer.T_EMPTY, 1, "", None, Tokenizer.A_NONE),
|
(Tokenizer.T_EMPTY, 1, "", None, Tokenizer.A_NONE),
|
||||||
]
|
]
|
||||||
assert tokens.theMarkdown[-1] == "#! Note Title\n\n"
|
assert tokens.allMarkdown[-1] == "#! Note Title\n\n"
|
||||||
|
|
||||||
# Header 1
|
# Header 1
|
||||||
# ========
|
# ========
|
||||||
@@ -279,7 +279,7 @@ def testCoreToken_HeaderFormat(mockGUI):
|
|||||||
(Tokenizer.T_HEAD1, 1, "Novel Title", None, Tokenizer.A_CENTRE),
|
(Tokenizer.T_HEAD1, 1, "Novel Title", None, Tokenizer.A_CENTRE),
|
||||||
(Tokenizer.T_EMPTY, 1, "", None, Tokenizer.A_NONE),
|
(Tokenizer.T_EMPTY, 1, "", None, Tokenizer.A_NONE),
|
||||||
]
|
]
|
||||||
assert tokens.theMarkdown[-1] == "# Novel Title\n\n"
|
assert tokens.allMarkdown[-1] == "# Novel Title\n\n"
|
||||||
|
|
||||||
# Note File
|
# Note File
|
||||||
tokens._isNovel = False
|
tokens._isNovel = False
|
||||||
@@ -292,7 +292,7 @@ def testCoreToken_HeaderFormat(mockGUI):
|
|||||||
(Tokenizer.T_HEAD1, 1, "Note Title", None, Tokenizer.A_NONE),
|
(Tokenizer.T_HEAD1, 1, "Note Title", None, Tokenizer.A_NONE),
|
||||||
(Tokenizer.T_EMPTY, 1, "", None, Tokenizer.A_NONE),
|
(Tokenizer.T_EMPTY, 1, "", None, Tokenizer.A_NONE),
|
||||||
]
|
]
|
||||||
assert tokens.theMarkdown[-1] == "# Note Title\n\n"
|
assert tokens.allMarkdown[-1] == "# Note Title\n\n"
|
||||||
|
|
||||||
# Header 2
|
# Header 2
|
||||||
# ========
|
# ========
|
||||||
@@ -307,7 +307,7 @@ def testCoreToken_HeaderFormat(mockGUI):
|
|||||||
(Tokenizer.T_HEAD2, 1, "Chapter One", None, Tokenizer.A_PBB),
|
(Tokenizer.T_HEAD2, 1, "Chapter One", None, Tokenizer.A_PBB),
|
||||||
(Tokenizer.T_EMPTY, 1, "", None, Tokenizer.A_NONE),
|
(Tokenizer.T_EMPTY, 1, "", None, Tokenizer.A_NONE),
|
||||||
]
|
]
|
||||||
assert tokens.theMarkdown[-1] == "## Chapter One\n\n"
|
assert tokens.allMarkdown[-1] == "## Chapter One\n\n"
|
||||||
|
|
||||||
# Note File
|
# Note File
|
||||||
tokens._isNovel = False
|
tokens._isNovel = False
|
||||||
@@ -319,7 +319,7 @@ def testCoreToken_HeaderFormat(mockGUI):
|
|||||||
(Tokenizer.T_HEAD2, 1, "Heading 2", None, Tokenizer.A_NONE),
|
(Tokenizer.T_HEAD2, 1, "Heading 2", None, Tokenizer.A_NONE),
|
||||||
(Tokenizer.T_EMPTY, 1, "", None, Tokenizer.A_NONE),
|
(Tokenizer.T_EMPTY, 1, "", None, Tokenizer.A_NONE),
|
||||||
]
|
]
|
||||||
assert tokens.theMarkdown[-1] == "## Heading 2\n\n"
|
assert tokens.allMarkdown[-1] == "## Heading 2\n\n"
|
||||||
|
|
||||||
# Header 3
|
# Header 3
|
||||||
# ========
|
# ========
|
||||||
@@ -334,7 +334,7 @@ def testCoreToken_HeaderFormat(mockGUI):
|
|||||||
(Tokenizer.T_HEAD3, 1, "Scene One", None, Tokenizer.A_NONE),
|
(Tokenizer.T_HEAD3, 1, "Scene One", None, Tokenizer.A_NONE),
|
||||||
(Tokenizer.T_EMPTY, 1, "", None, Tokenizer.A_NONE),
|
(Tokenizer.T_EMPTY, 1, "", None, Tokenizer.A_NONE),
|
||||||
]
|
]
|
||||||
assert tokens.theMarkdown[-1] == "### Scene One\n\n"
|
assert tokens.allMarkdown[-1] == "### Scene One\n\n"
|
||||||
|
|
||||||
# Note File
|
# Note File
|
||||||
tokens._isNovel = False
|
tokens._isNovel = False
|
||||||
@@ -346,7 +346,7 @@ def testCoreToken_HeaderFormat(mockGUI):
|
|||||||
(Tokenizer.T_HEAD3, 1, "Heading 3", None, Tokenizer.A_NONE),
|
(Tokenizer.T_HEAD3, 1, "Heading 3", None, Tokenizer.A_NONE),
|
||||||
(Tokenizer.T_EMPTY, 1, "", None, Tokenizer.A_NONE),
|
(Tokenizer.T_EMPTY, 1, "", None, Tokenizer.A_NONE),
|
||||||
]
|
]
|
||||||
assert tokens.theMarkdown[-1] == "### Heading 3\n\n"
|
assert tokens.allMarkdown[-1] == "### Heading 3\n\n"
|
||||||
|
|
||||||
# Header 4
|
# Header 4
|
||||||
# ========
|
# ========
|
||||||
@@ -361,7 +361,7 @@ def testCoreToken_HeaderFormat(mockGUI):
|
|||||||
(Tokenizer.T_HEAD4, 1, "A Section", None, Tokenizer.A_NONE),
|
(Tokenizer.T_HEAD4, 1, "A Section", None, Tokenizer.A_NONE),
|
||||||
(Tokenizer.T_EMPTY, 1, "", None, Tokenizer.A_NONE),
|
(Tokenizer.T_EMPTY, 1, "", None, Tokenizer.A_NONE),
|
||||||
]
|
]
|
||||||
assert tokens.theMarkdown[-1] == "#### A Section\n\n"
|
assert tokens.allMarkdown[-1] == "#### A Section\n\n"
|
||||||
|
|
||||||
# Note File
|
# Note File
|
||||||
tokens._isNovel = False
|
tokens._isNovel = False
|
||||||
@@ -373,7 +373,7 @@ def testCoreToken_HeaderFormat(mockGUI):
|
|||||||
(Tokenizer.T_HEAD4, 1, "Heading 4", None, Tokenizer.A_NONE),
|
(Tokenizer.T_HEAD4, 1, "Heading 4", None, Tokenizer.A_NONE),
|
||||||
(Tokenizer.T_EMPTY, 1, "", None, Tokenizer.A_NONE),
|
(Tokenizer.T_EMPTY, 1, "", None, Tokenizer.A_NONE),
|
||||||
]
|
]
|
||||||
assert tokens.theMarkdown[-1] == "#### Heading 4\n\n"
|
assert tokens.allMarkdown[-1] == "#### Heading 4\n\n"
|
||||||
|
|
||||||
# Title
|
# Title
|
||||||
# =====
|
# =====
|
||||||
@@ -388,7 +388,7 @@ def testCoreToken_HeaderFormat(mockGUI):
|
|||||||
(Tokenizer.T_TITLE, 1, "Title", None, Tokenizer.A_CENTRE),
|
(Tokenizer.T_TITLE, 1, "Title", None, Tokenizer.A_CENTRE),
|
||||||
(Tokenizer.T_EMPTY, 1, "", None, Tokenizer.A_NONE),
|
(Tokenizer.T_EMPTY, 1, "", None, Tokenizer.A_NONE),
|
||||||
]
|
]
|
||||||
assert tokens.theMarkdown[-1] == "#! Title\n\n"
|
assert tokens.allMarkdown[-1] == "#! Title\n\n"
|
||||||
|
|
||||||
# Note File
|
# Note File
|
||||||
tokens._isNovel = False
|
tokens._isNovel = False
|
||||||
@@ -400,7 +400,7 @@ def testCoreToken_HeaderFormat(mockGUI):
|
|||||||
(Tokenizer.T_HEAD1, 1, "Title", None, Tokenizer.A_CENTRE),
|
(Tokenizer.T_HEAD1, 1, "Title", None, Tokenizer.A_CENTRE),
|
||||||
(Tokenizer.T_EMPTY, 1, "", None, Tokenizer.A_NONE),
|
(Tokenizer.T_EMPTY, 1, "", None, Tokenizer.A_NONE),
|
||||||
]
|
]
|
||||||
assert tokens.theMarkdown[-1] == "#! Title\n\n"
|
assert tokens.allMarkdown[-1] == "#! Title\n\n"
|
||||||
|
|
||||||
# Unnumbered
|
# Unnumbered
|
||||||
# ==========
|
# ==========
|
||||||
@@ -415,7 +415,7 @@ def testCoreToken_HeaderFormat(mockGUI):
|
|||||||
(Tokenizer.T_UNNUM, 1, "Prologue", None, Tokenizer.A_PBB),
|
(Tokenizer.T_UNNUM, 1, "Prologue", None, Tokenizer.A_PBB),
|
||||||
(Tokenizer.T_EMPTY, 1, "", None, Tokenizer.A_NONE),
|
(Tokenizer.T_EMPTY, 1, "", None, Tokenizer.A_NONE),
|
||||||
]
|
]
|
||||||
assert tokens.theMarkdown[-1] == "##! Prologue\n\n"
|
assert tokens.allMarkdown[-1] == "##! Prologue\n\n"
|
||||||
|
|
||||||
# Note File
|
# Note File
|
||||||
tokens._isNovel = False
|
tokens._isNovel = False
|
||||||
@@ -427,7 +427,7 @@ def testCoreToken_HeaderFormat(mockGUI):
|
|||||||
(Tokenizer.T_HEAD2, 1, "Prologue", None, Tokenizer.A_NONE),
|
(Tokenizer.T_HEAD2, 1, "Prologue", None, Tokenizer.A_NONE),
|
||||||
(Tokenizer.T_EMPTY, 1, "", None, Tokenizer.A_NONE),
|
(Tokenizer.T_EMPTY, 1, "", None, Tokenizer.A_NONE),
|
||||||
]
|
]
|
||||||
assert tokens.theMarkdown[-1] == "##! Prologue\n\n"
|
assert tokens.allMarkdown[-1] == "##! Prologue\n\n"
|
||||||
|
|
||||||
# END Test testCoreToken_HeaderFormat
|
# END Test testCoreToken_HeaderFormat
|
||||||
|
|
||||||
@@ -446,11 +446,11 @@ def testCoreToken_MetaFormat(mockGUI):
|
|||||||
(Tokenizer.T_COMMENT, 0, "A comment", None, Tokenizer.A_NONE),
|
(Tokenizer.T_COMMENT, 0, "A comment", None, Tokenizer.A_NONE),
|
||||||
(Tokenizer.T_EMPTY, 0, "", None, Tokenizer.A_NONE),
|
(Tokenizer.T_EMPTY, 0, "", None, Tokenizer.A_NONE),
|
||||||
]
|
]
|
||||||
assert tokens.theMarkdown[-1] == "\n"
|
assert tokens.allMarkdown[-1] == "\n"
|
||||||
|
|
||||||
tokens.setComments(True)
|
tokens.setComments(True)
|
||||||
tokens.tokenizeText()
|
tokens.tokenizeText()
|
||||||
assert tokens.theMarkdown[-1] == "% A comment\n\n"
|
assert tokens.allMarkdown[-1] == "% A comment\n\n"
|
||||||
|
|
||||||
# Synopsis
|
# Synopsis
|
||||||
tokens._text = "%synopsis: The synopsis\n"
|
tokens._text = "%synopsis: The synopsis\n"
|
||||||
@@ -465,11 +465,11 @@ def testCoreToken_MetaFormat(mockGUI):
|
|||||||
(Tokenizer.T_SYNOPSIS, 0, "The synopsis", None, Tokenizer.A_NONE),
|
(Tokenizer.T_SYNOPSIS, 0, "The synopsis", None, Tokenizer.A_NONE),
|
||||||
(Tokenizer.T_EMPTY, 0, "", None, Tokenizer.A_NONE),
|
(Tokenizer.T_EMPTY, 0, "", None, Tokenizer.A_NONE),
|
||||||
]
|
]
|
||||||
assert tokens.theMarkdown[-1] == "\n"
|
assert tokens.allMarkdown[-1] == "\n"
|
||||||
|
|
||||||
tokens.setSynopsis(True)
|
tokens.setSynopsis(True)
|
||||||
tokens.tokenizeText()
|
tokens.tokenizeText()
|
||||||
assert tokens.theMarkdown[-1] == "% synopsis: The synopsis\n\n"
|
assert tokens.allMarkdown[-1] == "% synopsis: The synopsis\n\n"
|
||||||
|
|
||||||
# Short
|
# Short
|
||||||
tokens.setSynopsis(False)
|
tokens.setSynopsis(False)
|
||||||
@@ -479,11 +479,11 @@ def testCoreToken_MetaFormat(mockGUI):
|
|||||||
(Tokenizer.T_SHORT, 0, "A short description", None, Tokenizer.A_NONE),
|
(Tokenizer.T_SHORT, 0, "A short description", None, Tokenizer.A_NONE),
|
||||||
(Tokenizer.T_EMPTY, 0, "", None, Tokenizer.A_NONE),
|
(Tokenizer.T_EMPTY, 0, "", None, Tokenizer.A_NONE),
|
||||||
]
|
]
|
||||||
assert tokens.theMarkdown[-1] == "\n"
|
assert tokens.allMarkdown[-1] == "\n"
|
||||||
|
|
||||||
tokens.setSynopsis(True)
|
tokens.setSynopsis(True)
|
||||||
tokens.tokenizeText()
|
tokens.tokenizeText()
|
||||||
assert tokens.theMarkdown[-1] == "% short: A short description\n\n"
|
assert tokens.allMarkdown[-1] == "% short: A short description\n\n"
|
||||||
|
|
||||||
# Keyword
|
# Keyword
|
||||||
tokens._text = "@char: Bod\n"
|
tokens._text = "@char: Bod\n"
|
||||||
@@ -492,11 +492,11 @@ def testCoreToken_MetaFormat(mockGUI):
|
|||||||
(Tokenizer.T_KEYWORD, 0, "char: Bod", None, Tokenizer.A_NONE),
|
(Tokenizer.T_KEYWORD, 0, "char: Bod", None, Tokenizer.A_NONE),
|
||||||
(Tokenizer.T_EMPTY, 0, "", None, Tokenizer.A_NONE),
|
(Tokenizer.T_EMPTY, 0, "", None, Tokenizer.A_NONE),
|
||||||
]
|
]
|
||||||
assert tokens.theMarkdown[-1] == "\n"
|
assert tokens.allMarkdown[-1] == "\n"
|
||||||
|
|
||||||
tokens.setKeywords(True)
|
tokens.setKeywords(True)
|
||||||
tokens.tokenizeText()
|
tokens.tokenizeText()
|
||||||
assert tokens.theMarkdown[-1] == "@char: Bod\n\n"
|
assert tokens.allMarkdown[-1] == "@char: Bod\n\n"
|
||||||
|
|
||||||
tokens._text = "@pov: Bod\n@plot: Main\n@location: Europe\n"
|
tokens._text = "@pov: Bod\n@plot: Main\n@location: Europe\n"
|
||||||
tokens.tokenizeText()
|
tokens.tokenizeText()
|
||||||
@@ -509,7 +509,7 @@ def testCoreToken_MetaFormat(mockGUI):
|
|||||||
(Tokenizer.T_KEYWORD, 0, "location: Europe", None, styBtm),
|
(Tokenizer.T_KEYWORD, 0, "location: Europe", None, styBtm),
|
||||||
(Tokenizer.T_EMPTY, 0, "", None, Tokenizer.A_NONE),
|
(Tokenizer.T_EMPTY, 0, "", None, Tokenizer.A_NONE),
|
||||||
]
|
]
|
||||||
assert tokens.theMarkdown[-1] == "@pov: Bod\n@plot: Main\n@location: Europe\n\n"
|
assert tokens.allMarkdown[-1] == "@pov: Bod\n@plot: Main\n@location: Europe\n\n"
|
||||||
|
|
||||||
# END Test testCoreToken_MetaFormat
|
# END Test testCoreToken_MetaFormat
|
||||||
|
|
||||||
@@ -554,7 +554,7 @@ def testCoreToken_MarginFormat(mockGUI):
|
|||||||
(Tokenizer.T_EMPTY, 0, "", None, Tokenizer.A_NONE),
|
(Tokenizer.T_EMPTY, 0, "", None, Tokenizer.A_NONE),
|
||||||
(Tokenizer.T_EMPTY, 0, "", None, Tokenizer.A_NONE),
|
(Tokenizer.T_EMPTY, 0, "", None, Tokenizer.A_NONE),
|
||||||
]
|
]
|
||||||
assert tokens.theMarkdown[-1] == (
|
assert tokens.allMarkdown[-1] == (
|
||||||
"Some regular text\n\n"
|
"Some regular text\n\n"
|
||||||
"Some left-aligned text\n\n"
|
"Some left-aligned text\n\n"
|
||||||
"Some right-aligned text\n\n"
|
"Some right-aligned text\n\n"
|
||||||
@@ -676,7 +676,7 @@ def testCoreToken_TextFormat(mockGUI):
|
|||||||
(Tokenizer.T_EMPTY, 0, "", None, Tokenizer.A_NONE),
|
(Tokenizer.T_EMPTY, 0, "", None, Tokenizer.A_NONE),
|
||||||
(Tokenizer.T_EMPTY, 0, "", None, Tokenizer.A_NONE),
|
(Tokenizer.T_EMPTY, 0, "", None, Tokenizer.A_NONE),
|
||||||
]
|
]
|
||||||
assert tokens.theMarkdown[-1] == "Some plain text\non two lines\n\n\n\n"
|
assert tokens.allMarkdown[-1] == "Some plain text\non two lines\n\n\n\n"
|
||||||
|
|
||||||
tokens.setBodyText(False)
|
tokens.setBodyText(False)
|
||||||
tokens.tokenizeText()
|
tokens.tokenizeText()
|
||||||
@@ -685,7 +685,7 @@ def testCoreToken_TextFormat(mockGUI):
|
|||||||
(Tokenizer.T_EMPTY, 0, "", None, Tokenizer.A_NONE),
|
(Tokenizer.T_EMPTY, 0, "", None, Tokenizer.A_NONE),
|
||||||
(Tokenizer.T_EMPTY, 0, "", None, Tokenizer.A_NONE),
|
(Tokenizer.T_EMPTY, 0, "", None, Tokenizer.A_NONE),
|
||||||
]
|
]
|
||||||
assert tokens.theMarkdown[-1] == "\n\n\n"
|
assert tokens.allMarkdown[-1] == "\n\n\n"
|
||||||
tokens.setBodyText(True)
|
tokens.setBodyText(True)
|
||||||
|
|
||||||
# Text Emphasis
|
# Text Emphasis
|
||||||
@@ -703,7 +703,7 @@ def testCoreToken_TextFormat(mockGUI):
|
|||||||
),
|
),
|
||||||
(Tokenizer.T_EMPTY, 0, "", None, Tokenizer.A_NONE),
|
(Tokenizer.T_EMPTY, 0, "", None, Tokenizer.A_NONE),
|
||||||
]
|
]
|
||||||
assert tokens.theMarkdown[-1] == "Some **bolded text** on this lines\n\n"
|
assert tokens.allMarkdown[-1] == "Some **bolded text** on this lines\n\n"
|
||||||
|
|
||||||
tokens._text = "Some _italic text_ on this lines\n"
|
tokens._text = "Some _italic text_ on this lines\n"
|
||||||
tokens.tokenizeText()
|
tokens.tokenizeText()
|
||||||
@@ -719,7 +719,7 @@ def testCoreToken_TextFormat(mockGUI):
|
|||||||
),
|
),
|
||||||
(Tokenizer.T_EMPTY, 0, "", None, Tokenizer.A_NONE),
|
(Tokenizer.T_EMPTY, 0, "", None, Tokenizer.A_NONE),
|
||||||
]
|
]
|
||||||
assert tokens.theMarkdown[-1] == "Some _italic text_ on this lines\n\n"
|
assert tokens.allMarkdown[-1] == "Some _italic text_ on this lines\n\n"
|
||||||
|
|
||||||
tokens._text = "Some **_bold italic text_** on this lines\n"
|
tokens._text = "Some **_bold italic text_** on this lines\n"
|
||||||
tokens.tokenizeText()
|
tokens.tokenizeText()
|
||||||
@@ -737,7 +737,7 @@ def testCoreToken_TextFormat(mockGUI):
|
|||||||
),
|
),
|
||||||
(Tokenizer.T_EMPTY, 0, "", None, Tokenizer.A_NONE),
|
(Tokenizer.T_EMPTY, 0, "", None, Tokenizer.A_NONE),
|
||||||
]
|
]
|
||||||
assert tokens.theMarkdown[-1] == "Some **_bold italic text_** on this lines\n\n"
|
assert tokens.allMarkdown[-1] == "Some **_bold italic text_** on this lines\n\n"
|
||||||
|
|
||||||
tokens._text = "Some ~~strikethrough text~~ on this lines\n"
|
tokens._text = "Some ~~strikethrough text~~ on this lines\n"
|
||||||
tokens.tokenizeText()
|
tokens.tokenizeText()
|
||||||
@@ -753,7 +753,7 @@ def testCoreToken_TextFormat(mockGUI):
|
|||||||
),
|
),
|
||||||
(Tokenizer.T_EMPTY, 0, "", None, Tokenizer.A_NONE),
|
(Tokenizer.T_EMPTY, 0, "", None, Tokenizer.A_NONE),
|
||||||
]
|
]
|
||||||
assert tokens.theMarkdown[-1] == "Some ~~strikethrough text~~ on this lines\n\n"
|
assert tokens.allMarkdown[-1] == "Some ~~strikethrough text~~ on this lines\n\n"
|
||||||
|
|
||||||
tokens._text = "Some **nested bold and _italic_ and ~~strikethrough~~ text** here\n"
|
tokens._text = "Some **nested bold and _italic_ and ~~strikethrough~~ text** here\n"
|
||||||
tokens.tokenizeText()
|
tokens.tokenizeText()
|
||||||
@@ -773,7 +773,7 @@ def testCoreToken_TextFormat(mockGUI):
|
|||||||
),
|
),
|
||||||
(Tokenizer.T_EMPTY, 0, "", None, Tokenizer.A_NONE),
|
(Tokenizer.T_EMPTY, 0, "", None, Tokenizer.A_NONE),
|
||||||
]
|
]
|
||||||
assert tokens.theMarkdown[-1] == (
|
assert tokens.allMarkdown[-1] == (
|
||||||
"Some **nested bold and _italic_ and ~~strikethrough~~ text** here\n\n"
|
"Some **nested bold and _italic_ and ~~strikethrough~~ text** here\n\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+122
-122
@@ -33,127 +33,127 @@ def testCoreToMarkdown_ConvertFormat(mockGUI):
|
|||||||
"""Test the tokenizer and converter chain using the ToMarkdown
|
"""Test the tokenizer and converter chain using the ToMarkdown
|
||||||
class.
|
class.
|
||||||
"""
|
"""
|
||||||
theProject = NWProject()
|
project = NWProject()
|
||||||
theMD = ToMarkdown(theProject)
|
toMD = ToMarkdown(project)
|
||||||
|
|
||||||
# Headers
|
# Headers
|
||||||
# =======
|
# =======
|
||||||
|
|
||||||
theMD._isNovel = True
|
toMD._isNovel = True
|
||||||
theMD._isNote = False
|
toMD._isNote = False
|
||||||
theMD._isFirst = True
|
toMD._isFirst = True
|
||||||
|
|
||||||
# Header 1
|
# Header 1
|
||||||
theMD._text = "# Partition\n"
|
toMD._text = "# Partition\n"
|
||||||
theMD.tokenizeText()
|
toMD.tokenizeText()
|
||||||
theMD.doConvert()
|
toMD.doConvert()
|
||||||
assert theMD.theResult == "# Partition\n\n"
|
assert toMD.result == "# Partition\n\n"
|
||||||
|
|
||||||
# Header 2
|
# Header 2
|
||||||
theMD._text = "## Chapter Title\n"
|
toMD._text = "## Chapter Title\n"
|
||||||
theMD.tokenizeText()
|
toMD.tokenizeText()
|
||||||
theMD.doConvert()
|
toMD.doConvert()
|
||||||
assert theMD.theResult == "## Chapter Title\n\n"
|
assert toMD.result == "## Chapter Title\n\n"
|
||||||
|
|
||||||
# Header 3
|
# Header 3
|
||||||
theMD._text = "### Scene Title\n"
|
toMD._text = "### Scene Title\n"
|
||||||
theMD.tokenizeText()
|
toMD.tokenizeText()
|
||||||
theMD.doConvert()
|
toMD.doConvert()
|
||||||
assert theMD.theResult == "### Scene Title\n\n"
|
assert toMD.result == "### Scene Title\n\n"
|
||||||
|
|
||||||
# Header 4
|
# Header 4
|
||||||
theMD._text = "#### Section Title\n"
|
toMD._text = "#### Section Title\n"
|
||||||
theMD.tokenizeText()
|
toMD.tokenizeText()
|
||||||
theMD.doConvert()
|
toMD.doConvert()
|
||||||
assert theMD.theResult == "#### Section Title\n\n"
|
assert toMD.result == "#### Section Title\n\n"
|
||||||
|
|
||||||
# Title
|
# Title
|
||||||
theMD._text = "#! Title\n"
|
toMD._text = "#! Title\n"
|
||||||
theMD.tokenizeText()
|
toMD.tokenizeText()
|
||||||
theMD.doConvert()
|
toMD.doConvert()
|
||||||
assert theMD.theResult == "# Title\n\n"
|
assert toMD.result == "# Title\n\n"
|
||||||
|
|
||||||
# Unnumbered
|
# Unnumbered
|
||||||
theMD._text = "##! Prologue\n"
|
toMD._text = "##! Prologue\n"
|
||||||
theMD.tokenizeText()
|
toMD.tokenizeText()
|
||||||
theMD.doConvert()
|
toMD.doConvert()
|
||||||
assert theMD.theResult == "## Prologue\n\n"
|
assert toMD.result == "## Prologue\n\n"
|
||||||
|
|
||||||
# Paragraphs
|
# Paragraphs
|
||||||
# ==========
|
# ==========
|
||||||
|
|
||||||
# Text for Extended Markdown
|
# Text for Extended Markdown
|
||||||
theMD.setExtendedMarkdown()
|
toMD.setExtendedMarkdown()
|
||||||
theMD._text = "Some **nested bold and _italic_ and ~~strikethrough~~ text** here\n"
|
toMD._text = "Some **nested bold and _italic_ and ~~strikethrough~~ text** here\n"
|
||||||
theMD.tokenizeText()
|
toMD.tokenizeText()
|
||||||
theMD.doConvert()
|
toMD.doConvert()
|
||||||
assert theMD.theResult == (
|
assert toMD.result == (
|
||||||
"Some **nested bold and _italic_ and ~~strikethrough~~ text** here\n\n"
|
"Some **nested bold and _italic_ and ~~strikethrough~~ text** here\n\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Text for Standard Markdown
|
# Text for Standard Markdown
|
||||||
theMD.setStandardMarkdown()
|
toMD.setStandardMarkdown()
|
||||||
theMD._text = "Some **nested bold and _italic_ and ~~strikethrough~~ text** here\n"
|
toMD._text = "Some **nested bold and _italic_ and ~~strikethrough~~ text** here\n"
|
||||||
theMD.tokenizeText()
|
toMD.tokenizeText()
|
||||||
theMD.doConvert()
|
toMD.doConvert()
|
||||||
assert theMD.theResult == (
|
assert toMD.result == (
|
||||||
"Some **nested bold and _italic_ and strikethrough text** here\n\n"
|
"Some **nested bold and _italic_ and strikethrough text** here\n\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Text w/Hard Break
|
# Text w/Hard Break
|
||||||
theMD._text = "Line one \nLine two \nLine three\n"
|
toMD._text = "Line one \nLine two \nLine three\n"
|
||||||
theMD.tokenizeText()
|
toMD.tokenizeText()
|
||||||
theMD.doConvert()
|
toMD.doConvert()
|
||||||
assert theMD.theResult == "Line one \nLine two \nLine three\n\n"
|
assert toMD.result == "Line one \nLine two \nLine three\n\n"
|
||||||
|
|
||||||
# Synopsis, Short
|
# Synopsis, Short
|
||||||
theMD._text = "%synopsis: The synopsis ...\n"
|
toMD._text = "%synopsis: The synopsis ...\n"
|
||||||
theMD.tokenizeText()
|
toMD.tokenizeText()
|
||||||
theMD.doConvert()
|
toMD.doConvert()
|
||||||
assert theMD.theResult == ""
|
assert toMD.result == ""
|
||||||
|
|
||||||
theMD.setSynopsis(True)
|
toMD.setSynopsis(True)
|
||||||
theMD._text = "%synopsis: The synopsis ...\n"
|
toMD._text = "%synopsis: The synopsis ...\n"
|
||||||
theMD.tokenizeText()
|
toMD.tokenizeText()
|
||||||
theMD.doConvert()
|
toMD.doConvert()
|
||||||
assert theMD.theResult == "**Synopsis:** The synopsis ...\n\n"
|
assert toMD.result == "**Synopsis:** The synopsis ...\n\n"
|
||||||
|
|
||||||
theMD.setSynopsis(True)
|
toMD.setSynopsis(True)
|
||||||
theMD._text = "%short: A description ...\n"
|
toMD._text = "%short: A description ...\n"
|
||||||
theMD.tokenizeText()
|
toMD.tokenizeText()
|
||||||
theMD.doConvert()
|
toMD.doConvert()
|
||||||
assert theMD.theResult == "**Short Description:** A description ...\n\n"
|
assert toMD.result == "**Short Description:** A description ...\n\n"
|
||||||
|
|
||||||
# Comment
|
# Comment
|
||||||
theMD._text = "% A comment ...\n"
|
toMD._text = "% A comment ...\n"
|
||||||
theMD.tokenizeText()
|
toMD.tokenizeText()
|
||||||
theMD.doConvert()
|
toMD.doConvert()
|
||||||
assert theMD.theResult == ""
|
assert toMD.result == ""
|
||||||
|
|
||||||
theMD.setComments(True)
|
toMD.setComments(True)
|
||||||
theMD._text = "% A comment ...\n"
|
toMD._text = "% A comment ...\n"
|
||||||
theMD.tokenizeText()
|
toMD.tokenizeText()
|
||||||
theMD.doConvert()
|
toMD.doConvert()
|
||||||
assert theMD.theResult == "**Comment:** A comment ...\n\n"
|
assert toMD.result == "**Comment:** A comment ...\n\n"
|
||||||
|
|
||||||
# Keywords
|
# Keywords
|
||||||
theMD._text = "@char: Bod, Jane\n"
|
toMD._text = "@char: Bod, Jane\n"
|
||||||
theMD.tokenizeText()
|
toMD.tokenizeText()
|
||||||
theMD.doConvert()
|
toMD.doConvert()
|
||||||
assert theMD.theResult == ""
|
assert toMD.result == ""
|
||||||
|
|
||||||
theMD.setKeywords(True)
|
toMD.setKeywords(True)
|
||||||
theMD._text = "@char: Bod, Jane\n"
|
toMD._text = "@char: Bod, Jane\n"
|
||||||
theMD.tokenizeText()
|
toMD.tokenizeText()
|
||||||
theMD.doConvert()
|
toMD.doConvert()
|
||||||
assert theMD.theResult == "**Characters:** Bod, Jane\n\n"
|
assert toMD.result == "**Characters:** Bod, Jane\n\n"
|
||||||
|
|
||||||
# Multiple Keywords
|
# Multiple Keywords
|
||||||
theMD.setKeywords(True)
|
toMD.setKeywords(True)
|
||||||
theMD._text = "## Chapter\n\n@pov: Bod\n@plot: Main\n@location: Europe\n\n"
|
toMD._text = "## Chapter\n\n@pov: Bod\n@plot: Main\n@location: Europe\n\n"
|
||||||
theMD.tokenizeText()
|
toMD.tokenizeText()
|
||||||
theMD.doConvert()
|
toMD.doConvert()
|
||||||
assert theMD.theResult == (
|
assert toMD.result == (
|
||||||
"## Chapter\n\n"
|
"## Chapter\n\n"
|
||||||
"**Point of View:** Bod \n"
|
"**Point of View:** Bod \n"
|
||||||
"**Plot:** Main \n"
|
"**Plot:** Main \n"
|
||||||
@@ -166,49 +166,49 @@ def testCoreToMarkdown_ConvertFormat(mockGUI):
|
|||||||
@pytest.mark.core
|
@pytest.mark.core
|
||||||
def testCoreToMarkdown_ConvertDirect(mockGUI):
|
def testCoreToMarkdown_ConvertDirect(mockGUI):
|
||||||
"""Test the converter directly using the ToMarkdown class."""
|
"""Test the converter directly using the ToMarkdown class."""
|
||||||
theProject = NWProject()
|
project = NWProject()
|
||||||
theMD = ToMarkdown(theProject)
|
toMD = ToMarkdown(project)
|
||||||
|
|
||||||
theMD._isNovel = True
|
toMD._isNovel = True
|
||||||
theMD._isNote = False
|
toMD._isNote = False
|
||||||
|
|
||||||
# Special Titles
|
# Special Titles
|
||||||
# ==============
|
# ==============
|
||||||
|
|
||||||
# Title
|
# Title
|
||||||
theMD._tokens = [
|
toMD._tokens = [
|
||||||
(theMD.T_TITLE, 1, "A Title", None, theMD.A_PBB | theMD.A_CENTRE),
|
(toMD.T_TITLE, 1, "A Title", None, toMD.A_PBB | toMD.A_CENTRE),
|
||||||
(theMD.T_EMPTY, 1, "", None, theMD.A_NONE),
|
(toMD.T_EMPTY, 1, "", None, toMD.A_NONE),
|
||||||
]
|
]
|
||||||
theMD.doConvert()
|
toMD.doConvert()
|
||||||
assert theMD.theResult == "# A Title\n\n"
|
assert toMD.result == "# A Title\n\n"
|
||||||
|
|
||||||
# Unnumbered
|
# Unnumbered
|
||||||
theMD._tokens = [
|
toMD._tokens = [
|
||||||
(theMD.T_UNNUM, 1, "Prologue", None, theMD.A_PBB),
|
(toMD.T_UNNUM, 1, "Prologue", None, toMD.A_PBB),
|
||||||
(theMD.T_EMPTY, 1, "", None, theMD.A_NONE),
|
(toMD.T_EMPTY, 1, "", None, toMD.A_NONE),
|
||||||
]
|
]
|
||||||
theMD.doConvert()
|
toMD.doConvert()
|
||||||
assert theMD.theResult == "## Prologue\n\n"
|
assert toMD.result == "## Prologue\n\n"
|
||||||
|
|
||||||
# Separators
|
# Separators
|
||||||
# ==========
|
# ==========
|
||||||
|
|
||||||
# Separator
|
# Separator
|
||||||
theMD._tokens = [
|
toMD._tokens = [
|
||||||
(theMD.T_SEP, 1, "* * *", None, theMD.A_CENTRE),
|
(toMD.T_SEP, 1, "* * *", None, toMD.A_CENTRE),
|
||||||
(theMD.T_EMPTY, 1, "", None, theMD.A_NONE),
|
(toMD.T_EMPTY, 1, "", None, toMD.A_NONE),
|
||||||
]
|
]
|
||||||
theMD.doConvert()
|
toMD.doConvert()
|
||||||
assert theMD.theResult == "* * *\n\n"
|
assert toMD.result == "* * *\n\n"
|
||||||
|
|
||||||
# Skip
|
# Skip
|
||||||
theMD._tokens = [
|
toMD._tokens = [
|
||||||
(theMD.T_SKIP, 1, "", None, theMD.A_NONE),
|
(toMD.T_SKIP, 1, "", None, toMD.A_NONE),
|
||||||
(theMD.T_EMPTY, 1, "", None, theMD.A_NONE),
|
(toMD.T_EMPTY, 1, "", None, toMD.A_NONE),
|
||||||
]
|
]
|
||||||
theMD.doConvert()
|
toMD.doConvert()
|
||||||
assert theMD.theResult == "\n\n\n"
|
assert toMD.result == "\n\n\n"
|
||||||
|
|
||||||
# END Test testCoreToMarkdown_ConvertDirect
|
# END Test testCoreToMarkdown_ConvertDirect
|
||||||
|
|
||||||
@@ -216,9 +216,9 @@ def testCoreToMarkdown_ConvertDirect(mockGUI):
|
|||||||
@pytest.mark.core
|
@pytest.mark.core
|
||||||
def testCoreToMarkdown_Complex(mockGUI, fncPath):
|
def testCoreToMarkdown_Complex(mockGUI, fncPath):
|
||||||
"""Test the save method of the ToMarkdown class."""
|
"""Test the save method of the ToMarkdown class."""
|
||||||
theProject = NWProject()
|
project = NWProject()
|
||||||
theMD = ToMarkdown(theProject)
|
toMD = ToMarkdown(project)
|
||||||
theMD._isNovel = True
|
toMD._isNovel = True
|
||||||
|
|
||||||
# Build Project
|
# Build Project
|
||||||
# =============
|
# =============
|
||||||
@@ -243,23 +243,23 @@ def testCoreToMarkdown_Complex(mockGUI, fncPath):
|
|||||||
]
|
]
|
||||||
|
|
||||||
for i in range(len(docText)):
|
for i in range(len(docText)):
|
||||||
theMD._text = docText[i]
|
toMD._text = docText[i]
|
||||||
theMD.doPreProcessing()
|
toMD.doPreProcessing()
|
||||||
theMD.tokenizeText()
|
toMD.tokenizeText()
|
||||||
theMD.doConvert()
|
toMD.doConvert()
|
||||||
assert theMD.theResult == resText[i]
|
assert toMD.result == resText[i]
|
||||||
|
|
||||||
assert theMD.fullMD == resText
|
assert toMD.fullMD == resText
|
||||||
assert theMD.getFullResultSize() == len("".join(resText))
|
assert toMD.getFullResultSize() == len("".join(resText))
|
||||||
|
|
||||||
theMD.replaceTabs(nSpaces=4, spaceChar=" ")
|
toMD.replaceTabs(nSpaces=4, spaceChar=" ")
|
||||||
resText[6] = "#### A Section\n\n More text in scene two.\n\n"
|
resText[6] = "#### A Section\n\n More text in scene two.\n\n"
|
||||||
|
|
||||||
# Check File
|
# Check File
|
||||||
# ==========
|
# ==========
|
||||||
|
|
||||||
saveFile = fncPath / "outFile.md"
|
saveFile = fncPath / "outFile.md"
|
||||||
theMD.saveMarkdown(saveFile)
|
toMD.saveMarkdown(saveFile)
|
||||||
assert readFile(saveFile) == "".join(resText)
|
assert readFile(saveFile) == "".join(resText)
|
||||||
|
|
||||||
# END Test testCoreToHtml_Complex
|
# END Test testCoreToHtml_Complex
|
||||||
@@ -268,12 +268,12 @@ def testCoreToMarkdown_Complex(mockGUI, fncPath):
|
|||||||
@pytest.mark.core
|
@pytest.mark.core
|
||||||
def testCoreToMarkdown_Format(mockGUI):
|
def testCoreToMarkdown_Format(mockGUI):
|
||||||
"""Test all the formatters for the ToMarkdown class."""
|
"""Test all the formatters for the ToMarkdown class."""
|
||||||
theProject = NWProject()
|
project = NWProject()
|
||||||
theMD = ToMarkdown(theProject)
|
toMD = ToMarkdown(project)
|
||||||
|
|
||||||
assert theMD._formatKeywords("", theMD.A_NONE) == ""
|
assert toMD._formatKeywords("", toMD.A_NONE) == ""
|
||||||
assert theMD._formatKeywords("tag: Jane", theMD.A_NONE) == "**Tag:** Jane\n\n"
|
assert toMD._formatKeywords("tag: Jane", toMD.A_NONE) == "**Tag:** Jane\n\n"
|
||||||
assert theMD._formatKeywords("tag: Jane, John", theMD.A_NONE) == "**Tag:** Jane, John\n\n"
|
assert toMD._formatKeywords("tag: Jane, John", toMD.A_NONE) == "**Tag:** Jane, John\n\n"
|
||||||
assert theMD._formatKeywords("tag: Jane", theMD.A_Z_BTMMRG) == "**Tag:** Jane \n"
|
assert toMD._formatKeywords("tag: Jane", toMD.A_Z_BTMMRG) == "**Tag:** Jane \n"
|
||||||
|
|
||||||
# END Test testCoreToMarkdown_Format
|
# END Test testCoreToMarkdown_Format
|
||||||
|
|||||||
@@ -134,9 +134,9 @@ def testCoreToOdt_TextFormatting(mockGUI):
|
|||||||
"Heading_20_1", "Heading_20_2", "Heading_20_3", "Heading_20_4", "Header",
|
"Heading_20_1", "Heading_20_2", "Heading_20_3", "Heading_20_4", "Header",
|
||||||
]
|
]
|
||||||
|
|
||||||
theKey = "071d6b2e4764749f8c78d3c1ab9099fa04c07d2d53fd3de61eb1bdf1cb4845c3"
|
key = "071d6b2e4764749f8c78d3c1ab9099fa04c07d2d53fd3de61eb1bdf1cb4845c3"
|
||||||
assert odt._autoPara[theKey][0] == "P1"
|
assert odt._autoPara[key][0] == "P1"
|
||||||
assert isinstance(odt._autoPara[theKey][1], ODTParagraphStyle)
|
assert isinstance(odt._autoPara[key][1], ODTParagraphStyle)
|
||||||
|
|
||||||
# Paragraph Formatting
|
# Paragraph Formatting
|
||||||
# ====================
|
# ====================
|
||||||
@@ -624,48 +624,48 @@ def testCoreToOdt_ConvertDirect(mockGUI):
|
|||||||
"""Test the converter directly using the ToOdt class to reach some
|
"""Test the converter directly using the ToOdt class to reach some
|
||||||
otherwise hard to reach conditions.
|
otherwise hard to reach conditions.
|
||||||
"""
|
"""
|
||||||
theProject = NWProject()
|
project = NWProject()
|
||||||
theDoc = ToOdt(theProject, isFlat=True)
|
doc = ToOdt(project, isFlat=True)
|
||||||
|
|
||||||
theDoc._isNovel = True
|
doc._isNovel = True
|
||||||
|
|
||||||
# Justified
|
# Justified
|
||||||
theDoc = ToOdt(theProject, isFlat=True)
|
doc = ToOdt(project, isFlat=True)
|
||||||
theDoc._tokens = [
|
doc._tokens = [
|
||||||
(theDoc.T_TEXT, 1, "This is a paragraph", [], theDoc.A_JUSTIFY),
|
(doc.T_TEXT, 1, "This is a paragraph", [], doc.A_JUSTIFY),
|
||||||
(theDoc.T_EMPTY, 1, "", None, theDoc.A_NONE),
|
(doc.T_EMPTY, 1, "", None, doc.A_NONE),
|
||||||
]
|
]
|
||||||
theDoc.initDocument()
|
doc.initDocument()
|
||||||
theDoc.doConvert()
|
doc.doConvert()
|
||||||
theDoc.closeDocument()
|
doc.closeDocument()
|
||||||
assert (
|
assert (
|
||||||
'<style:style style:name="P1" style:family="paragraph" '
|
'<style:style style:name="P1" style:family="paragraph" '
|
||||||
'style:parent-style-name="Text_20_body">'
|
'style:parent-style-name="Text_20_body">'
|
||||||
'<style:paragraph-properties fo:text-align="justify" />'
|
'<style:paragraph-properties fo:text-align="justify" />'
|
||||||
'</style:style>'
|
'</style:style>'
|
||||||
) in xmlToText(theDoc._xAuto)
|
) in xmlToText(doc._xAuto)
|
||||||
assert xmlToText(theDoc._xText) == (
|
assert xmlToText(doc._xText) == (
|
||||||
'<office:text>'
|
'<office:text>'
|
||||||
'<text:p text:style-name="P1">This is a paragraph</text:p>'
|
'<text:p text:style-name="P1">This is a paragraph</text:p>'
|
||||||
'</office:text>'
|
'</office:text>'
|
||||||
)
|
)
|
||||||
|
|
||||||
# Page Break After
|
# Page Break After
|
||||||
theDoc = ToOdt(theProject, isFlat=True)
|
doc = ToOdt(project, isFlat=True)
|
||||||
theDoc._tokens = [
|
doc._tokens = [
|
||||||
(theDoc.T_TEXT, 1, "This is a paragraph", [], theDoc.A_PBA),
|
(doc.T_TEXT, 1, "This is a paragraph", [], doc.A_PBA),
|
||||||
(theDoc.T_EMPTY, 1, "", None, theDoc.A_NONE),
|
(doc.T_EMPTY, 1, "", None, doc.A_NONE),
|
||||||
]
|
]
|
||||||
theDoc.initDocument()
|
doc.initDocument()
|
||||||
theDoc.doConvert()
|
doc.doConvert()
|
||||||
theDoc.closeDocument()
|
doc.closeDocument()
|
||||||
assert (
|
assert (
|
||||||
'<style:style style:name="P1" style:family="paragraph" '
|
'<style:style style:name="P1" style:family="paragraph" '
|
||||||
'style:parent-style-name="Text_20_body">'
|
'style:parent-style-name="Text_20_body">'
|
||||||
'<style:paragraph-properties fo:break-after="page" />'
|
'<style:paragraph-properties fo:break-after="page" />'
|
||||||
'</style:style>'
|
'</style:style>'
|
||||||
) in xmlToText(theDoc._xAuto)
|
) in xmlToText(doc._xAuto)
|
||||||
assert xmlToText(theDoc._xText) == (
|
assert xmlToText(doc._xText) == (
|
||||||
'<office:text>'
|
'<office:text>'
|
||||||
'<text:p text:style-name="P1">This is a paragraph</text:p>'
|
'<text:p text:style-name="P1">This is a paragraph</text:p>'
|
||||||
'</office:text>'
|
'</office:text>'
|
||||||
@@ -767,12 +767,12 @@ def testCoreToOdt_SaveFull(mockGUI, fncPath, tstPaths):
|
|||||||
|
|
||||||
extaxtTo = tstPaths.outDir / "coreToOdt_SaveFull"
|
extaxtTo = tstPaths.outDir / "coreToOdt_SaveFull"
|
||||||
|
|
||||||
with zipfile.ZipFile(fullFile, mode="r") as theZip:
|
with zipfile.ZipFile(fullFile, mode="r") as zipObj:
|
||||||
theZip.extract("META-INF/manifest.xml", extaxtTo)
|
zipObj.extract("META-INF/manifest.xml", extaxtTo)
|
||||||
theZip.extract("settings.xml", extaxtTo)
|
zipObj.extract("settings.xml", extaxtTo)
|
||||||
theZip.extract("content.xml", extaxtTo)
|
zipObj.extract("content.xml", extaxtTo)
|
||||||
theZip.extract("meta.xml", extaxtTo)
|
zipObj.extract("meta.xml", extaxtTo)
|
||||||
theZip.extract("styles.xml", extaxtTo)
|
zipObj.extract("styles.xml", extaxtTo)
|
||||||
|
|
||||||
maniOut = tstPaths.outDir / "coreToOdt_SaveFull" / "META-INF" / "manifest.xml"
|
maniOut = tstPaths.outDir / "coreToOdt_SaveFull" / "META-INF" / "manifest.xml"
|
||||||
settOut = tstPaths.outDir / "coreToOdt_SaveFull" / "settings.xml"
|
settOut = tstPaths.outDir / "coreToOdt_SaveFull" / "settings.xml"
|
||||||
|
|||||||
+172
-172
@@ -39,23 +39,23 @@ from novelwriter.core.project import NWProject
|
|||||||
@pytest.fixture(scope="function")
|
@pytest.fixture(scope="function")
|
||||||
def mockItems(mockGUI, mockRnd):
|
def mockItems(mockGUI, mockRnd):
|
||||||
"""Create a list of mock items."""
|
"""Create a list of mock items."""
|
||||||
theProject = NWProject()
|
project = NWProject()
|
||||||
|
|
||||||
itemA = NWItem(theProject, "a000000000001")
|
itemA = NWItem(project, "a000000000001")
|
||||||
itemA._name = "Novel"
|
itemA._name = "Novel"
|
||||||
itemA._parent = None
|
itemA._parent = None
|
||||||
itemA._type = nwItemType.ROOT
|
itemA._type = nwItemType.ROOT
|
||||||
itemA._class = nwItemClass.NOVEL
|
itemA._class = nwItemClass.NOVEL
|
||||||
itemA._expanded = True
|
itemA._expanded = True
|
||||||
|
|
||||||
itemB = NWItem(theProject, "b000000000001")
|
itemB = NWItem(project, "b000000000001")
|
||||||
itemB._name = "Act One"
|
itemB._name = "Act One"
|
||||||
itemB._parent = "a000000000001"
|
itemB._parent = "a000000000001"
|
||||||
itemB._type = nwItemType.FOLDER
|
itemB._type = nwItemType.FOLDER
|
||||||
itemB._class = nwItemClass.NOVEL
|
itemB._class = nwItemClass.NOVEL
|
||||||
itemB._expanded = True
|
itemB._expanded = True
|
||||||
|
|
||||||
itemC = NWItem(theProject, "c000000000001")
|
itemC = NWItem(project, "c000000000001")
|
||||||
itemC._name = "Chapter One"
|
itemC._name = "Chapter One"
|
||||||
itemC._parent = "b000000000001"
|
itemC._parent = "b000000000001"
|
||||||
itemC._type = nwItemType.FILE
|
itemC._type = nwItemType.FILE
|
||||||
@@ -65,7 +65,7 @@ def mockItems(mockGUI, mockRnd):
|
|||||||
itemC._wordCount = 50
|
itemC._wordCount = 50
|
||||||
itemC._paraCount = 2
|
itemC._paraCount = 2
|
||||||
|
|
||||||
itemD = NWItem(theProject, "c000000000002")
|
itemD = NWItem(project, "c000000000002")
|
||||||
itemD._name = "Scene One"
|
itemD._name = "Scene One"
|
||||||
itemD._parent = "b000000000001"
|
itemD._parent = "b000000000001"
|
||||||
itemD._type = nwItemType.FILE
|
itemD._type = nwItemType.FILE
|
||||||
@@ -75,28 +75,28 @@ def mockItems(mockGUI, mockRnd):
|
|||||||
itemD._wordCount = 500
|
itemD._wordCount = 500
|
||||||
itemD._paraCount = 20
|
itemD._paraCount = 20
|
||||||
|
|
||||||
itemE = NWItem(theProject, "a000000000002")
|
itemE = NWItem(project, "a000000000002")
|
||||||
itemE._name = "Outtakes"
|
itemE._name = "Outtakes"
|
||||||
itemE._parent = None
|
itemE._parent = None
|
||||||
itemE._type = nwItemType.ROOT
|
itemE._type = nwItemType.ROOT
|
||||||
itemE._class = nwItemClass.ARCHIVE
|
itemE._class = nwItemClass.ARCHIVE
|
||||||
itemE._expanded = False
|
itemE._expanded = False
|
||||||
|
|
||||||
itemF = NWItem(theProject, "a000000000003")
|
itemF = NWItem(project, "a000000000003")
|
||||||
itemF._name = "Trash"
|
itemF._name = "Trash"
|
||||||
itemF._parent = None
|
itemF._parent = None
|
||||||
itemF._type = nwItemType.ROOT
|
itemF._type = nwItemType.ROOT
|
||||||
itemF._class = nwItemClass.TRASH
|
itemF._class = nwItemClass.TRASH
|
||||||
itemF._expanded = False
|
itemF._expanded = False
|
||||||
|
|
||||||
itemG = NWItem(theProject, "a000000000004")
|
itemG = NWItem(project, "a000000000004")
|
||||||
itemG._name = "Characters"
|
itemG._name = "Characters"
|
||||||
itemG._parent = None
|
itemG._parent = None
|
||||||
itemG._type = nwItemType.ROOT
|
itemG._type = nwItemType.ROOT
|
||||||
itemG._class = nwItemClass.CHARACTER
|
itemG._class = nwItemClass.CHARACTER
|
||||||
itemG._expanded = True
|
itemG._expanded = True
|
||||||
|
|
||||||
itemH = NWItem(theProject, "b000000000002")
|
itemH = NWItem(project, "b000000000002")
|
||||||
itemH._name = "Jane Doe"
|
itemH._name = "Jane Doe"
|
||||||
itemH._parent = "a000000000004"
|
itemH._parent = "a000000000004"
|
||||||
itemH._type = nwItemType.FILE
|
itemH._type = nwItemType.FILE
|
||||||
@@ -112,126 +112,126 @@ def mockItems(mockGUI, mockRnd):
|
|||||||
@pytest.mark.core
|
@pytest.mark.core
|
||||||
def testCoreTree_BuildTree(mockGUI, mockItems):
|
def testCoreTree_BuildTree(mockGUI, mockItems):
|
||||||
"""Test building a project tree from a list of items."""
|
"""Test building a project tree from a list of items."""
|
||||||
theProject = NWProject()
|
project = NWProject()
|
||||||
theTree = NWTree(theProject)
|
tree = NWTree(project)
|
||||||
|
|
||||||
# Check that tree is empty (calls NWTree.__bool__)
|
# Check that tree is empty (calls NWTree.__bool__)
|
||||||
assert bool(theTree) is False
|
assert bool(tree) is False
|
||||||
|
|
||||||
# Check for archive and trash folders
|
# Check for archive and trash folders
|
||||||
assert theTree.trashRoot is None
|
assert tree.trashRoot is None
|
||||||
|
|
||||||
aHandles = []
|
aHandles = []
|
||||||
for nwItem in mockItems:
|
for nwItem in mockItems:
|
||||||
aHandles.append(nwItem.itemHandle)
|
aHandles.append(nwItem.itemHandle)
|
||||||
assert theTree.append(nwItem) is True
|
assert tree.append(nwItem) is True
|
||||||
assert theTree.updateItemData(nwItem.itemHandle) is True
|
assert tree.updateItemData(nwItem.itemHandle) is True
|
||||||
|
|
||||||
assert theTree._changed is True
|
assert tree._changed is True
|
||||||
|
|
||||||
# Check that tree is not empty (calls __bool__)
|
# Check that tree is not empty (calls __bool__)
|
||||||
assert bool(theTree) is True
|
assert bool(tree) is True
|
||||||
|
|
||||||
# Check the number of elements (calls __len__)
|
# Check the number of elements (calls __len__)
|
||||||
assert len(theTree) == len(mockItems)
|
assert len(tree) == len(mockItems)
|
||||||
|
|
||||||
# Check that we have the correct handles
|
# Check that we have the correct handles
|
||||||
assert theTree.handles() == aHandles
|
assert tree.handles() == aHandles
|
||||||
|
|
||||||
# Check by iterator (calls __iter__, __next__ and __getitem__)
|
# Check by iterator (calls __iter__, __next__ and __getitem__)
|
||||||
for theItem, theHandle in zip(theTree, aHandles):
|
for item, handle in zip(tree, aHandles):
|
||||||
assert theItem.itemHandle == theHandle
|
assert item.itemHandle == handle
|
||||||
|
|
||||||
# Trash Folder
|
# Trash Folder
|
||||||
# ============
|
# ============
|
||||||
|
|
||||||
# Check that we have the correct archive and trash folders
|
# Check that we have the correct archive and trash folders
|
||||||
assert theTree.trashRoot == "a000000000003"
|
assert tree.trashRoot == "a000000000003"
|
||||||
assert theTree.findRoot(nwItemClass.ARCHIVE) == "a000000000002"
|
assert tree.findRoot(nwItemClass.ARCHIVE) == "a000000000002"
|
||||||
assert theTree.isTrash("a000000000003") is True
|
assert tree.isTrash("a000000000003") is True
|
||||||
|
|
||||||
# Check that we have the root classes
|
# Check that we have the root classes
|
||||||
assert theTree.rootClasses() == {
|
assert tree.rootClasses() == {
|
||||||
nwItemClass.NOVEL, nwItemClass.CHARACTER, nwItemClass.ARCHIVE, nwItemClass.TRASH
|
nwItemClass.NOVEL, nwItemClass.CHARACTER, nwItemClass.ARCHIVE, nwItemClass.TRASH
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check the isTrash function
|
# Check the isTrash function
|
||||||
assert theTree.isTrash("0000000000000") is True # Doesn't exist
|
assert tree.isTrash("0000000000000") is True # Doesn't exist
|
||||||
assert theTree.isTrash("a000000000003") is True # This the trash folder
|
assert tree.isTrash("a000000000003") is True # This the trash folder
|
||||||
|
|
||||||
theTree["a000000000003"].setClass(nwItemClass.NO_CLASS) # type: ignore
|
tree["a000000000003"].setClass(nwItemClass.NO_CLASS) # type: ignore
|
||||||
assert theTree.isTrash("a000000000003") is True # This is still trash
|
assert tree.isTrash("a000000000003") is True # This is still trash
|
||||||
theTree["a000000000003"].setClass(nwItemClass.TRASH) # type: ignore
|
tree["a000000000003"].setClass(nwItemClass.TRASH) # type: ignore
|
||||||
|
|
||||||
assert theTree.isTrash("b000000000002") is False # This is not trash
|
assert tree.isTrash("b000000000002") is False # This is not trash
|
||||||
|
|
||||||
value = theTree["b000000000002"].itemParent # type: ignore
|
value = tree["b000000000002"].itemParent # type: ignore
|
||||||
theTree["b000000000002"].setParent("a000000000003") # type: ignore
|
tree["b000000000002"].setParent("a000000000003") # type: ignore
|
||||||
assert theTree.isTrash("b000000000002") is True # This is in trash
|
assert tree.isTrash("b000000000002") is True # This is in trash
|
||||||
theTree["b000000000002"].setParent(value) # type: ignore
|
tree["b000000000002"].setParent(value) # type: ignore
|
||||||
|
|
||||||
value = theTree["b000000000002"].itemRoot # type: ignore
|
value = tree["b000000000002"].itemRoot # type: ignore
|
||||||
theTree["b000000000002"].setRoot("a000000000003") # type: ignore
|
tree["b000000000002"].setRoot("a000000000003") # type: ignore
|
||||||
assert theTree.isTrash("b000000000002") is True # This is in trash
|
assert tree.isTrash("b000000000002") is True # This is in trash
|
||||||
theTree["b000000000002"].setRoot(value) # type: ignore
|
tree["b000000000002"].setRoot(value) # type: ignore
|
||||||
|
|
||||||
# Try to add another trash folder
|
# Try to add another trash folder
|
||||||
itemT = NWItem(theProject, "1111111111111")
|
itemT = NWItem(project, "1111111111111")
|
||||||
itemT._name = "Trash"
|
itemT._name = "Trash"
|
||||||
itemT._type = nwItemType.ROOT
|
itemT._type = nwItemType.ROOT
|
||||||
itemT._class = nwItemClass.TRASH
|
itemT._class = nwItemClass.TRASH
|
||||||
itemT._expanded = False
|
itemT._expanded = False
|
||||||
|
|
||||||
assert theTree.append(itemT) is False
|
assert tree.append(itemT) is False
|
||||||
assert len(theTree) == len(mockItems)
|
assert len(tree) == len(mockItems)
|
||||||
|
|
||||||
# Create or Add Items
|
# Create or Add Items
|
||||||
# ===================
|
# ===================
|
||||||
|
|
||||||
# Create a new item, but with invalid parent
|
# Create a new item, but with invalid parent
|
||||||
assert theTree.create("New File", "blabla", nwItemType.FILE, nwItemClass.NO_CLASS) is None
|
assert tree.create("New File", "blabla", nwItemType.FILE, nwItemClass.NO_CLASS) is None
|
||||||
|
|
||||||
# Create a new, valid item
|
# Create a new, valid item
|
||||||
nHandle = theTree.create("New File", "b000000000001", nwItemType.FILE, nwItemClass.NO_CLASS)
|
nHandle = tree.create("New File", "b000000000001", nwItemType.FILE, nwItemClass.NO_CLASS)
|
||||||
assert isHandle(nHandle)
|
assert isHandle(nHandle)
|
||||||
assert nHandle == "0000000000000"
|
assert nHandle == "0000000000000"
|
||||||
|
|
||||||
# The new item should be the last item in the tree
|
# The new item should be the last item in the tree
|
||||||
theList = theTree.handles()
|
handles = tree.handles()
|
||||||
assert theList[-1] == nHandle
|
assert handles[-1] == nHandle
|
||||||
|
|
||||||
# Retrieve the item
|
# Retrieve the item
|
||||||
itemT = theTree[nHandle]
|
itemT = tree[nHandle]
|
||||||
assert isinstance(itemT, NWItem)
|
assert isinstance(itemT, NWItem)
|
||||||
assert len(theTree) == len(mockItems) + 1
|
assert len(tree) == len(mockItems) + 1
|
||||||
|
|
||||||
# We should not be allowed to add the item again
|
# We should not be allowed to add the item again
|
||||||
assert theTree.append(itemT) is False
|
assert tree.append(itemT) is False
|
||||||
assert len(theTree) == len(mockItems) + 1
|
assert len(tree) == len(mockItems) + 1
|
||||||
|
|
||||||
# Create an invalid item to add, which will be rejected
|
# Create an invalid item to add, which will be rejected
|
||||||
itemU = NWItem.duplicate(itemT, "blabla")
|
itemU = NWItem.duplicate(itemT, "blabla")
|
||||||
assert theTree.append(itemU) is False
|
assert tree.append(itemU) is False
|
||||||
assert len(theTree) == len(mockItems) + 1
|
assert len(tree) == len(mockItems) + 1
|
||||||
|
|
||||||
# Create a new root, but with a parent set anyway (the parent should be ignored)
|
# Create a new root, but with a parent set anyway (the parent should be ignored)
|
||||||
zHandle = theTree.create("Custom", "a000000000001", nwItemType.ROOT, nwItemClass.CUSTOM)
|
zHandle = tree.create("Custom", "a000000000001", nwItemType.ROOT, nwItemClass.CUSTOM)
|
||||||
assert isinstance(zHandle, str)
|
assert isinstance(zHandle, str)
|
||||||
itemZ = theTree[zHandle]
|
itemZ = tree[zHandle]
|
||||||
assert isinstance(itemZ, NWItem)
|
assert isinstance(itemZ, NWItem)
|
||||||
assert itemZ.itemParent is None
|
assert itemZ.itemParent is None
|
||||||
del theTree[zHandle]
|
del tree[zHandle]
|
||||||
|
|
||||||
# Duplicate Items
|
# Duplicate Items
|
||||||
# ===============
|
# ===============
|
||||||
|
|
||||||
# Duplicate a non-existing item
|
# Duplicate a non-existing item
|
||||||
assert theTree.duplicate("blabla") is None
|
assert tree.duplicate("blabla") is None
|
||||||
|
|
||||||
# Duplicate the new item
|
# Duplicate the new item
|
||||||
itemV = theTree.duplicate(nHandle)
|
itemV = tree.duplicate(nHandle)
|
||||||
assert isinstance(itemV, NWItem)
|
assert isinstance(itemV, NWItem)
|
||||||
assert len(theTree) == len(mockItems) + 2
|
assert len(tree) == len(mockItems) + 2
|
||||||
|
|
||||||
dHandle = itemV.itemHandle
|
dHandle = itemV.itemHandle
|
||||||
assert dHandle == "0000000000002"
|
assert dHandle == "0000000000002"
|
||||||
@@ -240,28 +240,28 @@ def testCoreTree_BuildTree(mockGUI, mockItems):
|
|||||||
# ============
|
# ============
|
||||||
|
|
||||||
# Delete a non-existing item
|
# Delete a non-existing item
|
||||||
del theTree["stuff"]
|
del tree["stuff"]
|
||||||
assert len(theTree) == len(mockItems) + 2
|
assert len(tree) == len(mockItems) + 2
|
||||||
|
|
||||||
# Delete the last items
|
# Delete the last items
|
||||||
del theTree[nHandle]
|
del tree[nHandle]
|
||||||
del theTree[dHandle]
|
del tree[dHandle]
|
||||||
assert len(theTree) == len(mockItems)
|
assert len(tree) == len(mockItems)
|
||||||
assert nHandle not in theTree
|
assert nHandle not in tree
|
||||||
|
|
||||||
# Delete the Novel, Archive and Trash folders
|
# Delete the Novel, Archive and Trash folders
|
||||||
del theTree["a000000000001"]
|
del tree["a000000000001"]
|
||||||
assert len(theTree) == len(mockItems) - 1
|
assert len(tree) == len(mockItems) - 1
|
||||||
assert "a000000000001" not in theTree
|
assert "a000000000001" not in tree
|
||||||
|
|
||||||
del theTree["a000000000002"]
|
del tree["a000000000002"]
|
||||||
assert len(theTree) == len(mockItems) - 2
|
assert len(tree) == len(mockItems) - 2
|
||||||
assert "a000000000002" not in theTree
|
assert "a000000000002" not in tree
|
||||||
|
|
||||||
del theTree["a000000000003"]
|
del tree["a000000000003"]
|
||||||
assert len(theTree) == len(mockItems) - 3
|
assert len(tree) == len(mockItems) - 3
|
||||||
assert "a000000000003" not in theTree
|
assert "a000000000003" not in tree
|
||||||
assert theTree.trashRoot is None
|
assert tree.trashRoot is None
|
||||||
|
|
||||||
# END Test testCoreTree_BuildTree
|
# END Test testCoreTree_BuildTree
|
||||||
|
|
||||||
@@ -269,28 +269,28 @@ def testCoreTree_BuildTree(mockGUI, mockItems):
|
|||||||
@pytest.mark.core
|
@pytest.mark.core
|
||||||
def testCoreTree_PackUnpack(mockGUI, mockItems):
|
def testCoreTree_PackUnpack(mockGUI, mockItems):
|
||||||
"""Test packing and unpacking data."""
|
"""Test packing and unpacking data."""
|
||||||
theProject = NWProject()
|
project = NWProject()
|
||||||
theTree = NWTree(theProject)
|
tree = NWTree(project)
|
||||||
|
|
||||||
aHandles = []
|
aHandles = []
|
||||||
for nwItem in mockItems:
|
for nwItem in mockItems:
|
||||||
aHandles.append(nwItem.itemHandle)
|
aHandles.append(nwItem.itemHandle)
|
||||||
theTree.append(nwItem)
|
tree.append(nwItem)
|
||||||
theTree.updateItemData(nwItem.itemHandle)
|
tree.updateItemData(nwItem.itemHandle)
|
||||||
|
|
||||||
assert len(theTree) == len(mockItems)
|
assert len(tree) == len(mockItems)
|
||||||
|
|
||||||
# Pack
|
# Pack
|
||||||
tree = theTree.pack()
|
packed = tree.pack()
|
||||||
for i, nwItem in enumerate(mockItems):
|
for i, nwItem in enumerate(mockItems):
|
||||||
assert tree[i]["itemAttr"]["handle"] == nwItem.itemHandle
|
assert packed[i]["itemAttr"]["handle"] == nwItem.itemHandle
|
||||||
|
|
||||||
# Unpack
|
# Unpack
|
||||||
theTree.clear()
|
tree.clear()
|
||||||
assert len(theTree) == 0
|
assert len(tree) == 0
|
||||||
assert theTree.handles() == []
|
assert tree.handles() == []
|
||||||
theTree.unpack(tree)
|
tree.unpack(packed)
|
||||||
assert theTree.handles() == aHandles
|
assert tree.handles() == aHandles
|
||||||
|
|
||||||
# END Test testCoreTree_PackUnpack
|
# END Test testCoreTree_PackUnpack
|
||||||
|
|
||||||
@@ -298,35 +298,35 @@ def testCoreTree_PackUnpack(mockGUI, mockItems):
|
|||||||
@pytest.mark.core
|
@pytest.mark.core
|
||||||
def testCoreTree_CheckConsistency(caplog: pytest.LogCaptureFixture, mockGUI, fncPath, mockRnd):
|
def testCoreTree_CheckConsistency(caplog: pytest.LogCaptureFixture, mockGUI, fncPath, mockRnd):
|
||||||
"""Check the project consistency."""
|
"""Check the project consistency."""
|
||||||
theProject = NWProject()
|
project = NWProject()
|
||||||
buildTestProject(theProject, fncPath)
|
buildTestProject(project, fncPath)
|
||||||
|
|
||||||
# By default, all is well
|
# By default, all is well
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
assert theProject.tree.checkConsistency("Recovered") == (0, 0)
|
assert project.tree.checkConsistency("Recovered") == (0, 0)
|
||||||
assert all(m.endswith("OK") for m in caplog.messages)
|
assert all(m.endswith("OK") for m in caplog.messages)
|
||||||
|
|
||||||
# Give the scene file an unknown parent
|
# Give the scene file an unknown parent
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
theProject.tree[C.hSceneDoc].setParent(C.hInvalid) # type: ignore
|
project.tree[C.hSceneDoc].setParent(C.hInvalid) # type: ignore
|
||||||
assert theProject.tree.checkConsistency("Recovered") == (1, 1)
|
assert project.tree.checkConsistency("Recovered") == (1, 1)
|
||||||
assert f"'{C.hSceneDoc}' ... ERROR" in caplog.text
|
assert f"'{C.hSceneDoc}' ... ERROR" in caplog.text
|
||||||
|
|
||||||
# The scene file should have been added back to its home
|
# The scene file should have been added back to its home
|
||||||
itemS = theProject.tree[C.hSceneDoc]
|
itemS = project.tree[C.hSceneDoc]
|
||||||
assert isinstance(itemS, NWItem)
|
assert isinstance(itemS, NWItem)
|
||||||
assert itemS.itemParent == C.hChapterDir
|
assert itemS.itemParent == C.hChapterDir
|
||||||
|
|
||||||
# Create a new file with no meta data, and let the function handle it as orphaned
|
# Create a new file with no meta data, and let the function handle it as orphaned
|
||||||
xHandle = "0123456789abc"
|
xHandle = "0123456789abc"
|
||||||
contentPath = theProject.storage.contentPath
|
contentPath = project.storage.contentPath
|
||||||
assert isinstance(contentPath, Path)
|
assert isinstance(contentPath, Path)
|
||||||
assert contentPath == fncPath / "content"
|
assert contentPath == fncPath / "content"
|
||||||
(contentPath / f"{xHandle}.nwd").write_text("### Stuff", encoding="utf-8")
|
(contentPath / f"{xHandle}.nwd").write_text("### Stuff", encoding="utf-8")
|
||||||
|
|
||||||
assert theProject.tree.checkConsistency("Recovered") == (1, 1)
|
assert project.tree.checkConsistency("Recovered") == (1, 1)
|
||||||
assert xHandle in theProject.tree
|
assert xHandle in project.tree
|
||||||
itemX = theProject.tree[xHandle]
|
itemX = project.tree[xHandle]
|
||||||
assert isinstance(itemX, NWItem)
|
assert isinstance(itemX, NWItem)
|
||||||
|
|
||||||
# It should by default be added as a Novel file
|
# It should by default be added as a Novel file
|
||||||
@@ -339,13 +339,13 @@ def testCoreTree_CheckConsistency(caplog: pytest.LogCaptureFixture, mockGUI, fnc
|
|||||||
itemX.setClass(nwItemClass.OBJECT)
|
itemX.setClass(nwItemClass.OBJECT)
|
||||||
itemX.setName("Stuff")
|
itemX.setName("Stuff")
|
||||||
itemX.setParent(C.hInvalid)
|
itemX.setParent(C.hInvalid)
|
||||||
theProject.storage.getDocument(xHandle).writeDocument("### Stuff") # This adds meta data
|
project.storage.getDocument(xHandle).writeDocument("### Stuff") # This adds meta data
|
||||||
|
|
||||||
# Remove the item in the project, and re-run the consistency check
|
# Remove the item in the project, and re-run the consistency check
|
||||||
del theProject.tree[xHandle]
|
del project.tree[xHandle]
|
||||||
assert theProject.tree.checkConsistency("Recovered") == (1, 1)
|
assert project.tree.checkConsistency("Recovered") == (1, 1)
|
||||||
assert xHandle in theProject.tree
|
assert xHandle in project.tree
|
||||||
itemX = theProject.tree[xHandle]
|
itemX = project.tree[xHandle]
|
||||||
assert isinstance(itemX, NWItem)
|
assert isinstance(itemX, NWItem)
|
||||||
|
|
||||||
# It should again be added as a Novel file
|
# It should again be added as a Novel file
|
||||||
@@ -355,11 +355,11 @@ def testCoreTree_CheckConsistency(caplog: pytest.LogCaptureFixture, mockGUI, fnc
|
|||||||
assert itemX.itemName == "[Recovered] Stuff"
|
assert itemX.itemName == "[Recovered] Stuff"
|
||||||
|
|
||||||
# If the tree is empty, a new root folder is created
|
# If the tree is empty, a new root folder is created
|
||||||
theProject.tree.clear()
|
project.tree.clear()
|
||||||
assert theProject.tree.checkConsistency("Recovered") == (4, 4)
|
assert project.tree.checkConsistency("Recovered") == (4, 4)
|
||||||
assert len(theProject.tree) == 5
|
assert len(project.tree) == 5
|
||||||
nHandle = theProject.tree.findRoot(nwItemClass.NOVEL)
|
nHandle = project.tree.findRoot(nwItemClass.NOVEL)
|
||||||
assert theProject.tree[nHandle].itemName == "Recovered" # type: ignore
|
assert project.tree[nHandle].itemName == "Recovered" # type: ignore
|
||||||
|
|
||||||
# END Test testCoreTree_CheckConsistency
|
# END Test testCoreTree_CheckConsistency
|
||||||
|
|
||||||
@@ -367,58 +367,58 @@ def testCoreTree_CheckConsistency(caplog: pytest.LogCaptureFixture, mockGUI, fnc
|
|||||||
@pytest.mark.core
|
@pytest.mark.core
|
||||||
def testCoreTree_Methods(monkeypatch, mockGUI, mockItems):
|
def testCoreTree_Methods(monkeypatch, mockGUI, mockItems):
|
||||||
"""Test various class methods."""
|
"""Test various class methods."""
|
||||||
theProject = NWProject()
|
project = NWProject()
|
||||||
theTree = NWTree(theProject)
|
tree = NWTree(project)
|
||||||
|
|
||||||
for nwItem in mockItems:
|
for nwItem in mockItems:
|
||||||
theTree.append(nwItem)
|
tree.append(nwItem)
|
||||||
theTree.updateItemData(nwItem.itemHandle)
|
tree.updateItemData(nwItem.itemHandle)
|
||||||
|
|
||||||
assert len(theTree) == len(mockItems)
|
assert len(tree) == len(mockItems)
|
||||||
|
|
||||||
# Update item data, nonsense handle
|
# Update item data, nonsense handle
|
||||||
assert theTree.updateItemData("stuff") is False
|
assert tree.updateItemData("stuff") is False
|
||||||
|
|
||||||
# Update item data, invalid item parent
|
# Update item data, invalid item parent
|
||||||
corrParent = theTree["b000000000001"].itemParent # type: ignore
|
corrParent = tree["b000000000001"].itemParent # type: ignore
|
||||||
theTree["b000000000001"].setParent("0000000000000") # type: ignore
|
tree["b000000000001"].setParent("0000000000000") # type: ignore
|
||||||
assert theTree.updateItemData("b000000000001") is False
|
assert tree.updateItemData("b000000000001") is False
|
||||||
|
|
||||||
# Update item data, valid item parent
|
# Update item data, valid item parent
|
||||||
theTree["b000000000001"].setParent(corrParent) # type: ignore
|
tree["b000000000001"].setParent(corrParent) # type: ignore
|
||||||
assert theTree.updateItemData("b000000000001") is True
|
assert tree.updateItemData("b000000000001") is True
|
||||||
|
|
||||||
# Update item data, root is unreachable
|
# Update item data, root is unreachable
|
||||||
with monkeypatch.context() as mp:
|
with monkeypatch.context() as mp:
|
||||||
mp.setattr("novelwriter.core.tree.MAX_DEPTH", 0)
|
mp.setattr("novelwriter.core.tree.MAX_DEPTH", 0)
|
||||||
with pytest.raises(RecursionError):
|
with pytest.raises(RecursionError):
|
||||||
theTree.updateItemData("b000000000001")
|
tree.updateItemData("b000000000001")
|
||||||
|
|
||||||
# Check type
|
# Check type
|
||||||
assert theTree.checkType("blabla", nwItemType.FILE) is False
|
assert tree.checkType("blabla", nwItemType.FILE) is False
|
||||||
assert theTree.checkType("b000000000001", nwItemType.FILE) is False
|
assert tree.checkType("b000000000001", nwItemType.FILE) is False
|
||||||
assert theTree.checkType("c000000000001", nwItemType.FILE) is True
|
assert tree.checkType("c000000000001", nwItemType.FILE) is True
|
||||||
|
|
||||||
# Root item lookup
|
# Root item lookup
|
||||||
assert theTree.findRoot(nwItemClass.WORLD) is None
|
assert tree.findRoot(nwItemClass.WORLD) is None
|
||||||
assert theTree.findRoot(nwItemClass.NOVEL) == "a000000000001"
|
assert tree.findRoot(nwItemClass.NOVEL) == "a000000000001"
|
||||||
assert theTree.findRoot(nwItemClass.CHARACTER) == "a000000000004"
|
assert tree.findRoot(nwItemClass.CHARACTER) == "a000000000004"
|
||||||
|
|
||||||
# Iter roots
|
# Iter roots
|
||||||
roots = list(theTree.iterRoots(None))
|
roots = list(tree.iterRoots(None))
|
||||||
assert roots[0][0] == "a000000000001"
|
assert roots[0][0] == "a000000000001"
|
||||||
assert roots[1][0] == "a000000000002"
|
assert roots[1][0] == "a000000000002"
|
||||||
assert roots[2][0] == "a000000000003"
|
assert roots[2][0] == "a000000000003"
|
||||||
assert roots[3][0] == "a000000000004"
|
assert roots[3][0] == "a000000000004"
|
||||||
|
|
||||||
# Add a fake item to root and check that it can handle it
|
# Add a fake item to root and check that it can handle it
|
||||||
theTree._roots["0000000000000"] = NWItem(theProject, "0000000000000")
|
tree._roots["0000000000000"] = NWItem(project, "0000000000000")
|
||||||
assert theTree.findRoot(nwItemClass.WORLD) is None
|
assert tree.findRoot(nwItemClass.WORLD) is None
|
||||||
del theTree._roots["0000000000000"]
|
del tree._roots["0000000000000"]
|
||||||
|
|
||||||
# Get item path
|
# Get item path
|
||||||
assert theTree.getItemPath("stuff") == []
|
assert tree.getItemPath("stuff") == []
|
||||||
assert theTree.getItemPath("c000000000001") == [
|
assert tree.getItemPath("c000000000001") == [
|
||||||
"c000000000001", "b000000000001", "a000000000001"
|
"c000000000001", "b000000000001", "a000000000001"
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -426,16 +426,16 @@ def testCoreTree_Methods(monkeypatch, mockGUI, mockItems):
|
|||||||
with monkeypatch.context() as mp:
|
with monkeypatch.context() as mp:
|
||||||
mp.setattr("novelwriter.core.tree.MAX_DEPTH", 0)
|
mp.setattr("novelwriter.core.tree.MAX_DEPTH", 0)
|
||||||
with pytest.raises(RecursionError):
|
with pytest.raises(RecursionError):
|
||||||
theTree.getItemPath("c000000000001")
|
tree.getItemPath("c000000000001")
|
||||||
|
|
||||||
# Break the folder parent handle
|
# Break the folder parent handle
|
||||||
theTree["b000000000001"]._parent = "stuff" # type: ignore
|
tree["b000000000001"]._parent = "stuff" # type: ignore
|
||||||
assert theTree.getItemPath("c000000000001") == [
|
assert tree.getItemPath("c000000000001") == [
|
||||||
"c000000000001", "b000000000001"
|
"c000000000001", "b000000000001"
|
||||||
]
|
]
|
||||||
|
|
||||||
theTree["b000000000001"]._parent = "a000000000001" # type: ignore
|
tree["b000000000001"]._parent = "a000000000001" # type: ignore
|
||||||
assert theTree.getItemPath("c000000000001") == [
|
assert tree.getItemPath("c000000000001") == [
|
||||||
"c000000000001", "b000000000001", "a000000000001"
|
"c000000000001", "b000000000001", "a000000000001"
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -446,26 +446,26 @@ def testCoreTree_Methods(monkeypatch, mockGUI, mockItems):
|
|||||||
def testCoreTree_MakeHandles(mockGUI):
|
def testCoreTree_MakeHandles(mockGUI):
|
||||||
"""Test generating item handles."""
|
"""Test generating item handles."""
|
||||||
random.seed(42)
|
random.seed(42)
|
||||||
theProject = NWProject()
|
project = NWProject()
|
||||||
theTree = NWTree(theProject)
|
tree = NWTree(project)
|
||||||
|
|
||||||
handles = ["1c803a3b1799d", "bdd6406671ad1", "3eb1346685257", "23b8c392456de"]
|
handles = ["1c803a3b1799d", "bdd6406671ad1", "3eb1346685257", "23b8c392456de"]
|
||||||
|
|
||||||
random.seed(42)
|
random.seed(42)
|
||||||
tHandle = theTree._makeHandle()
|
tHandle = tree._makeHandle()
|
||||||
assert tHandle == handles[0]
|
assert tHandle == handles[0]
|
||||||
theTree._tree[handles[0]] = None # type: ignore
|
tree._tree[handles[0]] = None # type: ignore
|
||||||
|
|
||||||
# Add the next in line to the project to force duplicate
|
# Add the next in line to the project to force duplicate
|
||||||
theTree._tree[handles[1]] = None # type: ignore
|
tree._tree[handles[1]] = None # type: ignore
|
||||||
tHandle = theTree._makeHandle()
|
tHandle = tree._makeHandle()
|
||||||
assert tHandle == handles[2]
|
assert tHandle == handles[2]
|
||||||
theTree._tree[handles[2]] = None # type: ignore
|
tree._tree[handles[2]] = None # type: ignore
|
||||||
|
|
||||||
# Reset the seed to force collissions, which should still end up
|
# Reset the seed to force collissions, which should still end up
|
||||||
# returning the next handle in the sequence
|
# returning the next handle in the sequence
|
||||||
random.seed(42)
|
random.seed(42)
|
||||||
tHandle = theTree._makeHandle()
|
tHandle = tree._makeHandle()
|
||||||
assert tHandle == handles[3]
|
assert tHandle == handles[3]
|
||||||
|
|
||||||
# END Test testCoreTree_MakeHandles
|
# END Test testCoreTree_MakeHandles
|
||||||
@@ -474,17 +474,17 @@ def testCoreTree_MakeHandles(mockGUI):
|
|||||||
@pytest.mark.core
|
@pytest.mark.core
|
||||||
def testCoreTree_Stats(mockGUI, mockItems):
|
def testCoreTree_Stats(mockGUI, mockItems):
|
||||||
"""Test project stats methods."""
|
"""Test project stats methods."""
|
||||||
theProject = NWProject()
|
project = NWProject()
|
||||||
theTree = NWTree(theProject)
|
tree = NWTree(project)
|
||||||
|
|
||||||
for nwItem in mockItems:
|
for nwItem in mockItems:
|
||||||
theTree.append(nwItem)
|
tree.append(nwItem)
|
||||||
|
|
||||||
assert len(theTree) == len(mockItems)
|
assert len(tree) == len(mockItems)
|
||||||
theTree._order.append("stuff")
|
tree._order.append("stuff")
|
||||||
|
|
||||||
# Count Words
|
# Count Words
|
||||||
novelWords, noteWords = theTree.sumWords()
|
novelWords, noteWords = tree.sumWords()
|
||||||
assert novelWords == 550
|
assert novelWords == 550
|
||||||
assert noteWords == 400
|
assert noteWords == 400
|
||||||
|
|
||||||
@@ -494,33 +494,33 @@ def testCoreTree_Stats(mockGUI, mockItems):
|
|||||||
@pytest.mark.core
|
@pytest.mark.core
|
||||||
def testCoreTree_Reorder(caplog, mockGUI, mockItems):
|
def testCoreTree_Reorder(caplog, mockGUI, mockItems):
|
||||||
"""Test changing tree order."""
|
"""Test changing tree order."""
|
||||||
theProject = NWProject()
|
project = NWProject()
|
||||||
theTree = NWTree(theProject)
|
tree = NWTree(project)
|
||||||
|
|
||||||
aHandle = []
|
aHandle = []
|
||||||
for nwItem in mockItems:
|
for nwItem in mockItems:
|
||||||
aHandle.append(nwItem.itemHandle)
|
aHandle.append(nwItem.itemHandle)
|
||||||
theTree.append(nwItem)
|
tree.append(nwItem)
|
||||||
|
|
||||||
assert len(theTree) == len(mockItems)
|
assert len(tree) == len(mockItems)
|
||||||
|
|
||||||
bHandle = aHandle.copy()
|
bHandle = aHandle.copy()
|
||||||
bHandle[2], bHandle[3] = bHandle[3], bHandle[2]
|
bHandle[2], bHandle[3] = bHandle[3], bHandle[2]
|
||||||
assert aHandle != bHandle
|
assert aHandle != bHandle
|
||||||
|
|
||||||
assert theTree.handles() == aHandle
|
assert tree.handles() == aHandle
|
||||||
theTree.setOrder(bHandle)
|
tree.setOrder(bHandle)
|
||||||
assert theTree.handles() == bHandle
|
assert tree.handles() == bHandle
|
||||||
|
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
theTree.setOrder(bHandle + ["stuff"])
|
tree.setOrder(bHandle + ["stuff"])
|
||||||
assert theTree.handles() == bHandle
|
assert tree.handles() == bHandle
|
||||||
assert "Handle 'stuff' in new tree order is not in old order" in caplog.text
|
assert "Handle 'stuff' in new tree order is not in old order" in caplog.text
|
||||||
|
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
theTree._order.append("stuff")
|
tree._order.append("stuff")
|
||||||
theTree.setOrder(bHandle)
|
tree.setOrder(bHandle)
|
||||||
assert theTree.handles() == bHandle
|
assert tree.handles() == bHandle
|
||||||
assert "Handle 'stuff' in old tree order is not in new order" in caplog.text
|
assert "Handle 'stuff' in old tree order is not in new order" in caplog.text
|
||||||
|
|
||||||
# END Test testCoreTree_Reorder
|
# END Test testCoreTree_Reorder
|
||||||
@@ -529,40 +529,40 @@ def testCoreTree_Reorder(caplog, mockGUI, mockItems):
|
|||||||
@pytest.mark.core
|
@pytest.mark.core
|
||||||
def testCoreTree_ToCFile(monkeypatch, fncPath, mockGUI, mockItems):
|
def testCoreTree_ToCFile(monkeypatch, fncPath, mockGUI, mockItems):
|
||||||
"""Test writing the ToC.txt file."""
|
"""Test writing the ToC.txt file."""
|
||||||
theProject = NWProject()
|
project = NWProject()
|
||||||
theTree = NWTree(theProject)
|
tree = NWTree(project)
|
||||||
|
|
||||||
for nwItem in mockItems:
|
for nwItem in mockItems:
|
||||||
theTree.append(nwItem)
|
tree.append(nwItem)
|
||||||
theTree.updateItemData(nwItem.itemHandle)
|
tree.updateItemData(nwItem.itemHandle)
|
||||||
|
|
||||||
assert len(theTree) == len(mockItems)
|
assert len(tree) == len(mockItems)
|
||||||
theTree._order.append("stuff")
|
tree._order.append("stuff")
|
||||||
|
|
||||||
def mockIsFile(fileName):
|
def mockIsFile(fileName):
|
||||||
"""Return True for items that are files in novelWriter and
|
"""Return True for items that are files in novelWriter and
|
||||||
should thus also be files in the project folder structure.
|
should thus also be files in the project folder structure.
|
||||||
"""
|
"""
|
||||||
dItem = theTree[fileName.name[:13]]
|
dItem = tree[fileName.name[:13]]
|
||||||
assert dItem is not None
|
assert dItem is not None
|
||||||
return dItem.itemType == nwItemType.FILE
|
return dItem.itemType == nwItemType.FILE
|
||||||
|
|
||||||
monkeypatch.setattr("pathlib.Path.is_file", mockIsFile)
|
monkeypatch.setattr("pathlib.Path.is_file", mockIsFile)
|
||||||
theProject._storage._runtimePath = fncPath
|
project._storage._runtimePath = fncPath
|
||||||
(fncPath / "content").mkdir()
|
(fncPath / "content").mkdir()
|
||||||
|
|
||||||
# Block extraction of the path
|
# Block extraction of the path
|
||||||
with monkeypatch.context() as mp:
|
with monkeypatch.context() as mp:
|
||||||
mp.setattr("novelwriter.core.storage.NWStorage.contentPath", lambda *a: None)
|
mp.setattr("novelwriter.core.storage.NWStorage.contentPath", lambda *a: None)
|
||||||
assert theTree.writeToCFile() is False
|
assert tree.writeToCFile() is False
|
||||||
|
|
||||||
# Block opening the file
|
# Block opening the file
|
||||||
with monkeypatch.context() as mp:
|
with monkeypatch.context() as mp:
|
||||||
mp.setattr("builtins.open", causeOSError)
|
mp.setattr("builtins.open", causeOSError)
|
||||||
assert theTree.writeToCFile() is False
|
assert tree.writeToCFile() is False
|
||||||
|
|
||||||
# Allow writing
|
# Allow writing
|
||||||
assert theTree.writeToCFile() is True
|
assert tree.writeToCFile() is True
|
||||||
|
|
||||||
pathA = str(Path("content") / "c000000000001.nwd")
|
pathA = str(Path("content") / "c000000000001.nwd")
|
||||||
pathB = str(Path("content") / "c000000000002.nwd")
|
pathB = str(Path("content") / "c000000000002.nwd")
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ def testDlgSplit_Main(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
|
|||||||
# Create a new project
|
# Create a new project
|
||||||
buildTestProject(nwGUI, projPath)
|
buildTestProject(nwGUI, projPath)
|
||||||
|
|
||||||
theProject = SHARED.project
|
project = SHARED.project
|
||||||
projTree = nwGUI.projView.projTree
|
projTree = nwGUI.projView.projTree
|
||||||
|
|
||||||
docText = (
|
docText = (
|
||||||
@@ -55,8 +55,8 @@ def testDlgSplit_Main(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
|
|||||||
"#### New Section\n\nText\n\n"
|
"#### New Section\n\nText\n\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
hSplitDoc = theProject.newFile("Split Doc", C.hNovelRoot)
|
hSplitDoc = project.newFile("Split Doc", C.hNovelRoot)
|
||||||
theProject.writeNewFile(hSplitDoc, 1, True, docText)
|
project.writeNewFile(hSplitDoc, 1, True, docText)
|
||||||
projTree.revealNewTreeItem(hSplitDoc, nHandle=C.hNovelRoot, wordCount=True)
|
projTree.revealNewTreeItem(hSplitDoc, nHandle=C.hNovelRoot, wordCount=True)
|
||||||
|
|
||||||
docText = f"# Split Doc\n\n{docText}"
|
docText = f"# Split Doc\n\n{docText}"
|
||||||
|
|||||||
@@ -365,7 +365,7 @@ def testGuiEditor_Actions(qtbot, nwGUI, projPath, ipsumText, mockRnd):
|
|||||||
|
|
||||||
text = "### A Scene\n\n%s" % "\n\n".join(ipsumText)
|
text = "### A Scene\n\n%s" % "\n\n".join(ipsumText)
|
||||||
nwGUI.docEditor.replaceText(text)
|
nwGUI.docEditor.replaceText(text)
|
||||||
theDoc = nwGUI.docEditor.document()
|
doc = nwGUI.docEditor.document()
|
||||||
|
|
||||||
# Select/Cut/Copy/Paste/Undo/Redo
|
# Select/Cut/Copy/Paste/Undo/Redo
|
||||||
# ===============================
|
# ===============================
|
||||||
@@ -374,17 +374,17 @@ def testGuiEditor_Actions(qtbot, nwGUI, projPath, ipsumText, mockRnd):
|
|||||||
|
|
||||||
# Select All
|
# Select All
|
||||||
assert nwGUI.docEditor.docAction(nwDocAction.SEL_ALL) is True
|
assert nwGUI.docEditor.docAction(nwDocAction.SEL_ALL) is True
|
||||||
theCursor = nwGUI.docEditor.textCursor()
|
cursor = nwGUI.docEditor.textCursor()
|
||||||
assert theCursor.hasSelection() is True
|
assert cursor.hasSelection() is True
|
||||||
assert theCursor.selectedText() == text.replace("\n", "\u2029")
|
assert cursor.selectedText() == text.replace("\n", "\u2029")
|
||||||
theCursor.clearSelection()
|
cursor.clearSelection()
|
||||||
|
|
||||||
# Select Paragraph
|
# Select Paragraph
|
||||||
nwGUI.docEditor.setCursorPosition(1000)
|
nwGUI.docEditor.setCursorPosition(1000)
|
||||||
assert nwGUI.docEditor.getCursorPosition() == 1000
|
assert nwGUI.docEditor.getCursorPosition() == 1000
|
||||||
assert nwGUI.docEditor.docAction(nwDocAction.SEL_PARA) is True
|
assert nwGUI.docEditor.docAction(nwDocAction.SEL_PARA) is True
|
||||||
theCursor = nwGUI.docEditor.textCursor()
|
cursor = nwGUI.docEditor.textCursor()
|
||||||
assert theCursor.selectedText() == ipsumText[1]
|
assert cursor.selectedText() == ipsumText[1]
|
||||||
|
|
||||||
# Cut Selected Text
|
# Cut Selected Text
|
||||||
nwGUI.docEditor.replaceText(text)
|
nwGUI.docEditor.replaceText(text)
|
||||||
@@ -411,10 +411,10 @@ def testGuiEditor_Actions(qtbot, nwGUI, projPath, ipsumText, mockRnd):
|
|||||||
assert nwGUI.docEditor.docAction(nwDocAction.COPY) is True
|
assert nwGUI.docEditor.docAction(nwDocAction.COPY) is True
|
||||||
|
|
||||||
# Paste at End
|
# Paste at End
|
||||||
nwGUI.docEditor.setCursorPosition(theDoc.characterCount())
|
nwGUI.docEditor.setCursorPosition(doc.characterCount())
|
||||||
theCursor = nwGUI.docEditor.textCursor()
|
cursor = nwGUI.docEditor.textCursor()
|
||||||
theCursor.insertBlock()
|
cursor.insertBlock()
|
||||||
theCursor.insertBlock()
|
cursor.insertBlock()
|
||||||
|
|
||||||
assert nwGUI.docEditor.docAction(nwDocAction.PASTE) is True
|
assert nwGUI.docEditor.docAction(nwDocAction.PASTE) is True
|
||||||
newText = nwGUI.docEditor.getText()
|
newText = nwGUI.docEditor.getText()
|
||||||
@@ -1017,8 +1017,8 @@ def testGuiEditor_BlockFormatting(qtbot, monkeypatch, nwGUI, projPath, ipsumText
|
|||||||
# Invalid and Generic
|
# Invalid and Generic
|
||||||
# ===================
|
# ===================
|
||||||
|
|
||||||
theText = "### A Scene\n\n%s" % ipsumText[0]
|
text = "### A Scene\n\n%s" % ipsumText[0]
|
||||||
nwGUI.docEditor.replaceText(theText)
|
nwGUI.docEditor.replaceText(text)
|
||||||
|
|
||||||
# Invalid Block
|
# Invalid Block
|
||||||
nwGUI.docEditor.setCursorPosition(0)
|
nwGUI.docEditor.setCursorPosition(0)
|
||||||
@@ -1561,9 +1561,9 @@ def testGuiEditor_WordCounters(qtbot, monkeypatch, nwGUI, projPath, ipsumText, m
|
|||||||
SHARED.project.tree[C.hSceneDoc]._wordCount = 0 # type: ignore
|
SHARED.project.tree[C.hSceneDoc]._wordCount = 0 # type: ignore
|
||||||
assert nwGUI.openDocument(C.hSceneDoc) is True
|
assert nwGUI.openDocument(C.hSceneDoc) is True
|
||||||
|
|
||||||
theText = "\n\n".join(ipsumText)
|
text = "\n\n".join(ipsumText)
|
||||||
cC, wC, pC = countWords(theText)
|
cC, wC, pC = countWords(text)
|
||||||
nwGUI.docEditor.replaceText(theText)
|
nwGUI.docEditor.replaceText(text)
|
||||||
|
|
||||||
# Check that a busy counter is blocked
|
# Check that a busy counter is blocked
|
||||||
with monkeypatch.context() as mp:
|
with monkeypatch.context() as mp:
|
||||||
@@ -1617,8 +1617,8 @@ def testGuiEditor_Search(qtbot, monkeypatch, nwGUI, prjLipsum):
|
|||||||
# Select the Word "est"
|
# Select the Word "est"
|
||||||
nwGUI.docEditor.setCursorPosition(630)
|
nwGUI.docEditor.setCursorPosition(630)
|
||||||
nwGUI.docEditor._makeSelection(QTextCursor.WordUnderCursor)
|
nwGUI.docEditor._makeSelection(QTextCursor.WordUnderCursor)
|
||||||
theCursor = nwGUI.docEditor.textCursor()
|
cursor = nwGUI.docEditor.textCursor()
|
||||||
assert theCursor.selectedText() == "est"
|
assert cursor.selectedText() == "est"
|
||||||
|
|
||||||
# Activate search
|
# Activate search
|
||||||
nwGUI.mainMenu.aFind.activate(QAction.Trigger)
|
nwGUI.mainMenu.aFind.activate(QAction.Trigger)
|
||||||
@@ -1747,8 +1747,8 @@ def testGuiEditor_Search(qtbot, monkeypatch, nwGUI, prjLipsum):
|
|||||||
nwGUI.docEditor.docSearch.cancelSearch.activate(QAction.Trigger)
|
nwGUI.docEditor.docSearch.cancelSearch.activate(QAction.Trigger)
|
||||||
nwGUI.docEditor.setCursorPosition(630)
|
nwGUI.docEditor.setCursorPosition(630)
|
||||||
nwGUI.docEditor._makeSelection(QTextCursor.WordUnderCursor)
|
nwGUI.docEditor._makeSelection(QTextCursor.WordUnderCursor)
|
||||||
theCursor = nwGUI.docEditor.textCursor()
|
cursor = nwGUI.docEditor.textCursor()
|
||||||
assert theCursor.selectedText() == "est"
|
assert cursor.selectedText() == "est"
|
||||||
|
|
||||||
# Activate search again
|
# Activate search again
|
||||||
nwGUI.mainMenu.aFind.activate(QAction.Trigger)
|
nwGUI.mainMenu.aFind.activate(QAction.Trigger)
|
||||||
|
|||||||
@@ -187,8 +187,8 @@ def testGuiMenu_EditFormat(qtbot, monkeypatch, nwGUI, prjLipsum):
|
|||||||
# Select Paragraph/All
|
# Select Paragraph/All
|
||||||
nwGUI.docEditor.setCursorPosition(42)
|
nwGUI.docEditor.setCursorPosition(42)
|
||||||
nwGUI.mainMenu.aSelectPar.activate(QAction.Trigger)
|
nwGUI.mainMenu.aSelectPar.activate(QAction.Trigger)
|
||||||
theCursor = nwGUI.docEditor.textCursor()
|
cursor = nwGUI.docEditor.textCursor()
|
||||||
assert theCursor.selectedText() == (
|
assert cursor.selectedText() == (
|
||||||
"Pellentesque nec erat ut nulla posuere commodo. Curabitur nisi augue, imperdiet et porta "
|
"Pellentesque nec erat ut nulla posuere commodo. Curabitur nisi augue, imperdiet et porta "
|
||||||
"imperdiet, efficitur id leo. Cras finibus arcu at nibh commodo congue. Proin suscipit "
|
"imperdiet, efficitur id leo. Cras finibus arcu at nibh commodo congue. Proin suscipit "
|
||||||
"placerat condimentum. Aenean ante enim, cursus id lorem a, blandit venenatis nibh. "
|
"placerat condimentum. Aenean ante enim, cursus id lorem a, blandit venenatis nibh. "
|
||||||
@@ -200,8 +200,8 @@ def testGuiMenu_EditFormat(qtbot, monkeypatch, nwGUI, prjLipsum):
|
|||||||
|
|
||||||
nwGUI.docEditor.setCursorPosition(42)
|
nwGUI.docEditor.setCursorPosition(42)
|
||||||
nwGUI.mainMenu.aSelectAll.activate(QAction.Trigger)
|
nwGUI.mainMenu.aSelectAll.activate(QAction.Trigger)
|
||||||
theCursor = nwGUI.docEditor.textCursor()
|
cursor = nwGUI.docEditor.textCursor()
|
||||||
assert len(theCursor.selectedText()) == 1895
|
assert len(cursor.selectedText()) == 1895
|
||||||
|
|
||||||
# Clear the Text
|
# Clear the Text
|
||||||
nwGUI.docEditor.clear()
|
nwGUI.docEditor.clear()
|
||||||
@@ -295,10 +295,10 @@ def testGuiMenu_EditFormat(qtbot, monkeypatch, nwGUI, prjLipsum):
|
|||||||
"Here is some text\non multiple\nlines.\n\n"
|
"Here is some text\non multiple\nlines.\n\n"
|
||||||
"With another paragraph\nhere."
|
"With another paragraph\nhere."
|
||||||
))
|
))
|
||||||
theCursor = nwGUI.docEditor.textCursor()
|
cursor = nwGUI.docEditor.textCursor()
|
||||||
theCursor.setPosition(74)
|
cursor.setPosition(74)
|
||||||
theCursor.movePosition(QTextCursor.Right, QTextCursor.KeepAnchor, 29)
|
cursor.movePosition(QTextCursor.Right, QTextCursor.KeepAnchor, 29)
|
||||||
nwGUI.docEditor.setTextCursor(theCursor)
|
nwGUI.docEditor.setTextCursor(cursor)
|
||||||
nwGUI.mainMenu.aFmtRmBreaks.activate(QAction.Trigger)
|
nwGUI.mainMenu.aFmtRmBreaks.activate(QAction.Trigger)
|
||||||
assert nwGUI.docEditor.getText() == (
|
assert nwGUI.docEditor.getText() == (
|
||||||
"### New Text\n\n"
|
"### New Text\n\n"
|
||||||
@@ -348,21 +348,21 @@ def testGuiMenu_ContextMenus(qtbot, nwGUI, prjLipsum):
|
|||||||
assert nwGUI.openDocument("4c4f28287af27")
|
assert nwGUI.openDocument("4c4f28287af27")
|
||||||
|
|
||||||
# Editor Context Menu
|
# Editor Context Menu
|
||||||
theCursor = nwGUI.docEditor.textCursor()
|
cursor = nwGUI.docEditor.textCursor()
|
||||||
theCursor.setPosition(112)
|
cursor.setPosition(112)
|
||||||
nwGUI.docEditor.setTextCursor(theCursor)
|
nwGUI.docEditor.setTextCursor(cursor)
|
||||||
theRect = nwGUI.docEditor.cursorRect()
|
rect = nwGUI.docEditor.cursorRect()
|
||||||
|
|
||||||
nwGUI.docEditor._openContextMenu(theRect.bottomRight())
|
nwGUI.docEditor._openContextMenu(rect.bottomRight())
|
||||||
qtbot.mouseClick(nwGUI.docEditor, Qt.LeftButton, pos=theRect.topLeft())
|
qtbot.mouseClick(nwGUI.docEditor, Qt.LeftButton, pos=rect.topLeft())
|
||||||
|
|
||||||
nwGUI.docEditor._makePosSelection(QTextCursor.WordUnderCursor, theRect.center())
|
nwGUI.docEditor._makePosSelection(QTextCursor.WordUnderCursor, rect.center())
|
||||||
theCursor = nwGUI.docEditor.textCursor()
|
cursor = nwGUI.docEditor.textCursor()
|
||||||
assert theCursor.selectedText() == "imperdiet"
|
assert cursor.selectedText() == "imperdiet"
|
||||||
|
|
||||||
nwGUI.docEditor._makePosSelection(QTextCursor.BlockUnderCursor, theRect.center())
|
nwGUI.docEditor._makePosSelection(QTextCursor.BlockUnderCursor, rect.center())
|
||||||
theCursor = nwGUI.docEditor.textCursor()
|
cursor = nwGUI.docEditor.textCursor()
|
||||||
assert theCursor.selectedText() == (
|
assert cursor.selectedText() == (
|
||||||
"Pellentesque nec erat ut nulla posuere commodo. Curabitur nisi augue, imperdiet et porta "
|
"Pellentesque nec erat ut nulla posuere commodo. Curabitur nisi augue, imperdiet et porta "
|
||||||
"imperdiet, efficitur id leo. Cras finibus arcu at nibh commodo congue. Proin suscipit "
|
"imperdiet, efficitur id leo. Cras finibus arcu at nibh commodo congue. Proin suscipit "
|
||||||
"placerat condimentum. Aenean ante enim, cursus id lorem a, blandit venenatis nibh. "
|
"placerat condimentum. Aenean ante enim, cursus id lorem a, blandit venenatis nibh. "
|
||||||
@@ -375,21 +375,21 @@ def testGuiMenu_ContextMenus(qtbot, nwGUI, prjLipsum):
|
|||||||
# Viewer Context Menu
|
# Viewer Context Menu
|
||||||
assert nwGUI.viewDocument("4c4f28287af27")
|
assert nwGUI.viewDocument("4c4f28287af27")
|
||||||
|
|
||||||
theCursor = nwGUI.docViewer.textCursor()
|
cursor = nwGUI.docViewer.textCursor()
|
||||||
theCursor.setPosition(112)
|
cursor.setPosition(112)
|
||||||
nwGUI.docViewer.setTextCursor(theCursor)
|
nwGUI.docViewer.setTextCursor(cursor)
|
||||||
theRect = nwGUI.docViewer.cursorRect()
|
rect = nwGUI.docViewer.cursorRect()
|
||||||
|
|
||||||
nwGUI.docViewer._openContextMenu(theRect.bottomRight())
|
nwGUI.docViewer._openContextMenu(rect.bottomRight())
|
||||||
qtbot.mouseClick(nwGUI.docViewer, Qt.LeftButton, pos=theRect.topLeft())
|
qtbot.mouseClick(nwGUI.docViewer, Qt.LeftButton, pos=rect.topLeft())
|
||||||
|
|
||||||
nwGUI.docViewer._makePosSelection(QTextCursor.WordUnderCursor, theRect.center())
|
nwGUI.docViewer._makePosSelection(QTextCursor.WordUnderCursor, rect.center())
|
||||||
theCursor = nwGUI.docViewer.textCursor()
|
cursor = nwGUI.docViewer.textCursor()
|
||||||
assert theCursor.selectedText() == "imperdiet"
|
assert cursor.selectedText() == "imperdiet"
|
||||||
|
|
||||||
nwGUI.docEditor._makePosSelection(QTextCursor.BlockUnderCursor, theRect.center())
|
nwGUI.docEditor._makePosSelection(QTextCursor.BlockUnderCursor, rect.center())
|
||||||
theCursor = nwGUI.docEditor.textCursor()
|
cursor = nwGUI.docEditor.textCursor()
|
||||||
assert theCursor.selectedText() == (
|
assert cursor.selectedText() == (
|
||||||
"Pellentesque nec erat ut nulla posuere commodo. Curabitur nisi augue, imperdiet et porta "
|
"Pellentesque nec erat ut nulla posuere commodo. Curabitur nisi augue, imperdiet et porta "
|
||||||
"imperdiet, efficitur id leo. Cras finibus arcu at nibh commodo congue. Proin suscipit "
|
"imperdiet, efficitur id leo. Cras finibus arcu at nibh commodo congue. Proin suscipit "
|
||||||
"placerat condimentum. Aenean ante enim, cursus id lorem a, blandit venenatis nibh. "
|
"placerat condimentum. Aenean ante enim, cursus id lorem a, blandit venenatis nibh. "
|
||||||
@@ -629,12 +629,12 @@ def testGuiMenu_Insert(qtbot, monkeypatch, nwGUI, fncPath, projPath, mockRnd):
|
|||||||
assert not nwGUI.importDocument()
|
assert not nwGUI.importDocument()
|
||||||
|
|
||||||
# Then a valid path, but bot a file that exists
|
# Then a valid path, but bot a file that exists
|
||||||
theFile = fncPath / "import.txt"
|
iFile = fncPath / "import.txt"
|
||||||
monkeypatch.setattr(QFileDialog, "getOpenFileName", lambda *a, **k: (str(theFile), ""))
|
monkeypatch.setattr(QFileDialog, "getOpenFileName", lambda *a, **k: (str(iFile), ""))
|
||||||
assert not nwGUI.importDocument()
|
assert not nwGUI.importDocument()
|
||||||
|
|
||||||
# Create the file and try again, but with no target document open
|
# Create the file and try again, but with no target document open
|
||||||
writeFile(theFile, "Foo")
|
writeFile(iFile, "Foo")
|
||||||
assert not nwGUI.importDocument()
|
assert not nwGUI.importDocument()
|
||||||
|
|
||||||
# Open the document from before, and add some text to it
|
# Open the document from before, and add some text to it
|
||||||
|
|||||||
@@ -370,7 +370,7 @@ def testGuiProjTree_MoveItemToTrash(qtbot, caplog, monkeypatch, nwGUI, projPath,
|
|||||||
"""Test moving items to Trash."""
|
"""Test moving items to Trash."""
|
||||||
monkeypatch.setattr(GuiEditLabel, "getLabel", lambda *a, text: (text, True))
|
monkeypatch.setattr(GuiEditLabel, "getLabel", lambda *a, text: (text, True))
|
||||||
|
|
||||||
theProject = SHARED.project
|
project = SHARED.project
|
||||||
projTree = nwGUI.projView.projTree
|
projTree = nwGUI.projView.projTree
|
||||||
|
|
||||||
# Create a project
|
# Create a project
|
||||||
@@ -392,7 +392,7 @@ def testGuiProjTree_MoveItemToTrash(qtbot, caplog, monkeypatch, nwGUI, projPath,
|
|||||||
|
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
assert projTree.moveItemToTrash(C.hTitlePage) is False
|
assert projTree.moveItemToTrash(C.hTitlePage) is False
|
||||||
assert theProject.tree.isTrash(C.hTitlePage) is False
|
assert project.tree.isTrash(C.hTitlePage) is False
|
||||||
assert "Could not delete item" in caplog.text
|
assert "Could not delete item" in caplog.text
|
||||||
|
|
||||||
projTree._addTrashRoot = funcPointer
|
projTree._addTrashRoot = funcPointer
|
||||||
@@ -401,11 +401,11 @@ def testGuiProjTree_MoveItemToTrash(qtbot, caplog, monkeypatch, nwGUI, projPath,
|
|||||||
with monkeypatch.context() as mp:
|
with monkeypatch.context() as mp:
|
||||||
mp.setattr(QMessageBox, "result", lambda *a: QMessageBox.No)
|
mp.setattr(QMessageBox, "result", lambda *a: QMessageBox.No)
|
||||||
assert projTree.moveItemToTrash(C.hTitlePage) is False
|
assert projTree.moveItemToTrash(C.hTitlePage) is False
|
||||||
assert theProject.tree.isTrash(C.hTitlePage) is False
|
assert project.tree.isTrash(C.hTitlePage) is False
|
||||||
|
|
||||||
# Move a document to Trash
|
# Move a document to Trash
|
||||||
assert projTree.moveItemToTrash(C.hTitlePage) is True
|
assert projTree.moveItemToTrash(C.hTitlePage) is True
|
||||||
assert theProject.tree.isTrash(C.hTitlePage) is True
|
assert project.tree.isTrash(C.hTitlePage) is True
|
||||||
|
|
||||||
# Cannot be moved again
|
# Cannot be moved again
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
@@ -422,7 +422,7 @@ def testGuiProjTree_PermanentlyDeleteItem(qtbot, caplog, monkeypatch, nwGUI, pro
|
|||||||
"""Test permanently deleting items."""
|
"""Test permanently deleting items."""
|
||||||
monkeypatch.setattr(GuiEditLabel, "getLabel", lambda *a, text: (text, True))
|
monkeypatch.setattr(GuiEditLabel, "getLabel", lambda *a, text: (text, True))
|
||||||
|
|
||||||
theProject = SHARED.project
|
project = SHARED.project
|
||||||
projTree = nwGUI.projView.projTree
|
projTree = nwGUI.projView.projTree
|
||||||
|
|
||||||
# Create a project
|
# Create a project
|
||||||
@@ -437,31 +437,31 @@ def testGuiProjTree_PermanentlyDeleteItem(qtbot, caplog, monkeypatch, nwGUI, pro
|
|||||||
caplog.clear()
|
caplog.clear()
|
||||||
assert projTree.permDeleteItem(C.hNovelRoot) is False
|
assert projTree.permDeleteItem(C.hNovelRoot) is False
|
||||||
assert "Root folders can only be deleted when they are empty" in caplog.text
|
assert "Root folders can only be deleted when they are empty" in caplog.text
|
||||||
assert C.hNovelRoot in theProject.tree
|
assert C.hNovelRoot in project.tree
|
||||||
|
|
||||||
# Deleting unused root item is allowed
|
# Deleting unused root item is allowed
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
assert projTree.permDeleteItem(C.hPlotRoot) is True
|
assert projTree.permDeleteItem(C.hPlotRoot) is True
|
||||||
assert C.hPlotRoot not in theProject.tree
|
assert C.hPlotRoot not in project.tree
|
||||||
|
|
||||||
# User cancels action
|
# User cancels action
|
||||||
with monkeypatch.context() as mp:
|
with monkeypatch.context() as mp:
|
||||||
mp.setattr(QMessageBox, "result", lambda *a: QMessageBox.No)
|
mp.setattr(QMessageBox, "result", lambda *a: QMessageBox.No)
|
||||||
assert projTree.permDeleteItem(C.hTitlePage) is False
|
assert projTree.permDeleteItem(C.hTitlePage) is False
|
||||||
assert C.hTitlePage in theProject.tree
|
assert C.hTitlePage in project.tree
|
||||||
|
|
||||||
# Deleting file is OK, and if it is open, it should close
|
# Deleting file is OK, and if it is open, it should close
|
||||||
assert nwGUI.openDocument(C.hTitlePage) is True
|
assert nwGUI.openDocument(C.hTitlePage) is True
|
||||||
assert nwGUI.docEditor.docHandle == C.hTitlePage
|
assert nwGUI.docEditor.docHandle == C.hTitlePage
|
||||||
assert projTree.permDeleteItem(C.hTitlePage) is True
|
assert projTree.permDeleteItem(C.hTitlePage) is True
|
||||||
assert C.hTitlePage not in theProject.tree
|
assert C.hTitlePage not in project.tree
|
||||||
assert nwGUI.docEditor.docHandle is None
|
assert nwGUI.docEditor.docHandle is None
|
||||||
|
|
||||||
# Deleting folder + files recursively is ok
|
# Deleting folder + files recursively is ok
|
||||||
assert projTree.permDeleteItem(C.hChapterDir) is True
|
assert projTree.permDeleteItem(C.hChapterDir) is True
|
||||||
assert C.hChapterDir not in theProject.tree
|
assert C.hChapterDir not in project.tree
|
||||||
assert C.hChapterDoc not in theProject.tree
|
assert C.hChapterDoc not in project.tree
|
||||||
assert C.hSceneDoc not in theProject.tree
|
assert C.hSceneDoc not in project.tree
|
||||||
|
|
||||||
nwGUI.closeProject()
|
nwGUI.closeProject()
|
||||||
|
|
||||||
@@ -473,7 +473,7 @@ def testGuiProjTree_EmptyTrash(qtbot, caplog, monkeypatch, nwGUI, projPath, mock
|
|||||||
"""Test emptying Trash."""
|
"""Test emptying Trash."""
|
||||||
monkeypatch.setattr(GuiEditLabel, "getLabel", lambda *a, text: (text, True))
|
monkeypatch.setattr(GuiEditLabel, "getLabel", lambda *a, text: (text, True))
|
||||||
|
|
||||||
theProject = SHARED.project
|
project = SHARED.project
|
||||||
projTree = nwGUI.projView.projTree
|
projTree = nwGUI.projView.projTree
|
||||||
|
|
||||||
# No project open
|
# No project open
|
||||||
@@ -491,26 +491,26 @@ def testGuiProjTree_EmptyTrash(qtbot, caplog, monkeypatch, nwGUI, projPath, mock
|
|||||||
assert projTree.moveItemToTrash(C.hTitlePage) is True
|
assert projTree.moveItemToTrash(C.hTitlePage) is True
|
||||||
assert projTree.moveItemToTrash(C.hChapterDir) is True
|
assert projTree.moveItemToTrash(C.hChapterDir) is True
|
||||||
|
|
||||||
assert theProject.tree.isTrash(C.hTitlePage) is True
|
assert project.tree.isTrash(C.hTitlePage) is True
|
||||||
assert theProject.tree.isTrash(C.hChapterDir) is True
|
assert project.tree.isTrash(C.hChapterDir) is True
|
||||||
assert theProject.tree.isTrash(C.hChapterDoc) is True
|
assert project.tree.isTrash(C.hChapterDoc) is True
|
||||||
assert theProject.tree.isTrash(C.hSceneDoc) is True
|
assert project.tree.isTrash(C.hSceneDoc) is True
|
||||||
|
|
||||||
# User cancels
|
# User cancels
|
||||||
with monkeypatch.context() as mp:
|
with monkeypatch.context() as mp:
|
||||||
mp.setattr(QMessageBox, "result", lambda *a: QMessageBox.No)
|
mp.setattr(QMessageBox, "result", lambda *a: QMessageBox.No)
|
||||||
assert projTree.emptyTrash() is False
|
assert projTree.emptyTrash() is False
|
||||||
assert C.hTitlePage in theProject.tree
|
assert C.hTitlePage in project.tree
|
||||||
assert C.hChapterDir in theProject.tree
|
assert C.hChapterDir in project.tree
|
||||||
assert C.hChapterDoc in theProject.tree
|
assert C.hChapterDoc in project.tree
|
||||||
assert C.hSceneDoc in theProject.tree
|
assert C.hSceneDoc in project.tree
|
||||||
|
|
||||||
# Run again to empty all items
|
# Run again to empty all items
|
||||||
assert projTree.emptyTrash() is True
|
assert projTree.emptyTrash() is True
|
||||||
assert C.hTitlePage not in theProject.tree
|
assert C.hTitlePage not in project.tree
|
||||||
assert C.hChapterDir not in theProject.tree
|
assert C.hChapterDir not in project.tree
|
||||||
assert C.hChapterDoc not in theProject.tree
|
assert C.hChapterDoc not in project.tree
|
||||||
assert C.hSceneDoc not in theProject.tree
|
assert C.hSceneDoc not in project.tree
|
||||||
|
|
||||||
# Running Empty Trash again is cancelled due to empty folder
|
# Running Empty Trash again is cancelled due to empty folder
|
||||||
assert projTree.emptyTrash() is False
|
assert projTree.emptyTrash() is False
|
||||||
@@ -634,7 +634,7 @@ def testGuiProjTree_SplitDocument(qtbot, monkeypatch, nwGUI, projPath, mockRnd,
|
|||||||
# Create a project
|
# Create a project
|
||||||
buildTestProject(nwGUI, projPath)
|
buildTestProject(nwGUI, projPath)
|
||||||
|
|
||||||
theProject = SHARED.project
|
project = SHARED.project
|
||||||
projTree = nwGUI.projView.projTree
|
projTree = nwGUI.projView.projTree
|
||||||
|
|
||||||
docText = (
|
docText = (
|
||||||
@@ -652,8 +652,8 @@ def testGuiProjTree_SplitDocument(qtbot, monkeypatch, nwGUI, projPath, mockRnd,
|
|||||||
"#### New Section\n\nText\n\n"
|
"#### New Section\n\nText\n\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
hSplitDoc = theProject.newFile("Split Doc", C.hNovelRoot)
|
hSplitDoc = project.newFile("Split Doc", C.hNovelRoot)
|
||||||
theProject.writeNewFile(hSplitDoc, 1, True, docText) # type: ignore
|
project.writeNewFile(hSplitDoc, 1, True, docText) # type: ignore
|
||||||
projTree.revealNewTreeItem(hSplitDoc, nHandle=C.hNovelRoot, wordCount=True)
|
projTree.revealNewTreeItem(hSplitDoc, nHandle=C.hNovelRoot, wordCount=True)
|
||||||
|
|
||||||
docText = f"# Split Doc\n\n{docText}"
|
docText = f"# Split Doc\n\n{docText}"
|
||||||
@@ -700,25 +700,25 @@ def testGuiProjTree_SplitDocument(qtbot, monkeypatch, nwGUI, projPath, mockRnd,
|
|||||||
mp.setattr("builtins.open", causeOSError)
|
mp.setattr("builtins.open", causeOSError)
|
||||||
assert projTree._splitDocument(hSplitDoc) is True
|
assert projTree._splitDocument(hSplitDoc) is True
|
||||||
for tHandle in fstSet:
|
for tHandle in fstSet:
|
||||||
assert tHandle in theProject.tree
|
assert tHandle in project.tree
|
||||||
assert not (projPath / "content" / f"{tHandle}.nwd").is_file()
|
assert not (projPath / "content" / f"{tHandle}.nwd").is_file()
|
||||||
|
|
||||||
# Writing succeeds
|
# Writing succeeds
|
||||||
assert projTree._splitDocument(hSplitDoc) is True
|
assert projTree._splitDocument(hSplitDoc) is True
|
||||||
for tHandle in sndSet:
|
for tHandle in sndSet:
|
||||||
assert tHandle in theProject.tree
|
assert tHandle in project.tree
|
||||||
assert (projPath / "content" / f"{tHandle}.nwd").is_file()
|
assert (projPath / "content" / f"{tHandle}.nwd").is_file()
|
||||||
|
|
||||||
# Add to a folder and move source to trash
|
# Add to a folder and move source to trash
|
||||||
splitData["intoFolder"] = True
|
splitData["intoFolder"] = True
|
||||||
splitData["moveToTrash"] = True
|
splitData["moveToTrash"] = True
|
||||||
assert projTree._splitDocument(hSplitDoc) is True
|
assert projTree._splitDocument(hSplitDoc) is True
|
||||||
assert "0000000000029" in theProject.tree # The folder
|
assert "0000000000029" in project.tree # The folder
|
||||||
for tHandle in trdSet:
|
for tHandle in trdSet:
|
||||||
assert tHandle in theProject.tree
|
assert tHandle in project.tree
|
||||||
assert (projPath / "content" / f"{tHandle}.nwd").is_file()
|
assert (projPath / "content" / f"{tHandle}.nwd").is_file()
|
||||||
|
|
||||||
assert theProject.tree.isTrash(hSplitDoc) is True # type: ignore
|
assert project.tree.isTrash(hSplitDoc) is True # type: ignore
|
||||||
|
|
||||||
# Cancelled by user
|
# Cancelled by user
|
||||||
with monkeypatch.context() as mp:
|
with monkeypatch.context() as mp:
|
||||||
|
|||||||
Reference in New Issue
Block a user