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