"""Unit-тесты app.services.recipe_calculator (кроме unloading — см. test_recipe_calculator_unloading).""" from __future__ import annotations import unittest from app.services.recipe_calculator import ( calculate_ingredients, calculate_ingredients_from_dry_matter, calculate_recipe, calculate_totals, round_to_step5, ) class RecipeCalculatorTests(unittest.TestCase): def test_round_to_step5(self) -> None: self.assertEqual(round_to_step5(12), 10) self.assertEqual(round_to_step5(13), 15) self.assertEqual(round_to_step5(100), 100) def test_calculate_ingredients_basic(self) -> None: ingredients = [ {"weightPerHead": 2.0, "dryMatter": 50.0, "component_id": "c1"}, {"weightPerHead": 3.0, "dryMatter": 60.0, "component_id": "c2"}, ] result = calculate_ingredients(ingredients, heads_count=10, trip_percent=100.0) self.assertEqual(len(result), 2) self.assertEqual(result[0]["totalWeight"], 20.0) self.assertEqual(result[0]["tripWeight"], 20.0) self.assertEqual(result[0]["dryMatterPerHead"], 1.0) self.assertEqual(result[1]["totalWeight"], 30.0) def test_calculate_ingredients_uses_component_dm_map(self) -> None: ingredients = [{"weightPerHead": 1.0, "dryMatter": 0, "component_id": "c-map"}] result = calculate_ingredients( ingredients, heads_count=5, trip_percent=50.0, component_dry_matter_map={"c-map": 80.0}, ) self.assertEqual(result[0]["dryMatterPerHead"], 0.8) self.assertEqual(result[0]["tripWeight"], 2.5) def test_calculate_totals_sums_ingredients(self) -> None: calculated = [ {"totalWeight": 20.0, "tripWeight": 10.0, "dryMatterPerHead": 1.0, "weightPerHead": 2.0}, {"totalWeight": 30.0, "tripWeight": 15.0, "dryMatterPerHead": 1.5, "weightPerHead": 3.0}, ] totals = calculate_totals(calculated, []) self.assertEqual(totals["totalWeight"], 50.0) self.assertEqual(totals["totalTripWeight"], 25.0) self.assertEqual(totals["totalDryMatterPerHead"], 2.5) self.assertEqual(totals["totalWeightPerHead"], 5.0) def test_calculate_ingredients_from_dry_matter_inverse(self) -> None: ingredients = [{"dryMatterPerHead": 1.0, "dryMatter": 50.0}] result = calculate_ingredients_from_dry_matter( ingredients, heads_count=10, trip_percent=100.0 ) self.assertEqual(result[0]["weightPerHead"], 2.0) self.assertEqual(result[0]["totalWeight"], 20.0) self.assertEqual(result[0]["tripWeight"], 20.0) def test_calculate_ingredients_from_dry_matter_zero_dm_percent_zeros_weight(self) -> None: ingredients = [{"dryMatterPerHead": 1.0, "dryMatter": 0}] result = calculate_ingredients_from_dry_matter( ingredients, heads_count=10, trip_percent=100.0 ) self.assertEqual(result[0]["weightPerHead"], 0.0) def test_calculate_recipe_full_pipeline_weight_mode(self) -> None: result = calculate_recipe( ingredients=[{"weightPerHead": 2.0, "dryMatter": 50.0}], heads_count=100, trip_percent=100.0, unloading_groups=[{"distributionType": "percent", "value": 100}], ) self.assertEqual(result["totals"]["totalTripWeight"], 200.0) self.assertEqual(result["unloadingGroups"][0]["calculatedWeight"], 200) self.assertEqual(result["unloadingTotals"]["totalPercent"], 100.0) def test_calculate_recipe_from_dry_matter_mode(self) -> None: result = calculate_recipe( ingredients=[{"dryMatterPerHead": 0.5, "dryMatter": 50.0}], heads_count=20, trip_percent=50.0, calculate_from_dry_matter=True, ) self.assertEqual(result["ingredients"][0]["weightPerHead"], 1.0) self.assertEqual(result["totals"]["totalTripWeight"], 10.0) if __name__ == "__main__": unittest.main()