From f2038241cc91dbeee206151c1c17a3c42c5e1968 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 27 Oct 2021 05:02:19 +0200 Subject: Adding upstream version 0.1.1. Signed-off-by: Daniel Baumann --- tests/__init__.py | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 tests/__init__.py (limited to 'tests/__init__.py') diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..ae5cf6a --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1,80 @@ +""" +Test suite for pydyf. + +This module adds a PNG export based on GhostScript, that is released under +AGPL. As "the end user has the ability to opt out of installing the AGPL +version of [Ghostscript] during the install process", and with explicit +aggreement from Artifex, it is OK to distribute this code under BSD. + +See https://www.ghostscript.com/license.html. + +""" + +import io +import os +from pathlib import Path +from subprocess import PIPE, run + +from PIL import Image + +PIXELS_BY_CHAR = dict( + _=(255, 255, 255), # white + R=(255, 0, 0), # red + B=(0, 0, 255), # blue + G=(0, 255, 0), # lime green + K=(0, 0, 0), # black + z=None, # any color +) + + +def assert_pixels(document, reference_pixels): + """Test that the rendered document matches the reference pixels.""" + + # Transform the PDF document into a list of RGB tuples + pdf = io.BytesIO() + document.write(pdf) + command = [ + 'gs', '-q', '-dNOPAUSE', '-dSAFER', '-sDEVICE=png16m', + '-r576', '-dDownScaleFactor=8', '-sOutputFile=-', '-'] + png = run(command, input=pdf.getvalue(), stdout=PIPE).stdout + image = Image.open(io.BytesIO(png)) + pixels = image.getdata() + + # Transform reference drawings into a list of RGB tuples + lines = tuple( + line.strip() for line in reference_pixels.splitlines() if line.strip()) + assert len({len(line) for line in lines}) == 1, ( + 'The lines of reference pixels don’t have the same length') + width, height = len(lines[0]), len(lines) + assert (width, height) == image.size, ( + f'Reference size is {width}×{height}, ' + f'output size is {image.width}×{image.height}') + reference_pixels = tuple( + PIXELS_BY_CHAR[char] for line in lines for char in line) + + # Compare pixels + if pixels != reference_pixels: # pragma: no cover + for i, (value, reference) in enumerate(zip(pixels, reference_pixels)): + if reference is None: + continue + if any(value != reference + for value, reference in zip(value, reference)): + name = os.environ.get('PYTEST_CURRENT_TEST') + name = name.split(':')[-1].split(' ')[0] + write_png(f'{name}', pixels, width, height) + reference_pixels = [ + pixel or (255, 255, 255) for pixel in reference_pixels] + write_png(f'{name}-reference', reference_pixels, width, height) + x, y = i % width, i // width + assert 0, ( + f'Pixel ({x}, {y}) in {name}: ' + f'reference rgba{reference}, got rgba{value}') + + +def write_png(name, pixels, width, height): # pragma: no cover + """Take a pixel matrix and write a PNG file.""" + directory = Path(__file__).parent / 'results' + directory.mkdir(exist_ok=True) + image = Image.new('RGB', (width, height)) + image.putdata(pixels) + image.save(directory / f'{name}.png') -- cgit v1.2.3