"""Tests d'extraction des couleurs de têtes de minifigs.""" import csv from pathlib import Path from lib.rebrickable.colors_by_set import build_colors_lookup from lib.rebrickable.minifig_heads import ( aggregate_head_colors_by_set, aggregate_head_colors_by_year, build_head_part_set, load_parts_filtered, write_head_colors_by_set, write_head_colors_by_year, ) def write_csv(path: Path, headers: list[str], rows: list[list[str]]) -> None: """Écrit un CSV simple pour les besoins des tests.""" with path.open("w", newline="") as csv_file: writer = csv.writer(csv_file) writer.writerow(headers) writer.writerows(rows) def test_extract_minifig_heads_and_colors(tmp_path: Path) -> None: """Filtre les têtes de minifigs, agrège par set puis par année.""" parts_filtered = tmp_path / "parts_filtered.csv" parts_catalog = tmp_path / "parts.csv" colors_path = tmp_path / "colors.csv" heads_by_set_path = tmp_path / "heads_by_set.csv" heads_by_year_path = tmp_path / "heads_by_year.csv" write_csv( parts_filtered, [ "part_num", "color_rgb", "is_translucent", "set_num", "set_id", "year", "quantity_in_set", "is_spare", "is_minifig_part", ], [ ["3626b", "FFE1BD", "false", "1000-1", "1000", "2020", "1", "false", "true"], ["3626bpr1", "E7B68F", "false", "1000-1", "1000", "2020", "1", "false", "true"], ["3001", "FFFFFF", "false", "1000-1", "1000", "2020", "2", "false", "false"], ["3626b", "FFE1BD", "false", "2000-1", "2000", "2021", "2", "false", "true"], ["3626b", "FFE1BD", "false", "2000-1", "2000", "2021", "1", "true", "true"], ["3626b", "0033B2", "false", "2000-1", "2000", "2021", "1", "false", "true"], ], ) write_csv( parts_catalog, ["part_num", "name", "part_cat_id", "part_material"], [ ["3626b", "Minifig Head", "59", "Plastic"], ["3626bpr1", "Minifig Head with Print", "59", "Plastic"], ["3001", "Brick 2 x 4", "11", "Plastic"], ], ) write_csv( colors_path, ["id", "name", "rgb", "is_trans", "num_parts", "num_sets", "y1", "y2"], [ ["1", "Light Flesh", "FFE1BD", "False", "0", "0", "0", "0"], ["2", "Medium Dark Flesh", "E7B68F", "False", "0", "0", "0", "0"], ["3", "White", "FFFFFF", "False", "0", "0", "0", "0"], ["4", "Ignored Blue", "0033B2", "False", "0", "0", "0", "0"], ], ) parts_rows = load_parts_filtered(parts_filtered) head_parts = build_head_part_set(parts_catalog) colors_lookup = build_colors_lookup(colors_path) heads_by_set = aggregate_head_colors_by_set(parts_rows, head_parts, colors_lookup) heads_by_year = aggregate_head_colors_by_year(heads_by_set) write_head_colors_by_set(heads_by_set_path, heads_by_set) write_head_colors_by_year(heads_by_year_path, heads_by_year) with heads_by_set_path.open() as csv_file: rows_by_set = list(csv.DictReader(csv_file)) with heads_by_year_path.open() as csv_file: rows_by_year = list(csv.DictReader(csv_file)) assert rows_by_set == [ { "set_num": "1000-1", "set_id": "1000", "year": "2020", "color_rgb": "FFE1BD", "is_translucent": "false", "color_name": "Light Flesh", "quantity": "1", }, { "set_num": "1000-1", "set_id": "1000", "year": "2020", "color_rgb": "E7B68F", "is_translucent": "false", "color_name": "Medium Dark Flesh", "quantity": "1", }, { "set_num": "2000-1", "set_id": "2000", "year": "2021", "color_rgb": "FFE1BD", "is_translucent": "false", "color_name": "Light Flesh", "quantity": "2", }, ] assert rows_by_year == [ { "year": "2020", "color_rgb": "FFE1BD", "is_translucent": "false", "color_name": "Light Flesh", "quantity": "1", }, { "year": "2020", "color_rgb": "E7B68F", "is_translucent": "false", "color_name": "Medium Dark Flesh", "quantity": "1", }, { "year": "2021", "color_rgb": "FFE1BD", "is_translucent": "false", "color_name": "Light Flesh", "quantity": "2", }, ]