forked from python-pillow/Pillow
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtester.py
234 lines (205 loc) · 6.32 KB
/
tester.py
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
from __future__ import print_function
import sys
py3 = (sys.version_info >= (3,0))
# some test helpers
_target = None
_tempfiles = []
_logfile = None
def success():
import sys
success.count += 1
if _logfile:
print(sys.argv[0], success.count, failure.count, file=_logfile)
def failure(msg=None, frame=None):
import sys, linecache
failure.count += 1
if _target:
if frame is None:
frame = sys._getframe()
while frame.f_globals.get("__name__") != _target.__name__:
frame = frame.f_back
location = (frame.f_code.co_filename, frame.f_lineno)
prefix = "%s:%d: " % location
line = linecache.getline(*location)
print(prefix + line.strip() + " failed:")
if msg:
print("- " + msg)
if _logfile:
print(sys.argv[0], success.count, failure.count, file=_logfile)
success.count = failure.count = 0
# predicates
def assert_true(v, msg=None):
if v:
success()
else:
failure(msg or "got %r, expected true value" % v)
def assert_false(v, msg=None):
if v:
failure(msg or "got %r, expected false value" % v)
else:
success()
def assert_equal(a, b, msg=None):
if a == b:
success()
else:
failure(msg or "got %r, expected %r" % (a, b))
def assert_match(v, pattern, msg=None):
import re
if re.match(pattern, v):
success()
else:
failure(msg or "got %r, doesn't match pattern %r" % (v, pattern))
def assert_exception(exc_class, func):
import sys, traceback
try:
func()
except exc_class:
success()
except:
failure("expected %r exception, got %r" % (
exc_class.__name__, sys.exc_info()[0].__name__))
traceback.print_exc()
else:
failure("expected %r exception, got no exception" % exc_class.__name__)
def assert_no_exception(func):
import sys, traceback
try:
func()
except:
failure("expected no exception, got %r" % sys.exc_info()[0].__name__)
traceback.print_exc()
else:
success()
def assert_warning(warn_class, func):
# note: this assert calls func three times!
import warnings
def warn_error(message, category, **options):
raise category(message)
def warn_ignore(message, category, **options):
pass
warn = warnings.warn
result = None
try:
warnings.warn = warn_ignore
assert_no_exception(func)
result = func()
warnings.warn = warn_error
assert_exception(warn_class, func)
finally:
warnings.warn = warn # restore
return result
# helpers
from io import BytesIO
def fromstring(data):
from PIL import Image
return Image.open(BytesIO(data))
def tostring(im, format, **options):
out = BytesIO()
im.save(out, format, **options)
return out.getvalue()
def lena(mode="RGB", cache={}):
from PIL import Image
im = cache.get(mode)
if im is None:
if mode == "RGB":
im = Image.open("Images/lena.ppm")
elif mode == "F":
im = lena("L").convert(mode)
elif mode[:4] == "I;16":
im = lena("I").convert(mode)
else:
im = lena("RGB").convert(mode)
cache[mode] = im
return im
def assert_image(im, mode, size, msg=None):
if mode is not None and im.mode != mode:
failure(msg or "got mode %r, expected %r" % (im.mode, mode))
elif size is not None and im.size != size:
failure(msg or "got size %r, expected %r" % (im.size, size))
else:
success()
def assert_image_equal(a, b, msg=None):
if a.mode != b.mode:
failure(msg or "got mode %r, expected %r" % (a.mode, b.mode))
elif a.size != b.size:
failure(msg or "got size %r, expected %r" % (a.size, b.size))
elif a.tobytes() != b.tobytes():
failure(msg or "got different content")
# generate better diff?
else:
success()
def tempfile(template, *extra):
import os, sys
files = []
for temp in (template,) + extra:
assert temp[:5] in ("temp.", "temp_")
root, name = os.path.split(sys.argv[0])
name = temp[:4] + os.path.splitext(name)[0][4:]
name = name + "_%d" % len(_tempfiles) + temp[4:]
name = os.path.join(root, name)
files.append(name)
_tempfiles.extend(files)
return files[0]
# test runner
def run():
global _target, _tests, run
import sys, traceback
_target = sys.modules["__main__"]
run = None # no need to run twice
tests = []
for name, value in list(vars(_target).items()):
if name[:5] == "test_" and type(value) is type(success):
tests.append((value.__code__.co_firstlineno, name, value))
tests.sort() # sort by line
for lineno, name, func in tests:
try:
_tests = []
func()
for func, args in _tests:
func(*args)
except:
t, v, tb = sys.exc_info()
tb = tb.tb_next
if tb:
failure(frame=tb.tb_frame)
traceback.print_exception(t, v, tb)
else:
print("%s:%d: cannot call test function: %s" % (
sys.argv[0], lineno, v))
failure.count += 1
def yield_test(function, *args):
# collect delayed/generated tests
_tests.append((function, args))
def skip(msg=None):
import os
print("skip")
os._exit(0) # don't run exit handlers
def _setup():
global _logfile
def report():
if run:
run()
if success.count and not failure.count:
print("ok")
# only clean out tempfiles if test passed
import os
for file in _tempfiles:
try:
os.remove(file)
except OSError:
pass # report?
if "--coverage" in sys.argv:
import coverage
coverage.stop()
# The coverage module messes up when used from inside an
# atexit handler. Do an explicit save to make sure that
# we actually flush the coverage cache.
coverage.the_coverage.save()
import atexit, sys
atexit.register(report)
if "--coverage" in sys.argv:
import coverage
coverage.start()
if "--log" in sys.argv:
_logfile = open("test.log", "a")
_setup()