Интегрирован wesp в сайт
CI / quality (push) Canceled after 0s

This commit is contained in:
влад
2026-07-17 12:57:18 +03:00
parent 5dfa06ddbe
commit 355c0ef9f1
883 changed files with 194576 additions and 177 deletions
@@ -0,0 +1,77 @@
"""Canonical tests: WESP GfE 2001 ingredient derive (не Excel CSV)."""
from __future__ import annotations
import json
import math
import unittest
from pathlib import Path
from app.lab.calc.gfe_policies import DeriveContext, default_om_digestibility_pct
from app.lab.calc.ingredient_derive import derive_ingredient_nutrients
_FIXTURES = Path(__file__).resolve().parent / "fixtures" / "lab_derive_canonical.json"
def _load_cases() -> list[dict]:
with _FIXTURES.open(encoding="utf-8") as f:
return json.load(f)
class LabIngredientDeriveTests(unittest.TestCase):
def _assert_close(self, expected: float, actual: float, label: str) -> None:
tol = max(1e-3, abs(expected) * 1e-4)
self.assertTrue(
math.isclose(expected, actual, abs_tol=tol),
f"{label}: expected {expected}, got {actual}",
)
def test_derive_canonical_cases(self) -> None:
for case in _load_cases():
if "expected" not in case:
continue
ctx_raw = case.get("context") or {}
ctx = DeriveContext(
feed_group=ctx_raw.get("feed_group", "unknown"),
is_main_feed=bool(ctx_raw.get("is_main_feed")),
)
derived = derive_ingredient_nutrients(case["input"], context=ctx)
for key, expected in case["expected"].items():
self.assertIn(key, derived, msg=f"{case['id']}: missing {key}")
self._assert_close(float(expected), derived[key], f"{case['id']}/{key}")
def test_rnb_from_derive(self) -> None:
case = next(c for c in _load_cases() if c.get("id") == "rnb_formula")
ctx = DeriveContext(feed_group="concentrate")
derived = derive_ingredient_nutrients(case["input"], context=ctx)
cp = derived["уСП формул"]
rnb = (derived["Сыр. Протеин"] - cp) / 6.25
self._assert_close(case["expected_rnb"], rnb, "rnb_formula")
self._assert_close(case["expected_rnb"], derived["БРА"], "rnb_header")
def test_omd_default_by_feed_class(self) -> None:
self.assertEqual(default_om_digestibility_pct(DeriveContext(feed_group="rough")), 65.0)
self.assertEqual(
default_om_digestibility_pct(DeriveContext(feed_group="succulent")),
72.0,
)
self.assertEqual(
default_om_digestibility_pct(DeriveContext(feed_group="concentrate")),
91.0,
)
self.assertEqual(
default_om_digestibility_pct(DeriveContext(is_main_feed=True)),
65.0,
)
def test_straw_without_omd_not_91_pct(self) -> None:
case = next(c for c in _load_cases() if c.get("id") == "straw_default_omd_65")
ctx = DeriveContext(feed_group="rough", is_main_feed=True)
derived = derive_ingredient_nutrients(case["input"], context=ctx)
organic = case["input"]["СВ"] - case["input"]["Сырая зола"]
wrong = organic * 0.91
self.assertLess(derived["Перевар Орг Вещ"], wrong - 100)
if __name__ == "__main__":
unittest.main()