Unit test markup and fix all issues found
This commit is contained in:
parent
052bbfb6d2
commit
c035817ba8
3 changed files with 139 additions and 6 deletions
|
|
@ -1,10 +1,8 @@
|
|||
from typing import Any, Dict, Iterable, List, Optional, Tuple, Union
|
||||
from typing import Any, Iterable, List, Mapping, Optional, Tuple, Union
|
||||
|
||||
__all__ = ["Attributes", "Chunk", "AttributedText", "AT"]
|
||||
|
||||
|
||||
Attributes = Dict[str, Any]
|
||||
|
||||
Attributes = Mapping[str, Any]
|
||||
|
||||
# TODO remove empty Chunks in join_chunks
|
||||
class Chunk:
|
||||
|
|
@ -46,6 +44,12 @@ class Chunk:
|
|||
|
||||
# Uncommon special methods
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
if not isinstance(other, Chunk):
|
||||
return NotImplemented
|
||||
|
||||
return self._text == other._text and self._attributes == other._attributes
|
||||
|
||||
def __getitem__(self, key: Union[int, slice]) -> "Chunk":
|
||||
return Chunk(self.text[key], self._attributes)
|
||||
|
||||
|
|
@ -90,7 +94,6 @@ class Chunk:
|
|||
|
||||
return Chunk(self.text, new_attributes)
|
||||
|
||||
|
||||
class AttributedText:
|
||||
"""
|
||||
Objects of this class are immutable and behave str-like. Supported
|
||||
|
|
@ -139,6 +142,12 @@ class AttributedText:
|
|||
def __add__(self, other: "AttributedText") -> "AttributedText":
|
||||
return AttributedText.from_chunks(self._chunks + other._chunks)
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
if not isinstance(other, AttributedText):
|
||||
return NotImplemented
|
||||
|
||||
return self._chunks == other._chunks
|
||||
|
||||
def __getitem__(self, key: Union[int, slice]) -> "AttributedText":
|
||||
chunks: List[Chunk]
|
||||
|
||||
|
|
@ -152,6 +161,12 @@ class AttributedText:
|
|||
def __len__(self) -> int:
|
||||
return sum(map(len, self._chunks))
|
||||
|
||||
def __mul__(self, other: int) -> "AttributedText":
|
||||
if not isinstance(other, int):
|
||||
return NotImplemented
|
||||
|
||||
return self.from_chunks(self.chunks * other)
|
||||
|
||||
# Properties
|
||||
|
||||
@property
|
||||
|
|
@ -325,7 +340,7 @@ class AttributedText:
|
|||
return self[:start] + middle + self[stop:]
|
||||
|
||||
def set_at(self, name: str, value: Any, pos: int) -> "AttributedText":
|
||||
return self.set(name, value, pos, pos)
|
||||
return self.set(name, value, pos, pos + 1)
|
||||
|
||||
def remove(self,
|
||||
name: str,
|
||||
|
|
|
|||
5
test/__init__.py
Normal file
5
test/__init__.py
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
from .test_markup import *
|
||||
|
||||
__all__ = []
|
||||
|
||||
__all__+= test_element_rendering.__all__
|
||||
113
test/test_markup.py
Normal file
113
test/test_markup.py
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
import unittest
|
||||
|
||||
from cheuph import AT
|
||||
|
||||
__all__ = ["TestAttributedText"]
|
||||
|
||||
class TestAttributedText(unittest.TestCase):
|
||||
|
||||
SAMPLE_STRINGS = [
|
||||
"Hello world",
|
||||
"\n",
|
||||
" ",
|
||||
"multiline\nstring\nwith\nmultiple\nlines",
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
self.text = AT("This is a sample string.")
|
||||
self.text = self.text.set("attribute", "value", 5, 21)
|
||||
self.text = self.text.set_at("attribute2", "value2", 13)
|
||||
|
||||
def test_equality_of_empty_text(self):
|
||||
self.assertEqual(AT(), AT())
|
||||
|
||||
def test_string_to_AT_to_string(self):
|
||||
for string in self.SAMPLE_STRINGS:
|
||||
with self.subTest(string=repr(string)):
|
||||
self.assertEqual(string, str(AT(string)))
|
||||
|
||||
def test_homomorphism_on_string_concatenation(self):
|
||||
self.assertEqual("hello world", str(AT("hello") + AT(" world")))
|
||||
|
||||
result_1 = "".join(self.SAMPLE_STRINGS)
|
||||
result_2 = AT().join(AT(string) for string in self.SAMPLE_STRINGS)
|
||||
self.assertEqual(result_1, str(result_2))
|
||||
|
||||
def test_setting_and_getting_an_attribute(self):
|
||||
# Lower and upper bounds
|
||||
|
||||
self.assertIsNone(self.text.get(4, "attribute"))
|
||||
self.assertEqual("value", self.text.get(5, "attribute"))
|
||||
self.assertEqual("value", self.text.get(20, "attribute"))
|
||||
self.assertIsNone(self.text.get(21, "attribute"))
|
||||
|
||||
self.assertIsNone(self.text.get(12, "attribute2"))
|
||||
self.assertEqual("value2", self.text.get(13, "attribute2"))
|
||||
self.assertIsNone(self.text.get(14, "attribute2"))
|
||||
|
||||
# Variants on get()
|
||||
|
||||
self.assertEqual({"attribute": "value"}, self.text.at(10))
|
||||
self.assertEqual("value", self.text.at(10).get("attribute"))
|
||||
self.assertEqual("value", self.text.get(10, "attribute"))
|
||||
|
||||
self.assertEqual({}, self.text.at(2))
|
||||
self.assertIsNone(self.text.get(2, "attribute"))
|
||||
|
||||
|
||||
self.assertEqual({"attribute": "value", "attribute2": "value2"},
|
||||
self.text.at(13))
|
||||
|
||||
def test_slicing_and_putting_back_together_with_attributes(self):
|
||||
text2 = self.text[:4] + self.text[4:11] + self.text[11:22] + self.text[22:]
|
||||
text3 = self.text[:-20] + self.text[-20:-4] + self.text[-4:]
|
||||
|
||||
self.assertEqual(self.text, text2)
|
||||
self.assertEqual(self.text, text3)
|
||||
|
||||
def test_removing_attributes(self):
|
||||
text = self.text.remove("attribute", 9, 15)
|
||||
|
||||
# Lower and upper bounds
|
||||
|
||||
self.assertEqual("value", text.get(8, "attribute"))
|
||||
self.assertIsNone(text.get(9, "attribute"))
|
||||
self.assertIsNone(text.get(14, "attribute"))
|
||||
self.assertEqual("value", text.get(15, "attribute"))
|
||||
|
||||
# Other attribute wasn't touched
|
||||
|
||||
self.assertIsNone(text.get(12, "attribute2"))
|
||||
self.assertEqual("value2", text.get(13, "attribute2"))
|
||||
self.assertIsNone(text.get(14, "attribute2"))
|
||||
|
||||
def test_immutability(self):
|
||||
text = self.text
|
||||
text2 = text.remove("attribute", 10, 12)
|
||||
text3 = text2.set("attribute", "bar", 10, 14)
|
||||
text4 = text3.set_at("attribute", "xyz", 11)
|
||||
|
||||
for i in range(5, 21):
|
||||
self.assertEqual("value", text.get(i, "attribute"))
|
||||
|
||||
for i in range(10, 12):
|
||||
self.assertIsNone(text2.get(i, "attribute"))
|
||||
|
||||
for i in range(10, 14):
|
||||
self.assertEqual("bar", text3.get(i, "attribute"))
|
||||
|
||||
self.assertEqual("xyz", text4.get(11, "attribute"))
|
||||
|
||||
def test_joining_with_attributes(self):
|
||||
snippet1 = AT("hello", foo="bar")
|
||||
snippet2 = AT("world", foo="qux")
|
||||
space = AT(" ", space=True, foo="herbert")
|
||||
|
||||
text1 = snippet1 + space + snippet2
|
||||
text2 = space.join([snippet1, snippet2])
|
||||
|
||||
self.assertEqual(text1, text2)
|
||||
|
||||
# TODO test find_all()
|
||||
# TODO test split_by()
|
||||
# TODO test __mul__()
|
||||
Loading…
Add table
Add a link
Reference in a new issue