Convert to use pytest

This commit is contained in:
Hugo 2020-02-18 15:50:34 +02:00
parent 17c67a2cfb
commit d289a5b072
4 changed files with 338 additions and 345 deletions

View File

@ -1,19 +1,17 @@
import pytest import pytest
from PIL import Image from PIL import Image
from .helper import PillowTestCase, assert_image_equal, assert_image_similar, hopper from .helper import assert_image_equal, assert_image_similar, hopper
_webp = pytest.importorskip("PIL._webp", reason="WebP support not installed") _webp = pytest.importorskip("PIL._webp", reason="WebP support not installed")
class TestFileWebpAlpha(PillowTestCase): def setup_module():
def setUp(self): if _webp.WebPDecoderBuggyAlpha():
if _webp.WebPDecoderBuggyAlpha(self): pytest.skip("Buggy early version of WebP installed, not testing transparency")
self.skipTest(
"Buggy early version of WebP installed, not testing transparency"
)
def test_read_rgba(self):
def test_read_rgba():
""" """
Can we read an RGBA mode file without error? Can we read an RGBA mode file without error?
Does it have the bits we expect? Does it have the bits we expect?
@ -22,9 +20,9 @@ class TestFileWebpAlpha(PillowTestCase):
# Generated with `cwebp transparent.png -o transparent.webp` # Generated with `cwebp transparent.png -o transparent.webp`
file_path = "Tests/images/transparent.webp" file_path = "Tests/images/transparent.webp"
with Image.open(file_path) as image: with Image.open(file_path) as image:
self.assertEqual(image.mode, "RGBA") assert image.mode == "RGBA"
self.assertEqual(image.size, (200, 150)) assert image.size == (200, 150)
self.assertEqual(image.format, "WEBP") assert image.format == "WEBP"
image.load() image.load()
image.getdata() image.getdata()
@ -33,13 +31,14 @@ class TestFileWebpAlpha(PillowTestCase):
with Image.open("Tests/images/transparent.png") as target: with Image.open("Tests/images/transparent.png") as target:
assert_image_similar(image, target, 20.0) assert_image_similar(image, target, 20.0)
def test_write_lossless_rgb(self):
def test_write_lossless_rgb(tmp_path):
""" """
Can we write an RGBA mode file with lossless compression without Can we write an RGBA mode file with lossless compression without error?
error? Does it have the bits we expect? Does it have the bits we expect?
""" """
temp_file = self.tempfile("temp.webp") temp_file = str(tmp_path / "temp.webp")
# temp_file = "temp.webp" # temp_file = "temp.webp"
pil_image = hopper("RGBA") pil_image = hopper("RGBA")
@ -53,58 +52,60 @@ class TestFileWebpAlpha(PillowTestCase):
with Image.open(temp_file) as image: with Image.open(temp_file) as image:
image.load() image.load()
self.assertEqual(image.mode, "RGBA") assert image.mode == "RGBA"
self.assertEqual(image.size, pil_image.size) assert image.size == pil_image.size
self.assertEqual(image.format, "WEBP") assert image.format == "WEBP"
image.load() image.load()
image.getdata() image.getdata()
assert_image_equal(image, pil_image) assert_image_equal(image, pil_image)
def test_write_rgba(self):
def test_write_rgba(tmp_path):
""" """
Can we write a RGBA mode file to webp without error. Can we write a RGBA mode file to WebP without error.
Does it have the bits we expect? Does it have the bits we expect?
""" """
temp_file = self.tempfile("temp.webp") temp_file = str(tmp_path / "temp.webp")
pil_image = Image.new("RGBA", (10, 10), (255, 0, 0, 20)) pil_image = Image.new("RGBA", (10, 10), (255, 0, 0, 20))
pil_image.save(temp_file) pil_image.save(temp_file)
if _webp.WebPDecoderBuggyAlpha(self): if _webp.WebPDecoderBuggyAlpha():
return return
with Image.open(temp_file) as image: with Image.open(temp_file) as image:
image.load() image.load()
self.assertEqual(image.mode, "RGBA") assert image.mode == "RGBA"
self.assertEqual(image.size, (10, 10)) assert image.size == (10, 10)
self.assertEqual(image.format, "WEBP") assert image.format == "WEBP"
image.load() image.load()
image.getdata() image.getdata()
# early versions of webp are known to produce higher deviations: # Early versions of WebP are known to produce higher deviations:
# deal with it # deal with it
if _webp.WebPDecoderVersion(self) <= 0x201: if _webp.WebPDecoderVersion() <= 0x201:
assert_image_similar(image, pil_image, 3.0) assert_image_similar(image, pil_image, 3.0)
else: else:
assert_image_similar(image, pil_image, 1.0) assert_image_similar(image, pil_image, 1.0)
def test_write_unsupported_mode_PA(self):
def test_write_unsupported_mode_PA(tmp_path):
""" """
Saving a palette-based file with transparency to WebP format Saving a palette-based file with transparency to WebP format
should work, and be similar to the original file. should work, and be similar to the original file.
""" """
temp_file = self.tempfile("temp.webp") temp_file = str(tmp_path / "temp.webp")
file_path = "Tests/images/transparent.gif" file_path = "Tests/images/transparent.gif"
with Image.open(file_path) as im: with Image.open(file_path) as im:
im.save(temp_file) im.save(temp_file)
with Image.open(temp_file) as image: with Image.open(temp_file) as image:
self.assertEqual(image.mode, "RGBA") assert image.mode == "RGBA"
self.assertEqual(image.size, (200, 150)) assert image.size == (200, 150)
self.assertEqual(image.format, "WEBP") assert image.format == "WEBP"
image.load() image.load()
image.getdata() image.getdata()

View File

@ -1,54 +1,44 @@
import pytest import pytest
from PIL import Image from PIL import Image
from .helper import ( from .helper import assert_image_equal, assert_image_similar, is_big_endian, on_ci
PillowTestCase,
assert_image_equal,
assert_image_similar,
is_big_endian,
on_ci,
)
_webp = pytest.importorskip("PIL._webp", reason="WebP support not installed") _webp = pytest.importorskip("PIL._webp", reason="WebP support not installed")
class TestFileWebpAnimation(PillowTestCase): def setup_module():
def setUp(self):
if not _webp.HAVE_WEBPANIM: if not _webp.HAVE_WEBPANIM:
self.skipTest( pytest.skip(
"WebP library does not contain animation support, " "WebP library does not contain animation support, not testing animation"
"not testing animation"
) )
def test_n_frames(self):
""" def test_n_frames():
Ensure that WebP format sets n_frames and is_animated """Ensure that WebP format sets n_frames and is_animated attributes correctly."""
attributes correctly.
"""
with Image.open("Tests/images/hopper.webp") as im: with Image.open("Tests/images/hopper.webp") as im:
self.assertEqual(im.n_frames, 1) assert im.n_frames == 1
self.assertFalse(im.is_animated) assert not im.is_animated
with Image.open("Tests/images/iss634.webp") as im: with Image.open("Tests/images/iss634.webp") as im:
self.assertEqual(im.n_frames, 42) assert im.n_frames == 42
self.assertTrue(im.is_animated) assert im.is_animated
@pytest.mark.xfail(is_big_endian() and on_ci(), reason="Fails on big-endian")
def test_write_animation_L(self): @pytest.mark.xfail(is_big_endian() and on_ci(), reason="Fails on big-endian")
def test_write_animation_L(tmp_path):
""" """
Convert an animated GIF to animated WebP, then compare the Convert an animated GIF to animated WebP, then compare the frame count, and first
frame count, and first and last frames to ensure they're and last frames to ensure they're visually similar.
visually similar.
""" """
with Image.open("Tests/images/iss634.gif") as orig: with Image.open("Tests/images/iss634.gif") as orig:
self.assertGreater(orig.n_frames, 1) assert orig.n_frames > 1
temp_file = self.tempfile("temp.webp") temp_file = str(tmp_path / "temp.webp")
orig.save(temp_file, save_all=True) orig.save(temp_file, save_all=True)
with Image.open(temp_file) as im: with Image.open(temp_file) as im:
self.assertEqual(im.n_frames, orig.n_frames) assert im.n_frames == orig.n_frames
# Compare first and last frames to the original animated GIF # Compare first and last frames to the original animated GIF
orig.load() orig.load()
@ -60,8 +50,9 @@ class TestFileWebpAnimation(PillowTestCase):
im.load() im.load()
assert_image_similar(im, orig.convert("RGBA"), 25.0) assert_image_similar(im, orig.convert("RGBA"), 25.0)
@pytest.mark.xfail(is_big_endian() and on_ci(), reason="Fails on big-endian")
def test_write_animation_RGB(self): @pytest.mark.xfail(is_big_endian() and on_ci(), reason="Fails on big-endian")
def test_write_animation_RGB(tmp_path):
""" """
Write an animated WebP from RGB frames, and ensure the frames Write an animated WebP from RGB frames, and ensure the frames
are visually similar to the originals. are visually similar to the originals.
@ -69,7 +60,7 @@ class TestFileWebpAnimation(PillowTestCase):
def check(temp_file): def check(temp_file):
with Image.open(temp_file) as im: with Image.open(temp_file) as im:
self.assertEqual(im.n_frames, 2) assert im.n_frames == 2
# Compare first frame to original # Compare first frame to original
im.load() im.load()
@ -82,7 +73,7 @@ class TestFileWebpAnimation(PillowTestCase):
with Image.open("Tests/images/anim_frame1.webp") as frame1: with Image.open("Tests/images/anim_frame1.webp") as frame1:
with Image.open("Tests/images/anim_frame2.webp") as frame2: with Image.open("Tests/images/anim_frame2.webp") as frame2:
temp_file1 = self.tempfile("temp.webp") temp_file1 = str(tmp_path / "temp.webp")
frame1.copy().save( frame1.copy().save(
temp_file1, save_all=True, append_images=[frame2], lossless=True temp_file1, save_all=True, append_images=[frame2], lossless=True
) )
@ -92,7 +83,7 @@ class TestFileWebpAnimation(PillowTestCase):
def imGenerator(ims): def imGenerator(ims):
yield from ims yield from ims
temp_file2 = self.tempfile("temp_generator.webp") temp_file2 = str(tmp_path / "temp_generator.webp")
frame1.copy().save( frame1.copy().save(
temp_file2, temp_file2,
save_all=True, save_all=True,
@ -101,14 +92,15 @@ class TestFileWebpAnimation(PillowTestCase):
) )
check(temp_file2) check(temp_file2)
def test_timestamp_and_duration(self):
def test_timestamp_and_duration(tmp_path):
""" """
Try passing a list of durations, and make sure the encoded Try passing a list of durations, and make sure the encoded
timestamps and durations are correct. timestamps and durations are correct.
""" """
durations = [0, 10, 20, 30, 40] durations = [0, 10, 20, 30, 40]
temp_file = self.tempfile("temp.webp") temp_file = str(tmp_path / "temp.webp")
with Image.open("Tests/images/anim_frame1.webp") as frame1: with Image.open("Tests/images/anim_frame1.webp") as frame1:
with Image.open("Tests/images/anim_frame2.webp") as frame2: with Image.open("Tests/images/anim_frame2.webp") as frame2:
frame1.save( frame1.save(
@ -119,27 +111,27 @@ class TestFileWebpAnimation(PillowTestCase):
) )
with Image.open(temp_file) as im: with Image.open(temp_file) as im:
self.assertEqual(im.n_frames, 5) assert im.n_frames == 5
self.assertTrue(im.is_animated) assert im.is_animated
# Check that timestamps and durations match original values specified # Check that timestamps and durations match original values specified
ts = 0 ts = 0
for frame in range(im.n_frames): for frame in range(im.n_frames):
im.seek(frame) im.seek(frame)
im.load() im.load()
self.assertEqual(im.info["duration"], durations[frame]) assert im.info["duration"] == durations[frame]
self.assertEqual(im.info["timestamp"], ts) assert im.info["timestamp"] == ts
ts += durations[frame] ts += durations[frame]
def test_seeking(self):
def test_seeking(tmp_path):
""" """
Create an animated WebP file, and then try seeking through Create an animated WebP file, and then try seeking through frames in reverse-order,
frames in reverse-order, verifying the timestamps and durations verifying the timestamps and durations are correct.
are correct.
""" """
dur = 33 dur = 33
temp_file = self.tempfile("temp.webp") temp_file = str(tmp_path / "temp.webp")
with Image.open("Tests/images/anim_frame1.webp") as frame1: with Image.open("Tests/images/anim_frame1.webp") as frame1:
with Image.open("Tests/images/anim_frame2.webp") as frame2: with Image.open("Tests/images/anim_frame2.webp") as frame2:
frame1.save( frame1.save(
@ -150,22 +142,23 @@ class TestFileWebpAnimation(PillowTestCase):
) )
with Image.open(temp_file) as im: with Image.open(temp_file) as im:
self.assertEqual(im.n_frames, 5) assert im.n_frames == 5
self.assertTrue(im.is_animated) assert im.is_animated
# Traverse frames in reverse, checking timestamps and durations # Traverse frames in reverse, checking timestamps and durations
ts = dur * (im.n_frames - 1) ts = dur * (im.n_frames - 1)
for frame in reversed(range(im.n_frames)): for frame in reversed(range(im.n_frames)):
im.seek(frame) im.seek(frame)
im.load() im.load()
self.assertEqual(im.info["duration"], dur) assert im.info["duration"] == dur
self.assertEqual(im.info["timestamp"], ts) assert im.info["timestamp"] == ts
ts -= dur ts -= dur
def test_seek_errors(self):
def test_seek_errors():
with Image.open("Tests/images/iss634.webp") as im: with Image.open("Tests/images/iss634.webp") as im:
with self.assertRaises(EOFError): with pytest.raises(EOFError):
im.seek(-1) im.seek(-1)
with self.assertRaises(EOFError): with pytest.raises(EOFError):
im.seek(42) im.seek(42)

View File

@ -1,30 +1,28 @@
import pytest import pytest
from PIL import Image from PIL import Image
from .helper import PillowTestCase, assert_image_equal, hopper from .helper import assert_image_equal, hopper
_webp = pytest.importorskip("PIL._webp", reason="WebP support not installed") _webp = pytest.importorskip("PIL._webp", reason="WebP support not installed")
RGB_MODE = "RGB"
class TestFileWebpLossless(PillowTestCase):
def setUp(self): def test_write_lossless_rgb(tmp_path):
if _webp.WebPDecoderVersion() < 0x0200: if _webp.WebPDecoderVersion() < 0x0200:
self.skipTest("lossless not included") pytest.skip("lossless not included")
self.rgb_mode = "RGB" temp_file = str(tmp_path / "temp.webp")
def test_write_lossless_rgb(self): hopper(RGB_MODE).save(temp_file, lossless=True)
temp_file = self.tempfile("temp.webp")
hopper(self.rgb_mode).save(temp_file, lossless=True)
with Image.open(temp_file) as image: with Image.open(temp_file) as image:
image.load() image.load()
self.assertEqual(image.mode, self.rgb_mode) assert image.mode == RGB_MODE
self.assertEqual(image.size, (128, 128)) assert image.size == (128, 128)
self.assertEqual(image.format, "WEBP") assert image.format == "WEBP"
image.load() image.load()
image.getdata() image.getdata()
assert_image_equal(image, hopper(self.rgb_mode)) assert_image_equal(image, hopper(RGB_MODE))

View File

@ -3,36 +3,35 @@ from io import BytesIO
import pytest import pytest
from PIL import Image from PIL import Image
from .helper import PillowTestCase
_webp = pytest.importorskip("PIL._webp", reason="WebP support not installed") _webp = pytest.importorskip("PIL._webp", reason="WebP support not installed")
class TestFileWebpMetadata(PillowTestCase): def setup_module():
def setUp(self):
if not _webp.HAVE_WEBPMUX: if not _webp.HAVE_WEBPMUX:
self.skipTest("WebPMux support not installed") pytest.skip("WebPMux support not installed")
def test_read_exif_metadata(self):
def test_read_exif_metadata():
file_path = "Tests/images/flower.webp" file_path = "Tests/images/flower.webp"
with Image.open(file_path) as image: with Image.open(file_path) as image:
self.assertEqual(image.format, "WEBP") assert image.format == "WEBP"
exif_data = image.info.get("exif", None) exif_data = image.info.get("exif", None)
self.assertTrue(exif_data) assert exif_data
exif = image._getexif() exif = image._getexif()
# camera make # Camera make
self.assertEqual(exif[271], "Canon") assert exif[271] == "Canon"
with Image.open("Tests/images/flower.jpg") as jpeg_image: with Image.open("Tests/images/flower.jpg") as jpeg_image:
expected_exif = jpeg_image.info["exif"] expected_exif = jpeg_image.info["exif"]
self.assertEqual(exif_data, expected_exif) assert exif_data == expected_exif
def test_write_exif_metadata(self):
def test_write_exif_metadata():
file_path = "Tests/images/flower.jpg" file_path = "Tests/images/flower.jpg"
test_buffer = BytesIO() test_buffer = BytesIO()
with Image.open(file_path) as image: with Image.open(file_path) as image:
@ -43,26 +42,28 @@ class TestFileWebpMetadata(PillowTestCase):
test_buffer.seek(0) test_buffer.seek(0)
with Image.open(test_buffer) as webp_image: with Image.open(test_buffer) as webp_image:
webp_exif = webp_image.info.get("exif", None) webp_exif = webp_image.info.get("exif", None)
self.assertTrue(webp_exif) assert webp_exif
if webp_exif: if webp_exif:
self.assertEqual(webp_exif, expected_exif, "WebP EXIF didn't match") assert webp_exif == expected_exif, "WebP EXIF didn't match"
def test_read_icc_profile(self):
def test_read_icc_profile():
file_path = "Tests/images/flower2.webp" file_path = "Tests/images/flower2.webp"
with Image.open(file_path) as image: with Image.open(file_path) as image:
self.assertEqual(image.format, "WEBP") assert image.format == "WEBP"
self.assertTrue(image.info.get("icc_profile", None)) assert image.info.get("icc_profile", None)
icc = image.info["icc_profile"] icc = image.info["icc_profile"]
with Image.open("Tests/images/flower2.jpg") as jpeg_image: with Image.open("Tests/images/flower2.jpg") as jpeg_image:
expected_icc = jpeg_image.info["icc_profile"] expected_icc = jpeg_image.info["icc_profile"]
self.assertEqual(icc, expected_icc) assert icc == expected_icc
def test_write_icc_metadata(self):
def test_write_icc_metadata():
file_path = "Tests/images/flower2.jpg" file_path = "Tests/images/flower2.jpg"
test_buffer = BytesIO() test_buffer = BytesIO()
with Image.open(file_path) as image: with Image.open(file_path) as image:
@ -74,33 +75,33 @@ class TestFileWebpMetadata(PillowTestCase):
with Image.open(test_buffer) as webp_image: with Image.open(test_buffer) as webp_image:
webp_icc_profile = webp_image.info.get("icc_profile", None) webp_icc_profile = webp_image.info.get("icc_profile", None)
self.assertTrue(webp_icc_profile) assert webp_icc_profile
if webp_icc_profile: if webp_icc_profile:
self.assertEqual( assert webp_icc_profile == expected_icc_profile, "Webp ICC didn't match"
webp_icc_profile, expected_icc_profile, "Webp ICC didn't match"
)
def test_read_no_exif(self):
def test_read_no_exif():
file_path = "Tests/images/flower.jpg" file_path = "Tests/images/flower.jpg"
test_buffer = BytesIO() test_buffer = BytesIO()
with Image.open(file_path) as image: with Image.open(file_path) as image:
self.assertIn("exif", image.info) assert "exif" in image.info
image.save(test_buffer, "webp") image.save(test_buffer, "webp")
test_buffer.seek(0) test_buffer.seek(0)
with Image.open(test_buffer) as webp_image: with Image.open(test_buffer) as webp_image:
self.assertFalse(webp_image._getexif()) assert not webp_image._getexif()
def test_write_animated_metadata(self):
def test_write_animated_metadata(tmp_path):
if not _webp.HAVE_WEBPANIM: if not _webp.HAVE_WEBPANIM:
self.skipTest("WebP animation support not available") pytest.skip("WebP animation support not available")
iccp_data = b"<iccp_data>" iccp_data = b"<iccp_data>"
exif_data = b"<exif_data>" exif_data = b"<exif_data>"
xmp_data = b"<xmp_data>" xmp_data = b"<xmp_data>"
temp_file = self.tempfile("temp.webp") temp_file = str(tmp_path / "temp.webp")
with Image.open("Tests/images/anim_frame1.webp") as frame1: with Image.open("Tests/images/anim_frame1.webp") as frame1:
with Image.open("Tests/images/anim_frame2.webp") as frame2: with Image.open("Tests/images/anim_frame2.webp") as frame2:
frame1.save( frame1.save(
@ -113,9 +114,9 @@ class TestFileWebpMetadata(PillowTestCase):
) )
with Image.open(temp_file) as image: with Image.open(temp_file) as image:
self.assertIn("icc_profile", image.info) assert "icc_profile" in image.info
self.assertIn("exif", image.info) assert "exif" in image.info
self.assertIn("xmp", image.info) assert "xmp" in image.info
self.assertEqual(iccp_data, image.info.get("icc_profile", None)) assert iccp_data == image.info.get("icc_profile", None)
self.assertEqual(exif_data, image.info.get("exif", None)) assert exif_data == image.info.get("exif", None)
self.assertEqual(xmp_data, image.info.get("xmp", None)) assert xmp_data == image.info.get("xmp", None)