1
etude_lego_jurassic_world/tests/test_minifig_character_collages.py

131 lines
5.1 KiB
Python

"""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", "part_num": "p1"},
{"set_num": "1000-1", "known_character": "Alice", "fig_num": "fig-1", "part_num": "p1"},
{"set_num": "1001-1", "known_character": "Bob", "fig_num": "fig-2", "part_num": "p2"},
{"set_num": "1002-1", "known_character": "Bob", "fig_num": "fig-3", "part_num": "p3"},
{"set_num": "1004-1", "known_character": "Claire Dearing", "fig_num": "fig-5", "part_num": "p5"},
{"set_num": "1003-1", "known_character": "Figurant", "fig_num": "fig-4", "part_num": "p4"},
]
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",
"part_num": "p1",
},
{
"known_character": "Bob",
"set_num": "1001-1",
"set_id": "1001",
"year": "2021",
"fig_num": "fig-2",
"in_collection": "false",
"part_num": "p2",
},
{
"known_character": "Bob",
"set_num": "1002-1",
"set_id": "1002",
"year": "2022",
"fig_num": "fig-3",
"in_collection": "false",
"part_num": "p3",
},
{
"known_character": "Claire Dearing",
"set_num": "1004-1",
"set_id": "1004",
"year": "2024",
"fig_num": "fig-5",
"in_collection": "true",
"part_num": "p5",
},
]
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)