Update test coverage
This commit is contained in:
@@ -987,7 +987,7 @@ class ItemIndex:
|
|||||||
|
|
||||||
def unpackData(self, data: dict) -> None:
|
def unpackData(self, data: dict) -> None:
|
||||||
"""Iterate through the itemIndex loaded from cache and check
|
"""Iterate through the itemIndex loaded from cache and check
|
||||||
that it's valid. This will raise errors if there is a problem.
|
that it's valid. This will raise errors if there are problems.
|
||||||
"""
|
"""
|
||||||
self._items = {}
|
self._items = {}
|
||||||
if not isinstance(data, dict):
|
if not isinstance(data, dict):
|
||||||
|
|||||||
@@ -114,17 +114,17 @@ class IndexNode:
|
|||||||
self._headings[sTitle].setSynopsis(text)
|
self._headings[sTitle].setSynopsis(text)
|
||||||
return
|
return
|
||||||
|
|
||||||
def setHeadingTag(self, sTitle: str, tagKey: str) -> None:
|
def setHeadingTag(self, sTitle: str, tag: str) -> None:
|
||||||
"""Set the tag of a heading."""
|
"""Set the tag of a heading."""
|
||||||
if sTitle in self._headings:
|
if sTitle in self._headings:
|
||||||
self._headings[sTitle].setTag(tagKey)
|
self._headings[sTitle].setTag(tag)
|
||||||
return
|
return
|
||||||
|
|
||||||
def addHeadingRef(self, sTitle: str, tagKeys: list[str], refType: str) -> None:
|
def addHeadingRef(self, sTitle: str, tags: list[str], keyword: str) -> None:
|
||||||
"""Add a reference key and all its types to a heading."""
|
"""Add a reference key and all its types to a heading."""
|
||||||
if sTitle in self._headings:
|
if sTitle in self._headings:
|
||||||
for tagKey in tagKeys:
|
for tag in tags:
|
||||||
self._headings[sTitle].addReference(tagKey, refType)
|
self._headings[sTitle].addReference(tag, keyword)
|
||||||
return
|
return
|
||||||
|
|
||||||
def addNoteKey(self, style: T_NoteTypes, key: str) -> None:
|
def addNoteKey(self, style: T_NoteTypes, key: str) -> None:
|
||||||
@@ -187,7 +187,7 @@ class IndexNode:
|
|||||||
raise ValueError("The notes keys must be a list of strings")
|
raise ValueError("The notes keys must be a list of strings")
|
||||||
self._notes[style] = set(keys)
|
self._notes[style] = set(keys)
|
||||||
else:
|
else:
|
||||||
raise ValueError("The itemIndex contains an invalid title key")
|
raise KeyError("Index node contains an invalid key")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1310,3 +1310,23 @@ def testCoreIndex_ItemIndex(mockGUI, fncPath, mockRnd):
|
|||||||
# Delete new item
|
# Delete new item
|
||||||
del itemIndex[uHandle] # type: ignore
|
del itemIndex[uHandle] # type: ignore
|
||||||
assert uHandle not in itemIndex
|
assert uHandle not in itemIndex
|
||||||
|
|
||||||
|
# Unpack Error Handling
|
||||||
|
# =====================
|
||||||
|
|
||||||
|
# Pack/unpack should restore state
|
||||||
|
content = itemIndex.packData()
|
||||||
|
itemIndex.clear()
|
||||||
|
itemIndex.unpackData(content)
|
||||||
|
assert itemIndex.packData() == content
|
||||||
|
itemIndex.clear()
|
||||||
|
|
||||||
|
# Data must be dictionary
|
||||||
|
with pytest.raises(ValueError) as exc:
|
||||||
|
itemIndex.unpackData("stuff") # type: ignore
|
||||||
|
assert str(exc.value) == "itemIndex is not a dict"
|
||||||
|
|
||||||
|
# Keys must be valid handles
|
||||||
|
with pytest.raises(ValueError) as exc:
|
||||||
|
itemIndex.unpackData({"stuff": "more stuff"})
|
||||||
|
assert str(exc.value) == "itemIndex keys must be handles"
|
||||||
|
|||||||
@@ -22,7 +22,143 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from novelwriter.core.indexdata import IndexHeading
|
from novelwriter.core.indexdata import IndexHeading, IndexNode
|
||||||
|
from novelwriter.core.item import NWItem
|
||||||
|
from novelwriter.core.project import NWProject
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.core
|
||||||
|
def testCoreIndexData_IndexNode(mockGUI):
|
||||||
|
"""Test the IndexNode class."""
|
||||||
|
handle = "0123456789abc"
|
||||||
|
project = NWProject()
|
||||||
|
item = NWItem(project, handle)
|
||||||
|
|
||||||
|
# Defaults
|
||||||
|
node = IndexNode(handle, item)
|
||||||
|
assert node.handle == handle
|
||||||
|
assert node.item is item
|
||||||
|
assert str(node) == f"<IndexNode handle='{handle}'>"
|
||||||
|
assert repr(node) == f"<IndexNode handle='{handle}'>"
|
||||||
|
assert len(node) == 1
|
||||||
|
assert "T0000" in node # Placeholder heading
|
||||||
|
|
||||||
|
# Add a heading
|
||||||
|
head1 = IndexHeading(node.nextHeading(), line=1, level="H1", title="Heading 1")
|
||||||
|
head2 = IndexHeading(node.nextHeading(), line=10, level="H2", title="Heading 2")
|
||||||
|
node.addHeading(head1)
|
||||||
|
node.addHeading(head2)
|
||||||
|
assert len(node) == 2
|
||||||
|
assert "T0000" not in node # Placeholder heading should be gone
|
||||||
|
assert "T0001" in node
|
||||||
|
assert "T0002" in node
|
||||||
|
assert node["T0001"] is head1
|
||||||
|
assert node["T0002"] is head2
|
||||||
|
assert node.headings() == ["T0001", "T0002"]
|
||||||
|
assert dict(node.items()) == {"T0001": head1, "T0002": head2}
|
||||||
|
|
||||||
|
# Next heading should be T0003
|
||||||
|
assert node.nextHeading() == "T0003"
|
||||||
|
|
||||||
|
# Set counts
|
||||||
|
node.setHeadingCounts("T0001", 42, 13, 3)
|
||||||
|
node.setHeadingCounts("T0002", 84, 26, 6)
|
||||||
|
assert head1.charCount == 42
|
||||||
|
assert head1.wordCount == 13
|
||||||
|
assert head1.paraCount == 3
|
||||||
|
assert head2.charCount == 84
|
||||||
|
assert head2.wordCount == 26
|
||||||
|
assert head2.paraCount == 6
|
||||||
|
|
||||||
|
# Set synopsis
|
||||||
|
node.setHeadingSynopsis("T0001", "The first")
|
||||||
|
node.setHeadingSynopsis("T0002", "The second")
|
||||||
|
assert head1.synopsis == "The first"
|
||||||
|
assert head2.synopsis == "The second"
|
||||||
|
|
||||||
|
# Set tags
|
||||||
|
node.setHeadingTag("T0001", "part1")
|
||||||
|
node.setHeadingTag("T0002", "part2")
|
||||||
|
assert head1.tag == "part1"
|
||||||
|
assert head2.tag == "part2"
|
||||||
|
assert node.allTags() == ["part1", "part2"]
|
||||||
|
|
||||||
|
# Add references
|
||||||
|
node.addHeadingRef("T0001", ["jane"], "@pov")
|
||||||
|
node.addHeadingRef("T0001", ["jane", "john"], "@char")
|
||||||
|
node.addHeadingRef("T0002", ["earth", "space"], "@location")
|
||||||
|
assert head1.references["jane"] == {"@char", "@pov"}
|
||||||
|
assert head1.references["john"] == {"@char"}
|
||||||
|
assert head2.references["earth"] == {"@location"}
|
||||||
|
assert head2.references["space"] == {"@location"}
|
||||||
|
|
||||||
|
# Add note keys
|
||||||
|
assert node.noteKeys("footnotes") == set()
|
||||||
|
node.addNoteKey("footnotes", "key1")
|
||||||
|
node.addNoteKey("footnotes", "key2")
|
||||||
|
assert node.noteKeys("footnotes") == {"key1", "key2"}
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.core
|
||||||
|
def testCoreIndexData_IndexNodePackUnpack(mockGUI):
|
||||||
|
"""Test the pack and unpack methods of the IndexNode class."""
|
||||||
|
handle = "0123456789abc"
|
||||||
|
project = NWProject()
|
||||||
|
item = NWItem(project, handle)
|
||||||
|
node = IndexNode(handle, item)
|
||||||
|
|
||||||
|
# Add some headings and notes
|
||||||
|
head1 = IndexHeading(node.nextHeading(), line=1, level="H1", title="Heading 1")
|
||||||
|
head2 = IndexHeading(node.nextHeading(), line=10, level="H2", title="Heading 2")
|
||||||
|
node.addHeading(head1)
|
||||||
|
node.addHeading(head2)
|
||||||
|
node.setHeadingCounts("T0001", 42, 13, 3)
|
||||||
|
node.setHeadingCounts("T0002", 84, 26, 6)
|
||||||
|
node.addNoteKey("footnotes", "key1")
|
||||||
|
node.addNoteKey("footnotes", "key2")
|
||||||
|
|
||||||
|
# Check packing
|
||||||
|
data = node.packData()
|
||||||
|
assert data["T0001"] == {"meta": {
|
||||||
|
"level": "H1", "title": "Heading 1", "line": 1, "tag": "", "counts": (42, 13, 3)
|
||||||
|
}}
|
||||||
|
assert data["T0002"] == {"meta": {
|
||||||
|
"level": "H2", "title": "Heading 2", "line": 10, "tag": "", "counts": (84, 26, 6)
|
||||||
|
}}
|
||||||
|
assert set(data["document"]["footnotes"]) == {"key1", "key2"}
|
||||||
|
|
||||||
|
# Create a new node
|
||||||
|
new = IndexNode(handle, item)
|
||||||
|
|
||||||
|
# Unpack heading one
|
||||||
|
data = {"T0001": {"meta": {
|
||||||
|
"level": "H1", "title": "Heading 1", "line": 1, "tag": "", "counts": (42, 13, 3)
|
||||||
|
}}}
|
||||||
|
new.unpackData(data)
|
||||||
|
data = new.packData()
|
||||||
|
assert data["T0001"] == {"meta": {
|
||||||
|
"level": "H1", "title": "Heading 1", "line": 1, "tag": "", "counts": (42, 13, 3)
|
||||||
|
}}
|
||||||
|
|
||||||
|
# Unpack invalid key
|
||||||
|
data = {"stuff": "whatever"}
|
||||||
|
with pytest.raises(KeyError, match="Index node contains an invalid key"):
|
||||||
|
new.unpackData(data)
|
||||||
|
|
||||||
|
# Unpack invalid document keys
|
||||||
|
data = {"document": {"whatever": []}}
|
||||||
|
with pytest.raises(ValueError, match="The notes style is invalid"):
|
||||||
|
new.unpackData(data)
|
||||||
|
|
||||||
|
# Unpack invalid document values
|
||||||
|
data = {"document": {"footnotes": [1, 2, 3]}}
|
||||||
|
with pytest.raises(ValueError, match="The notes keys must be a list of strings"):
|
||||||
|
new.unpackData(data)
|
||||||
|
|
||||||
|
# Unpack valid keys
|
||||||
|
data = {"document": {"footnotes": ["key1", "key2"]}}
|
||||||
|
new.unpackData(data)
|
||||||
|
assert set(new.packData()["document"]["footnotes"]) == {"key1", "key2"}
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.core
|
@pytest.mark.core
|
||||||
@@ -30,8 +166,8 @@ def testCoreIndexData_IndexHeading():
|
|||||||
"""Test the IndexHeading class."""
|
"""Test the IndexHeading class."""
|
||||||
# Defaults
|
# Defaults
|
||||||
head = IndexHeading("T0001")
|
head = IndexHeading("T0001")
|
||||||
assert repr(head) == "<IndexHeading key='T0001'>"
|
|
||||||
assert str(head) == "<IndexHeading key='T0001'>"
|
assert str(head) == "<IndexHeading key='T0001'>"
|
||||||
|
assert repr(head) == "<IndexHeading key='T0001'>"
|
||||||
assert head.key == "T0001"
|
assert head.key == "T0001"
|
||||||
assert head.line == 0
|
assert head.line == 0
|
||||||
assert head.level == "H0"
|
assert head.level == "H0"
|
||||||
|
|||||||
Reference in New Issue
Block a user