You've already forked etude_lego_jurassic_world
Premiers éléments de l'étude
This commit is contained in:
144
tests/test_inventory_gaps.py
Normal file
144
tests/test_inventory_gaps.py
Normal file
@@ -0,0 +1,144 @@
|
||||
"""Tests des écarts d'inventaire calculés depuis parts_filtered.csv."""
|
||||
|
||||
import csv
|
||||
from pathlib import Path
|
||||
|
||||
from lib.rebrickable.inventory_reconciliation import (
|
||||
compute_inventory_gaps,
|
||||
index_sets_by_num,
|
||||
write_inventory_gaps_csv,
|
||||
write_inventory_gaps_markdown,
|
||||
)
|
||||
|
||||
|
||||
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_compute_inventory_gaps_excludes_spares(tmp_path: Path) -> None:
|
||||
"""Ignore les pièces de rechange et ne conserve que les sets en écart."""
|
||||
sets_path = tmp_path / "sets_enriched.csv"
|
||||
parts_path = tmp_path / "parts_filtered.csv"
|
||||
write_csv(
|
||||
sets_path,
|
||||
["set_num", "set_id", "num_parts", "in_collection"],
|
||||
[
|
||||
["1000-1", "1000", "4", "true"],
|
||||
["2000-1", "2000", "3", "false"],
|
||||
["3000-1", "3000", "1", "true"],
|
||||
],
|
||||
)
|
||||
write_csv(
|
||||
parts_path,
|
||||
["part_num", "color_rgb", "is_translucent", "set_num", "set_id", "quantity_in_set", "is_spare"],
|
||||
[
|
||||
["A", "AAAAAA", "false", "1000-1", "1000", "2", "false"],
|
||||
["B", "BBBBBB", "false", "1000-1", "1000", "2", "false"],
|
||||
["S", "SSSSSS", "false", "1000-1", "1000", "5", "true"],
|
||||
["C", "CCCCCC", "false", "2000-1", "2000", "2", "false"],
|
||||
["D", "DDDDDD", "false", "3000-1", "3000", "1", "false"],
|
||||
],
|
||||
)
|
||||
|
||||
gaps = compute_inventory_gaps(sets_path, parts_path)
|
||||
|
||||
assert gaps == [
|
||||
{
|
||||
"set_num": "1000-1",
|
||||
"set_id": "1000",
|
||||
"expected_parts": 4,
|
||||
"inventory_parts": 9,
|
||||
"inventory_parts_non_spare": 4,
|
||||
"delta": 5,
|
||||
"delta_non_spare": 0,
|
||||
"in_collection": "true",
|
||||
},
|
||||
{
|
||||
"set_num": "2000-1",
|
||||
"set_id": "2000",
|
||||
"expected_parts": 3,
|
||||
"inventory_parts": 2,
|
||||
"inventory_parts_non_spare": 2,
|
||||
"delta": 1,
|
||||
"delta_non_spare": 1,
|
||||
"in_collection": "false",
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
def test_write_inventory_gaps_csv(tmp_path: Path) -> None:
|
||||
"""Sérialise le rapport d'écarts dans un CSV dédié."""
|
||||
destination_path = tmp_path / "inventory_gaps.csv"
|
||||
rows = [
|
||||
{
|
||||
"set_num": "2000-1",
|
||||
"set_id": "2000",
|
||||
"expected_parts": 3,
|
||||
"inventory_parts": 2,
|
||||
"inventory_parts_non_spare": 2,
|
||||
"delta": 1,
|
||||
"delta_non_spare": 1,
|
||||
"in_collection": "false",
|
||||
}
|
||||
]
|
||||
|
||||
write_inventory_gaps_csv(destination_path, rows)
|
||||
|
||||
with destination_path.open() as csv_file:
|
||||
written_rows = list(csv.DictReader(csv_file))
|
||||
|
||||
assert written_rows == [
|
||||
{
|
||||
"set_num": "2000-1",
|
||||
"set_id": "2000",
|
||||
"expected_parts": "3",
|
||||
"inventory_parts": "2",
|
||||
"inventory_parts_non_spare": "2",
|
||||
"delta": "1",
|
||||
"delta_non_spare": "1",
|
||||
"in_collection": "false",
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
def test_write_inventory_gaps_markdown(tmp_path: Path) -> None:
|
||||
"""Produit un tableau Markdown listant les sets en écart."""
|
||||
destination_path = tmp_path / "inventory_gaps.md"
|
||||
gaps = [
|
||||
{
|
||||
"set_num": "2000-1",
|
||||
"set_id": "2000",
|
||||
"expected_parts": 3,
|
||||
"inventory_parts": 2,
|
||||
"inventory_parts_non_spare": 2,
|
||||
"delta": 1,
|
||||
"delta_non_spare": 1,
|
||||
"in_collection": "false",
|
||||
}
|
||||
]
|
||||
sets = [
|
||||
{
|
||||
"set_num": "2000-1",
|
||||
"set_id": "2000",
|
||||
"num_parts": "3",
|
||||
"name": "Test Set",
|
||||
"year": "2020",
|
||||
"rebrickable_url": "https://rebrickable.com/sets/2000-1",
|
||||
"in_collection": "false",
|
||||
}
|
||||
]
|
||||
|
||||
write_inventory_gaps_markdown(destination_path, gaps, index_sets_by_num(sets))
|
||||
|
||||
with destination_path.open() as markdown_file:
|
||||
content = markdown_file.read().splitlines()
|
||||
|
||||
assert content[0].startswith("| set_id | name |")
|
||||
assert (
|
||||
"| [2000](https://rebrickable.com/sets/2000-1) | Test Set | 2020 | 1 | 1 | 3 | 2 | 2 | false | [PDF](https://www.lego.com/service/buildinginstructions/2000) |"
|
||||
in content
|
||||
)
|
||||
Reference in New Issue
Block a user