| import json |
| from pathlib import Path |
|
|
| import pytest |
|
|
| from pino.draft_engine import FormulaGenerator |
|
|
| RULES_PATH = Path(__file__).parent.parent / "data" / "genre_rules.json" |
| REGISTRY_PATH = Path(__file__).parent.parent / "src" / "pino" / "registry.db" |
|
|
|
|
| def test_formula_generator_sum_to_one() -> None: |
| gen = FormulaGenerator( |
| genre="citrus_cologne", |
| rules_path=RULES_PATH, |
| registry_path=REGISTRY_PATH, |
| seed=42, |
| min_k=5, |
| max_k=10, |
| ) |
| formula, formula_id = gen.generate(idx=0) |
| total = sum(f["weight_fraction"] for f in formula) |
| assert pytest.approx(total, 1e-6) == 1.0 |
| assert formula_id.startswith("gen_") |
|
|
|
|
| def test_formula_generator_ethanol_present() -> None: |
| gen = FormulaGenerator( |
| genre="citrus_cologne", |
| rules_path=RULES_PATH, |
| registry_path=REGISTRY_PATH, |
| seed=42, |
| min_k=5, |
| max_k=10, |
| ) |
| formula, _ = gen.generate(idx=0) |
| cas_list = [f["cas"] for f in formula] |
| assert "64-17-5" in cas_list |
|
|
|
|
| def test_formula_generator_genre_bounds_respected() -> None: |
| """Citrus cologne must contain at least one top-note compound.""" |
| gen = FormulaGenerator( |
| genre="citrus_cologne", |
| rules_path=RULES_PATH, |
| registry_path=REGISTRY_PATH, |
| seed=42, |
| ) |
| top_cas = set(gen.tiers["top"]) |
| for _ in range(20): |
| formula, _ = gen.generate() |
| cas_list = {f["cas"] for f in formula} |
| assert cas_list & top_cas, "citrus_cologne formula missing top notes" |
|
|
|
|
| def test_formula_generator_bounds_respected() -> None: |
| gen = FormulaGenerator( |
| genre="wildcard", |
| rules_path=RULES_PATH, |
| registry_path=REGISTRY_PATH, |
| seed=42, |
| min_k=5, |
| max_k=10, |
| ) |
| for _ in range(20): |
| formula, _ = gen.generate() |
| for f in formula: |
| meta = gen.compounds.get(f["cas"]) |
| if meta is None: |
| continue |
| max_w = meta["max_weight_fraction"] |
| assert f["weight_fraction"] <= max_w + 1e-9 |
|
|
|
|
| def test_ifra_light_check_blocks_prohibited() -> None: |
| gen = FormulaGenerator( |
| genre="wildcard", |
| rules_path=RULES_PATH, |
| registry_path=REGISTRY_PATH, |
| seed=42, |
| ) |
| |
| formula = [ |
| {"cas": "81-15-2", "weight_fraction": 0.01}, |
| {"cas": "64-17-5", "weight_fraction": 0.99}, |
| ] |
| assert not gen.light_ifra_check(formula)["passed"] |
|
|