127 lines
4.6 KiB
Python
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()
|