Removed use of PillowTestCase

This commit is contained in:
Andrew Murray 2020-03-23 06:54:54 +11:00
parent 7859f81828
commit 7ff2db143d
13 changed files with 1243 additions and 1188 deletions

View File

@ -7,14 +7,13 @@ import time
import pytest
from PIL import Image, PdfParser
from .helper import PillowTestCase, hopper
from .helper import hopper
class TestFilePdf(PillowTestCase):
def helper_save_as_pdf(self, mode, **kwargs):
def helper_save_as_pdf(tmp_path, mode, **kwargs):
# Arrange
im = hopper(mode)
outfile = self.tempfile("temp_" + mode + ".pdf")
outfile = str(tmp_path / ("temp_" + mode + ".pdf"))
# Act
im.save(outfile, **kwargs)
@ -30,63 +29,69 @@ class TestFilePdf(PillowTestCase):
with open(outfile, "rb") as fp:
contents = fp.read()
size = tuple(
int(d)
for d in contents.split(b"/MediaBox [ 0 0 ")[1].split(b"]")[0].split()
int(d) for d in contents.split(b"/MediaBox [ 0 0 ")[1].split(b"]")[0].split()
)
assert im.size == size
return outfile
def test_monochrome(self):
def test_monochrome(tmp_path):
# Arrange
mode = "1"
# Act / Assert
self.helper_save_as_pdf(mode)
helper_save_as_pdf(tmp_path, mode)
def test_greyscale(self):
def test_greyscale(tmp_path):
# Arrange
mode = "L"
# Act / Assert
self.helper_save_as_pdf(mode)
helper_save_as_pdf(tmp_path, mode)
def test_rgb(self):
def test_rgb(tmp_path):
# Arrange
mode = "RGB"
# Act / Assert
self.helper_save_as_pdf(mode)
helper_save_as_pdf(tmp_path, mode)
def test_p_mode(self):
def test_p_mode(tmp_path):
# Arrange
mode = "P"
# Act / Assert
self.helper_save_as_pdf(mode)
helper_save_as_pdf(tmp_path, mode)
def test_cmyk_mode(self):
def test_cmyk_mode(tmp_path):
# Arrange
mode = "CMYK"
# Act / Assert
self.helper_save_as_pdf(mode)
helper_save_as_pdf(tmp_path, mode)
def test_unsupported_mode(self):
def test_unsupported_mode(tmp_path):
im = hopper("LA")
outfile = self.tempfile("temp_LA.pdf")
outfile = str(tmp_path / "temp_LA.pdf")
with pytest.raises(ValueError):
im.save(outfile)
def test_save_all(self):
def test_save_all(tmp_path):
# Single frame image
self.helper_save_as_pdf("RGB", save_all=True)
helper_save_as_pdf(tmp_path, "RGB", save_all=True)
# Multiframe image
with Image.open("Tests/images/dispose_bgnd.gif") as im:
outfile = self.tempfile("temp.pdf")
outfile = str(tmp_path / "temp.pdf")
im.save(outfile, save_all=True)
assert os.path.isfile(outfile)
@ -115,17 +120,19 @@ class TestFilePdf(PillowTestCase):
assert os.path.isfile(outfile)
assert os.path.getsize(outfile) > 0
def test_multiframe_normal_save(self):
def test_multiframe_normal_save(tmp_path):
# Test saving a multiframe image without save_all
with Image.open("Tests/images/dispose_bgnd.gif") as im:
outfile = self.tempfile("temp.pdf")
outfile = str(tmp_path / "temp.pdf")
im.save(outfile)
assert os.path.isfile(outfile)
assert os.path.getsize(outfile) > 0
def test_pdf_open(self):
def test_pdf_open(tmp_path):
# fail on a buffer full of null bytes
with pytest.raises(PdfParser.PdfFormatError):
PdfParser.PdfParser(buf=bytearray(65536))
@ -138,7 +145,7 @@ class TestFilePdf(PillowTestCase):
assert not empty_pdf.should_close_file
# make a PDF file
pdf_filename = self.helper_save_as_pdf("RGB")
pdf_filename = helper_save_as_pdf(tmp_path, "RGB")
# open the PDF file
with PdfParser.PdfParser(filename=pdf_filename) as hopper_pdf:
@ -161,13 +168,15 @@ class TestFilePdf(PillowTestCase):
assert hopper_pdf.should_close_buf
assert not hopper_pdf.should_close_file
def test_pdf_append_fails_on_nonexistent_file(self):
def test_pdf_append_fails_on_nonexistent_file():
im = hopper("RGB")
with tempfile.TemporaryDirectory() as temp_dir:
with pytest.raises(IOError):
im.save(os.path.join(temp_dir, "nonexistent.pdf"), append=True)
def check_pdf_pages_consistency(self, pdf):
def check_pdf_pages_consistency(pdf):
pages_info = pdf.read_indirect(pdf.pages_ref)
assert b"Parent" not in pages_info
assert b"Kids" in pages_info
@ -184,9 +193,10 @@ class TestFilePdf(PillowTestCase):
assert pdf.pages_ref == page_info[b"Parent"]
assert kids_not_used == []
def test_pdf_append(self):
def test_pdf_append(tmp_path):
# make a PDF file
pdf_filename = self.helper_save_as_pdf("RGB", producer="PdfParser")
pdf_filename = helper_save_as_pdf(tmp_path, "RGB", producer="PdfParser")
# open it, check pages and info
with PdfParser.PdfParser(pdf_filename, mode="r+b") as pdf:
@ -196,7 +206,7 @@ class TestFilePdf(PillowTestCase):
assert pdf.info.Producer == "PdfParser"
assert b"CreationDate" in pdf.info
assert b"ModDate" in pdf.info
self.check_pdf_pages_consistency(pdf)
check_pdf_pages_consistency(pdf)
# append some info
pdf.info.Title = "abc"
@ -214,7 +224,7 @@ class TestFilePdf(PillowTestCase):
assert pdf.info.Title == "abc"
assert b"CreationDate" in pdf.info
assert b"ModDate" in pdf.info
self.check_pdf_pages_consistency(pdf)
check_pdf_pages_consistency(pdf)
# append two images
mode_CMYK = hopper("CMYK")
@ -232,11 +242,13 @@ class TestFilePdf(PillowTestCase):
assert pdf.info.Subject == "ghi\uABCD"
assert b"CreationDate" in pdf.info
assert b"ModDate" in pdf.info
self.check_pdf_pages_consistency(pdf)
check_pdf_pages_consistency(pdf)
def test_pdf_info(self):
def test_pdf_info(tmp_path):
# make a PDF file
pdf_filename = self.helper_save_as_pdf(
pdf_filename = helper_save_as_pdf(
tmp_path,
"RGB",
title="title",
author="author",
@ -259,9 +271,10 @@ class TestFilePdf(PillowTestCase):
assert pdf.info.Producer == "producer"
assert pdf.info.CreationDate == time.strptime("2000", "%Y")
assert pdf.info.ModDate == time.strptime("2001", "%Y")
self.check_pdf_pages_consistency(pdf)
check_pdf_pages_consistency(pdf)
def test_pdf_append_to_bytesio(self):
def test_pdf_append_to_bytesio():
im = hopper("RGB")
f = io.BytesIO()
im.save(f, format="PDF")

View File

@ -5,21 +5,36 @@ from itertools import product
import pytest
from PIL import Image
from .helper import PillowTestCase, assert_image_equal, hopper
from .helper import assert_image_equal, hopper
_TGA_DIR = os.path.join("Tests", "images", "tga")
_TGA_DIR_COMMON = os.path.join(_TGA_DIR, "common")
class TestFileTga(PillowTestCase):
_MODES = ("L", "LA", "P", "RGB", "RGBA")
_ORIGINS = ("tl", "bl")
_ORIGIN_TO_ORIENTATION = {"tl": 1, "bl": -1}
def test_sanity(self):
for mode in self._MODES:
def test_sanity(tmp_path):
for mode in _MODES:
def roundtrip(original_im):
out = str(tmp_path / "temp.tga")
original_im.save(out, rle=rle)
with Image.open(out) as saved_im:
if rle:
assert (
saved_im.info["compression"] == original_im.info["compression"]
)
assert saved_im.info["orientation"] == original_im.info["orientation"]
if mode == "P":
assert saved_im.getpalette() == original_im.getpalette()
assert_image_equal(saved_im, original_im)
png_paths = glob(
os.path.join(_TGA_DIR_COMMON, "*x*_{}.png".format(mode.lower()))
)
@ -29,7 +44,7 @@ class TestFileTga(PillowTestCase):
assert reference_im.mode == mode
path_no_ext = os.path.splitext(png_path)[0]
for origin, rle in product(self._ORIGINS, (True, False)):
for origin, rle in product(_ORIGINS, (True, False)):
tga_path = "{}_{}_{}.tga".format(
path_no_ext, origin, "rle" if rle else "raw"
)
@ -41,41 +56,17 @@ class TestFileTga(PillowTestCase):
assert original_im.info["compression"] == "tga_rle"
assert (
original_im.info["orientation"]
== self._ORIGIN_TO_ORIENTATION[origin]
== _ORIGIN_TO_ORIENTATION[origin]
)
if mode == "P":
assert (
original_im.getpalette()
== reference_im.getpalette()
)
assert original_im.getpalette() == reference_im.getpalette()
assert_image_equal(original_im, reference_im)
# Generate a new test name every time so the
# test will not fail with permission error
# on Windows.
out = self.tempfile("temp.tga")
roundtrip(original_im)
original_im.save(out, rle=rle)
with Image.open(out) as saved_im:
if rle:
assert (
saved_im.info["compression"]
== original_im.info["compression"]
)
assert (
saved_im.info["orientation"]
== original_im.info["orientation"]
)
if mode == "P":
assert (
saved_im.getpalette()
== original_im.getpalette()
)
assert_image_equal(saved_im, original_im)
def test_id_field(self):
def test_id_field():
# tga file with id field
test_file = "Tests/images/tga_id_field.tga"
@ -85,7 +76,8 @@ class TestFileTga(PillowTestCase):
# Assert
assert im.size == (100, 100)
def test_id_field_rle(self):
def test_id_field_rle():
# tga file with id field
test_file = "Tests/images/rgb32rle.tga"
@ -95,10 +87,11 @@ class TestFileTga(PillowTestCase):
# Assert
assert im.size == (199, 199)
def test_save(self):
def test_save(tmp_path):
test_file = "Tests/images/tga_id_field.tga"
with Image.open(test_file) as im:
out = self.tempfile("temp.tga")
out = str(tmp_path / "temp.tga")
# Save
im.save(out)
@ -111,17 +104,19 @@ class TestFileTga(PillowTestCase):
with Image.open(out) as test_im:
assert test_im.size == (100, 100)
def test_save_wrong_mode(self):
def test_save_wrong_mode(tmp_path):
im = hopper("PA")
out = self.tempfile("temp.tga")
out = str(tmp_path / "temp.tga")
with pytest.raises(OSError):
im.save(out)
def test_save_id_section(self):
def test_save_id_section(tmp_path):
test_file = "Tests/images/rgb32rle.tga"
with Image.open(test_file) as im:
out = self.tempfile("temp.tga")
out = str(tmp_path / "temp.tga")
# Check there is no id section
im.save(out)
@ -147,9 +142,10 @@ class TestFileTga(PillowTestCase):
with Image.open(out) as test_im:
assert "id_section" not in test_im.info
def test_save_orientation(self):
def test_save_orientation(tmp_path):
test_file = "Tests/images/rgb32rle.tga"
out = self.tempfile("temp.tga")
out = str(tmp_path / "temp.tga")
with Image.open(test_file) as im:
assert im.info["orientation"] == -1
@ -157,12 +153,13 @@ class TestFileTga(PillowTestCase):
with Image.open(out) as test_im:
assert test_im.info["orientation"] == 1
def test_save_rle(self):
def test_save_rle(tmp_path):
test_file = "Tests/images/rgb32rle.tga"
with Image.open(test_file) as im:
assert im.info["compression"] == "tga_rle"
out = self.tempfile("temp.tga")
out = str(tmp_path / "temp.tga")
# Save
im.save(out)
@ -189,7 +186,8 @@ class TestFileTga(PillowTestCase):
with Image.open(out) as test_im:
assert test_im.info["compression"] == "tga_rle"
def test_save_l_transparency(self):
def test_save_l_transparency(tmp_path):
# There are 559 transparent pixels in la.tga.
num_transparent = 559
@ -198,7 +196,7 @@ class TestFileTga(PillowTestCase):
assert im.mode == "LA"
assert im.getchannel("A").getcolors()[0][0] == num_transparent
out = self.tempfile("temp.tga")
out = str(tmp_path / "temp.tga")
im.save(out)
with Image.open(out) as test_im:

View File

@ -2,7 +2,6 @@ import pytest
from PIL import Image, WebPImagePlugin
from .helper import (
PillowTestCase,
assert_image_similar,
assert_image_similar_tofile,
hopper,
@ -17,23 +16,21 @@ except ImportError:
HAVE_WEBP = False
class TestUnsupportedWebp(PillowTestCase):
class TestUnsupportedWebp:
def test_unsupported(self):
if HAVE_WEBP:
WebPImagePlugin.SUPPORTED = False
file_path = "Tests/images/hopper.webp"
pytest.warns(
UserWarning, lambda: self.assertRaises(IOError, Image.open, file_path)
)
pytest.warns(UserWarning, lambda: pytest.raises(IOError, Image.open, file_path))
if HAVE_WEBP:
WebPImagePlugin.SUPPORTED = True
@skip_unless_feature("webp")
class TestFileWebp(PillowTestCase):
def setUp(self):
class TestFileWebp:
def setup_method(self):
self.rgb_mode = "RGB"
def test_version(self):
@ -57,13 +54,13 @@ class TestFileWebp(PillowTestCase):
# dwebp -ppm ../../Tests/images/hopper.webp -o hopper_webp_bits.ppm
assert_image_similar_tofile(image, "Tests/images/hopper_webp_bits.ppm", 1.0)
def test_write_rgb(self):
def test_write_rgb(self, tmp_path):
"""
Can we write a RGB mode file to webp without error.
Does it have the bits we expect?
"""
temp_file = self.tempfile("temp.webp")
temp_file = str(tmp_path / "temp.webp")
hopper(self.rgb_mode).save(temp_file)
with Image.open(temp_file) as image:
@ -86,13 +83,13 @@ class TestFileWebp(PillowTestCase):
target = hopper(self.rgb_mode)
assert_image_similar(image, target, 12.0)
def test_write_unsupported_mode_L(self):
def test_write_unsupported_mode_L(self, tmp_path):
"""
Saving a black-and-white file to WebP format should work, and be
similar to the original file.
"""
temp_file = self.tempfile("temp.webp")
temp_file = str(tmp_path / "temp.webp")
hopper("L").save(temp_file)
with Image.open(temp_file) as image:
assert image.mode == self.rgb_mode
@ -105,13 +102,13 @@ class TestFileWebp(PillowTestCase):
assert_image_similar(image, target, 10.0)
def test_write_unsupported_mode_P(self):
def test_write_unsupported_mode_P(self, tmp_path):
"""
Saving a palette-based file to WebP format should work, and be
similar to the original file.
"""
temp_file = self.tempfile("temp.webp")
temp_file = str(tmp_path / "temp.webp")
hopper("P").save(temp_file)
with Image.open(temp_file) as image:
assert image.mode == self.rgb_mode
@ -146,10 +143,10 @@ class TestFileWebp(PillowTestCase):
with pytest.raises(TypeError):
_webp.WebPDecode()
def test_no_resource_warning(self):
def test_no_resource_warning(self, tmp_path):
file_path = "Tests/images/hopper.webp"
with Image.open(file_path) as image:
temp_file = self.tempfile("temp.webp")
temp_file = str(tmp_path / "temp.webp")
pytest.warns(None, image.save, temp_file)
def test_file_pointer_could_be_reused(self):
@ -160,16 +157,16 @@ class TestFileWebp(PillowTestCase):
@skip_unless_feature("webp")
@skip_unless_feature("webp_anim")
def test_background_from_gif(self):
def test_background_from_gif(self, tmp_path):
with Image.open("Tests/images/chi.gif") as im:
original_value = im.convert("RGB").getpixel((1, 1))
# Save as WEBP
out_webp = self.tempfile("temp.webp")
out_webp = str(tmp_path / "temp.webp")
im.save(out_webp, save_all=True)
# Save as GIF
out_gif = self.tempfile("temp.gif")
out_gif = str(tmp_path / "temp.gif")
Image.open(out_webp).save(out_gif)
with Image.open(out_gif) as reread:

View File

@ -1,10 +1,8 @@
import pytest
from PIL import Image, ImageMath, ImageMode
from .helper import PillowTestCase, convert_to_comparable
from .helper import convert_to_comparable
class TestImageReduce(PillowTestCase):
# There are several internal implementations
remarkable_factors = [
# special implementations
@ -32,12 +30,11 @@ class TestImageReduce(PillowTestCase):
(19, 17),
]
@classmethod
def setUpClass(cls):
cls.gradients_image = Image.open("Tests/images/radial_gradients.png")
cls.gradients_image.load()
gradients_image = Image.open("Tests/images/radial_gradients.png")
gradients_image.load()
def test_args_factor(self):
def test_args_factor():
im = Image.new("L", (10, 10))
assert (4, 4) == im.reduce(3).size
@ -51,7 +48,8 @@ class TestImageReduce(PillowTestCase):
with pytest.raises(ValueError):
im.reduce((0, 10))
def test_args_box(self):
def test_args_box():
im = Image.new("L", (10, 10))
assert (5, 5) == im.reduce(2, (0, 0, 10, 10)).size
@ -74,7 +72,8 @@ class TestImageReduce(PillowTestCase):
with pytest.raises(ValueError):
im.reduce(2, (5, 0, 5, 10))
def test_unsupported_modes(self):
def test_unsupported_modes():
im = Image.new("P", (10, 10))
with pytest.raises(ValueError):
im.reduce(3)
@ -87,10 +86,11 @@ class TestImageReduce(PillowTestCase):
with pytest.raises(ValueError):
im.reduce(3)
def get_image(self, mode):
def get_image(mode):
mode_info = ImageMode.getmode(mode)
if mode_info.basetype == "L":
bands = [self.gradients_image]
bands = [gradients_image]
for _ in mode_info.bands[1:]:
# rotate previous image
band = bands[-1].transpose(Image.ROTATE_90)
@ -102,17 +102,19 @@ class TestImageReduce(PillowTestCase):
im = Image.merge(mode, bands)
else:
assert len(mode_info.bands) == 1
im = self.gradients_image.convert(mode)
im = gradients_image.convert(mode)
# change the height to make a not-square image
return im.crop((0, 0, im.width, im.height - 5))
def compare_reduce_with_box(self, im, factor):
def compare_reduce_with_box(im, factor):
box = (11, 13, 146, 164)
reduced = im.reduce(factor, box=box)
reference = im.crop(box).reduce(factor)
assert reduced == reference
def compare_reduce_with_reference(self, im, factor, average_diff=0.4, max_diff=1):
def compare_reduce_with_reference(im, factor, average_diff=0.4, max_diff=1):
"""Image.reduce() should look very similar to Image.resize(BOX).
A reference image is compiled from a large source area
@ -152,9 +154,10 @@ class TestImageReduce(PillowTestCase):
last_pixel = im.resize((1, 1), Image.BOX, last_pixel_box)
reference.paste(last_pixel, area_size)
self.assert_compare_images(reduced, reference, average_diff, max_diff)
assert_compare_images(reduced, reference, average_diff, max_diff)
def assert_compare_images(self, a, b, max_average_diff, max_diff=255):
def assert_compare_images(a, b, max_average_diff, max_diff=255):
assert a.mode == b.mode, "got mode %r, expected %r" % (a.mode, b.mode)
assert a.size == b.size, "got size %r, expected %r" % (a.size, b.size)
@ -179,60 +182,68 @@ class TestImageReduce(PillowTestCase):
last_diff, max_diff, band
)
def test_mode_L(self):
im = self.get_image("L")
for factor in self.remarkable_factors:
self.compare_reduce_with_reference(im, factor)
self.compare_reduce_with_box(im, factor)
def test_mode_LA(self):
im = self.get_image("LA")
for factor in self.remarkable_factors:
self.compare_reduce_with_reference(im, factor, 0.8, 5)
def test_mode_L():
im = get_image("L")
for factor in remarkable_factors:
compare_reduce_with_reference(im, factor)
compare_reduce_with_box(im, factor)
def test_mode_LA():
im = get_image("LA")
for factor in remarkable_factors:
compare_reduce_with_reference(im, factor, 0.8, 5)
# With opaque alpha, an error should be way smaller.
im.putalpha(Image.new("L", im.size, 255))
for factor in self.remarkable_factors:
self.compare_reduce_with_reference(im, factor)
self.compare_reduce_with_box(im, factor)
for factor in remarkable_factors:
compare_reduce_with_reference(im, factor)
compare_reduce_with_box(im, factor)
def test_mode_La(self):
im = self.get_image("La")
for factor in self.remarkable_factors:
self.compare_reduce_with_reference(im, factor)
self.compare_reduce_with_box(im, factor)
def test_mode_RGB(self):
im = self.get_image("RGB")
for factor in self.remarkable_factors:
self.compare_reduce_with_reference(im, factor)
self.compare_reduce_with_box(im, factor)
def test_mode_La():
im = get_image("La")
for factor in remarkable_factors:
compare_reduce_with_reference(im, factor)
compare_reduce_with_box(im, factor)
def test_mode_RGBA(self):
im = self.get_image("RGBA")
for factor in self.remarkable_factors:
self.compare_reduce_with_reference(im, factor, 0.8, 5)
def test_mode_RGB():
im = get_image("RGB")
for factor in remarkable_factors:
compare_reduce_with_reference(im, factor)
compare_reduce_with_box(im, factor)
def test_mode_RGBA():
im = get_image("RGBA")
for factor in remarkable_factors:
compare_reduce_with_reference(im, factor, 0.8, 5)
# With opaque alpha, an error should be way smaller.
im.putalpha(Image.new("L", im.size, 255))
for factor in self.remarkable_factors:
self.compare_reduce_with_reference(im, factor)
self.compare_reduce_with_box(im, factor)
for factor in remarkable_factors:
compare_reduce_with_reference(im, factor)
compare_reduce_with_box(im, factor)
def test_mode_RGBa(self):
im = self.get_image("RGBa")
for factor in self.remarkable_factors:
self.compare_reduce_with_reference(im, factor)
self.compare_reduce_with_box(im, factor)
def test_mode_I(self):
im = self.get_image("I")
for factor in self.remarkable_factors:
self.compare_reduce_with_reference(im, factor)
self.compare_reduce_with_box(im, factor)
def test_mode_RGBa():
im = get_image("RGBa")
for factor in remarkable_factors:
compare_reduce_with_reference(im, factor)
compare_reduce_with_box(im, factor)
def test_mode_F(self):
im = self.get_image("F")
for factor in self.remarkable_factors:
self.compare_reduce_with_reference(im, factor, 0, 0)
self.compare_reduce_with_box(im, factor)
def test_mode_I():
im = get_image("I")
for factor in remarkable_factors:
compare_reduce_with_reference(im, factor)
compare_reduce_with_box(im, factor)
def test_mode_F():
im = get_image("F")
for factor in remarkable_factors:
compare_reduce_with_reference(im, factor, 0, 0)
compare_reduce_with_box(im, factor)

View File

@ -3,10 +3,10 @@ import math
import pytest
from PIL import Image, ImageTransform
from .helper import PillowTestCase, assert_image_equal, assert_image_similar, hopper
from .helper import assert_image_equal, assert_image_similar, hopper
class TestImageTransform(PillowTestCase):
class TestImageTransform:
def test_sanity(self):
im = Image.new("L", (100, 100))
@ -177,7 +177,7 @@ class TestImageTransform(PillowTestCase):
im.transform((100, 100), Image.EXTENT, (0, 0, w, h), resample)
class TestImageTransformAffine(PillowTestCase):
class TestImageTransformAffine:
transform = Image.AFFINE
def _test_image(self):

View File

@ -4,7 +4,6 @@ import pytest
from PIL import EpsImagePlugin, Image, ImageFile, features
from .helper import (
PillowTestCase,
assert_image,
assert_image_equal,
assert_image_similar,
@ -19,7 +18,7 @@ MAXBLOCK = ImageFile.MAXBLOCK
SAFEBLOCK = ImageFile.SAFEBLOCK
class TestImageFile(PillowTestCase):
class TestImageFile:
def test_parser(self):
def roundtrip(format):
@ -163,7 +162,7 @@ class MockImageFile(ImageFile.ImageFile):
self.tile = [("MOCK", (xoff, yoff, xoff + xsize, yoff + ysize), 32, None)]
class TestPyDecoder(PillowTestCase):
class TestPyDecoder:
def get_decoder(self):
decoder = MockPyDecoder(None)
@ -239,7 +238,7 @@ class TestPyDecoder(PillowTestCase):
assert im.format is None
assert im.get_format_mimetype() is None
def test_exif_jpeg(self):
def test_exif_jpeg(self, tmp_path):
with Image.open("Tests/images/exif-72dpi-int.jpg") as im: # Little endian
exif = im.getexif()
assert 258 not in exif
@ -247,7 +246,7 @@ class TestPyDecoder(PillowTestCase):
assert exif[40963] == 450
assert exif[11] == "gThumb 3.0.1"
out = self.tempfile("temp.jpg")
out = str(tmp_path / "temp.jpg")
exif[258] = 8
del exif[40960]
exif[40963] = 455
@ -267,7 +266,7 @@ class TestPyDecoder(PillowTestCase):
assert exif[40963] == 200
assert exif[305] == "Adobe Photoshop CC 2017 (Macintosh)"
out = self.tempfile("temp.jpg")
out = str(tmp_path / "temp.jpg")
exif[258] = 8
del exif[34665]
exif[40963] = 455
@ -282,12 +281,12 @@ class TestPyDecoder(PillowTestCase):
@skip_unless_feature("webp")
@skip_unless_feature("webp_anim")
def test_exif_webp(self):
def test_exif_webp(self, tmp_path):
with Image.open("Tests/images/hopper.webp") as im:
exif = im.getexif()
assert exif == {}
out = self.tempfile("temp.webp")
out = str(tmp_path / "temp.webp")
exif[258] = 8
exif[40963] = 455
exif[305] = "Pillow test"
@ -304,12 +303,12 @@ class TestPyDecoder(PillowTestCase):
im.save(out, exif=exif, save_all=True)
check_exif()
def test_exif_png(self):
def test_exif_png(self, tmp_path):
with Image.open("Tests/images/exif.png") as im:
exif = im.getexif()
assert exif == {274: 1}
out = self.tempfile("temp.png")
out = str(tmp_path / "temp.png")
exif[258] = 8
del exif[274]
exif[40963] = 455

View File

@ -1,21 +1,23 @@
import pytest
from PIL import Image, ImageDraw, ImageFont
from .helper import PillowTestCase, assert_image_similar, skip_unless_feature
from .helper import assert_image_similar, skip_unless_feature
FONT_SIZE = 20
FONT_PATH = "Tests/fonts/DejaVuSans.ttf"
pytestmark = skip_unless_feature("raqm")
@skip_unless_feature("raqm")
class TestImagecomplextext(PillowTestCase):
def test_english(self):
def test_english():
# smoke test, this should not fail
ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE)
im = Image.new(mode="RGB", size=(300, 100))
draw = ImageDraw.Draw(im)
draw.text((0, 0), "TEST", font=ttf, fill=500, direction="ltr")
def test_complex_text(self):
def test_complex_text():
ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE)
im = Image.new(mode="RGB", size=(300, 100))
@ -26,7 +28,8 @@ class TestImagecomplextext(PillowTestCase):
with Image.open(target) as target_img:
assert_image_similar(im, target_img, 0.5)
def test_y_offset(self):
def test_y_offset():
ttf = ImageFont.truetype("Tests/fonts/NotoNastaliqUrdu-Regular.ttf", FONT_SIZE)
im = Image.new(mode="RGB", size=(300, 100))
@ -37,7 +40,8 @@ class TestImagecomplextext(PillowTestCase):
with Image.open(target) as target_img:
assert_image_similar(im, target_img, 1.7)
def test_complex_unicode_text(self):
def test_complex_unicode_text():
ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE)
im = Image.new(mode="RGB", size=(300, 100))
@ -58,7 +62,8 @@ class TestImagecomplextext(PillowTestCase):
with Image.open(target) as target_img:
assert_image_similar(im, target_img, 2.3)
def test_text_direction_rtl(self):
def test_text_direction_rtl():
ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE)
im = Image.new(mode="RGB", size=(300, 100))
@ -69,7 +74,8 @@ class TestImagecomplextext(PillowTestCase):
with Image.open(target) as target_img:
assert_image_similar(im, target_img, 0.5)
def test_text_direction_ltr(self):
def test_text_direction_ltr():
ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE)
im = Image.new(mode="RGB", size=(300, 100))
@ -80,7 +86,8 @@ class TestImagecomplextext(PillowTestCase):
with Image.open(target) as target_img:
assert_image_similar(im, target_img, 0.5)
def test_text_direction_rtl2(self):
def test_text_direction_rtl2():
ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE)
im = Image.new(mode="RGB", size=(300, 100))
@ -91,7 +98,8 @@ class TestImagecomplextext(PillowTestCase):
with Image.open(target) as target_img:
assert_image_similar(im, target_img, 0.5)
def test_text_direction_ttb(self):
def test_text_direction_ttb():
ttf = ImageFont.truetype("Tests/fonts/NotoSansJP-Regular.otf", FONT_SIZE)
im = Image.new(mode="RGB", size=(100, 300))
@ -100,13 +108,14 @@ class TestImagecomplextext(PillowTestCase):
draw.text((0, 0), "English あい", font=ttf, fill=500, direction="ttb")
except ValueError as ex:
if str(ex) == "libraqm 0.7 or greater required for 'ttb' direction":
self.skipTest("libraqm 0.7 or greater not available")
pytest.skip("libraqm 0.7 or greater not available")
target = "Tests/images/test_direction_ttb.png"
with Image.open(target) as target_img:
assert_image_similar(im, target_img, 1.15)
def test_text_direction_ttb_stroke(self):
def test_text_direction_ttb_stroke():
ttf = ImageFont.truetype("Tests/fonts/NotoSansJP-Regular.otf", 50)
im = Image.new(mode="RGB", size=(100, 300))
@ -123,13 +132,14 @@ class TestImagecomplextext(PillowTestCase):
)
except ValueError as ex:
if str(ex) == "libraqm 0.7 or greater required for 'ttb' direction":
self.skipTest("libraqm 0.7 or greater not available")
pytest.skip("libraqm 0.7 or greater not available")
target = "Tests/images/test_direction_ttb_stroke.png"
with Image.open(target) as target_img:
assert_image_similar(im, target_img, 12.4)
def test_ligature_features(self):
def test_ligature_features():
ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE)
im = Image.new(mode="RGB", size=(300, 100))
@ -142,7 +152,8 @@ class TestImagecomplextext(PillowTestCase):
liga_size = ttf.getsize("fi", features=["-liga"])
assert liga_size == (13, 19)
def test_kerning_features(self):
def test_kerning_features():
ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE)
im = Image.new(mode="RGB", size=(300, 100))
@ -153,7 +164,8 @@ class TestImagecomplextext(PillowTestCase):
with Image.open(target) as target_img:
assert_image_similar(im, target_img, 0.5)
def test_arabictext_features(self):
def test_arabictext_features():
ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE)
im = Image.new(mode="RGB", size=(300, 100))
@ -170,7 +182,8 @@ class TestImagecomplextext(PillowTestCase):
with Image.open(target) as target_img:
assert_image_similar(im, target_img, 0.5)
def test_x_max_and_y_offset(self):
def test_x_max_and_y_offset():
ttf = ImageFont.truetype("Tests/fonts/ArefRuqaa-Regular.ttf", 40)
im = Image.new(mode="RGB", size=(50, 100))
@ -181,7 +194,8 @@ class TestImagecomplextext(PillowTestCase):
with Image.open(target) as target_img:
assert_image_similar(im, target_img, 0.5)
def test_language(self):
def test_language():
ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE)
im = Image.new(mode="RGB", size=(300, 100))

View File

@ -1,12 +1,14 @@
import subprocess
import sys
from .helper import PillowTestCase, assert_image
import pytest
from .helper import assert_image
try:
from PIL import ImageGrab
class TestImageGrab(PillowTestCase):
class TestImageGrab:
def test_grab(self):
for im in [
ImageGrab.grab(),
@ -39,12 +41,13 @@ $bmp = New-Object Drawing.Bitmap 200, 200
except ImportError:
class TestImageGrab(PillowTestCase):
class TestImageGrab:
@pytest.mark.skip(reason="ImageGrab ImportError")
def test_skip(self):
self.skipTest("ImportError")
pass
class TestImageGrabImport(PillowTestCase):
class TestImageGrabImport:
def test_import(self):
# Arrange
exception = None

View File

@ -2,33 +2,10 @@
import pytest
from PIL import Image, ImageMorph, _imagingmorph
from .helper import PillowTestCase, assert_image_equal, hopper
from .helper import assert_image_equal, hopper
class MorphTests(PillowTestCase):
def setUp(self):
self.A = self.string_to_img(
"""
.......
.......
..111..
..111..
..111..
.......
.......
"""
)
def img_to_string(self, im):
"""Turn a (small) binary image into a string representation"""
chars = ".1"
width, height = im.size
return "\n".join(
"".join(chars[im.getpixel((c, r)) > 0] for c in range(width))
for r in range(height)
)
def string_to_img(self, image_string):
def string_to_img(image_string):
"""Turn a string image representation into a binary image"""
rows = [s for s in image_string.replace(" ", "").split("\n") if len(s)]
height = len(rows)
@ -42,28 +19,57 @@ class MorphTests(PillowTestCase):
return im
def img_string_normalize(self, im):
return self.img_to_string(self.string_to_img(im))
def assert_img_equal(self, A, B):
assert self.img_to_string(A) == self.img_to_string(B)
A = string_to_img(
"""
.......
.......
..111..
..111..
..111..
.......
.......
"""
)
def assert_img_equal_img_string(self, A, Bstring):
assert self.img_to_string(A) == self.img_string_normalize(Bstring)
def test_str_to_img(self):
def img_to_string(im):
"""Turn a (small) binary image into a string representation"""
chars = ".1"
width, height = im.size
return "\n".join(
"".join(chars[im.getpixel((c, r)) > 0] for c in range(width))
for r in range(height)
)
def img_string_normalize(im):
return img_to_string(string_to_img(im))
def assert_img_equal(A, B):
assert img_to_string(A) == img_to_string(B)
def assert_img_equal_img_string(A, Bstring):
assert img_to_string(A) == img_string_normalize(Bstring)
def test_str_to_img():
with Image.open("Tests/images/morph_a.png") as im:
assert_image_equal(self.A, im)
assert_image_equal(A, im)
def create_lut(self):
def create_lut():
for op in ("corner", "dilation4", "dilation8", "erosion4", "erosion8", "edge"):
lb = ImageMorph.LutBuilder(op_name=op)
lut = lb.build_lut()
with open("Tests/images/%s.lut" % op, "wb") as f:
f.write(lut)
# create_lut()
def test_lut(self):
def test_lut():
for op in ("corner", "dilation4", "dilation8", "erosion4", "erosion8", "edge"):
lb = ImageMorph.LutBuilder(op_name=op)
assert lb.get_lut() is None
@ -72,7 +78,8 @@ class MorphTests(PillowTestCase):
with open("Tests/images/%s.lut" % op, "rb") as f:
assert lut == bytearray(f.read())
def test_no_operator_loaded(self):
def test_no_operator_loaded():
mop = ImageMorph.MorphOp()
with pytest.raises(Exception) as e:
mop.apply(None)
@ -84,13 +91,14 @@ class MorphTests(PillowTestCase):
mop.save_lut(None)
assert str(e.value) == "No operator loaded"
# Test the named patterns
def test_erosion8(self):
def test_erosion8():
# erosion8
mop = ImageMorph.MorphOp(op_name="erosion8")
count, Aout = mop.apply(self.A)
count, Aout = mop.apply(A)
assert count == 8
self.assert_img_equal_img_string(
assert_img_equal_img_string(
Aout,
"""
.......
@ -103,12 +111,13 @@ class MorphTests(PillowTestCase):
""",
)
def test_dialation8(self):
def test_dialation8():
# dialation8
mop = ImageMorph.MorphOp(op_name="dilation8")
count, Aout = mop.apply(self.A)
count, Aout = mop.apply(A)
assert count == 16
self.assert_img_equal_img_string(
assert_img_equal_img_string(
Aout,
"""
.......
@ -121,12 +130,13 @@ class MorphTests(PillowTestCase):
""",
)
def test_erosion4(self):
def test_erosion4():
# erosion4
mop = ImageMorph.MorphOp(op_name="dilation4")
count, Aout = mop.apply(self.A)
count, Aout = mop.apply(A)
assert count == 12
self.assert_img_equal_img_string(
assert_img_equal_img_string(
Aout,
"""
.......
@ -139,12 +149,13 @@ class MorphTests(PillowTestCase):
""",
)
def test_edge(self):
def test_edge():
# edge
mop = ImageMorph.MorphOp(op_name="edge")
count, Aout = mop.apply(self.A)
count, Aout = mop.apply(A)
assert count == 1
self.assert_img_equal_img_string(
assert_img_equal_img_string(
Aout,
"""
.......
@ -157,12 +168,13 @@ class MorphTests(PillowTestCase):
""",
)
def test_corner(self):
def test_corner():
# Create a corner detector pattern
mop = ImageMorph.MorphOp(patterns=["1:(... ... ...)->0", "4:(00. 01. ...)->1"])
count, Aout = mop.apply(self.A)
count, Aout = mop.apply(A)
assert count == 5
self.assert_img_equal_img_string(
assert_img_equal_img_string(
Aout,
"""
.......
@ -176,7 +188,7 @@ class MorphTests(PillowTestCase):
)
# Test the coordinate counting with the same operator
coords = mop.match(self.A)
coords = mop.match(A)
assert len(coords) == 4
assert tuple(coords) == ((2, 2), (4, 2), (2, 4), (4, 4))
@ -184,12 +196,13 @@ class MorphTests(PillowTestCase):
assert len(coords) == 4
assert tuple(coords) == ((2, 2), (4, 2), (2, 4), (4, 4))
def test_mirroring(self):
def test_mirroring():
# Test 'M' for mirroring
mop = ImageMorph.MorphOp(patterns=["1:(... ... ...)->0", "M:(00. 01. ...)->1"])
count, Aout = mop.apply(self.A)
count, Aout = mop.apply(A)
assert count == 7
self.assert_img_equal_img_string(
assert_img_equal_img_string(
Aout,
"""
.......
@ -202,12 +215,13 @@ class MorphTests(PillowTestCase):
""",
)
def test_negate(self):
def test_negate():
# Test 'N' for negate
mop = ImageMorph.MorphOp(patterns=["1:(... ... ...)->0", "N:(00. 01. ...)->1"])
count, Aout = mop.apply(self.A)
count, Aout = mop.apply(A)
assert count == 8
self.assert_img_equal_img_string(
assert_img_equal_img_string(
Aout,
"""
.......
@ -220,7 +234,8 @@ class MorphTests(PillowTestCase):
""",
)
def test_non_binary_images(self):
def test_non_binary_images():
im = hopper("RGB")
mop = ImageMorph.MorphOp(op_name="erosion8")
@ -234,7 +249,8 @@ class MorphTests(PillowTestCase):
mop.get_on_pixels(im)
assert str(e.value) == "Image must be binary, meaning it must use mode L"
def test_add_patterns(self):
def test_add_patterns():
# Arrange
lb = ImageMorph.LutBuilder(op_name="corner")
assert lb.patterns == ["1:(... ... ...)->0", "4:(00. 01. ...)->1"]
@ -251,11 +267,13 @@ class MorphTests(PillowTestCase):
"N:(00. 01. ...)->1",
]
def test_unknown_pattern(self):
def test_unknown_pattern():
with pytest.raises(Exception):
ImageMorph.LutBuilder(op_name="unknown")
def test_pattern_syntax_error(self):
def test_pattern_syntax_error():
# Arrange
lb = ImageMorph.LutBuilder(op_name="corner")
new_patterns = ["a pattern with a syntax error"]
@ -266,7 +284,8 @@ class MorphTests(PillowTestCase):
lb.build_lut()
assert str(e.value) == 'Syntax error in pattern "a pattern with a syntax error"'
def test_load_invalid_mrl(self):
def test_load_invalid_mrl():
# Arrange
invalid_mrl = "Tests/images/hopper.png"
mop = ImageMorph.MorphOp()
@ -276,9 +295,10 @@ class MorphTests(PillowTestCase):
mop.load_lut(invalid_mrl)
assert str(e.value) == "Wrong size operator file!"
def test_roundtrip_mrl(self):
def test_roundtrip_mrl(tmp_path):
# Arrange
tempfile = self.tempfile("temp.mrl")
tempfile = str(tmp_path / "temp.mrl")
mop = ImageMorph.MorphOp(op_name="corner")
initial_lut = mop.lut
@ -289,7 +309,8 @@ class MorphTests(PillowTestCase):
# Act / Assert
assert mop.lut == initial_lut
def test_set_lut(self):
def test_set_lut():
# Arrange
lb = ImageMorph.LutBuilder(op_name="corner")
lut = lb.build_lut()
@ -301,7 +322,8 @@ class MorphTests(PillowTestCase):
# Assert
assert mop.lut == lut
def test_wrong_mode(self):
def test_wrong_mode():
lut = ImageMorph.LutBuilder(op_name="corner").build_lut()
imrgb = Image.new("RGB", (10, 10))
iml = Image.new("L", (10, 10))

View File

@ -4,10 +4,8 @@ import struct
import pytest
from PIL import Image, ImagePath
from .helper import PillowTestCase
class TestImagePath(PillowTestCase):
class TestImagePath:
def test_path(self):
p = ImagePath.Path(list(range(10)))

View File

@ -3,12 +3,10 @@ import sys
import pytest
from PIL import Image
from .helper import PillowTestCase
X = 255
class TestLibPack(PillowTestCase):
class TestLibPack:
def assert_pack(self, mode, rawmode, data, *pixels):
"""
data - either raw bytes with data or just number of bytes in rawmode.
@ -223,7 +221,7 @@ class TestLibPack(PillowTestCase):
)
class TestLibUnpack(PillowTestCase):
class TestLibUnpack:
def assert_unpack(self, mode, rawmode, data, *pixels):
"""
data - either raw bytes with data or just number of bytes in rawmode.

View File

@ -1,14 +1,12 @@
from PIL import Image
from .helper import PillowTestCase, hopper
class TestModeI16(PillowTestCase):
from .helper import hopper
original = hopper().resize((32, 32)).convert("I")
def verify(self, im1):
im2 = self.original.copy()
def verify(im1):
im2 = original.copy()
assert im1.size == im2.size
pix1 = im1.load()
pix2 = im2.load()
@ -21,40 +19,41 @@ class TestModeI16(PillowTestCase):
p1, im1.mode, xy, p2
)
def test_basic(self):
def test_basic(tmp_path):
# PIL 1.1 has limited support for 16-bit image data. Check that
# create/copy/transform and save works as expected.
def basic(mode):
imIn = self.original.convert(mode)
self.verify(imIn)
imIn = original.convert(mode)
verify(imIn)
w, h = imIn.size
imOut = imIn.copy()
self.verify(imOut) # copy
verify(imOut) # copy
imOut = imIn.transform((w, h), Image.EXTENT, (0, 0, w, h))
self.verify(imOut) # transform
verify(imOut) # transform
filename = self.tempfile("temp.im")
filename = str(tmp_path / "temp.im")
imIn.save(filename)
with Image.open(filename) as imOut:
self.verify(imIn)
self.verify(imOut)
verify(imIn)
verify(imOut)
imOut = imIn.crop((0, 0, w, h))
self.verify(imOut)
verify(imOut)
imOut = Image.new(mode, (w, h), None)
imOut.paste(imIn.crop((0, 0, w // 2, h)), (0, 0))
imOut.paste(imIn.crop((w // 2, 0, w, h)), (w // 2, 0))
self.verify(imIn)
self.verify(imOut)
verify(imIn)
verify(imOut)
imIn = Image.new(mode, (1, 1), 1)
assert imIn.getpixel((0, 0)) == 1
@ -81,7 +80,8 @@ class TestModeI16(PillowTestCase):
basic("I")
def test_tobytes(self):
def test_tobytes():
def tobytes(mode):
return Image.new(mode, (1, 1), 1).tobytes()
@ -92,14 +92,15 @@ class TestModeI16(PillowTestCase):
assert tobytes("I;16B") == b"\x00\x01"
assert tobytes("I") == b"\x01\x00\x00\x00"[::order]
def test_convert(self):
im = self.original.copy()
def test_convert():
self.verify(im.convert("I;16"))
self.verify(im.convert("I;16").convert("L"))
self.verify(im.convert("I;16").convert("I"))
im = original.copy()
self.verify(im.convert("I;16B"))
self.verify(im.convert("I;16B").convert("L"))
self.verify(im.convert("I;16B").convert("I"))
verify(im.convert("I;16"))
verify(im.convert("I;16").convert("L"))
verify(im.convert("I;16").convert("I"))
verify(im.convert("I;16B"))
verify(im.convert("I;16B").convert("L"))
verify(im.convert("I;16B").convert("I"))

View File

@ -2,14 +2,11 @@ import pickle
from PIL import Image
from .helper import PillowTestCase
class TestPickle(PillowTestCase):
def helper_pickle_file(self, pickle, protocol=0, mode=None):
def helper_pickle_file(tmp_path, pickle, protocol=0, mode=None):
# Arrange
with Image.open("Tests/images/hopper.jpg") as im:
filename = self.tempfile("temp.pkl")
filename = str(tmp_path / "temp.pkl")
if mode:
im = im.convert(mode)
@ -22,8 +19,9 @@ class TestPickle(PillowTestCase):
# Assert
assert im == loaded_im
def helper_pickle_string(
self, pickle, protocol=0, test_file="Tests/images/hopper.jpg", mode=None
pickle, protocol=0, test_file="Tests/images/hopper.jpg", mode=None
):
with Image.open(test_file) as im:
if mode:
@ -36,13 +34,15 @@ class TestPickle(PillowTestCase):
# Assert
assert im == loaded_im
def test_pickle_image(self):
def test_pickle_image(tmp_path):
# Act / Assert
for protocol in range(0, pickle.HIGHEST_PROTOCOL + 1):
self.helper_pickle_string(pickle, protocol)
self.helper_pickle_file(pickle, protocol)
helper_pickle_string(pickle, protocol)
helper_pickle_file(tmp_path, pickle, protocol)
def test_pickle_p_mode(self):
def test_pickle_p_mode():
# Act / Assert
for test_file in [
"Tests/images/test-card.png",
@ -55,25 +55,26 @@ class TestPickle(PillowTestCase):
"Tests/images/itxt_chunks.png",
]:
for protocol in range(0, pickle.HIGHEST_PROTOCOL + 1):
self.helper_pickle_string(
pickle, protocol=protocol, test_file=test_file
)
helper_pickle_string(pickle, protocol=protocol, test_file=test_file)
def test_pickle_pa_mode(self):
def test_pickle_pa_mode(tmp_path):
# Act / Assert
for protocol in range(0, pickle.HIGHEST_PROTOCOL + 1):
self.helper_pickle_string(pickle, protocol, mode="PA")
self.helper_pickle_file(pickle, protocol, mode="PA")
helper_pickle_string(pickle, protocol, mode="PA")
helper_pickle_file(tmp_path, pickle, protocol, mode="PA")
def test_pickle_l_mode(self):
def test_pickle_l_mode(tmp_path):
# Act / Assert
for protocol in range(0, pickle.HIGHEST_PROTOCOL + 1):
self.helper_pickle_string(pickle, protocol, mode="L")
self.helper_pickle_file(pickle, protocol, mode="L")
helper_pickle_string(pickle, protocol, mode="L")
helper_pickle_file(tmp_path, pickle, protocol, mode="L")
def test_pickle_la_mode_with_palette(self):
def test_pickle_la_mode_with_palette(tmp_path):
# Arrange
filename = self.tempfile("temp.pkl")
filename = str(tmp_path / "temp.pkl")
with Image.open("Tests/images/hopper.jpg") as im:
im = im.convert("PA")