Skip to content

Commit 4a42761

Browse files
committed
Add __eq__ to Indent
1 parent b47ecab commit 4a42761

File tree

2 files changed

+145
-6
lines changed

2 files changed

+145
-6
lines changed

domdf_python_tools/stringlist.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
# stdlib
2727
from contextlib import contextmanager
28-
from typing import Iterable, List, Tuple, Union, cast, overload
28+
from typing import Any, Iterable, Iterator, List, Tuple, Union, cast, overload
2929

3030
# 3rd party
3131
from typing_extensions import Protocol
@@ -42,7 +42,7 @@ class String(Protocol):
4242
"""
4343

4444
def __str__(self) -> str:
45-
...
45+
... # pragma: no cover
4646

4747

4848
class Indent:
@@ -54,7 +54,7 @@ def __init__(self, size: int = 0, type: str = "\t"):
5454
self.size = int(size)
5555
self.type = str(type)
5656

57-
def __iter__(self) -> Iterable:
57+
def __iter__(self) -> Iterator[Union[str, Any]]:
5858
"""
5959
Returns the size and type of the :class:`~domdf_python_tools.stringlist.Indent`
6060
"""
@@ -102,6 +102,16 @@ def __repr__(self) -> str:
102102

103103
return f"{type(self).__name__}(size={self.size}, type={self.type!r})"
104104

105+
def __eq__(self, other):
106+
if isinstance(other, Indent):
107+
return other.size == self.size and other.type == self.type
108+
elif isinstance(other, str):
109+
return str(self) == other
110+
elif isinstance(other, tuple):
111+
return tuple(self) == other
112+
else:
113+
return NotImplemented
114+
105115

106116
class StringList(List[str]):
107117
"""
@@ -132,7 +142,7 @@ def _make_line(self, line: str) -> str:
132142
if not str(self.indent).strip(" \t") and self.convert_indents:
133143
if self.indent_type == '\t':
134144
line = convert_indents(line, tab_width=1, from_=' ', to='\t')
135-
else:
145+
else: # pragma: no cover
136146
line = convert_indents(line, tab_width=1, from_='\t', to=self.indent_type)
137147

138148
return f"{self.indent}{line}".rstrip()
@@ -192,7 +202,7 @@ def __setitem__(self, index: Union[int, slice], line: Union[String, Iterable[Str
192202
elif isinstance(index, slice):
193203
for line, index in zip(
194204
reversed(line), # type: ignore
195-
reversed(range(index.start, index.stop + 1, index.step or 1)),
205+
reversed(range(index.start or 0, index.stop + 1, index.step or 1)),
196206
):
197207
self[index] = line
198208

tests/test_stringlist.py

Lines changed: 130 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import pytest
66

77
# this package
8-
from domdf_python_tools.stringlist import StringList
8+
from domdf_python_tools.stringlist import Indent, StringList
99

1010

1111
class TestStringList:
@@ -235,6 +235,48 @@ def __repr__(self) -> str:
235235
assert str(sl) == expected_string
236236
assert sl == expected_string
237237

238+
sl = StringList()
239+
sl.append("class Foo:")
240+
sl.set_indent(Indent(0, " "))
241+
sl.blankline(True)
242+
243+
with sl.with_indent_size(1):
244+
sl.append("def bar(self, listicle: List[Item]):")
245+
with sl.with_indent_size(2):
246+
sl.append("...")
247+
sl.blankline(True)
248+
sl.append("def __repr__(self) -> str:")
249+
with sl.with_indent_size(2):
250+
sl.append('return "Foo()"')
251+
sl.blankline(True)
252+
253+
assert sl.indent_size == 0
254+
255+
assert sl == [x.expandtabs(4) for x in expected_list]
256+
assert str(sl) == expected_string.expandtabs(4)
257+
assert sl == expected_string.expandtabs(4)
258+
259+
sl = StringList()
260+
sl.append("class Foo:")
261+
sl.set_indent(" ", 0)
262+
sl.blankline(True)
263+
264+
with sl.with_indent_size(1):
265+
sl.append("def bar(self, listicle: List[Item]):")
266+
with sl.with_indent_size(2):
267+
sl.append("...")
268+
sl.blankline(True)
269+
sl.append("def __repr__(self) -> str:")
270+
with sl.with_indent_size(2):
271+
sl.append('return "Foo()"')
272+
sl.blankline(True)
273+
274+
assert sl.indent_size == 0
275+
276+
assert sl == [x.expandtabs(4) for x in expected_list]
277+
assert str(sl) == expected_string.expandtabs(4)
278+
assert sl == expected_string.expandtabs(4)
279+
238280
sl = StringList()
239281
sl.append("class Foo:")
240282
sl.blankline(True)
@@ -263,3 +305,90 @@ def test_convert_indents(self):
263305
sl.append(" Indented")
264306

265307
assert sl == ["\tIndented"]
308+
309+
def test_set_indent_error(self):
310+
sl = StringList()
311+
with pytest.raises(TypeError, match="'size' argument cannot be used when providing an 'Indent' object."):
312+
sl.set_indent(Indent(0, " "), 5)
313+
314+
315+
class TestIndent:
316+
317+
def test_creation(self):
318+
indent = Indent()
319+
assert indent.size == 0
320+
assert indent.type == "\t"
321+
322+
indent = Indent(3, " ")
323+
assert indent.size == 3
324+
assert indent.type == " "
325+
326+
def test_iter(self):
327+
indent = Indent(3, " ")
328+
assert tuple(indent) == (3, " ")
329+
assert list(iter(indent)) == [3, " "]
330+
331+
def test_size(self):
332+
indent = Indent()
333+
334+
indent.size = 1
335+
assert indent.size == 1
336+
337+
indent.size = "2" # type: ignore
338+
assert indent.size == 2
339+
340+
indent.size = 3.0 # type: ignore
341+
assert indent.size == 3
342+
343+
def test_type(self):
344+
indent = Indent()
345+
346+
indent.type = " "
347+
assert indent.type == " "
348+
349+
indent.type = " "
350+
assert indent.type == " "
351+
352+
indent.type = 1 # type: ignore
353+
assert indent.type == "1"
354+
355+
indent.type = ">>> "
356+
assert indent.type == ">>> "
357+
358+
with pytest.raises(ValueError, match="'type' cannot an empty string."):
359+
indent.type = ''
360+
361+
def test_str(self):
362+
assert str(Indent()) == ""
363+
assert str(Indent(1)) == "\t"
364+
assert str(Indent(5)) == "\t\t\t\t\t"
365+
assert str(Indent(type=" ")) == ""
366+
assert str(Indent(1, type=" ")) == " "
367+
assert str(Indent(5, type=" ")) == " " * 5
368+
assert str(Indent(type=">>> ")) == ""
369+
assert str(Indent(1, type=">>> ")) == ">>> "
370+
371+
def test_repr(self):
372+
assert repr(Indent()) == "Indent(size=0, type='\\t')"
373+
assert repr(Indent(1)) == "Indent(size=1, type='\\t')"
374+
assert repr(Indent(5)) == "Indent(size=5, type='\\t')"
375+
assert repr(Indent(type=" ")) == "Indent(size=0, type=' ')"
376+
assert repr(Indent(1, type=" ")) == "Indent(size=1, type=' ')"
377+
assert repr(Indent(5, type=" ")) == "Indent(size=5, type=' ')"
378+
assert repr(Indent(type=">>> ")) == "Indent(size=0, type='>>> ')"
379+
assert repr(Indent(1, type=">>> ")) == "Indent(size=1, type='>>> ')"
380+
381+
def test_eq(self):
382+
assert Indent() == Indent()
383+
assert Indent() == (0, "\t")
384+
assert Indent() == ''
385+
386+
assert Indent(1, " ") == Indent(1, " ")
387+
assert Indent(1, " ") == (1, " ")
388+
assert Indent(1, " ") == ' '
389+
390+
assert Indent(2, "\t") == Indent(2, "\t")
391+
assert Indent(2, "\t") == (2, "\t")
392+
assert Indent(2, "\t") == '\t\t'
393+
394+
assert not Indent() == 1

0 commit comments

Comments
 (0)