"""Tests des têtes dual-face.""" import csv from pathlib import Path from lib.rebrickable.minifig_head_faces import ( aggregate_by_character, aggregate_by_set, aggregate_by_year, build_head_faces, detect_dual_face, ) def write_csv(path: Path, headers: list[str], rows: list[list[str]]) -> None: """Écrit un CSV simple pour les besoins de tests.""" with path.open("w", newline="") as csv_file: writer = csv.writer(csv_file) writer.writerow(headers) writer.writerows(rows) def test_detect_dual_face_matches_keywords() -> None: """Reconnaît les mentions dual-face dans le nom.""" assert detect_dual_face("Minifig Head Dual Sided Smile") == "true" assert detect_dual_face("Minifig Head w/ Alt Face") == "true" assert detect_dual_face("Minifig Head Angry") == "false" def test_build_head_faces_and_aggregates(tmp_path: Path) -> None: """Construit l'annotation dual-face puis agrège par set/année/personnage.""" minifigs_by_set = tmp_path / "minifigs_by_set.csv" write_csv( minifigs_by_set, ["set_num", "part_num", "known_character", "fig_num", "gender"], [ ["1000-1", "p1", "Alice", "fig-1", "female"], ["1000-1", "p2", "Bob", "fig-2", "male"], ["2000-1", "p1", "Alice", "fig-1", "female"], ], ) parts_catalog = tmp_path / "parts.csv" write_csv( parts_catalog, ["part_num", "name", "part_cat_id"], [ ["p1", "Minifig Head Dual Sided Grin", "59"], ["p2", "Minifig Head Serious", "59"], ], ) sets_enriched = tmp_path / "sets_enriched.csv" write_csv( sets_enriched, ["set_num", "set_id", "name", "year", "in_collection"], [ ["1000-1", "1000", "Set A", "2020", "true"], ["2000-1", "2000", "Set B", "2021", "false"], ], ) heads = build_head_faces(minifigs_by_set, parts_catalog, sets_enriched) by_year = aggregate_by_year(heads) by_set = aggregate_by_set(heads) by_character = aggregate_by_character(heads) assert heads == [ { "set_num": "1000-1", "set_id": "1000", "year": "2020", "name": "Set A", "in_collection": "true", "part_num": "p1", "part_name": "Minifig Head Dual Sided Grin", "fig_num": "fig-1", "known_character": "Alice", "gender": "female", "is_dual_face": "true", }, { "set_num": "1000-1", "set_id": "1000", "year": "2020", "name": "Set A", "in_collection": "true", "part_num": "p2", "part_name": "Minifig Head Serious", "fig_num": "fig-2", "known_character": "Bob", "gender": "male", "is_dual_face": "false", }, { "set_num": "2000-1", "set_id": "2000", "year": "2021", "name": "Set B", "in_collection": "false", "part_num": "p1", "part_name": "Minifig Head Dual Sided Grin", "fig_num": "fig-1", "known_character": "Alice", "gender": "female", "is_dual_face": "true", }, ] assert by_year == [ {"year": "2020", "total_heads": "2", "dual_heads": "1", "share_dual": "0.5000"}, {"year": "2021", "total_heads": "1", "dual_heads": "1", "share_dual": "1.0000"}, ] assert by_set == [ { "set_num": "2000-1", "set_id": "2000", "name": "Set B", "year": "2021", "in_collection": "false", "total_heads": "1", "dual_heads": "1", "share_dual": "1.0000", }, { "set_num": "1000-1", "set_id": "1000", "name": "Set A", "year": "2020", "in_collection": "true", "total_heads": "2", "dual_heads": "1", "share_dual": "0.5000", }, ] assert by_character == [ { "known_character": "Alice", "gender": "female", "total_heads": "2", "dual_heads": "2", "share_dual": "1.0000", }, { "known_character": "Bob", "gender": "male", "total_heads": "1", "dual_heads": "0", "share_dual": "0.0000", }, ]