"""Tests des frises chronologiques de minifigs par personnage.""" from pathlib import Path from PIL import Image from lib.plots.minifig_character_collages import build_character_collages from lib.rebrickable.minifig_character_sets import build_character_sets, group_by_character from lib.rebrickable.resources import sanitize_name def create_image(path: Path, color: tuple[int, int, int], size: tuple[int, int]) -> None: """Crée une image unie pour les besoins de tests.""" path.parent.mkdir(parents=True, exist_ok=True) Image.new("RGB", size, color).save(path) def test_build_character_sets_and_collages(tmp_path: Path) -> None: """Construit les apparitions par personnage puis les frises associées.""" minifigs_rows = [ {"set_num": "1000-1", "known_character": "Alice", "fig_num": "fig-1"}, {"set_num": "1000-1", "known_character": "Alice", "fig_num": "fig-1"}, {"set_num": "1001-1", "known_character": "Bob", "fig_num": "fig-2"}, {"set_num": "1002-1", "known_character": "Bob", "fig_num": "fig-3"}, {"set_num": "1004-1", "known_character": "Claire Dearing", "fig_num": "fig-5"}, {"set_num": "1003-1", "known_character": "Figurant", "fig_num": "fig-4"}, ] sets_lookup = { "1000-1": {"set_id": "1000", "year": "2020", "in_collection": "true"}, "1001-1": {"set_id": "1001", "year": "2021", "in_collection": "false"}, "1002-1": {"set_id": "1002", "year": "2022", "in_collection": "false"}, "1003-1": {"set_id": "1003", "year": "2023", "in_collection": "false"}, "1004-1": {"set_id": "1004", "year": "2024", "in_collection": "true"}, } character_sets = build_character_sets(minifigs_rows, sets_lookup, excluded_characters=["Figurant"]) assert character_sets == [ { "known_character": "Alice", "set_num": "1000-1", "set_id": "1000", "year": "2020", "fig_num": "fig-1", "in_collection": "true", }, { "known_character": "Bob", "set_num": "1001-1", "set_id": "1001", "year": "2021", "fig_num": "fig-2", "in_collection": "false", }, { "known_character": "Bob", "set_num": "1002-1", "set_id": "1002", "year": "2022", "fig_num": "fig-3", "in_collection": "false", }, { "known_character": "Claire Dearing", "set_num": "1004-1", "set_id": "1004", "year": "2024", "fig_num": "fig-5", "in_collection": "true", }, ] resources_dir = tmp_path / "resources" for entry in character_sets: image_path = resources_dir / entry["set_id"] / sanitize_name(entry["known_character"]) / "minifig.jpg" if "Claire" in entry["known_character"]: continue create_image(image_path, (120, 80, 60), (10, 10)) destination_dir = tmp_path / "output" missing_minifigs = { str(resources_dir / "1004" / sanitize_name("Claire Dearing") / "minifig.jpg"), } generated = build_character_collages( group_by_character(character_sets), resources_dir, destination_dir, missing_paths=missing_minifigs, image_filename="minifig.jpg", image_height=20, label_height=10, spacing=2, ) assert len(generated) == 3 alice = Image.open(destination_dir / f"{sanitize_name('Alice')}.png") bob = Image.open(destination_dir / f"{sanitize_name('Bob')}.png") claire = Image.open(destination_dir / f"{sanitize_name('Claire Dearing')}.png") assert alice.size == (20, 30) assert bob.size == (42, 30) assert claire.size == (20, 30) assert claire.getpixel((5, 10)) == (220, 220, 220) # Variante sur les têtes : utilise un autre fichier et un autre manque. heads_destination = tmp_path / "output_heads" head_missing = { str(resources_dir / "1001" / sanitize_name("Bob") / "head.jpg"), str(resources_dir / "1002" / sanitize_name("Bob") / "head.jpg"), str(resources_dir / "1004" / sanitize_name("Claire Dearing") / "head.jpg"), } head_image = resources_dir / "1000" / sanitize_name("Alice") / "head.jpg" create_image(head_image, (10, 120, 60), (8, 12)) head_collages = build_character_collages( group_by_character(character_sets), resources_dir, heads_destination, missing_paths=head_missing, image_filename="head.jpg", image_height=16, label_height=8, spacing=2, ) assert len(head_collages) == 3 alice_head = Image.open(heads_destination / f"{sanitize_name('Alice')}.png") bob_head = Image.open(heads_destination / f"{sanitize_name('Bob')}.png") assert alice_head.size[1] == 24 assert bob_head.getpixel((3, 8)) == (220, 220, 220)