Skip to content
This repository was archived by the owner on Oct 14, 2020. It is now read-only.

Commit 74b15bb

Browse files
committed
Copy python/cw-2.py to python3/cw-2.py
1 parent 70fc49a commit 74b15bb

File tree

1 file changed

+98
-14
lines changed

1 file changed

+98
-14
lines changed

frameworks/python3/cw-2.py

Lines changed: 98 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,48 @@ class AssertException(Exception):
44
pass
55

66

7+
_print = print
8+
9+
10+
'''Fix the dreaded Unicode Error Trap'''
11+
def print(*args, **kwargs):
12+
from sys import stdout
13+
sep = kwargs.get('sep', ' ')
14+
end = kwargs.get('end', '\n')
15+
file = kwargs.get('file', stdout)
16+
17+
def _replace(c):
18+
if ord(c) >= 128: return u'&#{};'.format(ord(c))
19+
return c
20+
def _escape(s): return ''.join(_replace(c) for c in s)
21+
22+
_print(*map(_escape, args), sep=_escape(sep), end=_escape(end), file=file)
23+
24+
725
def format_message(message):
8-
return message.replace("\n", "<:LF:>")
26+
def _replace(c):
27+
if ord(c) >= 65536: return r'\U' + hex(ord(c))[2:].zfill(8)
28+
if ord(c) >= 128: return r'\u' + hex(ord(c))[2:].zfill(4)
29+
return c
30+
def _escape(s): return ''.join(_replace(c) for c in s)
31+
return _escape(message.replace("\n", "<:LF:>"))
32+
33+
34+
def display(type, message, label="", mode=""):
35+
print("\n<{0}:{1}:{2}>{3}".format(type.upper(), mode.upper(), label, format_message(message)))
936

1037

1138
def expect(passed=None, message=None, allow_raise=False):
1239
if passed:
13-
print("<PASSED::>Test Passed")
40+
display('PASSED', 'Test Passed')
1441
else:
1542
message = message or "Value is not what was expected"
16-
print("<FAILED::>{0}".format(message))
43+
display('FAILED', message)
1744
if allow_raise:
1845
raise AssertException(message)
1946

2047

21-
def assert_equals(actual, expected, message=None, allow_raise=True):
48+
def assert_equals(actual, expected, message=None, allow_raise=False):
2249
equals_msg = "{0} should equal {1}".format(repr(actual), repr(expected))
2350
if message is None:
2451
message = equals_msg
@@ -28,15 +55,14 @@ def assert_equals(actual, expected, message=None, allow_raise=True):
2855
expect(actual == expected, message, allow_raise)
2956

3057

31-
def assert_not_equals(actual, expected, message=None, allow_raise=True):
32-
equals_msg = \
33-
"{0} should not equal {1}".format(repr(actual), repr(expected))
58+
def assert_not_equals(actual, expected, message=None, allow_raise=False):
59+
equals_msg = "{0} should not equal {1}".format(repr(actual), repr(expected))
3460
if message is None:
3561
message = equals_msg
3662
else:
3763
message += ": " + equals_msg
3864

39-
expect(actual != expected, message, allow_raise)
65+
expect(not (actual == expected), message, allow_raise)
4066

4167

4268
def expect_error(message, function):
@@ -48,9 +74,67 @@ def expect_error(message, function):
4874
expect(passed, message)
4975

5076

51-
def describe(message):
52-
print("<DESCRIBE::>{0}".format(format_message(message)))
53-
54-
55-
def it(message):
56-
print("<IT::>{0}".format(format_message(message)))
77+
def pass_(): expect(True)
78+
def fail(message): expect(False, message)
79+
80+
81+
def assert_approx_equals(actual, expected, margin=1e-9, message=None, allow_raise=False):
82+
equals_msg = "{0} should be close to {1} with absolute or relative margin of {2}".format(
83+
repr(actual), repr(expected), repr(margin))
84+
if message is None: message = equals_msg
85+
else: message += ": " + equals_msg
86+
div = max(abs(actual), abs(expected), 1)
87+
expect(abs((actual - expected) / div) < margin, message, allow_raise)
88+
89+
90+
'''
91+
Usage:
92+
@describe('describe text')
93+
def describe1():
94+
@it('it text')
95+
def it1():
96+
# some test cases...
97+
'''
98+
def _timed_block_factory(opening_text):
99+
from timeit import default_timer as timer
100+
from traceback import format_exception
101+
from sys import exc_info
102+
103+
def _timed_block_decorator(s, before=None, after=None):
104+
display(opening_text, s)
105+
def wrapper(func):
106+
if callable(before): before()
107+
time = timer()
108+
try: func()
109+
except:
110+
fail('Unexpected exception raised')
111+
tb_str = ''.join(format_exception(*exc_info()))
112+
display('ERROR', tb_str)
113+
display('COMPLETEDIN', '{:.2f}'.format((timer() - time) * 1000))
114+
if callable(after): after()
115+
return wrapper
116+
return _timed_block_decorator
117+
118+
describe = _timed_block_factory('DESCRIBE')
119+
it = _timed_block_factory('IT')
120+
121+
122+
'''
123+
Timeout utility
124+
Usage:
125+
@timeout(sec)
126+
def some_tests():
127+
any code block...
128+
Note: Timeout value can be a float.
129+
'''
130+
def timeout(sec):
131+
def wrapper(func):
132+
from multiprocessing import Process
133+
process = Process(target=func)
134+
process.start()
135+
process.join(sec)
136+
if process.is_alive():
137+
fail('Exceeded time limit of {:.3f} seconds'.format(sec))
138+
process.terminate()
139+
process.join()
140+
return wrapper

0 commit comments

Comments
 (0)