From e5c6dae080908e7fd49c7f8a31cf69359c026ccd Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Tue, 30 Jan 2024 10:42:07 +0100 Subject: [PATCH] Fix tests and tag index validation (uncommited changes from yesterday) --- novelwriter/core/index.py | 44 +++--- novelwriter/error.py | 2 +- .../coreIndex_LoadSave_tagsIndex.json | 6 +- tests/test_core/test_core_index.py | 129 +++++++++--------- 4 files changed, 92 insertions(+), 89 deletions(-) diff --git a/novelwriter/core/index.py b/novelwriter/core/index.py index 6fa0a024..6c749007 100644 --- a/novelwriter/core/index.py +++ b/novelwriter/core/index.py @@ -422,7 +422,7 @@ class NWIndex: if tBits[0] == nwKeyWords.TAG_KEY: tagKey = tBits[1] displayName = tBits[2] if len(tBits) > 2 else tagKey - self._tagsIndex.add(tagKey, displayName, tHandle, sTitle, itemClass) + self._tagsIndex.add(tagKey, displayName, tHandle, sTitle, itemClass.name) self._itemIndex.setHeadingTag(tHandle, sTitle, tagKey) tags[tagKey.lower()] = True else: @@ -733,15 +733,14 @@ class TagsIndex: """Return a dictionary view of all tags.""" return self._tags.items() - def add(self, tagKey: str, displayName: str, tHandle: str, sTitle: str, - itemClass: nwItemClass) -> None: + def add(self, tagKey: str, display: str, tHandle: str, sTitle: str, className: str) -> None: """Add a key to the index and set all values.""" self._tags[tagKey.lower()] = { "name": tagKey, - "display": displayName, + "display": display, "handle": tHandle, "heading": sTitle, - "class": itemClass.name, + "class": className, } return @@ -790,28 +789,27 @@ class TagsIndex: for key, entry in data.items(): if not isinstance(key, str): raise ValueError("tagsIndex keys must be a string") - if "name" not in entry: - raise KeyError("A tagIndex item is missing a name entry") - if "display" not in entry: - raise KeyError("A tagIndex item is missing a display entry") - if "handle" not in entry: - raise KeyError("A tagIndex item is missing a handle entry") - if "heading" not in entry: - raise KeyError("A tagIndex item is missing a heading entry") - if "class" not in entry: - raise KeyError("A tagIndex item is missing a class entry") - if not isinstance(entry["name"], str): - raise ValueError("tagsIndex name must be a string") - if not isinstance(entry["display"], str): - raise ValueError("tagsIndex display must be a string") - if not isHandle(entry["handle"]): + if not isinstance(entry, dict): + raise ValueError("tagsIndex entry is not a dict") + + name = entry.get("name") + display = entry.get("display") + handle = entry.get("handle", "") + heading = entry.get("heading", "") + className = entry.get("class", "") + + if not isinstance(name, str): + raise ValueError("tagsIndex name is not a string") + if not isinstance(display, str): + raise ValueError("tagsIndex display is not a string") + if not isHandle(handle): raise ValueError("tagsIndex handle must be a handle") - if not isTitleTag(entry["heading"]): + if not isTitleTag(heading): raise ValueError("tagsIndex heading must be a title tag") - if not isItemClass(entry["class"]): + if not isItemClass(className): raise ValueError("tagsIndex handle must be an nwItemClass") - self._tags = data + self.add(name, display, handle, heading, className) return diff --git a/novelwriter/error.py b/novelwriter/error.py index 2501c55a..1932e6b7 100644 --- a/novelwriter/error.py +++ b/novelwriter/error.py @@ -50,7 +50,7 @@ def logException() -> None: """Log the content of an exception message.""" exType, exValue, _ = sys.exc_info() if exType is not None: - logger.error("%s: %s", exType.__name__, str(exValue)) + logger.error(f"{exType.__name__}: {str(exValue)}", stacklevel=2) return diff --git a/tests/reference/coreIndex_LoadSave_tagsIndex.json b/tests/reference/coreIndex_LoadSave_tagsIndex.json index 014346af..a6f07969 100644 --- a/tests/reference/coreIndex_LoadSave_tagsIndex.json +++ b/tests/reference/coreIndex_LoadSave_tagsIndex.json @@ -1,8 +1,8 @@ { "novelWriter.tagsIndex": { - "bod": {"name": "Bod", "handle": "4c4f28287af27", "heading": "T0001", "class": "CHARACTER"}, - "main": {"name": "Main", "handle": "2426c6f0ca922", "heading": "T0001", "class": "PLOT"}, - "europe": {"name": "Europe", "handle": "04468803b92e1", "heading": "T0001", "class": "WORLD"} + "bod": {"name": "Bod", "display": "Bod", "handle": "4c4f28287af27", "heading": "T0001", "class": "CHARACTER"}, + "main": {"name": "Main", "display": "Main", "handle": "2426c6f0ca922", "heading": "T0001", "class": "PLOT"}, + "europe": {"name": "Europe", "display": "Europe", "handle": "04468803b92e1", "heading": "T0001", "class": "WORLD"} }, "novelWriter.itemIndex": { "7a992350f3eb6": { diff --git a/tests/test_core/test_core_index.py b/tests/test_core/test_core_index.py index 4954db9d..c0053ff4 100644 --- a/tests/test_core/test_core_index.py +++ b/tests/test_core/test_core_index.py @@ -272,23 +272,30 @@ def testCoreIndex_CheckThese(mockGUI, fncPath, mockRnd): assert index.checkThese([], cItem) == [] # One Item - assert index.checkThese(["@tag"], cItem) == [True] - assert index.checkThese(["@who"], cItem) == [False] + assert index.checkThese(["@tag"], cItem) == [1] + assert index.checkThese(["@who"], cItem) == [0] # Two Items - assert index.checkThese(["@tag", "Jane"], cItem) == [True, True] - assert index.checkThese(["@tag", "John"], cItem) == [True, True] - assert index.checkThese(["@tag", "Jane"], nItem) == [True, False] - assert index.checkThese(["@tag", "John"], nItem) == [True, True] - assert index.checkThese(["@pov", "John"], nItem) == [True, False] - assert index.checkThese(["@pov", "Jane"], nItem) == [True, True] - assert index.checkThese(["@ pov", "Jane"], nItem) == [False, False] - assert index.checkThese(["@what", "Jane"], nItem) == [False, False] + assert index.checkThese(["@tag", "Jane"], cItem) == [1, 2] + assert index.checkThese(["@tag", "John"], cItem) == [1, 2] + assert index.checkThese(["@tag", "Jane"], nItem) == [1, 0] + assert index.checkThese(["@tag", "John"], nItem) == [1, 2] + assert index.checkThese(["@pov", "John"], nItem) == [1, 0] + assert index.checkThese(["@pov", "Jane"], nItem) == [1, 2] + assert index.checkThese(["@ pov", "Jane"], nItem) == [0, 0] + assert index.checkThese(["@what", "Jane"], nItem) == [0, 0] # Three Items - assert index.checkThese(["@tag", "Jane", "John"], cItem) == [True, True, False] - assert index.checkThese(["@who", "Jane", "John"], cItem) == [False, False, False] - assert index.checkThese(["@pov", "Jane", "John"], nItem) == [True, True, False] + assert index.checkThese(["@tag", "Jane", "Jany"], cItem) == [1, 2, 3] + assert index.checkThese(["@who", "Jane", "John"], cItem) == [0, 0, 0] + assert index.checkThese(["@pov", "Jane", "John"], nItem) == [1, 2, 0] + assert index.checkThese(["@pov", "Jane", "Jane"], nItem) == [1, 2, 2] + + # Four Items + assert index.checkThese(["@tag", "Jane", "Jany", "John"], cItem) == [1, 2, 3, 0] + assert index.checkThese(["@who", "Jane", "Jane", "Jane"], cItem) == [0, 0, 0, 0] + assert index.checkThese(["@pov", "Jane", "John", "Jane"], nItem) == [1, 2, 0, 2] + assert index.checkThese(["@pov", "Jane", "Jane", "Jane"], nItem) == [1, 2, 2, 2] project.closeProject() @@ -849,18 +856,21 @@ def testCoreIndex_TagsIndex(): content = { "tag1": { "name": "Tag1", + "display": "Tag 1", "handle": "0000000000001", "heading": "T0001", "class": nwItemClass.NOVEL.name, }, "tag2": { "name": "Tag2", + "display": "Tag 2", "handle": "0000000000002", "heading": "T0002", "class": nwItemClass.CHARACTER.name, }, "tag3": { "name": "Tag3", + "display": "Tag 3", "handle": "0000000000003", "heading": "T0003", "class": nwItemClass.PLOT.name, @@ -868,9 +878,9 @@ def testCoreIndex_TagsIndex(): } # Add data - tagsIndex.add("Tag1", "0000000000001", "T0001", nwItemClass.NOVEL) - tagsIndex.add("Tag2", "0000000000002", "T0002", nwItemClass.CHARACTER) - tagsIndex.add("Tag3", "0000000000003", "T0003", nwItemClass.PLOT) + tagsIndex.add("Tag1", "Tag 1", "0000000000001", "T0001", "NOVEL") + tagsIndex.add("Tag2", "Tag 2", "0000000000002", "T0002", "CHARACTER") + tagsIndex.add("Tag3", "Tag 3", "0000000000003", "T0003", "PLOT") assert tagsIndex._tags == content # Get items @@ -885,6 +895,18 @@ def testCoreIndex_TagsIndex(): assert "Tag3" in tagsIndex assert "Tag4" not in tagsIndex + # Read back names + assert tagsIndex.tagName("Tag1") == "Tag1" + assert tagsIndex.tagName("Tag2") == "Tag2" + assert tagsIndex.tagName("Tag3") == "Tag3" + assert tagsIndex.tagName("Tag4") == "" + + # Read back display names + assert tagsIndex.tagDisplay("Tag1") == "Tag 1" + assert tagsIndex.tagDisplay("Tag2") == "Tag 2" + assert tagsIndex.tagDisplay("Tag3") == "Tag 3" + assert tagsIndex.tagDisplay("Tag4") == "" + # Read back handles assert tagsIndex.tagHandle("Tag1") == "0000000000001" assert tagsIndex.tagHandle("Tag2") == "0000000000002" @@ -935,59 +957,39 @@ def testCoreIndex_TagsIndex(): with pytest.raises(ValueError): tagsIndex.unpackData({ 1234: { - "name": "1234", - "handle": "0000000000001", - "heading": "T0001", - "class": "NOVEL", - } - }) - - # Missing name - with pytest.raises(KeyError): - tagsIndex.unpackData({ - "tag1": { - "handle": "0000000000001", - "heading": "T0001", - "class": "NOVEL", - } - }) - - # Missing handle - with pytest.raises(KeyError): - tagsIndex.unpackData({ - "tag1": { "name": "Tag1", + "display": "Tag1", + "handle": "0000000000001", "heading": "T0001", "class": "NOVEL", } }) - # Missing heading - with pytest.raises(KeyError): - tagsIndex.unpackData({ - "tag1": { - "name": "Tag1", - "handle": "0000000000001", - "class": "NOVEL", - } - }) - - # Missing class - with pytest.raises(KeyError): - tagsIndex.unpackData({ - "tag1": { - "name": "Tag1", - "handle": "0000000000001", - "heading": "T0001", - } - }) - - # Invalid key case + # Invalid entry with pytest.raises(ValueError): tagsIndex.unpackData({ - "Tag1": { + "tag1": None + }) + + # Invalid name + with pytest.raises(ValueError): + tagsIndex.unpackData({ + "tag1": { + "name": 1234, + "display": "Tag1", + "handle": "0000000000001", + "heading": "T0001", + "class": "NOVEL", + } + }) + + # Invalid display + with pytest.raises(ValueError): + tagsIndex.unpackData({ + "tag1": { "name": "Tag1", - "handle": "blablabla", + "display": 1234, + "handle": "0000000000001", "heading": "T0001", "class": "NOVEL", } @@ -998,6 +1000,7 @@ def testCoreIndex_TagsIndex(): tagsIndex.unpackData({ "tag1": { "name": "Tag1", + "display": "Tag1", "handle": "blablabla", "heading": "T0001", "class": "NOVEL", @@ -1009,8 +1012,9 @@ def testCoreIndex_TagsIndex(): tagsIndex.unpackData({ "tag1": { "name": "Tag1", + "display": "Tag1", "handle": "0000000000001", - "heading": "blabla", + "heading": "stuff", "class": "NOVEL", } }) @@ -1020,9 +1024,10 @@ def testCoreIndex_TagsIndex(): tagsIndex.unpackData({ "tag1": { "name": "Tag1", + "display": "Tag1", "handle": "0000000000001", "heading": "T0001", - "class": "blabla", + "class": "STUFF", } })