Add test coverage
This commit is contained in:
@@ -1198,13 +1198,13 @@ def testCoreIndex_ItemIndex(mockGUI, fncPath, mockRnd):
|
||||
idxData = itemIndex.packData()
|
||||
|
||||
assert idxData[cHandle]["T0001"]["meta"] == {
|
||||
"level": "H2", "line": 1, "title": "Chapter One", "tag": "one",
|
||||
"counts": (60, 10, 2), "summary": "In the beginning ...",
|
||||
"level": "H2", "line": 1, "title": "Chapter One", "tag": "one", "counts": (60, 10, 2),
|
||||
}
|
||||
assert "@pov" in idxData[cHandle]["T0001"]["refs"]["jane"]
|
||||
assert "@focus" in idxData[cHandle]["T0001"]["refs"]["jane"]
|
||||
assert "@char" in idxData[cHandle]["T0001"]["refs"]["jane"]
|
||||
assert "@char" in idxData[cHandle]["T0001"]["refs"]["john"]
|
||||
assert idxData[cHandle]["T0001"]["summary"] == "In the beginning ..."
|
||||
|
||||
# Add the other two files
|
||||
itemIndex.add(nHandle, project.tree[nHandle]) # type: ignore
|
||||
@@ -1310,112 +1310,3 @@ def testCoreIndex_ItemIndex(mockGUI, fncPath, mockRnd):
|
||||
# Delete new item
|
||||
del itemIndex[uHandle] # type: ignore
|
||||
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"
|
||||
|
||||
# Unknown keys should be skipped
|
||||
itemIndex.unpackData({C.hInvalid: {}})
|
||||
assert itemIndex._items == {}
|
||||
|
||||
# Known keys can be added, even without data
|
||||
itemIndex.unpackData({nHandle: {}})
|
||||
assert nHandle in itemIndex
|
||||
assert itemIndex[nHandle].handle == nHandle # type: ignore
|
||||
|
||||
# Title tags must be valid
|
||||
with pytest.raises(ValueError) as exc:
|
||||
itemIndex.unpackData({cHandle: {"headings": {"TTTTTTT": {}}}})
|
||||
assert str(exc.value) == "The itemIndex contains an invalid title key"
|
||||
|
||||
# Reference without a heading should be rejected
|
||||
itemIndex.unpackData({
|
||||
cHandle: {
|
||||
"headings": {"T0001": {}},
|
||||
"references": {"T0001": {}, "T0002": {}},
|
||||
}
|
||||
})
|
||||
assert "T0001" in itemIndex[cHandle] # type: ignore
|
||||
assert "T0002" not in itemIndex[cHandle] # type: ignore
|
||||
itemIndex.clear()
|
||||
|
||||
# Tag keys must be strings
|
||||
with pytest.raises(ValueError) as exc:
|
||||
itemIndex.unpackData({
|
||||
cHandle: {
|
||||
"headings": {"T0001": {}},
|
||||
"references": {"T0001": {1234: "@pov"}},
|
||||
"notes": {"footnotes": [], "comments": []},
|
||||
}
|
||||
})
|
||||
assert str(exc.value) == "itemIndex reference key must be a string"
|
||||
|
||||
# Type must be strings
|
||||
with pytest.raises(ValueError) as exc:
|
||||
itemIndex.unpackData({
|
||||
cHandle: {
|
||||
"headings": {"T0001": {}},
|
||||
"references": {"T0001": {"John": []}},
|
||||
"notes": {"footnotes": [], "comments": []},
|
||||
}
|
||||
})
|
||||
assert str(exc.value) == "itemIndex reference type must be a string"
|
||||
|
||||
# Types must be valid
|
||||
with pytest.raises(ValueError) as exc:
|
||||
itemIndex.unpackData({
|
||||
cHandle: {
|
||||
"headings": {"T0001": {}},
|
||||
"references": {"T0001": {"John": "@pov,@char,@stuff"}},
|
||||
"notes": {"footnotes": [], "comments": []},
|
||||
}
|
||||
})
|
||||
assert str(exc.value) == "The itemIndex contains an invalid reference type"
|
||||
|
||||
# Note type must be valid
|
||||
with pytest.raises(ValueError) as exc:
|
||||
itemIndex.unpackData({
|
||||
cHandle: {
|
||||
"headings": {"T0001": {}},
|
||||
"references": {"T0001": {"John": "@pov,@char"}},
|
||||
"notes": {"stuff": [], "comments": []},
|
||||
}
|
||||
})
|
||||
assert str(exc.value) == "The notes style is invalid"
|
||||
|
||||
# Note keys must be all strings
|
||||
with pytest.raises(ValueError) as exc:
|
||||
itemIndex.unpackData({
|
||||
cHandle: {
|
||||
"headings": {"T0001": {}},
|
||||
"references": {"T0001": {"John": "@pov,@char"}},
|
||||
"notes": {"footnotes": ["fkey", 1], "comments": []},
|
||||
}
|
||||
})
|
||||
assert str(exc.value) == "The notes keys must be a list of strings"
|
||||
|
||||
# This should pass
|
||||
itemIndex.unpackData({
|
||||
cHandle: {
|
||||
"headings": {"T0001": {}},
|
||||
"references": {"T0001": {"John": "@pov,@char"}},
|
||||
"notes": {"footnotes": ["fkey"], "comments": ["ckey"]},
|
||||
}
|
||||
})
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
"""
|
||||
novelWriter – NWIndex Class Tester
|
||||
==================================
|
||||
|
||||
This file is a part of novelWriter
|
||||
Copyright (C) 2020 Veronica Berglyd Olsen and novelWriter contributors
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from novelwriter.core.indexdata import IndexHeading
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreIndexData_IndexHeading():
|
||||
"""Test the IndexHeading class."""
|
||||
# Defaults
|
||||
head = IndexHeading("T0001")
|
||||
assert repr(head) == "<IndexHeading key='T0001'>"
|
||||
assert str(head) == "<IndexHeading key='T0001'>"
|
||||
assert head.key == "T0001"
|
||||
assert head.line == 0
|
||||
assert head.level == "H0"
|
||||
assert head.title == ""
|
||||
assert head.charCount == 0
|
||||
assert head.wordCount == 0
|
||||
assert head.paraCount == 0
|
||||
assert head.synopsis == ""
|
||||
assert head.tag == ""
|
||||
assert head.references == {}
|
||||
|
||||
# Set Level
|
||||
head.setLevel("Stuff") # Invalid
|
||||
assert head.level == "H0"
|
||||
head.setLevel("H1") # Valid
|
||||
assert head.level == "H1"
|
||||
|
||||
# Set Line
|
||||
head.setLine(-1) # Invalid
|
||||
assert head.line == 0
|
||||
head.setLine(42) # Valid
|
||||
assert head.line == 42
|
||||
|
||||
# Set Counts
|
||||
head.setCounts([1, 2]) # Invalid, must be three values
|
||||
assert head.charCount == 0
|
||||
assert head.wordCount == 0
|
||||
assert head.paraCount == 0
|
||||
head.setCounts([42, 4, 2]) # Valid
|
||||
assert head.charCount == 42
|
||||
assert head.wordCount == 4
|
||||
assert head.paraCount == 2
|
||||
|
||||
# Set Summary
|
||||
head.setSynopsis("In the beginning ...")
|
||||
assert head.synopsis == "In the beginning ..."
|
||||
|
||||
# Set Tag
|
||||
head.setTag("Stuff")
|
||||
assert head.tag == "stuff" # Case insensitive
|
||||
|
||||
# Add References
|
||||
head.addReference("Stuff", "@stuff") # Invalid type
|
||||
assert head.references == {}
|
||||
head.addReference("Stuff", "@object") # Valid type
|
||||
assert head.references == {"stuff": {"@object"}}
|
||||
|
||||
# Pack Data
|
||||
assert head.packData() == {
|
||||
"meta": {"level": "H1", "title": "", "line": 42, "tag": "stuff", "counts": (42, 4, 2)},
|
||||
"refs": {"stuff": "@object"},
|
||||
"summary": "In the beginning ...",
|
||||
}
|
||||
|
||||
# Unpack KeyError
|
||||
with pytest.raises(KeyError, match="Unknown key in heading entry"):
|
||||
head.unpackData({"stuff": "more stuff"})
|
||||
|
||||
# Unpack Comments
|
||||
head.unpackData({"summary": "How it started ..."})
|
||||
assert head.synopsis == "How it started ..."
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreIndexData_IndexHeadingUnpackMeta():
|
||||
"""Test IndexHeading class meta unpacking."""
|
||||
# Valid
|
||||
data = {"meta": {
|
||||
"level": "H1", "title": "So it Begins", "line": 1, "tag": "begins", "counts": [95, 18, 1]
|
||||
}}
|
||||
head = IndexHeading("T0001")
|
||||
head.unpackData(data)
|
||||
assert head.level == "H1"
|
||||
assert head.title == "So it Begins"
|
||||
assert head.line == 1
|
||||
assert head.tag == "begins"
|
||||
assert head.charCount == 95
|
||||
assert head.wordCount == 18
|
||||
assert head.paraCount == 1
|
||||
|
||||
# Invalid
|
||||
data = {"meta": {
|
||||
"level": "H9", "title": None, "line": None, "tag": None, "counts": [42]
|
||||
}}
|
||||
head = IndexHeading("T0001")
|
||||
head.unpackData(data)
|
||||
assert head.level == "H0"
|
||||
assert head.title == "None"
|
||||
assert head.line == 0
|
||||
assert head.tag == "None"
|
||||
assert head.charCount == 0
|
||||
assert head.wordCount == 0
|
||||
assert head.paraCount == 0
|
||||
|
||||
# Empty
|
||||
data = {"meta": {}}
|
||||
head = IndexHeading("T0001")
|
||||
head.unpackData(data)
|
||||
assert head.level == "H0"
|
||||
assert head.title == ""
|
||||
assert head.line == 0
|
||||
assert head.tag == ""
|
||||
assert head.charCount == 0
|
||||
assert head.wordCount == 0
|
||||
assert head.paraCount == 0
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreIndexData_IndexHeadingUnpackRefs():
|
||||
"""Test IndexHeading class refs unpacking."""
|
||||
# Valid
|
||||
data = {"refs": {
|
||||
"jane": "@char,@pov", "john": "@char", "earth": "@location", "space": "@mention,@location"
|
||||
}}
|
||||
head = IndexHeading("T0001")
|
||||
head.unpackData(data)
|
||||
assert head.references["jane"] == {"@char", "@pov"}
|
||||
assert head.references["john"] == {"@char"}
|
||||
assert head.references["earth"] == {"@location"}
|
||||
assert head.references["space"] == {"@location", "@mention"}
|
||||
|
||||
# Invalid key
|
||||
data = {"refs": {0: "@char,@pov"}}
|
||||
head = IndexHeading("T0001")
|
||||
with pytest.raises(ValueError, match="Heading reference key must be a string"):
|
||||
head.unpackData(data)
|
||||
|
||||
# Invalid value
|
||||
data = {"refs": {"jane": None}}
|
||||
head = IndexHeading("T0001")
|
||||
with pytest.raises(ValueError, match="Heading reference value must be a string"):
|
||||
head.unpackData(data)
|
||||
|
||||
# Invalid keyword
|
||||
data = {"refs": {"jane": "@char,@pov,@stuff"}}
|
||||
head = IndexHeading("T0001")
|
||||
with pytest.raises(ValueError, match="Heading reference contains an invalid keyword"):
|
||||
head.unpackData(data)
|
||||
Reference in New Issue
Block a user