import io from pathlib import Path from PIL import Image, ImageDraw from logimage.infrastructure.image.pillow_converter import PillowImageConverter from logimage.infrastructure.image.local_file_source import LocalFileImageSource from tests.helpers import count_blocks def _make_icon_bytes() -> bytes: """Maison simple : rectangle + triangle sur fond blanc.""" img = Image.new("RGB", (100, 100), color=(255, 255, 255)) draw = ImageDraw.Draw(img) # Corps de la maison draw.rectangle([25, 50, 75, 90], fill=(0, 0, 0)) # Toit (triangle approximatif) draw.polygon([(50, 10), (20, 50), (80, 50)], fill=(0, 0, 0)) buf = io.BytesIO() img.save(buf, format="PNG") return buf.getvalue() def test_house_icon_produces_playable_grid() -> None: """Une icône maison simple doit donner une grille jouable (≤ 6 blocs).""" converter = PillowImageConverter(max_clue_blocks=6) grid = converter.to_grid(_make_icon_bytes(), width=20, height=20) for i in range(grid.height): blocks = count_blocks(grid.row(i)) assert blocks <= 6, f"Ligne {i} a {blocks} blocs" for j in range(grid.width): blocks = count_blocks(grid.col(j)) assert blocks <= 6, f"Colonne {j} a {blocks} blocs" def test_local_source_feeds_converter(tmp_path: Path) -> None: """LocalFileImageSource + PillowImageConverter produisent une grille valide.""" icon_path = tmp_path / "house.png" icon_path.write_bytes(_make_icon_bytes()) source = LocalFileImageSource(icon_path) image_data = source.fetch() converter = PillowImageConverter(max_clue_blocks=6) grid = converter.to_grid(image_data.content, width=15, height=15) assert len(image_data.content) > 0 assert grid.width == 15 assert grid.height == 15 total_filled = sum(cell for r in range(grid.height) for cell in grid.row(r)) assert total_filled > 0, "Pipeline should produce some filled cells for house icon"