aboutsummaryrefslogtreecommitdiffstats
path: root/tests/test_task_scale_images.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_task_scale_images.py')
-rw-r--r--tests/test_task_scale_images.py126
1 files changed, 126 insertions, 0 deletions
diff --git a/tests/test_task_scale_images.py b/tests/test_task_scale_images.py
new file mode 100644
index 0000000..46a39a4
--- /dev/null
+++ b/tests/test_task_scale_images.py
@@ -0,0 +1,126 @@
+import os
+from tempfile import NamedTemporaryFile
+
+import pytest
+from PIL import Image, ImageDraw
+
+from nikola.plugins.task import scale_images
+
+# These tests don't require valid profiles. They need only to verify
+# that profile data is/isn't saved with images.
+# It would be nice to use PIL.ImageCms to create valid profiles, but
+# in many Pillow distributions ImageCms is a stub.
+# ICC file data format specification:
+# http://www.color.org/icc32.pdf
+PROFILE = b"invalid profile data"
+
+
+def test_handling_icc_profiles(test_images, destination_dir):
+ filename, expected_profile = test_images
+
+ pathname = os.path.join(str(destination_dir), filename)
+ assert os.path.exists(pathname), pathname
+
+ img = Image.open(pathname)
+ actual_profile = img.info.get("icc_profile")
+ assert actual_profile == expected_profile
+
+
+@pytest.fixture(
+ params=[
+ pytest.param(True, id="with icc filename"),
+ pytest.param(False, id="without icc filename"),
+ ]
+)
+def test_images(request, preserve_icc_profiles, source_dir, site):
+ image_filename = create_src_image(str(source_dir), request.param)
+ run_task(site)
+
+ if request.param:
+ yield image_filename, PROFILE if preserve_icc_profiles else None
+ else:
+ yield image_filename, None
+
+
+@pytest.fixture(
+ params=[
+ pytest.param(True, id="profiles preserved"),
+ pytest.param(False, id="profiles not preserved"),
+ ]
+)
+def preserve_icc_profiles(request):
+ return request.param
+
+
+@pytest.fixture
+def source_dir(tmpdir_factory):
+ return tmpdir_factory.mktemp("image_source")
+
+
+@pytest.fixture
+def site(preserve_icc_profiles, source_dir, destination_dir):
+ config = {
+ "IMAGE_FOLDERS": {str(source_dir): ""},
+ "OUTPUT_FOLDER": str(destination_dir),
+ "IMAGE_THUMBNAIL_SIZE": 128,
+ "IMAGE_THUMBNAIL_FORMAT": "{name}.thumbnail{ext}",
+ "MAX_IMAGE_SIZE": 512,
+ "FILTERS": {},
+ "PRESERVE_EXIF_DATA": False,
+ "EXIF_WHITELIST": {},
+ "PRESERVE_ICC_PROFILES": preserve_icc_profiles,
+ }
+ return FakeSite(config)
+
+
+class FakeSite:
+ def __init__(self, config):
+ self.config = config
+ self.debug = True
+
+
+@pytest.fixture
+def destination_dir(tmpdir_factory):
+ return tmpdir_factory.mktemp("image_output")
+
+
+def run_task(site):
+ task_instance = get_task_instance(site)
+ for task in task_instance.gen_tasks():
+ for action, args in task.get("actions", []):
+ action(*args)
+
+
+def get_task_instance(site):
+ result = scale_images.ScaleImage()
+ result.set_site(site)
+ return result
+
+
+def create_src_image(testdir, use_icc_profile):
+ img = create_test_image()
+ pathname = tmp_img_name(testdir)
+
+ # Test two variants: with and without an associated icc_profile
+ if use_icc_profile:
+ img.save(pathname, icc_profile=PROFILE)
+ else:
+ img.save(pathname)
+
+ return os.path.basename(pathname)
+
+
+def create_test_image():
+ # Make a white image with a red stripe on the diagonal.
+ width = 64
+ height = 64
+ img = Image.new("RGB", (width, height), (255, 255, 255))
+ draw = ImageDraw.Draw(img)
+ draw.line((0, 0, width, height), fill=(255, 128, 128))
+ draw.line((width, 0, 0, height), fill=(128, 128, 255))
+ return img
+
+
+def tmp_img_name(dirname):
+ pathname = NamedTemporaryFile(suffix=".jpg", dir=dirname, delete=False)
+ return pathname.name