Skip to content

Commit 7d6ad4e

Browse files
committed
Improved unit tests by making them more self documenting
The expected output in the unit tests is now in a human-readable form. This makes the unit tests and the module overall much more self-documenting. Also: - Made a tweak to see if it fixes the unit test problems on Python 3.4 on TravisCI.
1 parent c07e40c commit 7d6ad4e

File tree

2 files changed

+133
-48
lines changed

2 files changed

+133
-48
lines changed

tableformatter.py

Lines changed: 16 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -14,43 +14,22 @@
1414
# Python 3.6+ should have Collection in the typing module
1515
from typing import Collection
1616
except ImportError:
17-
from typing import Container, Sized
18-
import sys
19-
20-
# Unfortunately need slightly different solutions for Python 3.4 vs 3.5
21-
if sys.version_info < (3, 5):
22-
# Python 3.4
23-
# noinspection PyAbstractClass
24-
class Collection(Container, Sized, Iterable):
25-
"""hack to enable Collection typing"""
26-
__slots__ = ()
27-
28-
# noinspection PyPep8Naming
29-
@classmethod
30-
def __subclasshook__(cls, C):
31-
if cls is Collection:
32-
if any("__len__" in B.__dict__ for B in C.__mro__) and \
33-
any("__iter__" in B.__dict__ for B in C.__mro__) and \
34-
any("__contains__" in B.__dict__ for B in C.__mro__):
35-
return True
36-
return NotImplemented
37-
else:
38-
# Python 3.5
39-
# noinspection PyAbstractClass
40-
from typing import Generic, TypeVar
41-
class Collection(Generic[TypeVar('T_co', covariant=True)], Container, Sized, Iterable):
42-
"""hack to enable Collection typing"""
43-
__slots__ = ()
44-
45-
# noinspection PyPep8Naming
46-
@classmethod
47-
def __subclasshook__(cls, C):
48-
if cls is Collection:
49-
if any("__len__" in B.__dict__ for B in C.__mro__) and \
50-
any("__iter__" in B.__dict__ for B in C.__mro__) and \
51-
any("__contains__" in B.__dict__ for B in C.__mro__):
52-
return True
53-
return NotImplemented
17+
from typing import Container, Generic, Sized, TypeVar
18+
# Python 3.5
19+
# noinspection PyAbstractClass
20+
class Collection(Generic[TypeVar('T_co', covariant=True)], Container, Sized, Iterable):
21+
"""hack to enable Collection typing"""
22+
__slots__ = ()
23+
24+
# noinspection PyPep8Naming
25+
@classmethod
26+
def __subclasshook__(cls, C):
27+
if cls is Collection:
28+
if any("__len__" in B.__dict__ for B in C.__mro__) and \
29+
any("__iter__" in B.__dict__ for B in C.__mro__) and \
30+
any("__contains__" in B.__dict__ for B in C.__mro__):
31+
return True
32+
return NotImplemented
5433

5534

5635
ANSI_ESCAPE_RE = re.compile(r'\x1b[^m]*m')

tests/test_simple.py

Lines changed: 117 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,29 @@
1111
# Make the test results reproducible regardless of what color libraries are installed
1212
tf.TableColors.set_color_library('none')
1313

14-
WITH_HEADER = '╔══════╤══════╤══════╤══════╗\n║ Col1 │ Col2 │ Col3 │ Col4 ║\n╠══════╪══════╪══════╪══════╣\n║ A1 │ A2 │ A3 │ A4 ║\n║ B1 │ B2 │ B3 │ B4 ║\n║ │ B2 │ │ ║\n║ │ B2 │ │ ║\n║ C1 │ C2 │ C3 │ C4 ║\n║ D1 │ D2 │ D3 │ D4 ║\n╚══════╧══════╧══════╧══════╝\n'
15-
HEADER_TRANSPOSED = '╔══════╦════╤════╤════╤════╗\n║ Col1 ║ A1 │ B1 │ C1 │ D1 ║\n║ Col2 ║ A2 │ B2 │ C2 │ D2 ║\n║ ║ │ B2 │ │ ║\n║ ║ │ B2 │ │ ║\n║ Col3 ║ A3 │ B3 │ C3 │ D3 ║\n║ Col4 ║ A4 │ B4 │ C4 │ D4 ║\n╚══════╩════╧════╧════╧════╝\n'
14+
WITH_HEADER = '''
15+
╔══════╤══════╤══════╤══════╗
16+
║ Col1 │ Col2 │ Col3 │ Col4 ║
17+
╠══════╪══════╪══════╪══════╣
18+
║ A1 │ A2 │ A3 │ A4 ║
19+
║ B1 │ B2 │ B3 │ B4 ║
20+
║ │ B2 │ │ ║
21+
║ │ B2 │ │ ║
22+
║ C1 │ C2 │ C3 │ C4 ║
23+
║ D1 │ D2 │ D3 │ D4 ║
24+
╚══════╧══════╧══════╧══════╝
25+
'''.lstrip('\n')
26+
27+
HEADER_TRANSPOSED = '''
28+
╔══════╦════╤════╤════╤════╗
29+
║ Col1 ║ A1 │ B1 │ C1 │ D1 ║
30+
║ Col2 ║ A2 │ B2 │ C2 │ D2 ║
31+
║ ║ │ B2 │ │ ║
32+
║ ║ │ B2 │ │ ║
33+
║ Col3 ║ A3 │ B3 │ C3 │ D3 ║
34+
║ Col4 ║ A4 │ B4 │ C4 │ D4 ║
35+
╚══════╩════╧════╧════╧════╝
36+
'''.lstrip('\n')
1637

1738

1839
@pytest.fixture
@@ -29,22 +50,58 @@ def cols():
2950
return columns
3051

3152
def test_basic_table(rows):
32-
expected = '╔════╤════╤════╤════╗\n║ A1 │ A2 │ A3 │ A4 ║\n║ B1 │ B2 │ B3 │ B4 ║\n║ │ B2 │ │ ║\n║ │ B2 │ │ ║\n║ C1 │ C2 │ C3 │ C4 ║\n║ D1 │ D2 │ D3 │ D4 ║\n╚════╧════╧════╧════╝\n'
53+
expected = '''
54+
╔════╤════╤════╤════╗
55+
║ A1 │ A2 │ A3 │ A4 ║
56+
║ B1 │ B2 │ B3 │ B4 ║
57+
║ │ B2 │ │ ║
58+
║ │ B2 │ │ ║
59+
║ C1 │ C2 │ C3 │ C4 ║
60+
║ D1 │ D2 │ D3 │ D4 ║
61+
╚════╧════╧════╧════╝
62+
'''.lstrip('\n')
3363
table = tf.generate_table(rows)
3464
assert table == expected
3565

3666
def test_basic_transposed(rows):
37-
expected = '╔════╤════╤════╤════╗\n║ A1 │ B1 │ C1 │ D1 ║\n║ A2 │ B2 │ C2 │ D2 ║\n║ │ B2 │ │ ║\n║ │ B2 │ │ ║\n║ A3 │ B3 │ C3 │ D3 ║\n║ A4 │ B4 │ C4 │ D4 ║\n╚════╧════╧════╧════╝\n'
67+
expected = '''
68+
╔════╤════╤════╤════╗
69+
║ A1 │ B1 │ C1 │ D1 ║
70+
║ A2 │ B2 │ C2 │ D2 ║
71+
║ │ B2 │ │ ║
72+
║ │ B2 │ │ ║
73+
║ A3 │ B3 │ C3 │ D3 ║
74+
║ A4 │ B4 │ C4 │ D4 ║
75+
╚════╧════╧════╧════╝
76+
'''.lstrip('\n')
3877
table = tf.generate_table(rows, transpose=True)
3978
assert table == expected
4079

4180
def test_basic_fancy_grid(rows):
42-
expected = '╔════╤════╤════╤════╗\n║ A1 │ A2 │ A3 │ A4 ║\n╟────┼────┼────┼────╢\n║ B1 │ B2 │ B3 │ B4 ║\n║ │ B2 │ │ ║\n║ │ B2 │ │ ║\n╟────┼────┼────┼────╢\n║ C1 │ C2 │ C3 │ C4 ║\n╟────┼────┼────┼────╢\n║ D1 │ D2 │ D3 │ D4 ║\n╚════╧════╧════╧════╝\n'
81+
expected = '''
82+
╔════╤════╤════╤════╗
83+
║ A1 │ A2 │ A3 │ A4 ║
84+
╟────┼────┼────┼────╢
85+
║ B1 │ B2 │ B3 │ B4 ║
86+
║ │ B2 │ │ ║
87+
║ │ B2 │ │ ║
88+
╟────┼────┼────┼────╢
89+
║ C1 │ C2 │ C3 │ C4 ║
90+
╟────┼────┼────┼────╢
91+
║ D1 │ D2 │ D3 │ D4 ║
92+
╚════╧════╧════╧════╝
93+
'''.lstrip('\n')
4394
table = tf.generate_table(rows, grid_style=tf.FancyGrid)
4495
assert table == expected
4596

4697
def test_basic_sparse_grid(rows):
47-
expected = ' A1 A2 A3 A4 \n B1 B2 B3 B4 \n B2 \n B2 \n C1 C2 C3 C4 \n D1 D2 D3 D4 \n \n'
98+
expected = '''
99+
A1 A2 A3 A4
100+
B1 B2 B3 B4
101+
B2
102+
B2
103+
C1 C2 C3 C4
104+
D1 D2 D3 D4 \n \n'''.lstrip('\n')
48105
table = tf.generate_table(rows, grid_style=tf.SparseGrid)
49106
assert table == expected
50107

@@ -57,12 +114,30 @@ def test_table_with_header_transposed(rows, cols):
57114
assert table == HEADER_TRANSPOSED
58115

59116
def test_table_with_header_transposed_fancy(rows, cols):
60-
expected = '╔══════╦════╤════╤════╤════╗\n║ Col1 ║ A1 │ B1 │ C1 │ D1 ║\n╟──────╫────┼────┼────┼────╢\n║ Col2 ║ A2 │ B2 │ C2 │ D2 ║\n║ ║ │ B2 │ │ ║\n║ ║ │ B2 │ │ ║\n╟──────╫────┼────┼────┼────╢\n║ Col3 ║ A3 │ B3 │ C3 │ D3 ║\n╟──────╫────┼────┼────┼────╢\n║ Col4 ║ A4 │ B4 │ C4 │ D4 ║\n╚══════╩════╧════╧════╧════╝\n'
117+
expected = '''
118+
╔══════╦════╤════╤════╤════╗
119+
║ Col1 ║ A1 │ B1 │ C1 │ D1 ║
120+
╟──────╫────┼────┼────┼────╢
121+
║ Col2 ║ A2 │ B2 │ C2 │ D2 ║
122+
║ ║ │ B2 │ │ ║
123+
║ ║ │ B2 │ │ ║
124+
╟──────╫────┼────┼────┼────╢
125+
║ Col3 ║ A3 │ B3 │ C3 │ D3 ║
126+
╟──────╫────┼────┼────┼────╢
127+
║ Col4 ║ A4 │ B4 │ C4 │ D4 ║
128+
╚══════╩════╧════╧════╧════╝
129+
'''.lstrip('\n')
61130
table = tf.generate_table(rows, cols, grid_style=tf.FancyGrid, transpose=True)
62131
assert table == expected
63132

64133
def test_table_with_header_transposed_sparse(rows, cols):
65-
expected = ' Col1 A1 B1 C1 D1 \n Col2 A2 B2 C2 D2 \n B2 \n B2 \n Col3 A3 B3 C3 D3 \n Col4 A4 B4 C4 D4 \n \n'
134+
expected = '''
135+
Col1 A1 B1 C1 D1
136+
Col2 A2 B2 C2 D2
137+
B2
138+
B2
139+
Col3 A3 B3 C3 D3
140+
Col4 A4 B4 C4 D4 \n \n'''.lstrip('\n')
66141
table = tf.generate_table(rows, cols, grid_style=tf.SparseGrid, transpose=True)
67142
assert table == expected
68143

@@ -105,12 +180,32 @@ def test_object_table_transposed(obj_rows, obj_cols):
105180
assert table == HEADER_TRANSPOSED
106181

107182
def test_object_table_fancy_grid(obj_rows, obj_cols):
108-
expected = '╔══════╤══════╤══════╤══════╗\n║ Col1 │ Col2 │ Col3 │ Col4 ║\n╠══════╪══════╪══════╪══════╣\n║ A1 │ A2 │ A3 │ A4 ║\n╟──────┼──────┼──────┼──────╢\n║ B1 │ B2 │ B3 │ B4 ║\n║ │ B2 │ │ ║\n║ │ B2 │ │ ║\n╟──────┼──────┼──────┼──────╢\n║ C1 │ C2 │ C3 │ C4 ║\n╟──────┼──────┼──────┼──────╢\n║ D1 │ D2 │ D3 │ D4 ║\n╚══════╧══════╧══════╧══════╝\n'
183+
expected = '''
184+
╔══════╤══════╤══════╤══════╗
185+
║ Col1 │ Col2 │ Col3 │ Col4 ║
186+
╠══════╪══════╪══════╪══════╣
187+
║ A1 │ A2 │ A3 │ A4 ║
188+
╟──────┼──────┼──────┼──────╢
189+
║ B1 │ B2 │ B3 │ B4 ║
190+
║ │ B2 │ │ ║
191+
║ │ B2 │ │ ║
192+
╟──────┼──────┼──────┼──────╢
193+
║ C1 │ C2 │ C3 │ C4 ║
194+
╟──────┼──────┼──────┼──────╢
195+
║ D1 │ D2 │ D3 │ D4 ║
196+
╚══════╧══════╧══════╧══════╝
197+
'''.lstrip('\n')
109198
table = tf.generate_table(obj_rows, obj_cols, grid_style=tf.FancyGrid)
110199
assert table == expected
111200

112201
def test_object_table_sparse_grid(obj_rows, obj_cols):
113-
expected = ' A1 A2 A3 A4 \n B1 B2 B3 B4 \n B2 \n B2 \n C1 C2 C3 C4 \n D1 D2 D3 D4 \n \n'
202+
expected = '''
203+
A1 A2 A3 A4
204+
B1 B2 B3 B4
205+
B2
206+
B2
207+
C1 C2 C3 C4
208+
D1 D2 D3 D4 \n \n'''.lstrip('\n')
114209
table = tf.generate_table(obj_rows, obj_cols, grid_style=tf.SparseGrid)
115210
assert table == expected
116211

@@ -119,7 +214,18 @@ def test_object_table_columns_rearranged(obj_rows):
119214
tf.Column('Col2', attrib='field2'),
120215
tf.Column('Col3', attrib='field1'),
121216
tf.Column('Col4', attrib='field4'))
122-
expected = '╔══════╤══════╤══════╤══════╗\n║ Col1 │ Col2 │ Col3 │ Col4 ║\n╠══════╪══════╪══════╪══════╣\n║ │ A2 │ A1 │ A4 ║\n║ │ B2 │ B1 │ B4 ║\n║ │ B2 │ │ ║\n║ │ B2 │ │ ║\n║ │ C2 │ C1 │ C4 ║\n║ │ D2 │ D1 │ D4 ║\n╚══════╧══════╧══════╧══════╝\n'
217+
expected = '''
218+
╔══════╤══════╤══════╤══════╗
219+
║ Col1 │ Col2 │ Col3 │ Col4 ║
220+
╠══════╪══════╪══════╪══════╣
221+
║ │ A2 │ A1 │ A4 ║
222+
║ │ B2 │ B1 │ B4 ║
223+
║ │ B2 │ │ ║
224+
║ │ B2 │ │ ║
225+
║ │ C2 │ C1 │ C4 ║
226+
║ │ D2 │ D1 │ D4 ║
227+
╚══════╧══════╧══════╧══════╝
228+
'''.lstrip('\n')
123229
table = tf.generate_table(obj_rows, cols2)
124230
assert table == expected
125231

0 commit comments

Comments
 (0)