From d7a8cb1537f70929b360a1b2b06355b19001b4d1 Mon Sep 17 00:00:00 2001
From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com>
Date: Sat, 16 Apr 2022 15:38:13 +0200
Subject: [PATCH] Rewrite NWStatus class tests
---
novelwriter/core/status.py | 10 +
tests/test_core/test_core_status.py | 344 +++++++++++++++++++++-------
2 files changed, 268 insertions(+), 86 deletions(-)
diff --git a/novelwriter/core/status.py b/novelwriter/core/status.py
index a3792764..4e9317f2 100644
--- a/novelwriter/core/status.py
+++ b/novelwriter/core/status.py
@@ -106,6 +106,13 @@ class NWStatus():
del self._reverse[self._store[key]["name"]]
del self._store[key]
+ keys = list(self._store.keys())
+ if key == self._default:
+ if len(keys) > 0:
+ self._default = keys[0]
+ else:
+ self._default = None
+
return True
def check(self, value):
@@ -242,6 +249,9 @@ class NWStatus():
# Iterator Bits
##
+ def __len__(self):
+ return len(self._store)
+
def __getitem__(self, key):
return self._store[key]
diff --git a/tests/test_core/test_core_status.py b/tests/test_core/test_core_status.py
index a7a2d55e..611f8327 100644
--- a/tests/test_core/test_core_status.py
+++ b/tests/test_core/test_core_status.py
@@ -20,6 +20,7 @@ along with this program. If not, see .
"""
import pytest
+import random
from lxml import etree
@@ -29,103 +30,268 @@ from novelwriter.core.status import NWStatus
@pytest.mark.core
-def testCoreStatus_Entries():
- """Test all the simple setters for the NWItem class.
+def testCoreStatus_Internal(constData):
+ """Test all the internal functions of the NWStatus class.
"""
- theStatus = NWStatus()
+ random.seed(42)
+ theStatus = NWStatus(NWStatus.STATUS)
+ theImport = NWStatus(NWStatus.IMPORT)
- # Add entries
- theStatus.addEntry("New", (100, 100, 100))
- theStatus.addEntry("Minor", (200, 50, 0))
- theStatus.addEntry("Major", (200, 150, 0))
- theStatus.addEntry("Main", (50, 200, 0))
+ with pytest.raises(Exception):
+ NWStatus(999)
- assert theStatus._theLabels == ["New", "Minor", "Major", "Main"]
- assert theStatus._theColours == [(100, 100, 100), (200, 50, 0), (200, 150, 0), (50, 200, 0)]
- assert theStatus._theCounts == [0, 0, 0, 0]
- assert theStatus._theMap["New"] == 0
- assert theStatus._theMap["Minor"] == 1
- assert theStatus._theMap["Major"] == 2
- assert theStatus._theMap["Main"] == 3
- assert theStatus._theLength == 4
+ # Generate Key
+ # ============
- # Lookups
- assert theStatus._getIndex(None) is None
- assert theStatus._getIndex("stuff") is None
- assert theStatus._getIndex("Main") == 3
+ assert theStatus._newKey() == constData.statusKeys[0]
+ assert theStatus._newKey() == constData.statusKeys[1]
- # Checks
- assert theStatus.checkEntry(123) == "New"
- assert theStatus.checkEntry("Stuff") == "New"
- assert theStatus.checkEntry("New ") == "New"
- assert theStatus.checkEntry(" Main ") == "Main"
+ # Key collision, should move to key 3
+ theStatus.write(constData.statusKeys[2], "Crash", (0, 0, 0))
+ assert theStatus._newKey() == constData.statusKeys[3]
- # Icons
- assert isinstance(theStatus.getIcon("Stuff"), QIcon)
- assert isinstance(theStatus.getIcon("New"), QIcon)
+ assert theImport._newKey() == constData.importKeys[0]
+ assert theImport._newKey() == constData.importKeys[1]
- # Set new list
- newList = [
- ("New", 1, 1, 1, "New"),
- ("Minor", 2, 2, 2, "Minor"),
- ("Major", 3, 3, 3, "Major"),
- ("Min", 4, 4, 4, "Main"),
- ("Max", 5, 5, 5, None),
- ]
- assert theStatus.setNewEntries(None) == {}
- assert theStatus.setNewEntries(newList) == {"Main": "Min"}
+ # Key collision, should move to key 3
+ theImport.write(constData.importKeys[2], "Crash", (0, 0, 0))
+ assert theImport._newKey() == constData.importKeys[3]
- assert theStatus._theLabels == ["New", "Minor", "Major", "Min", "Max"]
- assert theStatus._theColours == [(1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4), (5, 5, 5)]
- assert theStatus._theCounts == [0, 0, 0, 0, 0]
- assert theStatus._theMap["New"] == 0
- assert theStatus._theMap["Minor"] == 1
- assert theStatus._theMap["Major"] == 2
- assert theStatus._theMap["Min"] == 3
- assert theStatus._theMap["Max"] == 4
- assert theStatus._theLength == 5
+ # Check Key
+ # =========
- # Add counts
- countTo = [3, 5, 7, 9, 11]
- for i, n in enumerate(countTo):
- for _ in range(n):
- theStatus.countEntry(theStatus._theLabels[i])
- assert theStatus._theCounts == countTo
+ 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 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
+
+# END Test testCoreStatus_Internal
+
+
+@pytest.mark.core
+def testCoreStatus_Iterator(constData):
+ """Test the iterator functions of the NWStatus class.
+ """
+ random.seed(42)
+ 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))
+
+ # Direct access
+ entry = theStatus[constData.statusKeys[0]]
+ assert entry["cols"] == (100, 100, 100)
+ assert entry["name"] == "New"
+ assert entry["count"] == 0
+ assert isinstance(entry["icon"], QIcon)
# Iterate
- for i, (sA, sB, sC, sD) in enumerate(theStatus):
- assert sA == theStatus._theLabels[i]
- assert sB == theStatus._theColours[i]
- assert sC == theStatus._theCounts[i]
- assert sD == theStatus._theIcons[i]
+ entries = list(theStatus)
+ assert len(entries) == 4
+ assert len(theStatus) == 4
- sA, sB, sC, sD = theStatus[9]
- assert sA is None
- assert sB is None
- assert sC is None
- assert isinstance(sD, QIcon)
+ # Keys
+ assert list(theStatus.keys()) == constData.statusKeys
+
+ # Items
+ for index, (key, entry) in enumerate(theStatus.items()):
+ assert key == constData.statusKeys[index]
+ assert "cols" in entry
+ assert "name" in entry
+ assert "count" in entry
+ assert "icon" in entry
+
+ # Valuse
+ for entry in theStatus.values():
+ assert "cols" in entry
+ assert "name" in entry
+ assert "count" in entry
+ assert "icon" in entry
+
+# END Test testCoreStatus_Iterator
+
+
+@pytest.mark.core
+def testCoreStatus_Entries(constData):
+ """Test all the simple setters for the NWStatus class.
+ """
+ random.seed(42)
+ theStatus = NWStatus(NWStatus.STATUS)
+
+ # Write
+ # =====
+
+ # Have a key
+ theStatus.write(constData.statusKeys[0], "Entry 1", (200, 100, 50))
+ assert theStatus[constData.statusKeys[0]]["name"] == "Entry 1"
+ assert theStatus[constData.statusKeys[0]]["cols"] == (200, 100, 50)
+
+ # Don't have a key
+ theStatus.write(None, "Entry 2", (210, 110, 60))
+ assert theStatus[constData.statusKeys[1]]["name"] == "Entry 2"
+ assert theStatus[constData.statusKeys[1]]["cols"] == (210, 110, 60)
+
+ # Wrong colour spec
+ theStatus.write(None, "Entry 3", "what?")
+ assert theStatus[constData.statusKeys[2]]["name"] == "Entry 3"
+ assert theStatus[constData.statusKeys[2]]["cols"] == (100, 100, 100)
+
+ # Wrong colour count
+ theStatus.write(None, "Entry 4", (10, 20))
+ assert theStatus[constData.statusKeys[3]]["name"] == "Entry 4"
+ assert theStatus[constData.statusKeys[3]]["cols"] == (100, 100, 100)
+
+ # Check reverse map
+ assert theStatus._reverse == {
+ "Entry 1": constData.statusKeys[0],
+ "Entry 2": constData.statusKeys[1],
+ "Entry 3": constData.statusKeys[2],
+ "Entry 4": constData.statusKeys[3],
+ }
+
+ # Check
+ # =====
+
+ # Normal lookup
+ for key in constData.statusKeys:
+ assert theStatus.check(key) == key
+
+ # Reverse map lookup
+ assert theStatus.check("Entry 1") == constData.statusKeys[0]
+ assert theStatus.check("Entry 2") == constData.statusKeys[1]
+ assert theStatus.check("Entry 3") == constData.statusKeys[2]
+ assert theStatus.check("Entry 4") == constData.statusKeys[3]
+
+ # Non-existing name
+ assert theStatus.check("Entry 5") == constData.statusKeys[0]
+
+ # Name Access
+ # ===========
+
+ assert theStatus.name(constData.statusKeys[0]) == "Entry 1"
+ assert theStatus.name(constData.statusKeys[1]) == "Entry 2"
+ assert theStatus.name(constData.statusKeys[2]) == "Entry 3"
+ assert theStatus.name(constData.statusKeys[3]) == "Entry 4"
+ assert theStatus.name("blablabla") == "Entry 1"
+
+ # Colour Access
+ # =============
+
+ assert theStatus.cols(constData.statusKeys[0]) == (200, 100, 50)
+ assert theStatus.cols(constData.statusKeys[1]) == (210, 110, 60)
+ assert theStatus.cols(constData.statusKeys[2]) == (100, 100, 100)
+ assert theStatus.cols(constData.statusKeys[3]) == (100, 100, 100)
+ assert theStatus.cols("blablabla") == (200, 100, 50)
+
+ # Icon Access
+ # ===========
+
+ assert isinstance(theStatus.icon(constData.statusKeys[0]), QIcon)
+ assert isinstance(theStatus.icon(constData.statusKeys[1]), QIcon)
+ assert isinstance(theStatus.icon(constData.statusKeys[2]), QIcon)
+ assert isinstance(theStatus.icon(constData.statusKeys[3]), QIcon)
+ assert isinstance(theStatus.icon("blablabla"), QIcon)
+
+ # Increment and Count Access
+ # ==========================
+
+ countTo = [3, 5, 7, 9]
+ for i, n in enumerate(countTo):
+ for _ in range(n):
+ theStatus.increment(constData.statusKeys[i])
+
+ assert theStatus.count(constData.statusKeys[0]) == countTo[0]
+ assert theStatus.count(constData.statusKeys[1]) == countTo[1]
+ assert theStatus.count(constData.statusKeys[2]) == countTo[2]
+ assert theStatus.count(constData.statusKeys[3]) == countTo[3]
+ assert theStatus.count("blablabla") == countTo[0]
- # Clear counts
theStatus.resetCounts()
- assert theStatus._theCounts == [0, 0, 0, 0, 0]
+
+ assert theStatus.count(constData.statusKeys[0]) == 0
+ assert theStatus.count(constData.statusKeys[1]) == 0
+ assert theStatus.count(constData.statusKeys[2]) == 0
+ assert theStatus.count(constData.statusKeys[3]) == 0
+
+ # Default
+ # =======
+
+ default = theStatus._default
+ theStatus._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)
+
+ theStatus._default = default
+
+ # Remove
+ # ======
+
+ # Non-existing entry
+ assert theStatus.remove("blablabla") is False
+
+ # Non-zero entry
+ theStatus.increment(constData.statusKeys[3])
+ assert theStatus.remove(constData.statusKeys[3]) is False
+
+ # Delete last entry
+ theStatus.resetCounts()
+ lastName = theStatus.name(constData.statusKeys[3])
+ assert lastName == "Entry 4"
+ assert theStatus.remove(constData.statusKeys[3]) is True
+ assert theStatus.check(constData.statusKeys[3]) == theStatus._default
+ assert theStatus.check(lastName) == theStatus._default
+
+ # Delete default entry, Entry 2 is new default
+ firstName = theStatus.name(theStatus._default)
+ assert firstName == "Entry 1"
+ assert theStatus.remove(theStatus._default) is True
+ assert theStatus.name(firstName) == "Entry 2"
+
+ # Remove remaining entries
+ assert theStatus.remove(constData.statusKeys[1]) is True
+ assert theStatus.remove(constData.statusKeys[2]) is True
+
+ assert len(theStatus) == 0
+ assert theStatus._default is None
# END Test testCoreStatus_Entries
@pytest.mark.core
-def testCoreStatus_XMLPackUnpack():
- """Test all the simple setters for the NWItem class.
+def testCoreStatus_XMLPackUnpack(constData):
+ """Test all the XML pack/unpack of the NWStatus class.
"""
- theStatus = NWStatus()
- theStatus.addEntry("New", (100, 100, 100))
- theStatus.addEntry("Minor", (200, 50, 0))
- theStatus.addEntry("Major", (200, 150, 0))
- theStatus.addEntry("Main", (50, 200, 0))
+ random.seed(42)
+ 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))
countTo = [3, 5, 7, 9]
for i, n in enumerate(countTo):
for _ in range(n):
- theStatus.countEntry(theStatus._theLabels[i])
+ theStatus.increment(constData.statusKeys[i])
nwXML = etree.Element("novelWriterXML")
@@ -134,23 +300,29 @@ def testCoreStatus_XMLPackUnpack():
theStatus.packXML(xStatus)
assert etree.tostring(xStatus, pretty_print=False, encoding="utf-8") == (
b''
- b'New'
- b'Minor'
- b'Major'
- b'Main'
+ b'New'
+ b'Note'
+ b'Draft'
+ b'Finished'
b''
)
# Unpack
- theStatus = NWStatus()
+ theStatus = NWStatus(NWStatus.STATUS)
assert theStatus.unpackXML(xStatus)
- assert theStatus._theLabels == ["New", "Minor", "Major", "Main"]
- assert theStatus._theColours == [(100, 100, 100), (200, 50, 0), (200, 150, 0), (50, 200, 0)]
- assert theStatus._theCounts == [0, 0, 0, 0]
- assert theStatus._theMap["New"] == 0
- assert theStatus._theMap["Minor"] == 1
- assert theStatus._theMap["Major"] == 2
- assert theStatus._theMap["Main"] == 3
- assert theStatus._theLength == 4
+ assert len(theStatus._store) == 4
+ assert list(theStatus._store.keys()) == constData.statusKeys
+ assert theStatus._store[constData.statusKeys[0]]["name"] == "New"
+ assert theStatus._store[constData.statusKeys[1]]["name"] == "Note"
+ assert theStatus._store[constData.statusKeys[2]]["name"] == "Draft"
+ assert theStatus._store[constData.statusKeys[3]]["name"] == "Finished"
+ assert theStatus._store[constData.statusKeys[0]]["cols"] == (100, 100, 100)
+ assert theStatus._store[constData.statusKeys[1]]["cols"] == (200, 50, 0)
+ assert theStatus._store[constData.statusKeys[2]]["cols"] == (200, 150, 0)
+ assert theStatus._store[constData.statusKeys[3]]["cols"] == (50, 200, 0)
+ assert theStatus._store[constData.statusKeys[0]]["count"] == countTo[0]
+ assert theStatus._store[constData.statusKeys[1]]["count"] == countTo[1]
+ assert theStatus._store[constData.statusKeys[2]]["count"] == countTo[2]
+ assert theStatus._store[constData.statusKeys[3]]["count"] == countTo[3]
# END Test testCoreStatus_XMLPackUnpack