96 lines
4.0 KiB
Python
96 lines
4.0 KiB
Python
"""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()
|