-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathtests.py
More file actions
124 lines (106 loc) · 4.36 KB
/
Copy pathtests.py
File metadata and controls
124 lines (106 loc) · 4.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
from collections import abc as _abc
import inspect as _inspect
from clay.text import is_capitalized as _is_cap, \
uncapitalize as _uncap
_stack = _inspect.stack()
if _stack[-1].code_context is None:
# if __name__ == '__main__' equivalent
_frame = _stack[0]
else:
# if imported from another module
_frame = _stack[-1]
MODULE = _inspect.getmodulename(_frame[1]) + '.py'
print()
print('Running tests for "{}"...'.format(MODULE))
print()
def _show_success(expectation: str) -> None:
print('Passed: {}'.format(expectation))
def _show_failure(expectation: str, expected: object, actual: object) -> None:
print('Failed: {}. Expected {} but found {}' \
.format(expectation, expected, actual))
def testif(expectation: str,
test_input: object,
test_output: object,
name: str=None,
raises: BaseException=None,
transformer: _abc.Callable=lambda x: x) -> None:
"""
Tests whether the expectation is valid by comparing the
given test input to the test output. Test output may either
be a value or function accepting one argument.
"""
if name is not None:
if not isinstance(name, str):
raise TypeError('name must be of type str')
else:
# if the expectation is capitalized
if _is_cap(expectation):
# uncapitalize it
expectation = _uncap(expectation)
expectation = '{} {}'.format(name, expectation)
if type(test_input).__name__ == 'function' and raises is not None: # lambda expressions
if not isinstance(raises, type):
raise TypeError('raises must be an error type')
has_raised = False
is_correct_type = False
ex_raised = None
try:
test_input()
except Exception as ex:
has_raised = True
ex_raised = ex.__class__
if ex_raised == raises:
is_correct_type = True
_show_success(expectation)
if not has_raised or not is_correct_type:
_show_failure(expectation, raises, ex_raised)
else:
if type(test_input).__name__ == 'function':
test_input = test_input()
result = transformer(test_input)
if result == test_output:
_show_success(expectation)
else:
_show_failure(expectation, test_output, result)
def testraises(raise_condition: str,
test_expression: _abc.Callable,
exception: BaseException,
name: str=None,
transformer: _abc.Callable=lambda x: x) -> None:
"""
Tests if the expression raises the given exception when
the condition is True. Shortcut to the `testif` function.
"""
# if the raise condition is capitalized
if _is_cap(raise_condition):
# uncapitalize it
raise_condition = _uncap(raise_condition)
testif('Raises {} if {}'.format(exception.__name__, raise_condition),
test_expression,
None,
name=name,
raises=exception,
transformer=transformer)
if __name__ == '__main__':
testif('testif raises TypeError when name is not of type str',
lambda: testif('should pass', 0, 0, name=testif),
None,
raises=TypeError)
testif('formats capitalized expectation with name correctly', 0, 0, name='testif')
testif('testif passes test for equal values', 0, 0)
print('The next test should fail')
testif('testif passes test for unequal values', 0, 1)
print('The next test should fail')
testif('testif passes test after applying transformer', [], 0, transformer=len)
try:
testif('testif passes test for raising division error', lambda: 0 / 0, None)
except ZeroDivisionError: # pseudo branch
print('Passed: testif passes test for raising division error when not specified')
try:
testif('testif raises TypeError for invalid error type', lambda: None, None, raises='NotAnError')
except TypeError:
print('Passed: testif raises TypeError for invalid error type')
testif('testif passes test for raising division error when specified', lambda: 0 / 0, None, raises=ZeroDivisionError)
print('The next test should fail')
testif('testif passes test for not raising division error when specified', lambda: 0 / 1, None, raises=ZeroDivisionError)
testif('testif passes test for lambda expression without error', lambda: 1 / 1, 1)