Spaces:
Runtime error
Runtime error
File size: 4,557 Bytes
2857cf3 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | from __future__ import annotations
from io import StringIO
from pathlib import Path
from PIL import Image
import pytest
from rich.console import Console
from typer.testing import CliRunner
import kneiff.cli.image as cli_image
from kneiff.utils.image import concat as concat_utils
from kneiff.utils.image import png2jpg as png2jpg_utils
from kneiff.progress import ProgressUpdate
from tests._cli_helpers import invoke_cli
def test_png2jpg_composites_alpha_and_writes_subdirectory(tmp_path: Path) -> None:
"""Cover PNG alpha handling and destination routing."""
image_path = tmp_path / "source.png"
image = Image.new("RGBA", (2, 1), color=(255, 0, 0, 128))
image.save(image_path)
exit_code = png2jpg_utils.png2jpg(
tmp_path,
out_subdir="jpg",
quality=95,
subsampling=0,
bg="#ffffff",
)
jpg_path = tmp_path / "jpg" / "source.jpg"
assert exit_code == 0
assert jpg_path.exists()
with Image.open(jpg_path) as converted:
assert converted.mode == "RGB"
red, green, blue = converted.getpixel((0, 0))
assert red > green
assert red > blue
def test_png2jpg_dry_run_does_not_write_files(tmp_path: Path) -> None:
"""Ensure dry-run mode reports success without touching output."""
image_path = tmp_path / "source.png"
Image.new("RGB", (2, 1), color="red").save(image_path)
exit_code = png2jpg_utils.png2jpg(tmp_path, dry_run=True)
assert exit_code == 0
assert not (tmp_path / "jpg" / "source.jpg").exists()
def test_convert_png_jobs_reports_every_status_and_progress(tmp_path: Path) -> None:
converted_source = tmp_path / "converted.png"
skipped_source = tmp_path / "skipped.png"
other_source = tmp_path / "other.png"
for path in (converted_source, skipped_source, other_source):
Image.new("RGB", (2, 1), color="red").save(path)
jobs = png2jpg_utils.discover_png_conversion_jobs(tmp_path, out_subdir="jpg")
skipped_output = tmp_path / "jpg" / "skipped.jpg"
skipped_output.parent.mkdir()
Image.new("RGB", (2, 1), color="blue").save(skipped_output)
updates: list[ProgressUpdate] = []
results = png2jpg_utils.convert_png_jobs(
jobs,
quality=95,
subsampling=0,
bg_rgb=(255, 255, 255),
overwrite=False,
dry_run=False,
progress_callback=updates.append,
)
assert [result.status for result in results] == [
"converted",
"converted",
"skipped",
]
assert len(updates) == 3
assert sum(update.advance for update in updates) == 3
def test_img_png2jpg_redirected_output_keeps_legacy_lines(
tmp_path: Path,
isolated_cli_project: Path,
) -> None:
del isolated_cli_project
source = tmp_path / "source.png"
Image.new("RGB", (2, 1), color="red").save(source)
result = invoke_cli(CliRunner(), ["img", "png2jpg", str(tmp_path)])
assert result.exit_code == 0, result.output
assert f"[ok] {source} -> {tmp_path / 'jpg' / 'source.jpg'}" in result.output
assert "\x1b[" not in result.output
def test_img_png2jpg_terminal_replaces_item_lines_with_progress(
monkeypatch: pytest.MonkeyPatch,
tmp_path: Path,
isolated_cli_project: Path,
) -> None:
del isolated_cli_project
source = tmp_path / "source.png"
Image.new("RGB", (2, 1), color="red").save(source)
terminal_output = StringIO()
console = Console(
file=terminal_output,
force_terminal=True,
color_system=None,
width=100,
)
monkeypatch.setattr(cli_image, "stderr_progress_console", lambda: console)
result = invoke_cli(CliRunner(), ["img", "png2jpg", str(tmp_path)])
assert result.exit_code == 0, result.output
assert "[ok]" not in result.output
assert "PNG conversion complete" in terminal_output.getvalue()
assert "1/1" in terminal_output.getvalue()
def test_concat_imgs_scales_to_exact_width(tmp_path: Path) -> None:
"""Cover horizontal stacking and rounding drift correction."""
left = tmp_path / "left.png"
right = tmp_path / "right.png"
output = tmp_path / "collage.png"
Image.new("RGBA", (10, 5), color=(255, 0, 0, 255)).save(left)
Image.new("RGBA", (20, 10), color=(0, 255, 0, 255)).save(right)
result = concat_utils.concat_imgs(
[left, right],
output=output,
width=33,
gap=3,
bg="transparent",
align="bottom",
)
assert result == output
with Image.open(output) as collage:
assert collage.size == (33, 10)
|