709 lines
24 KiB
Python
709 lines
24 KiB
Python
"""
|
|
Tests for PDF export functionality
|
|
"""
|
|
|
|
import os
|
|
import tempfile
|
|
from pyPhotoAlbum.project import Project, Page
|
|
from pyPhotoAlbum.page_layout import PageLayout
|
|
from pyPhotoAlbum.models import ImageData, TextBoxData
|
|
from pyPhotoAlbum.pdf_exporter import PDFExporter
|
|
|
|
|
|
def test_pdf_exporter_basic():
|
|
"""Test basic PDF export with single page"""
|
|
# Create a simple project
|
|
project = Project("Test Project")
|
|
project.page_size_mm = (210, 297) # A4
|
|
|
|
# Add a single page
|
|
page = Page(page_number=1, is_double_spread=False)
|
|
project.add_page(page)
|
|
|
|
# Export to temporary file
|
|
with tempfile.NamedTemporaryFile(suffix='.pdf', delete=False) as tmp:
|
|
tmp_path = tmp.name
|
|
|
|
try:
|
|
exporter = PDFExporter(project)
|
|
success, warnings = exporter.export(tmp_path)
|
|
|
|
assert success, f"Export failed: {warnings}"
|
|
assert os.path.exists(tmp_path), "PDF file was not created"
|
|
assert os.path.getsize(tmp_path) > 0, "PDF file is empty"
|
|
|
|
print(f"✓ Basic PDF export successful: {tmp_path}")
|
|
if warnings:
|
|
print(f" Warnings: {warnings}")
|
|
|
|
finally:
|
|
if os.path.exists(tmp_path):
|
|
os.remove(tmp_path)
|
|
|
|
|
|
def test_pdf_exporter_double_spread():
|
|
"""Test PDF export with double-page spread"""
|
|
project = Project("Test Spread Project")
|
|
project.page_size_mm = (210, 297) # A4
|
|
|
|
# Add a double-page spread
|
|
spread_page = Page(page_number=1, is_double_spread=True)
|
|
project.add_page(spread_page)
|
|
|
|
# Export to temporary file
|
|
with tempfile.NamedTemporaryFile(suffix='.pdf', delete=False) as tmp:
|
|
tmp_path = tmp.name
|
|
|
|
try:
|
|
exporter = PDFExporter(project)
|
|
success, warnings = exporter.export(tmp_path)
|
|
|
|
assert success, f"Export failed: {warnings}"
|
|
assert os.path.exists(tmp_path), "PDF file was not created"
|
|
|
|
print(f"✓ Double-spread PDF export successful: {tmp_path}")
|
|
if warnings:
|
|
print(f" Warnings: {warnings}")
|
|
|
|
finally:
|
|
if os.path.exists(tmp_path):
|
|
os.remove(tmp_path)
|
|
|
|
|
|
def test_pdf_exporter_with_text():
|
|
"""Test PDF export with text boxes"""
|
|
project = Project("Test Text Project")
|
|
project.page_size_mm = (210, 297)
|
|
|
|
# Create page with text box
|
|
page = Page(page_number=1, is_double_spread=False)
|
|
|
|
# Add a text box
|
|
text_box = TextBoxData(
|
|
text_content="Hello, World!",
|
|
font_settings={"family": "Helvetica", "size": 24, "color": (0, 0, 0)},
|
|
alignment="center",
|
|
x=50, y=50, width=100, height=30
|
|
)
|
|
page.layout.add_element(text_box)
|
|
|
|
project.add_page(page)
|
|
|
|
# Export to temporary file
|
|
with tempfile.NamedTemporaryFile(suffix='.pdf', delete=False) as tmp:
|
|
tmp_path = tmp.name
|
|
|
|
try:
|
|
exporter = PDFExporter(project)
|
|
success, warnings = exporter.export(tmp_path)
|
|
|
|
assert success, f"Export failed: {warnings}"
|
|
assert os.path.exists(tmp_path), "PDF file was not created"
|
|
|
|
print(f"✓ Text box PDF export successful: {tmp_path}")
|
|
if warnings:
|
|
print(f" Warnings: {warnings}")
|
|
|
|
finally:
|
|
if os.path.exists(tmp_path):
|
|
os.remove(tmp_path)
|
|
|
|
|
|
def test_pdf_exporter_facing_pages_alignment():
|
|
"""Test that double spreads align to facing pages"""
|
|
project = Project("Test Facing Pages")
|
|
project.page_size_mm = (210, 297)
|
|
|
|
# Add single page (page 1)
|
|
page1 = Page(page_number=1, is_double_spread=False)
|
|
project.add_page(page1)
|
|
|
|
# Add double spread (should start on page 2, which requires blank insert)
|
|
# Since page 1 is odd, a blank page should be inserted, making the spread pages 2-3
|
|
spread = Page(page_number=2, is_double_spread=True)
|
|
project.add_page(spread)
|
|
|
|
# Export to temporary file
|
|
with tempfile.NamedTemporaryFile(suffix='.pdf', delete=False) as tmp:
|
|
tmp_path = tmp.name
|
|
|
|
try:
|
|
exporter = PDFExporter(project)
|
|
success, warnings = exporter.export(tmp_path)
|
|
|
|
assert success, f"Export failed: {warnings}"
|
|
assert os.path.exists(tmp_path), "PDF file was not created"
|
|
|
|
print(f"✓ Facing pages alignment successful: {tmp_path}")
|
|
print(f" Expected: Page 1 (single), blank page, Pages 2-3 (spread)")
|
|
if warnings:
|
|
print(f" Warnings: {warnings}")
|
|
|
|
finally:
|
|
if os.path.exists(tmp_path):
|
|
os.remove(tmp_path)
|
|
|
|
|
|
def test_pdf_exporter_missing_image():
|
|
"""Test PDF export with missing image (should warn but not fail)"""
|
|
project = Project("Test Missing Image")
|
|
project.page_size_mm = (210, 297)
|
|
|
|
# Create page with image that doesn't exist
|
|
page = Page(page_number=1, is_double_spread=False)
|
|
|
|
# Add image with non-existent path
|
|
image = ImageData(
|
|
image_path="/nonexistent/path/to/image.jpg",
|
|
x=50, y=50, width=100, height=100
|
|
)
|
|
page.layout.add_element(image)
|
|
|
|
project.add_page(page)
|
|
|
|
# Export to temporary file
|
|
with tempfile.NamedTemporaryFile(suffix='.pdf', delete=False) as tmp:
|
|
tmp_path = tmp.name
|
|
|
|
try:
|
|
exporter = PDFExporter(project)
|
|
success, warnings = exporter.export(tmp_path)
|
|
|
|
assert success, "Export should succeed even with missing images"
|
|
assert len(warnings) > 0, "Should have warnings for missing image"
|
|
assert "not found" in warnings[0].lower(), "Warning should mention missing image"
|
|
|
|
print(f"✓ Missing image handling successful: {tmp_path}")
|
|
print(f" Warnings: {warnings}")
|
|
|
|
finally:
|
|
if os.path.exists(tmp_path):
|
|
os.remove(tmp_path)
|
|
|
|
|
|
def test_pdf_exporter_spanning_image():
|
|
"""Test PDF export with image spanning across center line of double spread"""
|
|
import tempfile
|
|
from PIL import Image as PILImage
|
|
|
|
project = Project("Test Spanning Image")
|
|
project.page_size_mm = (210, 297) # A4
|
|
project.working_dpi = 96 # Standard DPI
|
|
|
|
# Create a test image (solid color for easy verification)
|
|
test_img = PILImage.new('RGB', (400, 200), color='red')
|
|
|
|
# Save test image to temporary file
|
|
with tempfile.NamedTemporaryFile(suffix='.png', delete=False) as img_tmp:
|
|
img_path = img_tmp.name
|
|
test_img.save(img_path)
|
|
|
|
try:
|
|
# Create a double-page spread
|
|
spread_page = Page(page_number=1, is_double_spread=True)
|
|
|
|
# Calculate center position in pixels (for a 210mm page width at 96 DPI)
|
|
# Spread width is 2 * 210mm = 420mm
|
|
spread_width_px = 420 * 96 / 25.4 # ~1587 pixels
|
|
center_px = spread_width_px / 2 # ~794 pixels
|
|
|
|
# Add an image that spans across the center
|
|
# Position it so it overlaps the center line
|
|
image_width_px = 400
|
|
image_x_px = center_px - 200 # Start 200px before center, end 200px after
|
|
|
|
spanning_image = ImageData(
|
|
image_path=img_path,
|
|
x=image_x_px,
|
|
y=100,
|
|
width=image_width_px,
|
|
height=200
|
|
)
|
|
spread_page.layout.add_element(spanning_image)
|
|
|
|
project.add_page(spread_page)
|
|
|
|
# Export to temporary PDF
|
|
with tempfile.NamedTemporaryFile(suffix='.pdf', delete=False) as pdf_tmp:
|
|
pdf_path = pdf_tmp.name
|
|
|
|
try:
|
|
exporter = PDFExporter(project)
|
|
success, warnings = exporter.export(pdf_path)
|
|
|
|
assert success, f"Export failed: {warnings}"
|
|
assert os.path.exists(pdf_path), "PDF file was not created"
|
|
|
|
print(f"✓ Spanning image export successful: {pdf_path}")
|
|
print(f" Image spans from {image_x_px:.1f}px to {image_x_px + image_width_px:.1f}px")
|
|
print(f" Center line at {center_px:.1f}px")
|
|
if warnings:
|
|
print(f" Warnings: {warnings}")
|
|
|
|
finally:
|
|
if os.path.exists(pdf_path):
|
|
os.remove(pdf_path)
|
|
|
|
finally:
|
|
if os.path.exists(img_path):
|
|
os.remove(img_path)
|
|
|
|
|
|
def test_pdf_exporter_multiple_spanning_elements():
|
|
"""Test PDF export with multiple images spanning the center line"""
|
|
import tempfile
|
|
from PIL import Image as PILImage
|
|
|
|
project = Project("Test Multiple Spanning")
|
|
project.page_size_mm = (210, 297) # A4
|
|
project.working_dpi = 96
|
|
|
|
# Create test images
|
|
test_img1 = PILImage.new('RGB', (300, 150), color='blue')
|
|
test_img2 = PILImage.new('RGB', (250, 200), color='green')
|
|
|
|
with tempfile.NamedTemporaryFile(suffix='.png', delete=False) as img_tmp1:
|
|
img_path1 = img_tmp1.name
|
|
test_img1.save(img_path1)
|
|
|
|
with tempfile.NamedTemporaryFile(suffix='.png', delete=False) as img_tmp2:
|
|
img_path2 = img_tmp2.name
|
|
test_img2.save(img_path2)
|
|
|
|
try:
|
|
spread_page = Page(page_number=1, is_double_spread=True)
|
|
|
|
# Calculate positions
|
|
spread_width_px = 420 * 96 / 25.4
|
|
center_px = spread_width_px / 2
|
|
|
|
# First spanning image
|
|
image1 = ImageData(
|
|
image_path=img_path1,
|
|
x=center_px - 150, # Centered on split line
|
|
y=50,
|
|
width=300,
|
|
height=150
|
|
)
|
|
|
|
# Second spanning image (different position)
|
|
image2 = ImageData(
|
|
image_path=img_path2,
|
|
x=center_px - 100,
|
|
y=250,
|
|
width=250,
|
|
height=200
|
|
)
|
|
|
|
spread_page.layout.add_element(image1)
|
|
spread_page.layout.add_element(image2)
|
|
|
|
project.add_page(spread_page)
|
|
|
|
with tempfile.NamedTemporaryFile(suffix='.pdf', delete=False) as pdf_tmp:
|
|
pdf_path = pdf_tmp.name
|
|
|
|
try:
|
|
exporter = PDFExporter(project)
|
|
success, warnings = exporter.export(pdf_path)
|
|
|
|
assert success, f"Export failed: {warnings}"
|
|
assert os.path.exists(pdf_path), "PDF file was not created"
|
|
|
|
print(f"✓ Multiple spanning images export successful: {pdf_path}")
|
|
if warnings:
|
|
print(f" Warnings: {warnings}")
|
|
|
|
finally:
|
|
if os.path.exists(pdf_path):
|
|
os.remove(pdf_path)
|
|
|
|
finally:
|
|
if os.path.exists(img_path1):
|
|
os.remove(img_path1)
|
|
if os.path.exists(img_path2):
|
|
os.remove(img_path2)
|
|
|
|
|
|
def test_pdf_exporter_edge_case_barely_spanning():
|
|
"""Test image that barely crosses the threshold"""
|
|
import tempfile
|
|
from PIL import Image as PILImage
|
|
|
|
project = Project("Test Edge Case")
|
|
project.page_size_mm = (210, 297)
|
|
project.working_dpi = 96
|
|
|
|
test_img = PILImage.new('RGB', (100, 100), color='yellow')
|
|
|
|
with tempfile.NamedTemporaryFile(suffix='.png', delete=False) as img_tmp:
|
|
img_path = img_tmp.name
|
|
test_img.save(img_path)
|
|
|
|
try:
|
|
spread_page = Page(page_number=1, is_double_spread=True)
|
|
|
|
spread_width_px = 420 * 96 / 25.4
|
|
center_px = spread_width_px / 2
|
|
|
|
# Image that just barely crosses the center line
|
|
image = ImageData(
|
|
image_path=img_path,
|
|
x=center_px - 5, # Just 5px overlap
|
|
y=100,
|
|
width=100,
|
|
height=100
|
|
)
|
|
|
|
spread_page.layout.add_element(image)
|
|
project.add_page(spread_page)
|
|
|
|
with tempfile.NamedTemporaryFile(suffix='.pdf', delete=False) as pdf_tmp:
|
|
pdf_path = pdf_tmp.name
|
|
|
|
try:
|
|
exporter = PDFExporter(project)
|
|
success, warnings = exporter.export(pdf_path)
|
|
|
|
assert success, f"Export failed: {warnings}"
|
|
|
|
print(f"✓ Edge case (barely spanning) export successful: {pdf_path}")
|
|
if warnings:
|
|
print(f" Warnings: {warnings}")
|
|
|
|
finally:
|
|
if os.path.exists(pdf_path):
|
|
os.remove(pdf_path)
|
|
|
|
finally:
|
|
if os.path.exists(img_path):
|
|
os.remove(img_path)
|
|
|
|
|
|
def test_pdf_exporter_text_spanning():
|
|
"""Test text box spanning the center line"""
|
|
project = Project("Test Spanning Text")
|
|
project.page_size_mm = (210, 297)
|
|
project.working_dpi = 96
|
|
|
|
spread_page = Page(page_number=1, is_double_spread=True)
|
|
|
|
spread_width_px = 420 * 96 / 25.4
|
|
center_px = spread_width_px / 2
|
|
|
|
# Text box spanning the center
|
|
text_box = TextBoxData(
|
|
text_content="Spanning Text",
|
|
font_settings={"family": "Helvetica", "size": 24, "color": (0, 0, 0)},
|
|
alignment="center",
|
|
x=center_px - 100,
|
|
y=100,
|
|
width=200,
|
|
height=50
|
|
)
|
|
|
|
spread_page.layout.add_element(text_box)
|
|
project.add_page(spread_page)
|
|
|
|
with tempfile.NamedTemporaryFile(suffix='.pdf', delete=False) as pdf_tmp:
|
|
pdf_path = pdf_tmp.name
|
|
|
|
try:
|
|
exporter = PDFExporter(project)
|
|
success, warnings = exporter.export(pdf_path)
|
|
|
|
assert success, f"Export failed: {warnings}"
|
|
|
|
print(f"✓ Spanning text box export successful: {pdf_path}")
|
|
if warnings:
|
|
print(f" Warnings: {warnings}")
|
|
|
|
finally:
|
|
if os.path.exists(pdf_path):
|
|
os.remove(pdf_path)
|
|
|
|
|
|
def test_pdf_exporter_spanning_image_aspect_ratio():
|
|
"""Test that spanning images maintain correct aspect ratio and can be recombined"""
|
|
import tempfile
|
|
from PIL import Image as PILImage, ImageDraw
|
|
|
|
project = Project("Test Aspect Ratio")
|
|
project.page_size_mm = (210, 297) # A4
|
|
project.working_dpi = 96
|
|
|
|
# Create a distinctive test image: red left half, blue right half, with a vertical line in center
|
|
test_width, test_height = 800, 400
|
|
test_img = PILImage.new('RGB', (test_width, test_height))
|
|
draw = ImageDraw.Draw(test_img)
|
|
|
|
# Fill left half red
|
|
draw.rectangle([0, 0, test_width // 2, test_height], fill=(255, 0, 0))
|
|
|
|
# Fill right half blue
|
|
draw.rectangle([test_width // 2, 0, test_width, test_height], fill=(0, 0, 255))
|
|
|
|
# Draw a black vertical line in the middle
|
|
draw.line([test_width // 2, 0, test_width // 2, test_height], fill=(0, 0, 0), width=5)
|
|
|
|
# Draw horizontal reference lines for visual verification
|
|
for y in range(0, test_height, 50):
|
|
draw.line([0, y, test_width, y], fill=(255, 255, 255), width=2)
|
|
|
|
# Save test image to temporary file
|
|
with tempfile.NamedTemporaryFile(suffix='.png', delete=False) as img_tmp:
|
|
img_path = img_tmp.name
|
|
test_img.save(img_path)
|
|
|
|
try:
|
|
# Create a double-page spread
|
|
spread_page = Page(page_number=1, is_double_spread=True)
|
|
|
|
# Calculate positions
|
|
spread_width_px = 420 * 96 / 25.4 # ~1587 pixels
|
|
center_px = spread_width_px / 2 # ~794 pixels
|
|
|
|
# Create an image element that spans the center with a specific aspect ratio
|
|
# Make it 600px wide and 300px tall (2:1 aspect ratio)
|
|
image_width_px = 600
|
|
image_height_px = 300
|
|
image_x_px = center_px - 300 # Centered on the split line
|
|
|
|
spanning_image = ImageData(
|
|
image_path=img_path,
|
|
x=image_x_px,
|
|
y=100,
|
|
width=image_width_px,
|
|
height=image_height_px
|
|
)
|
|
spread_page.layout.add_element(spanning_image)
|
|
|
|
project.add_page(spread_page)
|
|
|
|
# Export to temporary PDF
|
|
with tempfile.NamedTemporaryFile(suffix='.pdf', delete=False) as pdf_tmp:
|
|
pdf_path = pdf_tmp.name
|
|
|
|
try:
|
|
exporter = PDFExporter(project)
|
|
success, warnings = exporter.export(pdf_path)
|
|
|
|
assert success, f"Export failed: {warnings}"
|
|
assert os.path.exists(pdf_path), "PDF file was not created"
|
|
|
|
# Verify the PDF was created and has expected properties
|
|
# We can't easily extract and verify pixel-perfect image reconstruction without
|
|
# additional dependencies, but we can verify the export succeeded
|
|
file_size = os.path.getsize(pdf_path)
|
|
assert file_size > 1000, "PDF file seems too small"
|
|
|
|
print(f"✓ Spanning image aspect ratio test successful: {pdf_path}")
|
|
print(f" Original image: {test_width}x{test_height} (aspect {test_width/test_height:.2f}:1)")
|
|
print(f" Element size: {image_width_px}x{image_height_px} (aspect {image_width_px/image_height_px:.2f}:1)")
|
|
print(f" Split at: {center_px:.1f}px")
|
|
print(f" Left portion: {center_px - image_x_px:.1f}px wide")
|
|
print(f" Right portion: {image_width_px - (center_px - image_x_px):.1f}px wide")
|
|
print(f" PDF size: {file_size} bytes")
|
|
|
|
if warnings:
|
|
print(f" Warnings: {warnings}")
|
|
|
|
finally:
|
|
if os.path.exists(pdf_path):
|
|
os.remove(pdf_path)
|
|
|
|
finally:
|
|
if os.path.exists(img_path):
|
|
os.remove(img_path)
|
|
|
|
|
|
def test_pdf_exporter_varying_aspect_ratios():
|
|
"""Test spanning images with various aspect ratios"""
|
|
import tempfile
|
|
from PIL import Image as PILImage, ImageDraw
|
|
|
|
project = Project("Test Varying Aspects")
|
|
project.page_size_mm = (210, 297)
|
|
project.working_dpi = 96
|
|
|
|
# Test different aspect ratios
|
|
test_configs = [
|
|
("Square", 400, 400), # 1:1
|
|
("Landscape", 800, 400), # 2:1
|
|
("Portrait", 400, 800), # 1:2
|
|
("Wide", 1200, 400), # 3:1
|
|
]
|
|
|
|
spread_width_px = 420 * 96 / 25.4
|
|
center_px = spread_width_px / 2
|
|
|
|
for idx, (name, img_w, img_h) in enumerate(test_configs):
|
|
# Create test image
|
|
test_img = PILImage.new('RGB', (img_w, img_h))
|
|
draw = ImageDraw.Draw(test_img)
|
|
|
|
# Different colors for each test
|
|
colors = [(255, 0, 0), (0, 255, 0), (0, 0, 255), (255, 255, 0)]
|
|
draw.rectangle([0, 0, img_w // 2, img_h], fill=colors[idx])
|
|
draw.rectangle([img_w // 2, 0, img_w, img_h], fill=(255-colors[idx][0], 255-colors[idx][1], 255-colors[idx][2]))
|
|
|
|
with tempfile.NamedTemporaryFile(suffix='.png', delete=False) as img_tmp:
|
|
img_path = img_tmp.name
|
|
test_img.save(img_path)
|
|
|
|
try:
|
|
spread_page = Page(page_number=idx + 1, is_double_spread=True)
|
|
|
|
# Position spanning element
|
|
element_width_px = 500
|
|
element_height_px = int(500 * img_h / img_w) # Maintain aspect ratio
|
|
|
|
spanning_image = ImageData(
|
|
image_path=img_path,
|
|
x=center_px - 250,
|
|
y=100 + idx * 200,
|
|
width=element_width_px,
|
|
height=element_height_px
|
|
)
|
|
spread_page.layout.add_element(spanning_image)
|
|
|
|
project.add_page(spread_page)
|
|
|
|
finally:
|
|
if os.path.exists(img_path):
|
|
os.remove(img_path)
|
|
|
|
# Export all pages
|
|
with tempfile.NamedTemporaryFile(suffix='.pdf', delete=False) as pdf_tmp:
|
|
pdf_path = pdf_tmp.name
|
|
|
|
try:
|
|
exporter = PDFExporter(project)
|
|
success, warnings = exporter.export(pdf_path)
|
|
|
|
assert success, f"Export failed: {warnings}"
|
|
assert os.path.exists(pdf_path), "PDF file was not created"
|
|
|
|
print(f"✓ Varying aspect ratios test successful: {pdf_path}")
|
|
print(f" Tested {len(test_configs)} different aspect ratios")
|
|
if warnings:
|
|
print(f" Warnings: {warnings}")
|
|
|
|
finally:
|
|
if os.path.exists(pdf_path):
|
|
os.remove(pdf_path)
|
|
|
|
|
|
def test_pdf_exporter_image_downsampling():
|
|
"""Test that export DPI controls image downsampling and reduces file size"""
|
|
import tempfile
|
|
from PIL import Image as PILImage
|
|
|
|
project = Project("Test Downsampling")
|
|
project.page_size_mm = (210, 297) # A4
|
|
project.working_dpi = 96
|
|
|
|
# Create a large test image (4000x3000 - typical high-res camera)
|
|
large_img = PILImage.new('RGB', (4000, 3000))
|
|
# Add some pattern so it doesn't compress too much
|
|
import random
|
|
pixels = large_img.load()
|
|
for i in range(0, 4000, 10):
|
|
for j in range(0, 3000, 10):
|
|
pixels[i, j] = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
|
|
|
|
with tempfile.NamedTemporaryFile(suffix='.png', delete=False) as img_tmp:
|
|
img_path = img_tmp.name
|
|
large_img.save(img_path)
|
|
|
|
try:
|
|
# Create a page with the large image
|
|
page = Page(page_number=1, is_double_spread=False)
|
|
|
|
# Add image at reasonable size (100mm x 75mm)
|
|
image = ImageData(
|
|
image_path=img_path,
|
|
x=50,
|
|
y=50,
|
|
width=int(100 * 96 / 25.4), # ~378 px
|
|
height=int(75 * 96 / 25.4) # ~283 px
|
|
)
|
|
page.layout.add_element(image)
|
|
project.add_page(page)
|
|
|
|
# Export with high DPI (300 - print quality)
|
|
with tempfile.NamedTemporaryFile(suffix='.pdf', delete=False) as pdf_tmp1:
|
|
pdf_path_300dpi = pdf_tmp1.name
|
|
|
|
# Export with low DPI (150 - screen quality)
|
|
with tempfile.NamedTemporaryFile(suffix='.pdf', delete=False) as pdf_tmp2:
|
|
pdf_path_150dpi = pdf_tmp2.name
|
|
|
|
try:
|
|
# Export at 300 DPI
|
|
exporter_300 = PDFExporter(project, export_dpi=300)
|
|
success1, warnings1 = exporter_300.export(pdf_path_300dpi)
|
|
assert success1, f"300 DPI export failed: {warnings1}"
|
|
|
|
# Export at 150 DPI
|
|
exporter_150 = PDFExporter(project, export_dpi=150)
|
|
success2, warnings2 = exporter_150.export(pdf_path_150dpi)
|
|
assert success2, f"150 DPI export failed: {warnings2}"
|
|
|
|
# Check file sizes
|
|
size_300dpi = os.path.getsize(pdf_path_300dpi)
|
|
size_150dpi = os.path.getsize(pdf_path_150dpi)
|
|
|
|
print(f"✓ Image downsampling test successful:")
|
|
print(f" Original image: 4000x3000 pixels")
|
|
print(f" Element size: 100mm x 75mm")
|
|
print(f" PDF at 300 DPI: {size_300dpi:,} bytes")
|
|
print(f" PDF at 150 DPI: {size_150dpi:,} bytes")
|
|
print(f" Size reduction: {(1 - size_150dpi/size_300dpi)*100:.1f}%")
|
|
|
|
# 150 DPI should be smaller than 300 DPI
|
|
assert size_150dpi < size_300dpi, \
|
|
f"150 DPI file ({size_150dpi}) should be smaller than 300 DPI file ({size_300dpi})"
|
|
|
|
# 150 DPI should be significantly smaller (at least 50% reduction)
|
|
reduction_ratio = size_150dpi / size_300dpi
|
|
assert reduction_ratio < 0.7, \
|
|
f"150 DPI should be at least 30% smaller, got {(1-reduction_ratio)*100:.1f}%"
|
|
|
|
finally:
|
|
if os.path.exists(pdf_path_300dpi):
|
|
os.remove(pdf_path_300dpi)
|
|
if os.path.exists(pdf_path_150dpi):
|
|
os.remove(pdf_path_150dpi)
|
|
|
|
finally:
|
|
if os.path.exists(img_path):
|
|
os.remove(img_path)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
print("Running PDF export tests...\n")
|
|
|
|
try:
|
|
test_pdf_exporter_basic()
|
|
test_pdf_exporter_double_spread()
|
|
test_pdf_exporter_with_text()
|
|
test_pdf_exporter_facing_pages_alignment()
|
|
test_pdf_exporter_missing_image()
|
|
test_pdf_exporter_spanning_image()
|
|
test_pdf_exporter_multiple_spanning_elements()
|
|
test_pdf_exporter_edge_case_barely_spanning()
|
|
test_pdf_exporter_text_spanning()
|
|
test_pdf_exporter_spanning_image_aspect_ratio()
|
|
test_pdf_exporter_varying_aspect_ratios()
|
|
test_pdf_exporter_image_downsampling()
|
|
|
|
print("\n✓ All tests passed!")
|
|
|
|
except AssertionError as e:
|
|
print(f"\n✗ Test failed: {e}")
|
|
raise
|
|
except Exception as e:
|
|
print(f"\n✗ Unexpected error: {e}")
|
|
raise
|