diff --git a/.travis.yml b/.travis.yml index 17a0b0363..1b864eecf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,12 +30,13 @@ script: # Don't cover PyPy: it fails intermittently and is x5.8 slower (#640) - if [ "$TRAVIS_PYTHON_VERSION" == "pypy" ]; then python selftest.py; fi - if [ "$TRAVIS_PYTHON_VERSION" == "pypy" ]; then python Tests/run.py; fi + - if [ "$TRAVIS_PYTHON_VERSION" == "pypy" ]; then nosetests test/; fi # Cover the others - if [ "$TRAVIS_PYTHON_VERSION" != "pypy" ]; then coverage run --append --include=PIL/* selftest.py; fi - if [ "$TRAVIS_PYTHON_VERSION" != "pypy" ]; then python Tests/run.py --coverage; fi + - if [ "$TRAVIS_PYTHON_VERSION" != "pypy" ]; then coverage run --append --include=PIL/* -m nose test/; fi - - nosetests test/ after_success: - coverage report diff --git a/Tests/test_image_frombytes.py b/Tests/test_image_frombytes.py deleted file mode 100644 index aa157aa6a..000000000 --- a/Tests/test_image_frombytes.py +++ /dev/null @@ -1,10 +0,0 @@ -from tester import * - -from PIL import Image - -def test_sanity(): - im1 = lena() - im2 = Image.frombytes(im1.mode, im1.size, im1.tobytes()) - - assert_image_equal(im1, im2) - diff --git a/Tests/test_image_getim.py b/Tests/test_image_getim.py deleted file mode 100644 index 8d2f12fc2..000000000 --- a/Tests/test_image_getim.py +++ /dev/null @@ -1,14 +0,0 @@ -from tester import * - -from PIL import Image - -def test_sanity(): - - im = lena() - type_repr = repr(type(im.getim())) - - if py3: - assert_true("PyCapsule" in type_repr) - - assert_true(isinstance(im.im.id, int)) - diff --git a/Tests/test_image_tobytes.py b/Tests/test_image_tobytes.py deleted file mode 100644 index d42399993..000000000 --- a/Tests/test_image_tobytes.py +++ /dev/null @@ -1,7 +0,0 @@ -from tester import * - -from PIL import Image - -def test_sanity(): - data = lena().tobytes() - assert_true(isinstance(data, bytes)) diff --git a/test/test_image_frombytes.py b/test/test_image_frombytes.py new file mode 100644 index 000000000..ee68b6722 --- /dev/null +++ b/test/test_image_frombytes.py @@ -0,0 +1,18 @@ +from tester import unittest, PillowTestCase, lena + +from PIL import Image + + +class TestImageFromBytes(PillowTestCase): + + def test_sanity(self): + im1 = lena() + im2 = Image.frombytes(im1.mode, im1.size, im1.tobytes()) + + self.assert_image_equal(im1, im2) + + +if __name__ == '__main__': + unittest.main() + +# End of file diff --git a/test/test_image_getim.py b/test/test_image_getim.py new file mode 100644 index 000000000..02744a529 --- /dev/null +++ b/test/test_image_getim.py @@ -0,0 +1,19 @@ +from tester import unittest, PillowTestCase, lena, py3 + + +class TestImageGetIm(PillowTestCase): + + def test_sanity(self): + im = lena() + type_repr = repr(type(im.getim())) + + if py3: + self.assertIn("PyCapsule", type_repr) + + self.assertIsInstance(im.im.id, int) + + +if __name__ == '__main__': + unittest.main() + +# End of file diff --git a/test/test_image_tobytes.py b/test/test_image_tobytes.py new file mode 100644 index 000000000..ee7b4c9e6 --- /dev/null +++ b/test/test_image_tobytes.py @@ -0,0 +1,13 @@ +from tester import unittest, lena + + +class TestImageToBytes(unittest.TestCase): + + def test_sanity(self): + data = lena().tobytes() + self.assertTrue(isinstance(data, bytes)) + +if __name__ == '__main__': + unittest.main() + +# End of file diff --git a/test/tester.py b/test/tester.py new file mode 100644 index 000000000..77b38a15a --- /dev/null +++ b/test/tester.py @@ -0,0 +1,393 @@ +""" +Helper functions. +""" +from __future__ import print_function +import sys + +if sys.version_info[:2] <= (2, 6): + import unittest2 as unittest +else: + import unittest + + +class PillowTestCase(unittest.TestCase): + + def assert_image_equal(self, a, b, msg=None): + self.assertEqual( + a.mode, b.mode, + msg or "got mode %r, expected %r" % (a.mode, b.mode)) + self.assertEqual( + a.size, b.size, + msg or "got size %r, expected %r" % (a.size, b.size)) + self.assertEqual( + a.tobytes(), b.tobytes(), + msg or "got different content") + + +# # require that deprecation warnings are triggered +# import warnings +# warnings.simplefilter('default') +# # temporarily turn off resource warnings that warn about unclosed +# # files in the test scripts. +# try: +# warnings.filterwarnings("ignore", category=ResourceWarning) +# except NameError: +# # we expect a NameError on py2.x, since it doesn't have ResourceWarnings. +# pass + +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) +# return True +# +# +# def failure(msg=None, frame=None): +# import sys +# import 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) +# return False +# +# success.count = failure.count = 0 +# +# +# # predicates +# +# def assert_almost_equal(a, b, msg=None, eps=1e-6): +# if abs(a-b) < eps: +# success() +# else: +# failure(msg or "got %r, expected %r" % (a, b)) +# +# +# def assert_deep_equal(a, b, msg=None): +# try: +# if len(a) == len(b): +# if all([x == y for x, y in zip(a, b)]): +# success() +# else: +# failure(msg or "got %s, expected %s" % (a, b)) +# else: +# failure(msg or "got length %s, expected %s" % (len(a), len(b))) +# except: +# assert_equal(a, b, msg) +# +# +# def assert_greater(a, b, msg=None): +# if a > b: +# success() +# else: +# failure(msg or "%r unexpectedly not greater than %r" % (a, b)) +# +# +# def assert_greater_equal(a, b, msg=None): +# if a >= b: +# success() +# else: +# failure( +# msg or "%r unexpectedly not greater than or equal to %r" +# % (a, b)) +# +# +# def assert_less(a, b, msg=None): +# if a < b: +# success() +# else: +# failure(msg or "%r unexpectedly not less than %r" % (a, b)) +# +# +# def assert_less_equal(a, b, msg=None): +# if a <= b: +# success() +# else: +# failure( +# msg or "%r unexpectedly not less than or equal to %r" % (a, b)) +# +# +# def assert_is_instance(a, b, msg=None): +# if isinstance(a, b): +# success() +# else: +# failure(msg or "got %r, expected %r" % (type(a), b)) +# +# +# def assert_in(a, b, msg=None): +# if a in b: +# success() +# else: +# failure(msg or "%r unexpectedly not in %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 +# import 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 +# import 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=UserWarning, **options): +# raise category(message) +# +# def warn_ignore(message, category=UserWarning, **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") +# else: +# success() +# +# +# def assert_image_completely_equal(a, b, msg=None): +# if a != b: +# failure(msg or "images different") +# else: +# success() +# +# +# def assert_image_similar(a, b, epsilon, msg=None): +# epsilon = float(epsilon) +# if a.mode != b.mode: +# return failure(msg or "got mode %r, expected %r" % (a.mode, b.mode)) +# elif a.size != b.size: +# return failure(msg or "got size %r, expected %r" % (a.size, b.size)) +# diff = 0 +# try: +# ord(b'0') +# for abyte, bbyte in zip(a.tobytes(), b.tobytes()): +# diff += abs(ord(abyte)-ord(bbyte)) +# except: +# for abyte, bbyte in zip(a.tobytes(), b.tobytes()): +# diff += abs(abyte-bbyte) +# ave_diff = float(diff)/(a.size[0]*a.size[1]) +# if epsilon < ave_diff: +# return failure( +# msg or "average pixel value difference %.4f > epsilon %.4f" % ( +# ave_diff, epsilon)) +# else: +# return success() +# +# +# def tempfile(template, *extra): +# import os +# import os.path +# import sys +# import tempfile +# files = [] +# root = os.path.join(tempfile.gettempdir(), 'pillow-tests') +# try: +# os.mkdir(root) +# except OSError: +# pass +# for temp in (template,) + extra: +# assert temp[:5] in ("temp.", "temp_") +# name = os.path.basename(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 +# import 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 ignore(pattern): +# """Tells the driver to ignore messages matching the pattern, for the +# duration of the current test.""" +# print('ignore: %s' % pattern) +# +# +# def _setup(): +# global _logfile +# +# import sys +# if "--coverage" in sys.argv: +# # Temporary: ignore PendingDeprecationWarning from Coverage (Py3.4) +# with warnings.catch_warnings(): +# warnings.simplefilter("ignore") +# import coverage +# cov = coverage.coverage(auto_data=True, include="PIL/*") +# cov.start() +# +# def report(): +# if run: +# run() +# if success.count and not failure.count: +# print("ok") +# # only clean out tempfiles if test passed +# import os +# import os.path +# import tempfile +# for file in _tempfiles: +# try: +# os.remove(file) +# except OSError: +# pass # report? +# temp_root = os.path.join(tempfile.gettempdir(), 'pillow-tests') +# try: +# os.rmdir(temp_root) +# except OSError: +# pass +# +# import atexit +# atexit.register(report) +# +# if "--log" in sys.argv: +# _logfile = open("test.log", "a") +# +# +# _setup() diff --git a/test/tests.py b/test/tests.py index eb4a8342d..1bd308922 100644 --- a/test/tests.py +++ b/test/tests.py @@ -1,7 +1,7 @@ -import unittest +from tester import unittest -class PillowTests(unittest.TestCase): +class SomeTests(unittest.TestCase): """ Can we start moving the test suite here? """ @@ -10,8 +10,10 @@ class PillowTests(unittest.TestCase): """ Great idea! """ - assert True is True + self.assertTrue(True) if __name__ == '__main__': unittest.main() + +# End of file