71 lines
2.4 KiB
PHP
71 lines
2.4 KiB
PHP
<?php
|
|
|
|
use App\Enums\PacePreference;
|
|
use App\Enums\PhysicalActivityLevel;
|
|
use App\Enums\UserSex;
|
|
use App\Enums\WeightGoal;
|
|
use App\Services\NutritionPlanCalculator;
|
|
use Carbon\CarbonImmutable;
|
|
|
|
beforeEach(function () {
|
|
CarbonImmutable::setTestNow('2026-08-14 10:00:00');
|
|
});
|
|
|
|
afterEach(function () {
|
|
CarbonImmutable::setTestNow();
|
|
});
|
|
|
|
it('calculates a reproducible maintenance plan', function () {
|
|
$plan = (new NutritionPlanCalculator)->calculate(
|
|
weightKg: 80,
|
|
heightCm: 180,
|
|
dateOfBirth: CarbonImmutable::parse('1996-08-14'),
|
|
sex: UserSex::MAN,
|
|
activityLevel: PhysicalActivityLevel::MODERATELY_ACTIVE,
|
|
weightGoal: WeightGoal::MAINTAIN_WEIGHT,
|
|
pacePreference: PacePreference::NORMAL,
|
|
);
|
|
|
|
expect($plan)
|
|
->formula_version->toBe('mifflin_st_jeor_v1')
|
|
->resting_metabolism->toBe(1780)
|
|
->maintenance_calories->toBe(2760)
|
|
->calorie_adjustment_percent->toBe(0.0)
|
|
->proteins->toBe(128)
|
|
->fats->toBe(77)
|
|
->carbs->toBe(389)
|
|
->calories->toBe(2761)
|
|
->and(($plan['proteins'] * 4) + ($plan['carbs'] * 4) + ($plan['fats'] * 9))
|
|
->toBe($plan['calories']);
|
|
});
|
|
|
|
it('applies bounded loss and gain adjustments', function (WeightGoal $goal, PacePreference $pace, float $expectedAdjustment) {
|
|
$plan = (new NutritionPlanCalculator)->calculate(
|
|
weightKg: 60,
|
|
heightCm: 165,
|
|
dateOfBirth: CarbonImmutable::parse('1990-01-01'),
|
|
sex: UserSex::WOMAN,
|
|
activityLevel: PhysicalActivityLevel::LIGHTLY_ACTIVE,
|
|
weightGoal: $goal,
|
|
pacePreference: $pace,
|
|
);
|
|
|
|
expect($plan['calorie_adjustment_percent'])->toBe($expectedAdjustment)
|
|
->and($plan['calories'])->toBeGreaterThanOrEqual(1200);
|
|
})->with([
|
|
'normal loss' => [WeightGoal::LOSE_WEIGHT, PacePreference::NORMAL, -0.15],
|
|
'fast gain' => [WeightGoal::GAIN_WEIGHT, PacePreference::FAST, 0.15],
|
|
]);
|
|
|
|
it('rejects a non binary metabolic calculation reference', function () {
|
|
(new NutritionPlanCalculator)->calculate(
|
|
weightKg: 70,
|
|
heightCm: 170,
|
|
dateOfBirth: CarbonImmutable::parse('1990-01-01'),
|
|
sex: UserSex::UNKNOWN,
|
|
activityLevel: PhysicalActivityLevel::SEDENTARY,
|
|
weightGoal: WeightGoal::MAINTAIN_WEIGHT,
|
|
pacePreference: PacePreference::SLOW,
|
|
);
|
|
})->throws(InvalidArgumentException::class);
|