170 lines
5.3 KiB
Python
170 lines
5.3 KiB
Python
"""Tests du calcul des pièces rares."""
|
||
|
||
import csv
|
||
from pathlib import Path
|
||
|
||
from lib.rebrickable.rare_parts import build_rare_parts, write_rare_parts_by_set, write_rare_parts_list
|
||
|
||
|
||
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_build_rare_parts_detects_exclusive_variations(tmp_path: Path) -> None:
|
||
"""Identifie les combinaisons pièce+couleur présentes dans un seul set."""
|
||
parts_filtered = tmp_path / "parts_filtered.csv"
|
||
write_csv(
|
||
parts_filtered,
|
||
[
|
||
"part_num",
|
||
"color_rgb",
|
||
"is_translucent",
|
||
"set_num",
|
||
"set_id",
|
||
"year",
|
||
"quantity_in_set",
|
||
"is_spare",
|
||
"is_minifig_part",
|
||
],
|
||
[
|
||
["p1", "AAAAAA", "false", "1000-1", "1000", "2020", "2", "false", "false"],
|
||
["p1", "AAAAAA", "false", "2000-1", "2000", "2021", "3", "false", "false"],
|
||
["p2", "BBBBBB", "false", "1000-1", "1000", "2020", "1", "false", "true"],
|
||
["p3", "CCCCCC", "true", "2000-1", "2000", "2021", "4", "false", "false"],
|
||
],
|
||
)
|
||
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"],
|
||
],
|
||
)
|
||
parts_catalog = tmp_path / "parts.csv"
|
||
write_csv(
|
||
parts_catalog,
|
||
["part_num", "name", "part_cat_id"],
|
||
[
|
||
["p1", "Brick 1x1", "1"],
|
||
["p2", "Head Custom", "59"],
|
||
["p3", "Slope 45", "2"],
|
||
],
|
||
)
|
||
colors = tmp_path / "colors.csv"
|
||
write_csv(
|
||
colors,
|
||
["id", "name", "rgb", "is_trans", "num_parts", "num_sets", "y1", "y2"],
|
||
[
|
||
["1", "Gray", "AAAAAA", "false", "0", "0", "0", "0"],
|
||
["2", "Blue", "BBBBBB", "false", "0", "0", "0", "0"],
|
||
["3", "Trans-Clear", "CCCCCC", "true", "0", "0", "0", "0"],
|
||
],
|
||
)
|
||
|
||
rare_parts, rare_by_set = build_rare_parts(parts_filtered, sets_enriched, parts_catalog, colors)
|
||
|
||
assert rare_parts == [
|
||
{
|
||
"set_num": "1000-1",
|
||
"set_id": "1000",
|
||
"set_name": "Set A",
|
||
"year": "2020",
|
||
"part_num": "p2",
|
||
"part_name": "Head Custom",
|
||
"part_cat_id": "59",
|
||
"color_rgb": "BBBBBB",
|
||
"color_name": "Blue",
|
||
"is_translucent": "false",
|
||
"is_minifig_part": "true",
|
||
"quantity_in_set": "1",
|
||
"in_collection": "true",
|
||
},
|
||
{
|
||
"set_num": "2000-1",
|
||
"set_id": "2000",
|
||
"set_name": "Set B",
|
||
"year": "2021",
|
||
"part_num": "p3",
|
||
"part_name": "Slope 45",
|
||
"part_cat_id": "2",
|
||
"color_rgb": "CCCCCC",
|
||
"color_name": "Trans-Clear",
|
||
"is_translucent": "true",
|
||
"is_minifig_part": "false",
|
||
"quantity_in_set": "4",
|
||
"in_collection": "false",
|
||
},
|
||
]
|
||
assert rare_by_set == [
|
||
{
|
||
"set_num": "2000-1",
|
||
"set_id": "2000",
|
||
"name": "Set B",
|
||
"year": "2021",
|
||
"in_collection": "false",
|
||
"rare_parts_distinct": "1",
|
||
"rare_parts_quantity": "4",
|
||
"rare_minifig_parts_distinct": "0",
|
||
"rare_minifig_quantity": "0",
|
||
},
|
||
{
|
||
"set_num": "1000-1",
|
||
"set_id": "1000",
|
||
"name": "Set A",
|
||
"year": "2020",
|
||
"in_collection": "true",
|
||
"rare_parts_distinct": "1",
|
||
"rare_parts_quantity": "1",
|
||
"rare_minifig_parts_distinct": "1",
|
||
"rare_minifig_quantity": "1",
|
||
},
|
||
]
|
||
|
||
|
||
def test_write_rare_parts_outputs_csv(tmp_path: Path) -> None:
|
||
"""Sérialise les pièces rares et l’agrégat par set."""
|
||
rare_parts_path = tmp_path / "rare_parts.csv"
|
||
rare_by_set_path = tmp_path / "rare_parts_by_set.csv"
|
||
rare_parts_sample = [
|
||
{
|
||
"set_num": "123-1",
|
||
"set_id": "123",
|
||
"set_name": "Sample",
|
||
"year": "2020",
|
||
"part_num": "p1",
|
||
"part_name": "Brick",
|
||
"part_cat_id": "1",
|
||
"color_rgb": "FFFFFF",
|
||
"color_name": "White",
|
||
"is_translucent": "false",
|
||
"is_minifig_part": "false",
|
||
"quantity_in_set": "2",
|
||
"in_collection": "true",
|
||
}
|
||
]
|
||
rare_by_set_sample = [
|
||
{
|
||
"set_num": "123-1",
|
||
"set_id": "123",
|
||
"name": "Sample",
|
||
"year": "2020",
|
||
"in_collection": "true",
|
||
"rare_parts_distinct": "1",
|
||
"rare_parts_quantity": "2",
|
||
"rare_minifig_parts_distinct": "0",
|
||
"rare_minifig_quantity": "0",
|
||
}
|
||
]
|
||
|
||
write_rare_parts_list(rare_parts_path, rare_parts_sample)
|
||
write_rare_parts_by_set(rare_by_set_path, rare_by_set_sample)
|
||
|
||
assert rare_parts_path.exists()
|
||
assert rare_by_set_path.exists()
|