1
0
Fork 0
pydyf/tests/__init__.py
Daniel Baumann 00981dc324
Adding upstream version 0.1.1.
Signed-off-by: Daniel Baumann <daniel@debian.org>
2025-02-08 07:33:47 +01:00

80 lines
2.9 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
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 dont 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')