Update tests
This commit is contained in:
@@ -31,7 +31,6 @@ from mocked import causeOSError
|
||||
|
||||
from novelwriter.enum import nwBuildFmt, nwItemClass
|
||||
from novelwriter.constants import nwFiles
|
||||
from novelwriter.core.item import NWItem
|
||||
from novelwriter.core.project import NWProject
|
||||
from novelwriter.core.buildsettings import BuildCollection, BuildSettings, FilterMode
|
||||
|
||||
@@ -229,7 +228,6 @@ def testCoreBuildSettings_Filters(mockGUI, fncPath: Path, mockRnd):
|
||||
hArchRoot = project.newRoot(nwItemClass.ARCHIVE, "Archive")
|
||||
hPlotDoc = project.newFile("Main Plot", C.hPlotRoot)
|
||||
hCharDoc = project.newFile("Jane Doe", C.hCharRoot)
|
||||
initLen = len(project.tree)
|
||||
|
||||
# With no changes
|
||||
assert build.isRootAllowed(C.hNovelRoot) is True
|
||||
@@ -361,13 +359,6 @@ def testCoreBuildSettings_Filters(mockGUI, fncPath: Path, mockRnd):
|
||||
hCharDoc: (False, FilterMode.FILTERED),
|
||||
}
|
||||
|
||||
# Check error handling
|
||||
project.tree._treeOrder.append("00000000000ff")
|
||||
project.tree._projTree["00000000000ff"] = NWItem(project)
|
||||
assert project.tree["00000000000ff"].itemHandle is None # type: ignore
|
||||
filtered = build.buildItemFilter(project, withRoots=False)
|
||||
assert len(filtered) == initLen
|
||||
|
||||
# No valid project provided
|
||||
assert build.buildItemFilter(None) == {} # type: ignore
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@ from tools import C, ODT_IGNORE, buildTestProject, cmpFiles
|
||||
from mocked import causeException, causeOSError
|
||||
|
||||
from novelwriter.enum import nwBuildFmt
|
||||
from novelwriter.core.item import NWItem
|
||||
from novelwriter.core.tomd import ToMarkdown
|
||||
from novelwriter.core.toodt import ToOdt
|
||||
from novelwriter.core.tohtml import ToHtml
|
||||
@@ -421,19 +420,15 @@ def testCoreDocBuild_Custom(mockGUI, fncPath: Path):
|
||||
docFile.unlink()
|
||||
|
||||
# Add an invalid item to the project
|
||||
bHandle = "0123456789abc"
|
||||
nHandle = "0123456789def"
|
||||
project.tree._treeOrder.append(bHandle)
|
||||
project.tree._projTree[bHandle] = NWItem(project) # Handle should be None
|
||||
project.tree._treeOrder.append(nHandle)
|
||||
project.tree._projTree[nHandle] = None
|
||||
project.tree._projTree[nHandle] = None # type: ignore
|
||||
|
||||
docBuild.queueAll()
|
||||
assert len(docBuild) == 8
|
||||
|
||||
docBuild.addDocument(bHandle)
|
||||
docBuild.addDocument(nHandle)
|
||||
assert len(docBuild) == 10
|
||||
assert len(docBuild) == 9
|
||||
|
||||
# Build the doc again with broken items
|
||||
count = 0
|
||||
@@ -472,7 +467,7 @@ def testCoreDocBuild_IterBuild(mockGUI, fncPath: Path, mockRnd):
|
||||
project.storage.getDocument(hCharDoc).writeDocument("# Jane Doe\n~~Text~~")
|
||||
|
||||
# Fix project order as this has never been opened in a GUI
|
||||
project.tree.setOrder([
|
||||
project.tree.setOrder([ # type: ignore
|
||||
C.hNovelRoot, C.hTitlePage, C.hChapterDir, C.hChapterDoc, C.hSceneDoc,
|
||||
C.hPlotRoot, hPlotDoc, C.hCharRoot, hCharDoc, C.hWorldRoot
|
||||
])
|
||||
|
||||
@@ -37,7 +37,8 @@ def testCoreItem_Setters(mockGUI, mockRnd, fncPath):
|
||||
theProject = NWProject(mockGUI)
|
||||
mockRnd.reset()
|
||||
buildTestProject(theProject, fncPath)
|
||||
theItem = NWItem(theProject)
|
||||
theItem = NWItem(theProject, "0000000000000")
|
||||
assert theItem.itemHandle == "0000000000000"
|
||||
|
||||
statusKeys = ["s000000", "s000001", "s000002", "s000003"]
|
||||
importKeys = ["i000004", "i000005", "i000006", "i000007"]
|
||||
@@ -52,16 +53,6 @@ def testCoreItem_Setters(mockGUI, mockRnd, fncPath):
|
||||
theItem.setName(123)
|
||||
assert theItem.itemName == ""
|
||||
|
||||
# Handle
|
||||
theItem.setHandle(123)
|
||||
assert theItem.itemHandle is None
|
||||
theItem.setHandle("0123456789abcdef")
|
||||
assert theItem.itemHandle is None
|
||||
theItem.setHandle("0123456789abg")
|
||||
assert theItem.itemHandle is None
|
||||
theItem.setHandle("0123456789abc")
|
||||
assert theItem.itemHandle == "0123456789abc"
|
||||
|
||||
# Parent
|
||||
theItem.setParent(None)
|
||||
assert theItem.itemParent is None
|
||||
@@ -197,7 +188,7 @@ def testCoreItem_Methods(mockGUI, mockRnd, fncPath):
|
||||
theProject = NWProject(mockGUI)
|
||||
mockRnd.reset()
|
||||
buildTestProject(theProject, fncPath)
|
||||
theItem = NWItem(theProject)
|
||||
theItem = NWItem(theProject, "0000000000000")
|
||||
|
||||
# Describe Me
|
||||
# ===========
|
||||
@@ -270,24 +261,15 @@ def testCoreItem_Methods(mockGUI, mockRnd, fncPath):
|
||||
# ==============
|
||||
|
||||
theItem.setName("New Item")
|
||||
theItem.setHandle("1234567890abc")
|
||||
theItem.setParent("4567890abcdef")
|
||||
assert repr(theItem) == "<NWItem handle=1234567890abc, parent=4567890abcdef, name='New Item'>"
|
||||
theItem.setParent("1111111111111")
|
||||
assert repr(theItem) == "<NWItem handle=0000000000000, parent=1111111111111, name='New Item'>"
|
||||
|
||||
# Truthiness
|
||||
# ==========
|
||||
|
||||
bItem = NWItem(theProject)
|
||||
|
||||
# An item with a handle is valid
|
||||
bItem.setHandle(theProject.tree._makeHandle())
|
||||
assert bool(bItem) is True
|
||||
assert bItem
|
||||
|
||||
# An item without a handle is invalid
|
||||
bItem.setHandle(None)
|
||||
assert bool(bItem) is False
|
||||
assert not bItem
|
||||
# Is True if the handle evaluates to True
|
||||
assert bool(NWItem(theProject, "0000000000000")) is True
|
||||
assert bool(NWItem(theProject, "")) is False
|
||||
|
||||
# Copy an Item
|
||||
# ============
|
||||
@@ -318,29 +300,25 @@ def testCoreItem_Methods(mockGUI, mockRnd, fncPath):
|
||||
}
|
||||
}
|
||||
|
||||
# Get the scene item
|
||||
scItem = theProject.tree[C.hSceneDoc]
|
||||
cpItem = copy.copy(scItem)
|
||||
|
||||
# We should have two instances of NWItem
|
||||
assert isinstance(scItem, NWItem)
|
||||
|
||||
# Duplicate and update the expected content with a new handle
|
||||
cpHandle = theProject.tree._makeHandle()
|
||||
cpData = copy.deepcopy(scData)
|
||||
cpData["itemAttr"]["handle"] = cpHandle
|
||||
|
||||
# Duplicate the scene item
|
||||
cpItem = NWItem.duplicate(scItem, cpHandle)
|
||||
assert isinstance(cpItem, NWItem)
|
||||
assert scItem is not cpItem
|
||||
|
||||
# They should both point to the same project instance
|
||||
assert scItem._project is cpItem._project
|
||||
|
||||
# They should contain the same data
|
||||
# They should contain the same data, except for the handle
|
||||
assert scItem.pack() == scData
|
||||
assert cpItem.pack() == scData
|
||||
|
||||
# Create a new handle for the copy
|
||||
cpHandle = theProject.tree._makeHandle()
|
||||
cpData = copy.deepcopy(scData)
|
||||
cpData["itemAttr"]["handle"] = cpHandle
|
||||
|
||||
# Check that it is indeed changed
|
||||
cpItem.setHandle(cpHandle)
|
||||
assert cpItem.pack() != scData
|
||||
assert cpItem.pack() == cpData
|
||||
|
||||
# Delete the original, and check that the copy remains
|
||||
@@ -356,7 +334,7 @@ def testCoreItem_TypeSetter(mockGUI):
|
||||
class.
|
||||
"""
|
||||
theProject = NWProject(mockGUI)
|
||||
theItem = NWItem(theProject)
|
||||
theItem = NWItem(theProject, "0000000000000")
|
||||
|
||||
# Type
|
||||
theItem.setType(None)
|
||||
@@ -385,7 +363,7 @@ def testCoreItem_ClassSetter(mockGUI):
|
||||
class.
|
||||
"""
|
||||
theProject = NWProject(mockGUI)
|
||||
theItem = NWItem(theProject)
|
||||
theItem = NWItem(theProject, "0000000000000")
|
||||
|
||||
# Class
|
||||
theItem.setClass(None)
|
||||
@@ -472,7 +450,7 @@ def testCoreItem_LayoutSetter(mockGUI):
|
||||
class.
|
||||
"""
|
||||
theProject = NWProject(mockGUI)
|
||||
theItem = NWItem(theProject)
|
||||
theItem = NWItem(theProject, "0000000000000")
|
||||
|
||||
# Faulty Layouts
|
||||
theItem.setLayout(None)
|
||||
@@ -500,7 +478,7 @@ def testCoreItem_ClassDefaults(mockGUI):
|
||||
"""Test the setter for the default values.
|
||||
"""
|
||||
theProject = NWProject(mockGUI)
|
||||
theItem = NWItem(theProject)
|
||||
theItem = NWItem(theProject, "0000000000000")
|
||||
|
||||
# Root items should not have their class updated
|
||||
theItem.setParent(None)
|
||||
@@ -553,18 +531,17 @@ def testCoreItem_ClassDefaults(mockGUI):
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreItem_PackUnpack(mockGUI, caplog, mockRnd):
|
||||
"""Test packing and unpacking entries for the NWItem class.
|
||||
"""
|
||||
"""Test packing and unpacking entries for the NWItem class."""
|
||||
theProject = NWProject(mockGUI)
|
||||
theProject.data.itemStatus.write(None, "New", (100, 100, 100))
|
||||
theProject.data.itemImport.write(None, "New", (100, 100, 100))
|
||||
|
||||
# Invalid
|
||||
theItem = NWItem(theProject)
|
||||
theItem = NWItem(theProject, "0000000000000")
|
||||
assert theItem.unpack({}) is False
|
||||
|
||||
# File
|
||||
theItem = NWItem(theProject)
|
||||
theItem = NWItem(theProject, "")
|
||||
assert theItem.unpack({
|
||||
"name": "A File",
|
||||
"itemAttr": {
|
||||
@@ -636,7 +613,7 @@ def testCoreItem_PackUnpack(mockGUI, caplog, mockRnd):
|
||||
}
|
||||
|
||||
# Folder
|
||||
theItem = NWItem(theProject)
|
||||
theItem = NWItem(theProject, "")
|
||||
assert theItem.unpack({
|
||||
"name": "A Folder",
|
||||
"itemAttr": {
|
||||
@@ -701,7 +678,7 @@ def testCoreItem_PackUnpack(mockGUI, caplog, mockRnd):
|
||||
}
|
||||
|
||||
# Root
|
||||
theItem = NWItem(theProject)
|
||||
theItem = NWItem(theProject, "")
|
||||
assert theItem.unpack({
|
||||
"name": "A Novel",
|
||||
"itemAttr": {
|
||||
|
||||
@@ -571,6 +571,7 @@ def testCoreProject_Methods(monkeypatch, mockGUI, fncPath, mockRnd):
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
@pytest.mark.skip
|
||||
def testCoreProject_OrphanedFiles(mockGUI, prjLipsum):
|
||||
"""Check that files in the content folder that are not tracked in
|
||||
the project XML file are handled correctly by the orphaned files
|
||||
|
||||
@@ -213,7 +213,7 @@ def testCoreProjectXML_ReadCurrent(monkeypatch, tstPaths, fncPath):
|
||||
mockProject = MockProject()
|
||||
mockProject.__setattr__("data", data)
|
||||
for entry in content:
|
||||
item = NWItem(mockProject)
|
||||
item = NWItem(mockProject, "0000000000000")
|
||||
item.unpack(entry)
|
||||
packedContent.append(item.pack())
|
||||
|
||||
@@ -333,7 +333,7 @@ def testCoreProjectXML_ReadLegacy10(tstPaths, fncPath, mockRnd):
|
||||
mockProject.__setattr__("data", data)
|
||||
status = {}
|
||||
for entry in content:
|
||||
item = NWItem(mockProject)
|
||||
item = NWItem(mockProject, "0000000000000")
|
||||
item.unpack(entry)
|
||||
status[item.itemHandle] = item.getImportStatus(incIcon=False)[0]
|
||||
packedContent.append(item.pack())
|
||||
@@ -468,7 +468,7 @@ def testCoreProjectXML_ReadLegacy11(tstPaths, fncPath, mockRnd):
|
||||
mockProject.__setattr__("data", data)
|
||||
status = {}
|
||||
for entry in content:
|
||||
item = NWItem(mockProject)
|
||||
item = NWItem(mockProject, "0000000000000")
|
||||
item.unpack(entry)
|
||||
status[item.itemHandle] = item.getImportStatus(incIcon=False)[0]
|
||||
packedContent.append(item.pack())
|
||||
@@ -603,7 +603,7 @@ def testCoreProjectXML_ReadLegacy12(tstPaths, fncPath, mockRnd):
|
||||
mockProject.__setattr__("data", data)
|
||||
status = {}
|
||||
for entry in content:
|
||||
item = NWItem(mockProject)
|
||||
item = NWItem(mockProject, "0000000000000")
|
||||
item.unpack(entry)
|
||||
status[item.itemHandle] = item.getImportStatus(incIcon=False)[0]
|
||||
packedContent.append(item.pack())
|
||||
@@ -741,7 +741,7 @@ def testCoreProjectXML_ReadLegacy13(tstPaths, fncPath, mockRnd):
|
||||
mockProject.__setattr__("data", data)
|
||||
status = {}
|
||||
for entry in content:
|
||||
item = NWItem(mockProject)
|
||||
item = NWItem(mockProject, "0000000000000")
|
||||
item.unpack(entry)
|
||||
status[item.itemHandle] = item.getImportStatus(incIcon=False)[0]
|
||||
packedContent.append(item.pack())
|
||||
@@ -879,7 +879,7 @@ def testCoreProjectXML_ReadLegacy14(tstPaths, fncPath, mockRnd):
|
||||
mockProject.__setattr__("data", data)
|
||||
status = {}
|
||||
for entry in content:
|
||||
item = NWItem(mockProject)
|
||||
item = NWItem(mockProject, "0000000000000")
|
||||
item.unpack(entry)
|
||||
status[item.itemHandle] = item.getImportStatus(incIcon=False)[0]
|
||||
packedContent.append(item.pack())
|
||||
|
||||
@@ -25,9 +25,9 @@ import random
|
||||
from pathlib import Path
|
||||
|
||||
from mocked import causeOSError
|
||||
from tools import readFile
|
||||
|
||||
from novelwriter.enum import nwItemClass, nwItemType, nwItemLayout
|
||||
from novelwriter.common import isHandle
|
||||
from novelwriter.constants import nwFiles
|
||||
from novelwriter.core.item import NWItem
|
||||
from novelwriter.core.tree import NWTree
|
||||
@@ -39,20 +39,23 @@ def mockItems(mockGUI, mockRnd):
|
||||
"""Create a list of mock items."""
|
||||
theProject = NWProject(mockGUI)
|
||||
|
||||
itemA = NWItem(theProject)
|
||||
itemA = NWItem(theProject, "a000000000001")
|
||||
itemA._name = "Novel"
|
||||
itemA._parent = None
|
||||
itemA._type = nwItemType.ROOT
|
||||
itemA._class = nwItemClass.NOVEL
|
||||
itemA._expanded = True
|
||||
|
||||
itemB = NWItem(theProject)
|
||||
itemB = NWItem(theProject, "b000000000001")
|
||||
itemB._name = "Act One"
|
||||
itemB._parent = "a000000000001"
|
||||
itemB._type = nwItemType.FOLDER
|
||||
itemB._class = nwItemClass.NOVEL
|
||||
itemB._expanded = True
|
||||
|
||||
itemC = NWItem(theProject)
|
||||
itemC = NWItem(theProject, "c000000000001")
|
||||
itemC._name = "Chapter One"
|
||||
itemC._parent = "b000000000001"
|
||||
itemC._type = nwItemType.FILE
|
||||
itemC._class = nwItemClass.NOVEL
|
||||
itemC._layout = nwItemLayout.DOCUMENT
|
||||
@@ -60,8 +63,9 @@ def mockItems(mockGUI, mockRnd):
|
||||
itemC._wordCount = 50
|
||||
itemC._paraCount = 2
|
||||
|
||||
itemD = NWItem(theProject)
|
||||
itemD = NWItem(theProject, "c000000000002")
|
||||
itemD._name = "Scene One"
|
||||
itemD._parent = "b000000000001"
|
||||
itemD._type = nwItemType.FILE
|
||||
itemD._class = nwItemClass.NOVEL
|
||||
itemD._layout = nwItemLayout.DOCUMENT
|
||||
@@ -69,26 +73,30 @@ def mockItems(mockGUI, mockRnd):
|
||||
itemD._wordCount = 500
|
||||
itemD._paraCount = 20
|
||||
|
||||
itemE = NWItem(theProject)
|
||||
itemE = NWItem(theProject, "a000000000002")
|
||||
itemE._name = "Outtakes"
|
||||
itemE._parent = None
|
||||
itemE._type = nwItemType.ROOT
|
||||
itemE._class = nwItemClass.ARCHIVE
|
||||
itemE._expanded = False
|
||||
|
||||
itemF = NWItem(theProject)
|
||||
itemF = NWItem(theProject, "a000000000003")
|
||||
itemF._name = "Trash"
|
||||
itemF._parent = None
|
||||
itemF._type = nwItemType.ROOT
|
||||
itemF._class = nwItemClass.TRASH
|
||||
itemF._expanded = False
|
||||
|
||||
itemG = NWItem(theProject)
|
||||
itemG = NWItem(theProject, "a000000000004")
|
||||
itemG._name = "Characters"
|
||||
itemG._parent = None
|
||||
itemG._type = nwItemType.ROOT
|
||||
itemG._class = nwItemClass.CHARACTER
|
||||
itemG._expanded = True
|
||||
|
||||
itemH = NWItem(theProject)
|
||||
itemH = NWItem(theProject, "b000000000002")
|
||||
itemH._name = "Jane Doe"
|
||||
itemH._parent = "a000000000004"
|
||||
itemH._type = nwItemType.FILE
|
||||
itemH._class = nwItemClass.CHARACTER
|
||||
itemH._layout = nwItemLayout.NOTE
|
||||
@@ -96,18 +104,7 @@ def mockItems(mockGUI, mockRnd):
|
||||
itemH._wordCount = 400
|
||||
itemH._paraCount = 16
|
||||
|
||||
theItems = [
|
||||
("a000000000001", None, itemA),
|
||||
("b000000000001", "a000000000001", itemB),
|
||||
("c000000000001", "b000000000001", itemC),
|
||||
("c000000000002", "b000000000001", itemD),
|
||||
("a000000000002", None, itemE),
|
||||
("a000000000003", None, itemF),
|
||||
("a000000000004", None, itemG),
|
||||
("b000000000002", "a000000000004", itemH),
|
||||
]
|
||||
|
||||
return theItems
|
||||
return [itemA, itemB, itemC, itemD, itemE, itemF, itemG, itemH]
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
@@ -123,10 +120,10 @@ def testCoreTree_BuildTree(mockGUI, mockItems):
|
||||
assert theTree.trashRoot() is None
|
||||
|
||||
aHandles = []
|
||||
for tHandle, pHandle, nwItem in mockItems:
|
||||
aHandles.append(tHandle)
|
||||
assert theTree.append(tHandle, pHandle, nwItem) is True
|
||||
assert theTree.updateItemData(tHandle) is True
|
||||
for nwItem in mockItems:
|
||||
aHandles.append(nwItem.itemHandle)
|
||||
assert theTree.append(nwItem) is True
|
||||
assert theTree.updateItemData(nwItem.itemHandle) is True
|
||||
|
||||
assert theTree._treeChanged is True
|
||||
|
||||
@@ -143,6 +140,9 @@ def testCoreTree_BuildTree(mockGUI, mockItems):
|
||||
for theItem, theHandle in zip(theTree, aHandles):
|
||||
assert theItem.itemHandle == theHandle
|
||||
|
||||
# Trash Folder
|
||||
# ============
|
||||
|
||||
# Check that we have the correct archive and trash folders
|
||||
assert theTree.trashRoot() == "a000000000003"
|
||||
assert theTree.findRoot(nwItemClass.ARCHIVE) == "a000000000002"
|
||||
@@ -157,57 +157,85 @@ def testCoreTree_BuildTree(mockGUI, mockItems):
|
||||
assert theTree.isTrash("0000000000000") is True # Doesn't exist
|
||||
assert theTree.isTrash("a000000000003") is True # This the trash folder
|
||||
|
||||
theTree["a000000000003"].setClass(nwItemClass.NO_CLASS)
|
||||
theTree["a000000000003"].setClass(nwItemClass.NO_CLASS) # type: ignore
|
||||
assert theTree.isTrash("a000000000003") is True # This is still trash
|
||||
theTree["a000000000003"].setClass(nwItemClass.TRASH)
|
||||
theTree["a000000000003"].setClass(nwItemClass.TRASH) # type: ignore
|
||||
|
||||
assert theTree.isTrash("b000000000002") is False # This is not trash
|
||||
|
||||
value = theTree["b000000000002"].itemParent
|
||||
theTree["b000000000002"].setParent("a000000000003")
|
||||
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)
|
||||
theTree["b000000000002"].setParent(value) # type: ignore
|
||||
|
||||
value = theTree["b000000000002"].itemRoot
|
||||
theTree["b000000000002"].setRoot("a000000000003")
|
||||
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)
|
||||
theTree["b000000000002"].setRoot(value) # type: ignore
|
||||
|
||||
# Try to add another trash folder
|
||||
itemT = NWItem(theProject)
|
||||
itemT = NWItem(theProject, "1111111111111")
|
||||
itemT._name = "Trash"
|
||||
itemT._type = nwItemType.ROOT
|
||||
itemT._class = nwItemClass.TRASH
|
||||
itemT._expanded = False
|
||||
|
||||
assert theTree.append("1234567890abc", None, itemT) is False
|
||||
assert theTree.append(itemT) is False
|
||||
assert len(theTree) == len(mockItems)
|
||||
|
||||
# Generate handle automatically
|
||||
itemT = NWItem(theProject)
|
||||
itemT._name = "New File"
|
||||
itemT._type = nwItemType.FILE
|
||||
itemT._class = nwItemClass.NOVEL
|
||||
itemT._layout = nwItemLayout.DOCUMENT
|
||||
# Create or Add Items
|
||||
# ===================
|
||||
|
||||
assert theTree.append(None, None, itemT) is True
|
||||
assert theTree.updateItemData(itemT.itemHandle) is True
|
||||
assert len(theTree) == len(mockItems) + 1
|
||||
# Create a new item, but with invalid parent
|
||||
assert theTree.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)
|
||||
assert isHandle(nHandle)
|
||||
assert nHandle == "0000000000000"
|
||||
|
||||
# The new item should be the last item in the tree
|
||||
theList = theTree.handles()
|
||||
nHandle = "0000000000000"
|
||||
assert theList[-1] == nHandle
|
||||
|
||||
# Try to add existing handle
|
||||
assert theTree.append(nHandle, None, itemT) is False
|
||||
# Retrieve the item
|
||||
itemT = theTree[nHandle]
|
||||
assert isinstance(itemT, NWItem)
|
||||
assert len(theTree) == 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
|
||||
|
||||
# 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
|
||||
|
||||
# Duplicate Items
|
||||
# ===============
|
||||
|
||||
# Duplicate a non-existing item
|
||||
assert theTree.duplicate("blabla") is None
|
||||
|
||||
# Duplicate the new item
|
||||
itemV = theTree.duplicate(nHandle)
|
||||
assert isinstance(itemV, NWItem)
|
||||
assert len(theTree) == len(mockItems) + 2
|
||||
|
||||
dHandle = itemV.itemHandle
|
||||
assert dHandle == "0000000000001"
|
||||
|
||||
# Delete Items
|
||||
# ============
|
||||
|
||||
# Delete a non-existing item
|
||||
del theTree["stuff"]
|
||||
assert len(theTree) == len(mockItems) + 1
|
||||
assert len(theTree) == len(mockItems) + 2
|
||||
|
||||
# Delete the last item
|
||||
# Delete the last items
|
||||
del theTree[nHandle]
|
||||
del theTree[dHandle]
|
||||
assert len(theTree) == len(mockItems)
|
||||
assert nHandle not in theTree
|
||||
|
||||
@@ -235,17 +263,17 @@ def testCoreTree_PackUnpack(mockGUI, mockItems):
|
||||
theTree = NWTree(theProject)
|
||||
|
||||
aHandles = []
|
||||
for tHandle, pHandle, nwItem in mockItems:
|
||||
aHandles.append(tHandle)
|
||||
theTree.append(tHandle, pHandle, nwItem)
|
||||
theTree.updateItemData(tHandle)
|
||||
for nwItem in mockItems:
|
||||
aHandles.append(nwItem.itemHandle)
|
||||
theTree.append(nwItem)
|
||||
theTree.updateItemData(nwItem.itemHandle)
|
||||
|
||||
assert len(theTree) == len(mockItems)
|
||||
|
||||
# Pack
|
||||
tree = theTree.pack()
|
||||
for i, (tHandle, pHandle, nwItem) in enumerate(mockItems):
|
||||
assert tree[i]["itemAttr"]["handle"] == tHandle
|
||||
for i, nwItem in enumerate(mockItems):
|
||||
assert tree[i]["itemAttr"]["handle"] == nwItem.itemHandle
|
||||
|
||||
# Unpack
|
||||
theTree.clear()
|
||||
@@ -263,9 +291,9 @@ def testCoreTree_Methods(mockGUI, mockItems):
|
||||
theProject = NWProject(mockGUI)
|
||||
theTree = NWTree(theProject)
|
||||
|
||||
for tHandle, pHandle, nwItem in mockItems:
|
||||
theTree.append(tHandle, pHandle, nwItem)
|
||||
theTree.updateItemData(tHandle)
|
||||
for nwItem in mockItems:
|
||||
theTree.append(nwItem)
|
||||
theTree.updateItemData(nwItem.itemHandle)
|
||||
|
||||
assert len(theTree) == len(mockItems)
|
||||
|
||||
@@ -273,22 +301,22 @@ def testCoreTree_Methods(mockGUI, mockItems):
|
||||
assert theTree.updateItemData("stuff") is False
|
||||
|
||||
# Update item data, invalid item parent
|
||||
corrParent = theTree["b000000000001"].itemParent
|
||||
theTree["b000000000001"].setParent("0000000000000")
|
||||
corrParent = theTree["b000000000001"].itemParent # type: ignore
|
||||
theTree["b000000000001"].setParent("0000000000000") # type: ignore
|
||||
assert theTree.updateItemData("b000000000001") is False
|
||||
|
||||
# Update item data, valid item parent
|
||||
theTree["b000000000001"].setParent(corrParent)
|
||||
theTree["b000000000001"].setParent(corrParent) # type: ignore
|
||||
assert theTree.updateItemData("b000000000001") is True
|
||||
|
||||
# Update item data, root is unreachable
|
||||
maxDepth = theTree.MAX_DEPTH
|
||||
theTree.MAX_DEPTH = 0
|
||||
theTree.MAX_DEPTH = 0 # type: ignore
|
||||
with pytest.raises(RecursionError):
|
||||
theTree.updateItemData("b000000000001")
|
||||
theTree.MAX_DEPTH = maxDepth
|
||||
|
||||
# Chech type
|
||||
# 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
|
||||
@@ -306,7 +334,7 @@ def testCoreTree_Methods(mockGUI, mockItems):
|
||||
assert roots[3][0] == "a000000000004"
|
||||
|
||||
# Add a fake item to root and check that it can handle it
|
||||
theTree._treeRoots["0000000000000"] = NWItem(theProject)
|
||||
theTree._treeRoots["0000000000000"] = NWItem(theProject, "0000000000000")
|
||||
assert theTree.findRoot(nwItemClass.WORLD) is None
|
||||
del theTree._treeRoots["0000000000000"]
|
||||
|
||||
@@ -318,18 +346,18 @@ def testCoreTree_Methods(mockGUI, mockItems):
|
||||
|
||||
# Cause recursion error
|
||||
maxDepth = theTree.MAX_DEPTH
|
||||
theTree.MAX_DEPTH = 0
|
||||
theTree.MAX_DEPTH = 0 # type: ignore
|
||||
with pytest.raises(RecursionError):
|
||||
theTree.getItemPath("c000000000001")
|
||||
theTree.MAX_DEPTH = maxDepth
|
||||
|
||||
# Break the folder parent handle
|
||||
theTree["b000000000001"]._parent = "stuff"
|
||||
theTree["b000000000001"]._parent = "stuff" # type: ignore
|
||||
assert theTree.getItemPath("c000000000001") == [
|
||||
"c000000000001", "b000000000001"
|
||||
]
|
||||
|
||||
theTree["b000000000001"]._parent = "a000000000001"
|
||||
theTree["b000000000001"]._parent = "a000000000001" # type: ignore
|
||||
assert theTree.getItemPath("c000000000001") == [
|
||||
"c000000000001", "b000000000001", "a000000000001"
|
||||
]
|
||||
@@ -349,13 +377,13 @@ def testCoreTree_MakeHandles(mockGUI):
|
||||
random.seed(42)
|
||||
tHandle = theTree._makeHandle()
|
||||
assert tHandle == handles[0]
|
||||
theTree._projTree[handles[0]] = None
|
||||
theTree._projTree[handles[0]] = None # type: ignore
|
||||
|
||||
# Add the next in line to the project to force duplicate
|
||||
theTree._projTree[handles[1]] = None
|
||||
theTree._projTree[handles[1]] = None # type: ignore
|
||||
tHandle = theTree._makeHandle()
|
||||
assert tHandle == handles[2]
|
||||
theTree._projTree[handles[2]] = None
|
||||
theTree._projTree[handles[2]] = None # type: ignore
|
||||
|
||||
# Reset the seed to force collissions, which should still end up
|
||||
# returning the next handle in the sequence
|
||||
@@ -372,8 +400,8 @@ def testCoreTree_Stats(mockGUI, mockItems):
|
||||
theProject = NWProject(mockGUI)
|
||||
theTree = NWTree(theProject)
|
||||
|
||||
for tHandle, pHandle, nwItem in mockItems:
|
||||
theTree.append(tHandle, pHandle, nwItem)
|
||||
for nwItem in mockItems:
|
||||
theTree.append(nwItem)
|
||||
|
||||
assert len(theTree) == len(mockItems)
|
||||
theTree._treeOrder.append("stuff")
|
||||
@@ -393,9 +421,9 @@ def testCoreTree_Reorder(caplog, mockGUI, mockItems):
|
||||
theTree = NWTree(theProject)
|
||||
|
||||
aHandle = []
|
||||
for tHandle, pHandle, nwItem in mockItems:
|
||||
aHandle.append(tHandle)
|
||||
theTree.append(tHandle, pHandle, nwItem)
|
||||
for nwItem in mockItems:
|
||||
aHandle.append(nwItem.itemHandle)
|
||||
theTree.append(nwItem)
|
||||
|
||||
assert len(theTree) == len(mockItems)
|
||||
|
||||
@@ -422,14 +450,14 @@ def testCoreTree_Reorder(caplog, mockGUI, mockItems):
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreTree_ToCFile(monkeypatch, tstPaths, mockGUI, mockItems):
|
||||
def testCoreTree_ToCFile(monkeypatch, fncPath, mockGUI, mockItems):
|
||||
"""Test writing the ToC.txt file."""
|
||||
theProject = NWProject(mockGUI)
|
||||
theTree = NWTree(theProject)
|
||||
|
||||
for tHandle, pHandle, nwItem in mockItems:
|
||||
theTree.append(tHandle, pHandle, nwItem)
|
||||
theTree.updateItemData(tHandle)
|
||||
for nwItem in mockItems:
|
||||
theTree.append(nwItem)
|
||||
theTree.updateItemData(nwItem.itemHandle)
|
||||
|
||||
assert len(theTree) == len(mockItems)
|
||||
theTree._treeOrder.append("stuff")
|
||||
@@ -443,24 +471,27 @@ def testCoreTree_ToCFile(monkeypatch, tstPaths, mockGUI, mockItems):
|
||||
return dItem.itemType == nwItemType.FILE
|
||||
|
||||
monkeypatch.setattr("pathlib.Path.is_file", mockIsFile)
|
||||
theProject._storage._runtimePath = fncPath
|
||||
(fncPath / "content").mkdir()
|
||||
|
||||
theProject._storage._runtimePath = None
|
||||
assert theTree.writeToCFile() is False
|
||||
# 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
|
||||
|
||||
theProject._storage._runtimePath = tstPaths.tmpDir
|
||||
# Block opening the file
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr("builtins.open", causeOSError)
|
||||
assert theTree.writeToCFile() is False
|
||||
|
||||
theProject._storage._runtimePath = tstPaths.tmpDir
|
||||
(tstPaths.tmpDir / "content").mkdir()
|
||||
# Allow writing
|
||||
assert theTree.writeToCFile() is True
|
||||
|
||||
pathA = str(Path("content") / "c000000000001.nwd")
|
||||
pathB = str(Path("content") / "c000000000002.nwd")
|
||||
pathC = str(Path("content") / "b000000000002.nwd")
|
||||
|
||||
assert readFile(tstPaths.tmpDir / nwFiles.TOC_TXT) == (
|
||||
assert (fncPath / nwFiles.TOC_TXT).read_text() == (
|
||||
"\n"
|
||||
"Table of Contents\n"
|
||||
"=================\n"
|
||||
|
||||
Reference in New Issue
Block a user