mirror of https://github.com/kcal-app/kcal.git
Add tests for Support classes
This commit is contained in:
parent
d69d962287
commit
01b414c22c
|
@ -71,12 +71,6 @@ class Nutrients
|
|||
|
||||
/**
|
||||
* Calculate a nutrient multiplier for a Food.
|
||||
*
|
||||
* @param \App\Models\Food $food
|
||||
* @param float $amount
|
||||
* @param string|null $fromUnit
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public static function calculateFoodNutrientMultiplier(
|
||||
Food $food,
|
||||
|
@ -93,6 +87,7 @@ class Nutrients
|
|||
return $amount / $food->serving_weight;
|
||||
}
|
||||
|
||||
// @todo Determine if `empty($food->serving_unit)` case makes sense.
|
||||
if (
|
||||
empty($fromUnit)
|
||||
|| empty($food->serving_unit)
|
||||
|
@ -130,13 +125,6 @@ class Nutrients
|
|||
|
||||
/**
|
||||
* Calculate a nutrient amount for a recipe.
|
||||
*
|
||||
* @param \App\Models\Recipe $recipe
|
||||
* @param string $nutrient
|
||||
* @param float $amount
|
||||
* @param string $fromUnit
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public static function calculateRecipeNutrientAmount(
|
||||
Recipe $recipe,
|
||||
|
|
|
@ -8,21 +8,81 @@ use Illuminate\Database\Eloquent\Factories\Factory;
|
|||
class FoodFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* The name of the factory's corresponding model.
|
||||
*
|
||||
* @var string
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $model = Food::class;
|
||||
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function definition()
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
'name' => $this->faker->word,
|
||||
'detail' => $this->faker->sentence(2),
|
||||
'brand' => $this->faker->word,
|
||||
'source' => $this->faker->url,
|
||||
'serving_size' => $this->faker->randomFloat(2, 1/2, 5),
|
||||
'serving_unit' => $this->faker->randomElement(['tsp', 'tbsp', 'cup']),
|
||||
'serving_weight' => $this->faker->numberBetween(5, 500),
|
||||
'calories' => $this->faker->randomFloat(2, 0, 100),
|
||||
'fat' => $this->faker->randomFloat(2, 0, 10),
|
||||
'cholesterol' => $this->faker->randomFloat(2, 0, 100),
|
||||
'sodium' => $this->faker->randomFloat(2, 0, 500),
|
||||
'carbohydrates' => $this->faker->randomFloat(2, 0, 20),
|
||||
'protein' => $this->faker->randomFloat(2, 0, 20),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Make instance with "tsp" serving unit.
|
||||
*/
|
||||
public function tspServingUnit()
|
||||
{
|
||||
return $this->state(function (array $attributes) {
|
||||
return [
|
||||
'serving_unit' => 'tsp',
|
||||
'serving_size' => 1,
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Make instance with "tbsp" serving unit.
|
||||
*/
|
||||
public function tbspServingUnit()
|
||||
{
|
||||
return $this->state(function (array $attributes) {
|
||||
return [
|
||||
'serving_unit' => 'tbsp',
|
||||
'serving_size' => 1,
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Make instance with "cup" serving unit.
|
||||
*/
|
||||
public function cupServingUnit()
|
||||
{
|
||||
return $this->state(function (array $attributes) {
|
||||
return [
|
||||
'serving_unit' => 'cup',
|
||||
'serving_size' => 1,
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Make instance with no" serving unit.
|
||||
*/
|
||||
public function noServingUnit()
|
||||
{
|
||||
return $this->state(function (array $attributes) {
|
||||
return [
|
||||
'serving_unit' => null,
|
||||
'serving_unit_name' => 'head'
|
||||
];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
<server name="APP_ENV" value="testing"/>
|
||||
<server name="BCRYPT_ROUNDS" value="4"/>
|
||||
<server name="CACHE_DRIVER" value="array"/>
|
||||
<!-- <server name="DB_CONNECTION" value="sqlite"/> -->
|
||||
<!-- <server name="DB_DATABASE" value=":memory:"/> -->
|
||||
<server name="DB_CONNECTION" value="sqlite"/>
|
||||
<server name="DB_DATABASE" value=":memory:"/>
|
||||
<server name="MAIL_MAILER" value="array"/>
|
||||
<server name="QUEUE_CONNECTION" value="sync"/>
|
||||
<server name="SESSION_DRIVER" value="array"/>
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
|
||||
class ExampleTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* A basic test example.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testBasicTest()
|
||||
{
|
||||
$response = $this->get('/');
|
||||
|
||||
$response->assertStatus(200);
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
|
||||
class RegistrationTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_registration_screen_can_be_rendered()
|
||||
{
|
||||
$response = $this->get('/register');
|
||||
|
||||
$response->assertStatus(200);
|
||||
}
|
||||
|
||||
public function test_new_users_can_register()
|
||||
{
|
||||
$response = $this->post('/register', [
|
||||
'name' => 'Test User',
|
||||
'email' => 'test@example.com',
|
||||
'password' => 'password',
|
||||
'password_confirmation' => 'password',
|
||||
]);
|
||||
|
||||
$this->assertAuthenticated();
|
||||
$response->assertRedirect(RouteServiceProvider::HOME);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Feature\Support;
|
||||
|
||||
use App\Models\Food;
|
||||
use App\Support\Nutrients;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
|
||||
class NutrientsTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
/**
|
||||
* Test invalid Food nutrient multiplier calculation.
|
||||
*
|
||||
* @dataProvider foodsInvalidNutrientMultipliersProvider
|
||||
*/
|
||||
public function testCalculateFoodInvalidNutrientMultiplier(
|
||||
Food $food,
|
||||
float $amount,
|
||||
string $fromUnit,
|
||||
): void {
|
||||
$this->expectException(\DomainException::class);
|
||||
Nutrients::calculateFoodNutrientMultiplier($food, $amount, $fromUnit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test valid Food nutrient multiplier calculation.
|
||||
*
|
||||
* @dataProvider foodsValidNutrientMultipliersProvider
|
||||
*/
|
||||
public function testCalculateFoodValidNutrientMultiplier(
|
||||
Food $food,
|
||||
float $amount,
|
||||
string $fromUnit,
|
||||
float $expectedMultiplier
|
||||
): void {
|
||||
$this->assertEquals(
|
||||
Nutrients::calculateFoodNutrientMultiplier($food, $amount, $fromUnit),
|
||||
$expectedMultiplier
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data providers.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provide example foods and expected nutrient multipliers.
|
||||
*/
|
||||
public function foodsInvalidNutrientMultipliersProvider(): array {
|
||||
$this->refreshApplication();
|
||||
|
||||
/** @var \App\Models\Food $foodInvalidUnit */
|
||||
$foodInvalidUnit = Food::factory()->make(['serving_unit' => 'invalid']);
|
||||
|
||||
return [
|
||||
[$foodInvalidUnit, 1, 'tsp'],
|
||||
[$foodInvalidUnit, 1, 'tbsp'],
|
||||
[$foodInvalidUnit, 1, 'cup'],
|
||||
[Food::factory()->tspServingUnit()->make(), 1, 'invalid'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide example foods and expected nutrient multipliers.
|
||||
*/
|
||||
public function foodsValidNutrientMultipliersProvider(): array {
|
||||
$this->refreshApplication();
|
||||
|
||||
/** @var \App\Models\Food[] $foods */
|
||||
$foods = [
|
||||
'tsp' => Food::factory()->tspServingUnit()->make(),
|
||||
'tbsp' => Food::factory()->tbspServingUnit()->make(),
|
||||
'cup' => Food::factory()->cupServingUnit()->make(),
|
||||
'none' => Food::factory()->noServingUnit()->make(),
|
||||
];
|
||||
|
||||
return [
|
||||
[$foods['tsp'], $foods['tsp']->serving_weight, 'oz', Nutrients::$gramsPerOunce],
|
||||
[$foods['tsp'], 1, 'serving', 1],
|
||||
[$foods['tsp'], $foods['tsp']->serving_weight * 1.5, 'gram', 1.5],
|
||||
[$foods['tsp'], 2, 'tsp', 2],
|
||||
[$foods['tsp'], 1, 'tbsp', 3],
|
||||
[$foods['tsp'], 1, 'cup', 48],
|
||||
[$foods['tbsp'], $foods['tbsp']->serving_weight, 'oz', Nutrients::$gramsPerOunce],
|
||||
[$foods['tbsp'], 1, 'serving', 1],
|
||||
[$foods['tbsp'], $foods['tbsp']->serving_weight * 2, 'gram', 2],
|
||||
[$foods['tbsp'], 2, 'tsp', 2/3],
|
||||
[$foods['tbsp'], 1, 'tbsp', 1],
|
||||
[$foods['tbsp'], 2, 'cup', 32],
|
||||
[$foods['cup'], $foods['cup']->serving_weight, 'oz', Nutrients::$gramsPerOunce],
|
||||
[$foods['cup'], 1, 'serving', 1],
|
||||
[$foods['cup'], $foods['cup']->serving_weight * 2.25, 'gram', 2.25],
|
||||
[$foods['cup'], 3, 'tsp', 1/16],
|
||||
[$foods['cup'], 2, 'tbsp', 1/8],
|
||||
[$foods['cup'], 5, 'cup', 5],
|
||||
[$foods['none'], $foods['none']->serving_weight, 'oz', Nutrients::$gramsPerOunce],
|
||||
[$foods['none'], 1, 'serving', 1],
|
||||
[$foods['none'], $foods['none']->serving_weight * 3.0125, 'gram', 3.0125],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Unit;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ExampleTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* A basic test example.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testBasicTest()
|
||||
{
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Unit\Support;
|
||||
|
||||
use App\Support\ArrayFormat;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ArrayFormatTest extends TestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* Test input array "flipping".
|
||||
*
|
||||
* @see \App\Support\ArrayFormat::flipTwoDimensionalKeys()
|
||||
*/
|
||||
public function testFlipTwoDimensionalKeys(): void
|
||||
{
|
||||
$input = [
|
||||
'ingredient' => [
|
||||
0 => 'ingredient-0',
|
||||
1 => 'ingredient-1',
|
||||
2 => 'ingredient-2',
|
||||
3 => 'ingredient-3',
|
||||
],
|
||||
'amount' => [
|
||||
0 => 'amount-0',
|
||||
1 => 'amount-1',
|
||||
2 => 'amount-2',
|
||||
3 => 'amount-3',
|
||||
],
|
||||
];
|
||||
$expected = [
|
||||
['ingredient' => 'ingredient-0', 'amount' => 'amount-0'],
|
||||
['ingredient' => 'ingredient-1', 'amount' => 'amount-1'],
|
||||
['ingredient' => 'ingredient-2', 'amount' => 'amount-2'],
|
||||
['ingredient' => 'ingredient-3', 'amount' => 'amount-3'],
|
||||
];
|
||||
$this->assertEqualsCanonicalizing($expected, ArrayFormat::flipTwoDimensionalKeys($input));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Unit\Support;
|
||||
|
||||
use App\Support\Number;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class NumberTest extends TestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* Test float to string conversion.
|
||||
*
|
||||
* @dataProvider decimalStringFloatsProvider
|
||||
* @dataProvider fractionStringFloatsProvider
|
||||
*
|
||||
* @see \App\Support\Number::floatFromString()
|
||||
*/
|
||||
public function testFloatFromString(string $string, float $expectedFloat): void
|
||||
{
|
||||
$result = Number::floatFromString($string);
|
||||
$this->assertIsFloat($result);
|
||||
$this->assertEquals($expectedFloat, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test (fraction) string to float conversion.
|
||||
*
|
||||
* @dataProvider fractionStringFloatsProvider
|
||||
*
|
||||
* @see \App\Support\Number::fractionStringFromFloat()
|
||||
*/
|
||||
public function testFractionStringFromFloat(string $expectedString, float $float): void
|
||||
{
|
||||
$result = Number::fractionStringFromFloat($float);
|
||||
$this->assertIsString($result);
|
||||
$this->assertEquals($expectedString, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data providers.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provide decimal string and float data.
|
||||
*
|
||||
* @see \Tests\Unit\Support\NumberTest::testFloatFromString()
|
||||
*/
|
||||
public function decimalStringFloatsProvider(): array {
|
||||
return [
|
||||
['0.0', 0.0], ['0.125', 1/8], ['0.25', 1/4], ['0.5', 1/2],
|
||||
['0.75', 3/4], ['1.0', 1.0], ['1.25', 1.25], ['1.5', 1.5],
|
||||
['2.5', 2.5], ['2.75', 2.75],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide fraction string and float data.
|
||||
*
|
||||
* @see \Tests\Unit\Support\NumberTest::testFloatFromString()
|
||||
* @see \Tests\Unit\Support\NumberTest::testFractionStringFromFloat()
|
||||
*/
|
||||
public function fractionStringFloatsProvider(): array {
|
||||
return [
|
||||
['0', 0.0], ['1/8', 1/8], ['1/4', 1/4], ['1/3', 1/3], ['1/2', 1/2],
|
||||
['2/3', 2/3], ['3/4', 3/4], ['1', 1.0], ['1 1/4', 1.25],
|
||||
['1 1/2', 1.5], ['2 1/2', 2.5], ['2 3/4', 2.75],
|
||||
];
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue