Files
2026-06-16 04:38:23 +00:00

127 lines
4.6 KiB
Python

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()