"""Tests du calcul de réutilisation des têtes de minifigs.""" import csv from pathlib import Path from lib.rebrickable.head_reuse import aggregate_head_reuse, build_head_presence from lib.rebrickable.minifigs_by_set import load_parts_catalog, select_head_parts def write_csv(path: Path, headers: list[str], rows: list[list[str]]) -> None: """Écrit un petit CSV pour les tests.""" path.parent.mkdir(parents=True, exist_ok=True) with path.open("w", newline="") as csv_file: writer = csv.writer(csv_file) writer.writerow(headers) writer.writerows(rows) def test_head_reuse_counts_sets_and_catalog(tmp_path: Path) -> None: """Compte les usages des têtes filtrées versus reste du catalogue.""" minifigs_by_set = tmp_path / "minifigs_by_set.csv" write_csv( minifigs_by_set, ["set_num", "part_num", "known_character", "fig_num", "gender"], [ ["s1-1", "p1", "Alice", "fig-1", "female"], ["s2-1", "p2", "Bob", "fig-2", "male"], ["s1-1", "p2", "Bob", "fig-2", "male"], ], ) parts_catalog = tmp_path / "parts.csv" write_csv( parts_catalog, ["part_num", "name", "part_cat_id"], [ ["p1", "Head 1", "59"], ["p2", "Head 2", "59"], ["x1", "Other", "1"], ], ) inventories = tmp_path / "inventories.csv" write_csv( inventories, ["id", "version", "set_num"], [ ["i1", "1", "s1-1"], ["i2", "1", "s2-1"], ["i3", "1", "s3-1"], ["i4", "1", "s4-1"], ], ) inventory_parts = tmp_path / "inventory_parts.csv" write_csv( inventory_parts, ["inventory_id", "part_num", "color_id", "quantity", "is_spare"], [ ["i1", "p1", "1", "1", "false"], ["i2", "p2", "1", "1", "false"], ["i3", "p2", "1", "1", "false"], ["i4", "p2", "1", "1", "true"], ["i4", "x1", "1", "1", "false"], ], ) head_parts = select_head_parts(load_parts_catalog(parts_catalog)) presence = build_head_presence(inventories, inventory_parts, head_parts) reuse = aggregate_head_reuse( [ {"set_num": "s1-1", "part_num": "p1", "known_character": "Alice", "fig_num": "fig-1"}, {"set_num": "s2-1", "part_num": "p2", "known_character": "Bob", "fig_num": "fig-2"}, {"set_num": "s1-1", "part_num": "p2", "known_character": "Bob", "fig_num": "fig-2"}, ], load_parts_catalog(parts_catalog), presence, { "s1-1": {"set_id": "s1"}, "s2-1": {"set_id": "s2"}, "s3-1": {"set_id": "s3"}, "s4-1": {"set_id": "s4"}, }, ) assert reuse == [ { "part_num": "p1", "part_name": "Head 1", "known_character": "Alice", "sample_set_id": "s1", "filtered_sets": "1", "other_sets": "0", "total_sets": "1", }, { "part_num": "p2", "part_name": "Head 2", "known_character": "Bob", "sample_set_id": "s1", "filtered_sets": "2", "other_sets": "1", "total_sets": "3", }, ]