import unittest from app.fitness.activity_budget import estimate_workout_active_kcal, infer_met, workouts_kcal_total from app.fitness.calculators import ( DEFAULT_NEAT_KCAL, bmr_mifflin, compute_daily_targets, compute_targets, compute_tdee, macro_targets, steps_kcal, water_target_l, ) PROFILE = { "sex": "male", "age": 30, "height_cm": 180, "weight_kg": 86, "goal": "maintain", "neat_base_kcal": 200, } class TdeeComponentsTests(unittest.TestCase): def test_rest_day_tdee_is_bmr_plus_neat(self) -> None: breakdown = compute_tdee(PROFILE, steps_total=0, workouts=[]) bmr = bmr_mifflin(sex="male", weight_kg=86, height_cm=180, age=30) self.assertEqual(breakdown["bmr"], round(bmr, 0)) self.assertEqual(breakdown["neat_kcal"], DEFAULT_NEAT_KCAL) self.assertEqual(breakdown["steps_kcal"], 0.0) self.assertEqual(breakdown["workout_kcal"], 0.0) self.assertEqual(breakdown["tdee"], round(bmr + DEFAULT_NEAT_KCAL, 0)) def test_steps_kcal_at_reference_weight(self) -> None: kcal = steps_kcal(steps=10000, weight_kg=86) self.assertAlmostEqual(kcal, 400.0, delta=1.0) def test_daily_targets_include_activity(self) -> None: daily = compute_daily_targets( PROFILE, steps_total=8000, workouts=[{"active_calories": 450}], ) self.assertGreater(daily["steps_kcal"], 0) self.assertEqual(daily["workout_kcal"], 450.0) self.assertEqual( daily["tdee"], daily["bmr"] + daily["neat_kcal"] + daily["steps_kcal"] + daily["workout_kcal"], ) self.assertEqual(daily["calorie_target"], daily["tdee"]) def test_compute_targets_rest_day(self) -> None: targets = compute_targets(PROFILE) self.assertEqual(targets["steps_kcal"], 0) self.assertEqual(targets["workout_kcal"], 0) self.assertEqual(targets["calorie_target"], targets["tdee"]) def test_water_target(self) -> None: self.assertEqual(water_target_l(70), 2.3) def test_workout_active_calories_priority(self) -> None: kcal = estimate_workout_active_kcal( {"active_calories": 300, "duration_min": 60, "met": 9.8}, weight_kg=86, ) self.assertEqual(kcal, 300.0) def test_workout_met_fallback(self) -> None: kcal = estimate_workout_active_kcal( {"title": "бег", "duration_min": 60}, weight_kg=86, ) self.assertAlmostEqual(kcal, 9.8 * 86, delta=1.0) def test_workout_no_data_returns_zero(self) -> None: self.assertEqual(estimate_workout_active_kcal({}, weight_kg=70), 0.0) def test_infer_met_from_title(self) -> None: self.assertEqual(infer_met({"title": "пробежал триатлон"}), 10.0) def test_workouts_kcal_total(self) -> None: total = workouts_kcal_total( [ {"active_calories": 100}, {"title": "ходьба", "duration_min": 30}, ], weight_kg=86, ) self.assertGreater(total, 100) class MacroTargetsTests(unittest.TestCase): def test_lose_macros_from_weight(self) -> None: macros = macro_targets(2363, 86, "lose") self.assertEqual(macros["protein_g"], 189) self.assertEqual(macros["fat_g"], 86) self.assertEqual(macros["carbs_g"], 208) def test_maintain_macros_from_weight(self) -> None: macros = macro_targets(2000, 86, "maintain") self.assertEqual(macros["protein_g"], 155) self.assertEqual(macros["fat_g"], 86) self.assertEqual(macros["carbs_g"], 152) def test_active_day_increases_carbs_only(self) -> None: rest = compute_daily_targets(PROFILE, steps_total=0, workouts=[]) active = compute_daily_targets( PROFILE, steps_total=8000, workouts=[{"active_calories": 450}], ) self.assertEqual(rest["protein_g"], active["protein_g"]) self.assertEqual(rest["fat_g"], active["fat_g"]) self.assertGreater(active["calorie_target"], rest["calorie_target"]) self.assertGreater(active["carbs_g"], rest["carbs_g"]) def test_low_calorie_target_floors_carbs_at_zero(self) -> None: macros = macro_targets(1000, 86, "lose") self.assertEqual(macros["protein_g"], 189) self.assertEqual(macros["fat_g"], 86) self.assertEqual(macros["carbs_g"], 0) if __name__ == "__main__": unittest.main()