diff --git a/README.md b/README.md index 2d21044..49c2a58 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ![example workflow](https://github.com/brewerwall/unitz/actions/workflows/main.yml/badge.svg) -### Introduction +## Introduction Unitz is a way to address easy conversions among various brewing/fermentation units. A utility that helps convert a unit to all types and agnostic to what type of unit it is. @@ -142,4 +142,241 @@ method that all units share. $weight = new Weight(kilogram: 7.5629145); $kilogram = $weight->getKilogram(3); // $kilogram = 7.563 -``` \ No newline at end of file +``` + +## Calculate + +A library of calculations that can be used with various Unitz classes. + +### Beer + +This class will calculate Beer related calculations. +___ + +#### Alcohol By Volume (ABV) + +Alcohol By Volume (ABV) is the percent of alcohol content in the beer based on the original gravity, final gravity and +formula version. Source of equation is +at [Brewer's Friend](https://www.brewersfriend.com/2011/06/16/alcohol-by-volume-calculator-updated/). + +```php +Beer::alcoholByVolume(Gravity $originalGravity, Gravity $finalGravity, string $formulaVersion = Beer::ABV_ALTERNATE_FORMULA): float +``` + +##### Arguments + +- `Gravity $originalGravity` - Original Gravity of the beer +- `Gravity $finalGravity` - Final Gravity of the beer +- `string $formulaVersion` - Formula ABV calculation: `Beer::ABV_STANDARD_FORMULA` + or `Beer::ABV_ALTERNATE_FORMULA` + +##### Returns + +- `float` - Alcohol By Volume (ABV) Value + +--- + +#### Alcohol By Weight (ABW) + +Alcohol By Weight (ABW) is weighing the amount of alcohol in a fixed volume of liquid and comparing it to the weight of +pure water based on the original gravity and final gravity. + +```php +Beer::alcoholByWeight(Gravity $originalGravity, Gravity $finalGravity): float +``` + +##### Arguments + +- `Gravity $originalGravity` - Original Gravity of the beer +- `Gravity $finalGravity` - Final Gravity of the beer + +##### Returns + +- `float` - Alcohol By Weight (ABW) Value + +--- + +#### Standard Reference Method (SRM) + +Standard Reference Method (Srm) is the method for color assessment of wort or beer as published in the recommended +methods of the American Society of Brewing Chemists + +```php +Beer::standardReferenceMethod(Weight $weight, Color $color, Volume $volume): Color +``` + +##### Arguments + +- `Weight $weight` - Weight of the grain +- `Color $color` - Color of the grain +- `Volume $volume` - Volume of the water + +##### Returns + +- `Unitz/Color` - Color (Color) Value + +--- + +#### Malt Color Unit (MCU) + +Malt Color Unit (MCU) is an equation that helps determine what color a beer would be. + +```php +Beer::maltColorUnit(Weight $weight, Color $color, Volume $volume): float +``` + +##### Arguments + +- `Weight $weight` - Weight of the grain +- `Color $color` - Color of the grain +- `Volume $volume` - Volume of the water + +##### Returns + +- `float` - Malt Color Unit (MCU) Value + +--- + +#### International Bitterness Units (IBU) + +International Bitterness Units (IBU) is the bitterness of the beer based on the alpha acid of the +hops, weight of the hops, time in the boil, gravity of the wort, and volume of the wort. + +Based off Palmer's Calculation + +```php +Beer::internationalBitternessUnits(float $alphaAcid, Weight $weight, Time $time, Gravity $gravity, Volume $volume) +``` + +##### Arguments + +- `float $alphaAcid` - Alpha Acid of the hops +- `Weight $weight` - Weight of the hops +- `Time $time` - Time in the boil +- `Gravity $gravity` - Gravity of the wort +- `Volume $volume` - Volume of the wort + +##### Returns + +- `float` - International Bitterness Units (IBU) Value + +--- + +#### Alpha Acid Units (AAU) + +Alpha Acid Units (AAU) is the potential bitterness of the hops based on the alpha acid and weight. + +```php +Beer::alphaAcidUnit(float $alphaAcid, Weight $weight): float +``` + +##### Arguments + +- `float $alphaAcid` - Alpha Acid of the hops +- `Weight $weight` - Weight of the hops + +##### Returns + +- `float` - Alpha Acid Units (AAU) Value + +--- + +#### Hop Utilization + +This is a hop utilization factor based on the Tinseth formula derived +by [Glenn Tinseth](https://beersmith.com/blog/2011/02/10/beer-bitterness-and-ibus-with-glenn-tinseth-bshb-podcast-9/]). + +```php +Beer::hopUtilization(Time $time, Gravity $gravity) +``` + +##### Arguments + +- `Time $time` - Time in the boil +- `Gravity $gravity` - Gravity of the wort + +##### Returns + +- `float` - Hop Utilization Value + +--- + +#### Calories + +Determines the number of calories in a finished beer based on the original gravity, final gravity and the volume of the +beer consumed. + +```php +Beer::calories(Gravity $originalGravity, Gravity $finalGravity, Volume $volume) +``` + +##### Arguments + +- `Gravity $originalGravity` - Original Gravity of the beer +- `Gravity $finalGravity` - Final Gravity of the beer +- `Volume $volume` - Volume of the beer consumed + +##### Returns + +- `float` - Calories + +--- + +#### Real Extract + +Real Extract (RE) is a precise calculation concerning the gravity of beer. +Source of equation is [Craft Beer & Brewing](https://beerandbrewing.com/dictionary/ewOeMFnY4x/) + +```php +Beer::realExtract(Gravity $originalGravity, Gravity $finalGravity) +``` + +##### Arguments + +- `Gravity $originalGravity` - Original Gravity of the beer +- `Gravity $finalGravity` - Final Gravity of the beer + +##### Returns + +- `float` - Real Extract + +--- + +#### Apparent Degree of Fermentation + +Apparent Degree of Fermentation (ADF) is a measure of the amount of sugar that has been converted to alcohol and carbon +dioxide by yeast during fermentation + +```php +Beer::apparentDegreeOfFermentation(Gravity $originalGravity, Gravity $finalGravity) +``` + +##### Arguments + +- `Gravity $originalGravity` - Original Gravity of the beer +- `Gravity $finalGravity` - Final Gravity of the beer + +##### Returns + +- `float` - Apparent Degree of Fermentation + +--- + +#### Gravity Correction + +Gravity Correction based on Temperature of Sample and Hydrometer Calibration. +Source [Brewers Friend](https://www.brewersfriend.com/hydrometer-temp/) + +```php +Beer::gravityCorrection(Gravity $gravity, Temperature $temperature, Temperature $calibrationTemperature) +``` + +##### Arguments + +- `Gravity $gravity` - Gravity of the Sample +- `Temperature $temperature` - Temperature of the sample +- `Temperature $calibrationTemperature` - Temperature hydrometer is calibrated to + +##### Returns + +- `Gravity` - Corrected Gravity of Sample diff --git a/composer.json b/composer.json index e9ef7cc..775ec79 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": "^8.0" + "php": "^8.1" }, "require-dev": { "phpunit/phpunit": "^10.2" diff --git a/composer.lock b/composer.lock index 248ef13..89de56a 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "1d8155e165cc6defef86fc5481ad175b", + "content-hash": "0349f553d7df173a1da7b57ac2e1b944", "packages": [], "packages-dev": [ { @@ -68,16 +68,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.16.0", + "version": "v4.17.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "19526a33fb561ef417e822e85f08a00db4059c17" + "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/19526a33fb561ef417e822e85f08a00db4059c17", - "reference": "19526a33fb561ef417e822e85f08a00db4059c17", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", + "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", "shasum": "" }, "require": { @@ -118,9 +118,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.16.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.17.1" }, - "time": "2023-06-25T14:52:30+00:00" + "time": "2023-08-13T19:53:39+00:00" }, { "name": "phar-io/manifest", @@ -235,16 +235,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "10.1.2", + "version": "10.1.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "db1497ec8dd382e82c962f7abbe0320e4882ee4e" + "reference": "cd59bb34756a16ca8253ce9b2909039c227fff71" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/db1497ec8dd382e82c962f7abbe0320e4882ee4e", - "reference": "db1497ec8dd382e82c962f7abbe0320e4882ee4e", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/cd59bb34756a16ca8253ce9b2909039c227fff71", + "reference": "cd59bb34756a16ca8253ce9b2909039c227fff71", "shasum": "" }, "require": { @@ -301,7 +301,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.2" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.4" }, "funding": [ { @@ -309,20 +309,20 @@ "type": "github" } ], - "time": "2023-05-22T09:04:27+00:00" + "time": "2023-08-31T14:04:38+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "4.0.2", + "version": "4.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "5647d65443818959172645e7ed999217360654b6" + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/5647d65443818959172645e7ed999217360654b6", - "reference": "5647d65443818959172645e7ed999217360654b6", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c", + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c", "shasum": "" }, "require": { @@ -362,7 +362,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.0.2" + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0" }, "funding": [ { @@ -370,7 +370,7 @@ "type": "github" } ], - "time": "2023-05-07T09:13:23+00:00" + "time": "2023-08-31T06:24:48+00:00" }, { "name": "phpunit/php-invoker", @@ -437,16 +437,16 @@ }, { "name": "phpunit/php-text-template", - "version": "3.0.0", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "9f3d3709577a527025f55bcf0f7ab8052c8bb37d" + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/9f3d3709577a527025f55bcf0f7ab8052c8bb37d", - "reference": "9f3d3709577a527025f55bcf0f7ab8052c8bb37d", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748", "shasum": "" }, "require": { @@ -484,7 +484,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.0" + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.1" }, "funding": [ { @@ -492,7 +493,7 @@ "type": "github" } ], - "time": "2023-02-03T06:56:46+00:00" + "time": "2023-08-31T14:07:24+00:00" }, { "name": "phpunit/php-timer", @@ -555,16 +556,16 @@ }, { "name": "phpunit/phpunit", - "version": "10.2.6", + "version": "10.3.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "1c17815c129f133f3019cc18e8d0c8622e6d9bcd" + "reference": "0dafb1175c366dd274eaa9a625e914451506bcd1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1c17815c129f133f3019cc18e8d0c8622e6d9bcd", - "reference": "1c17815c129f133f3019cc18e8d0c8622e6d9bcd", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0dafb1175c366dd274eaa9a625e914451506bcd1", + "reference": "0dafb1175c366dd274eaa9a625e914451506bcd1", "shasum": "" }, "require": { @@ -589,7 +590,7 @@ "sebastian/diff": "^5.0", "sebastian/environment": "^6.0", "sebastian/exporter": "^5.0", - "sebastian/global-state": "^6.0", + "sebastian/global-state": "^6.0.1", "sebastian/object-enumerator": "^5.0", "sebastian/recursion-context": "^5.0", "sebastian/type": "^4.0", @@ -604,7 +605,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "10.2-dev" + "dev-main": "10.3-dev" } }, "autoload": { @@ -636,7 +637,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.2.6" + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.3.2" }, "funding": [ { @@ -652,7 +653,7 @@ "type": "tidelift" } ], - "time": "2023-07-17T12:08:28+00:00" + "time": "2023-08-15T05:34:23+00:00" }, { "name": "sebastian/cli-parser", @@ -823,16 +824,16 @@ }, { "name": "sebastian/comparator", - "version": "5.0.0", + "version": "5.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "72f01e6586e0caf6af81297897bd112eb7e9627c" + "reference": "2db5010a484d53ebf536087a70b4a5423c102372" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/72f01e6586e0caf6af81297897bd112eb7e9627c", - "reference": "72f01e6586e0caf6af81297897bd112eb7e9627c", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2db5010a484d53ebf536087a70b4a5423c102372", + "reference": "2db5010a484d53ebf536087a70b4a5423c102372", "shasum": "" }, "require": { @@ -843,7 +844,7 @@ "sebastian/exporter": "^5.0" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^10.3" }, "type": "library", "extra": { @@ -887,7 +888,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.0" + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.1" }, "funding": [ { @@ -895,20 +897,20 @@ "type": "github" } ], - "time": "2023-02-03T07:07:16+00:00" + "time": "2023-08-14T13:18:12+00:00" }, { "name": "sebastian/complexity", - "version": "3.0.0", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "e67d240970c9dc7ea7b2123a6d520e334dd61dc6" + "reference": "c70b73893e10757af9c6a48929fa6a333b56a97a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/e67d240970c9dc7ea7b2123a6d520e334dd61dc6", - "reference": "e67d240970c9dc7ea7b2123a6d520e334dd61dc6", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/c70b73893e10757af9c6a48929fa6a333b56a97a", + "reference": "c70b73893e10757af9c6a48929fa6a333b56a97a", "shasum": "" }, "require": { @@ -944,7 +946,8 @@ "homepage": "https://github.com/sebastianbergmann/complexity", "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", - "source": "https://github.com/sebastianbergmann/complexity/tree/3.0.0" + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/3.0.1" }, "funding": [ { @@ -952,7 +955,7 @@ "type": "github" } ], - "time": "2023-02-03T06:59:47+00:00" + "time": "2023-08-31T09:55:53+00:00" }, { "name": "sebastian/diff", @@ -1226,16 +1229,16 @@ }, { "name": "sebastian/lines-of-code", - "version": "2.0.0", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "17c4d940ecafb3d15d2cf916f4108f664e28b130" + "reference": "649e40d279e243d985aa8fb6e74dd5bb28dc185d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/17c4d940ecafb3d15d2cf916f4108f664e28b130", - "reference": "17c4d940ecafb3d15d2cf916f4108f664e28b130", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/649e40d279e243d985aa8fb6e74dd5bb28dc185d", + "reference": "649e40d279e243d985aa8fb6e74dd5bb28dc185d", "shasum": "" }, "require": { @@ -1271,7 +1274,8 @@ "homepage": "https://github.com/sebastianbergmann/lines-of-code", "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.0" + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.1" }, "funding": [ { @@ -1279,7 +1283,7 @@ "type": "github" } ], - "time": "2023-02-03T07:08:02+00:00" + "time": "2023-08-31T09:25:50+00:00" }, { "name": "sebastian/object-enumerator", @@ -1622,7 +1626,7 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": "^8.0" + "php": "^8.1" }, "platform-dev": [], "plugin-api-version": "2.3.0" diff --git a/src/AbstractUnitz.php b/src/AbstractUnitz.php index 5ceca4d..afdb4da 100644 --- a/src/AbstractUnitz.php +++ b/src/AbstractUnitz.php @@ -47,7 +47,7 @@ protected function hasOnlyOneValue(array $values): bool { $count = 0; foreach ($values as $value) { - if (!is_null($value)) { + if (is_numeric($value)) { $count++; } } diff --git a/src/BaseUnitz.php b/src/BaseUnitz.php index 6ea818c..839433e 100644 --- a/src/BaseUnitz.php +++ b/src/BaseUnitz.php @@ -21,6 +21,9 @@ public function __construct(array $preferences = []) $this->preferences = array_merge(self::DEFAULT_PREFERENCES, $preferences); } + /** + * @return array + */ public function getPreferences(): array { return $this->preferences; diff --git a/src/Calculate/Beer.php b/src/Calculate/Beer.php new file mode 100644 index 0000000..3f32cae --- /dev/null +++ b/src/Calculate/Beer.php @@ -0,0 +1,245 @@ +getGallon() === 0.0) { + throw new RuntimeException('Volume cannot be zero'); + } + + return ($weight->getPound() * $color->getLovibond()) / $volume->getGallon(); + } + + /** + * International Bitterness Units (IBU) + * + * International Bitterness Units (IBU) is the bitterness of the beer based on the alpha acid of the + * hops, weight of the hops, time in the boil, gravity of the wort, and volume of the wort. + * + * Based off Palmer's Calculation + * + * @param float $alphaAcid + * @param \Unitz\Weight $weight + * @param \Unitz\Time $time + * @param \Unitz\Gravity $gravity + * @param \Unitz\Volume $volume + * @return float + */ + public static function internationalBitternessUnits( + float $alphaAcid, + Weight $weight, + Time $time, + Gravity $gravity, + Volume $volume + ): float { + if ($volume->getGallon() === 0.0) { + throw new RuntimeException('Volume cannot be zero'); + } + + return self::alphaAcidUnit($alphaAcid, $weight) * self::hopUtilization( + $time, + $gravity + ) * 75 / $volume->getGallon(); + } + + /** + * Alpha Acid Units (AAU) + * + * Alpha Acid Units (AAU) is the potential bitterness of the hops based on the alpha acid and weight. + * + * @param float $alphaAcid + * @param \Unitz\Weight $weight + * @return float + */ + public static function alphaAcidUnit(float $alphaAcid, Weight $weight): float + { + return $alphaAcid * $weight->getOunce(); + } + + /** + * Hop Utilization + * + * This is a hop utilization factor based on the Tinseth formula derived + * by [Glenn Tinseth](https://beersmith.com/blog/2011/02/10/beer-bitterness-and-ibus-with-glenn-tinseth-bshb-podcast-9/]). + * + * @param \Unitz\Time $time + * @param \Unitz\Gravity $gravity + * @return float + */ + public static function hopUtilization(Time $time, Gravity $gravity): float + { + return (1.65 * (0.000125 ** ($gravity->getSpecificGravity() - 1))) * (1 - (M_E ** (-0.04 * $time->getMinute( + )))) / 4.15; + } + + /** + * Calories + * + * Determines the number of calories in a finished beer based on the original gravity, final gravity and the volume of the + * beer consumed. + * + * @param \Unitz\Gravity $originalGravity + * @param \Unitz\Gravity $finalGravity + * @param \Unitz\Volume $volume + * @return float + */ + public static function calories( + Gravity $originalGravity, + Gravity $finalGravity, + Volume $volume = new Volume(ounce: self::CALORIE_BASE_VOLUME_IN_OUNCE) + ): float { + $volumeMultiplier = $volume->getOunce() / self::CALORIE_BASE_VOLUME_IN_OUNCE; + return $volumeMultiplier * ((6.9 * self::alcoholByWeight( + $originalGravity, + $finalGravity + )) + 4.0 * (self::realExtract( + $originalGravity, + $finalGravity + ) - 0.1)) * $finalGravity->getSpecificGravity() * 3.55; + } + + /** + * ABW + * + * @param \Unitz\Gravity $originalGravity + * @param \Unitz\Gravity $finalGravity + * @return float + * @throws \RuntimeException + */ + public static function alcoholByWeight(Gravity $originalGravity, Gravity $finalGravity): float + { + if ($finalGravity->getSpecificGravity() === 0.0) { + throw new RuntimeException('Final Gravity cannot be zero'); + } + + return (0.79 * self::alcoholByVolume($originalGravity, $finalGravity)) / $finalGravity->getSpecificGravity(); + } + + /** + * ABV + * + * Source: https://www.brewersfriend.com/abv-calculator/ + * Source: https://www.brewersfriend.com/2011/06/16/alcohol-by-volume-calculator-updated/ + * + * @param \Unitz\Gravity $originalGravity + * @param \Unitz\Gravity $finalGravity + * @param string $formulaVersion + * @return float + * @throws \UnexpectedValueException + */ + public static function alcoholByVolume( + Gravity $originalGravity, + Gravity $finalGravity, + string $formulaVersion = self::ABV_ALTERNATE_FORMULA + ): float { + if ($formulaVersion === self::ABV_ALTERNATE_FORMULA) { + return (76.08 * ($originalGravity->getSpecificGravity() - $finalGravity->getSpecificGravity( + )) / (1.775 - $originalGravity->getSpecificGravity())) * ($finalGravity->getSpecificGravity( + ) / 0.794); + } + + if ($formulaVersion === self::ABV_STANDARD_FORMULA) { + return ($originalGravity->getSpecificGravity() - $finalGravity->getSpecificGravity()) * 131.25; + } + + throw new UnexpectedValueException('Invalid ABV formula version'); + } + + /** + * Determine the Real Extract value. + * https://beerandbrewing.com/dictionary/ewOeMFnY4x/ + * + * @param \Unitz\Gravity $originalGravity + * @param \Unitz\Gravity $finalGravity + * @return float + */ + public static function realExtract(Gravity $originalGravity, Gravity $finalGravity): float + { + return (0.1808 * $originalGravity->getPlato()) + (0.8192 * $finalGravity->getPlato()); + } + + /** + * Apparent Degree of Fermentation (ADF) + * + * @param \Unitz\Gravity $originalGravity + * @param \Unitz\Gravity $finalGravity + * @return float + */ + public static function apparentDegreeOfFermentation(Gravity $originalGravity, Gravity $finalGravity): float + { + if ($originalGravity->getSpecificGravity() <= 1.0) { + throw new RuntimeException('Original Gravity cannot be less than 1.0'); + } + + return ($originalGravity->getSpecificGravity() - $finalGravity->getSpecificGravity( + )) / ($originalGravity->getSpecificGravity() - 1); + } + + /** + * Gravity Correction based on the Sample Temperature, Sample Gravity and Hydrometer Calibration Temperature + * Source: https://www.brewersfriend.com/hydrometer-temp/ + * + * @param \Unitz\Temperature $sampleTemperature + * @param \Unitz\Gravity $gravity + * @param \Unitz\Temperature $calibrateTemperature //The temperature in which your hydrometer is calibrated to. + * @return \Unitz\Gravity + */ + public static function gravityCorrection( + Temperature $sampleTemperature, + Gravity $gravity, + Temperature $calibrateTemperature = new Temperature(fahrenheit: self::DEFAULT_CALIBRATE_TEMPERATURE) + ): Gravity { + $sampleTemperatureFahrenheit = $sampleTemperature->getFahrenheit(); + $calibrateTemperatureFahrenheit = $calibrateTemperature->getFahrenheit(); + $specificGravity = $gravity->getSpecificGravity(); + + $specificGravity *= ((1.00130346 - 0.000134722124 * $sampleTemperatureFahrenheit + 0.00000204052596 * ($sampleTemperatureFahrenheit ** 2) - 0.00000000232820948 * ($sampleTemperatureFahrenheit ** 3)) / (1.00130346 - 0.000134722124 * $calibrateTemperatureFahrenheit + 0.00000204052596 * ($calibrateTemperatureFahrenheit ** 2) - 0.00000000232820948 * ($calibrateTemperatureFahrenheit ** 3))); + + return new Gravity(specificGravity: $specificGravity); + } +} \ No newline at end of file diff --git a/src/Color.php b/src/Color.php index 5fae31c..feadcce 100644 --- a/src/Color.php +++ b/src/Color.php @@ -23,19 +23,19 @@ public function __construct( parent::__construct($preferences); - if ($srm) { + if (is_numeric($srm)) { $this->setSrm($srm); } - if ($ebc) { + if (is_numeric($ebc)) { $this->setEbc($ebc); } - if ($lovibond) { + if (is_numeric($lovibond)) { $this->setLovibond($lovibond); } - if ($userValue) { + if (is_numeric($userValue)) { $this->setValue($userValue); } } diff --git a/src/Gravity.php b/src/Gravity.php index 2ceb6a1..9269a72 100644 --- a/src/Gravity.php +++ b/src/Gravity.php @@ -25,19 +25,19 @@ public function __construct( parent::__construct($preferences); - if ($plato) { + if (is_numeric($plato)) { $this->setPlato($plato); } - if ($specificGravity) { + if (is_numeric($specificGravity)) { $this->setSpecificGravity($specificGravity); } - if ($brix) { + if (is_numeric($brix)) { $this->setBrix($brix); } - if ($userValue) { + if (is_numeric($userValue)) { $this->setValue($userValue); } } @@ -109,12 +109,14 @@ public function setBrix(float $brix): self } /** + * Source: Brewers Friend - https://www.brewersfriend.com/plato-to-sg-conversion-chart/ + * * @param float $plato * @return float */ public static function convertPlatoToSpecificGravity(float $plato): float { - return 259 / (259 - $plato); + return 1 + ($plato / (258.6 - (($plato / 258.2) * 227.1))); } /** @@ -129,12 +131,14 @@ public static function convertPlatoToBrix(float $plato): float } /** + * Source: Brewers Friend - https://www.brewersfriend.com/plato-to-sg-conversion-chart/ + * * @param float $specificGravity * @return float */ public static function convertSpecificGravityToPlato(float $specificGravity): float { - return 259 - (259 / $specificGravity); + return (-1 * 616.868) + (1111.14 * $specificGravity) - (630.272 * $specificGravity ** 2) + (135.997 * $specificGravity ** 3); } /** diff --git a/src/Pressure.php b/src/Pressure.php index 79cc5d5..5f911fb 100644 --- a/src/Pressure.php +++ b/src/Pressure.php @@ -21,15 +21,15 @@ public function __construct( parent::__construct($preferences); - if ($bar) { + if (is_numeric($bar)) { $this->setBar($bar); } - if ($psi) { + if (is_numeric($psi)) { $this->setPsi($psi); } - if ($userValue) { + if (is_numeric($userValue)) { $this->setValue($userValue); } } diff --git a/src/Temperature.php b/src/Temperature.php index 80928bd..8c8d605 100644 --- a/src/Temperature.php +++ b/src/Temperature.php @@ -21,15 +21,15 @@ public function __construct( parent::__construct($preferences); - if ($fahrenheit) { + if (is_numeric($fahrenheit)) { $this->setFahrenheit($fahrenheit); } - if ($celsius) { + if (is_numeric($celsius)) { $this->setCelsius($celsius); } - if ($userValue) { + if (is_numeric($userValue)) { $this->setValue($userValue); } } diff --git a/src/Time.php b/src/Time.php index a916379..3af4962 100644 --- a/src/Time.php +++ b/src/Time.php @@ -35,39 +35,39 @@ public function __construct( parent::__construct($preferences); - if ($millisecond) { + if (is_numeric($millisecond)) { $this->setMillisecond($millisecond); } - if ($second) { + if (is_numeric($second)) { $this->setSecond($second); } - if ($minute) { + if (is_numeric($minute)) { $this->setMinute($minute); } - if ($hour) { + if (is_numeric($hour)) { $this->setHour($hour); } - if ($day) { + if (is_numeric($day)) { $this->setDay($day); } - if ($week) { + if (is_numeric($week)) { $this->setWeek($week); } - if ($month) { + if (is_numeric($month)) { $this->setMonth($month); } - if ($year) { + if (is_numeric($year)) { $this->setYear($year); } - if ($userValue) { + if (is_numeric($userValue)) { $this->setValue($userValue); } } diff --git a/src/Volume.php b/src/Volume.php index 3a3b120..664beac 100644 --- a/src/Volume.php +++ b/src/Volume.php @@ -29,31 +29,31 @@ public function __construct( parent::__construct($preferences); - if ($ounce) { + if (is_numeric($ounce)) { $this->setOunce($ounce); } - if ($gallon) { + if (is_numeric($gallon)) { $this->setGallon($gallon); } - if ($barrel) { + if (is_numeric($barrel)) { $this->setBarrel($barrel); } - if ($milliliter) { + if (is_numeric($milliliter)) { $this->setMilliliter($milliliter); } - if ($liter) { + if (is_numeric($liter)) { $this->setLiter($liter); } - if ($hectoliter) { + if (is_numeric($hectoliter)) { $this->setHectoliter($hectoliter); } - if ($userValue) { + if (is_numeric($userValue)) { $this->setValue($userValue); } } diff --git a/src/Weight.php b/src/Weight.php index 946d048..6a6c36b 100644 --- a/src/Weight.php +++ b/src/Weight.php @@ -25,23 +25,23 @@ public function __construct( parent::__construct($preferences); - if ($ounce) { + if (is_numeric($ounce)) { $this->setOunce($ounce); } - if ($pound) { + if (is_numeric($pound)) { $this->setPound($pound); } - if ($gram) { + if (is_numeric($gram)) { $this->setGram($gram); } - if ($kilogram) { + if (is_numeric($kilogram)) { $this->setKilogram($kilogram); } - if ($userValue) { + if (is_numeric($userValue)) { $this->setValue($userValue); } } diff --git a/tests/Calculate/BeerTest.php b/tests/Calculate/BeerTest.php new file mode 100644 index 0000000..2890644 --- /dev/null +++ b/tests/Calculate/BeerTest.php @@ -0,0 +1,176 @@ +assertEquals($expected, $actual); + } + + public function testStandardReferenceMethodThrowsRuntimeException(): void + { + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('Volume cannot be zero'); + + $weight = new Weight(pound: 7); + $color = new Color(lovibond: 5); + $volume = new Volume(gallon: 0); + Beer::standardReferenceMethod($weight, $color, $volume); + } + + public function testMaltColorUnitCalculatesCorrectly(): void + { + $weight = new Weight(pound: 5); + $color = new Color(lovibond: 5); + $volume = new Volume(gallon: 5); + $expected = 5; + $actual = Beer::maltColorUnit($weight, $color, $volume); + $this->assertEquals($expected, $actual); + } + + public function testMaltColorUnitThrowsRuntimeException(): void + { + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('Volume cannot be zero'); + + $weight = new Weight(pound: 7); + $color = new Color(lovibond: 5); + $volume = new Volume(gallon: 0); + Beer::maltColorUnit($weight, $color, $volume); + } + + public function testInternationalBitternessUnitsCalculatesCorrectly(): void + { + $alphaAcid = 6.4; + $weight = new Weight(ounce: 1.5); + $time = new Time(minute: 60); + $gravity = new Gravity(specificGravity: 1.080); + $volume = new Volume(gallon: 5); + $expected = 25.365869680614512; + $actual = Beer::internationalBitternessUnits($alphaAcid, $weight, $time, $gravity, $volume); + $this->assertEquals($expected, $actual); + } + + public function testInternationalBitternessUnitsThrowsRuntimeException(): void + { + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('Volume cannot be zero'); + + $alphaAcid = 6.4; + $weight = new Weight(ounce: 1.5); + $time = new Time(minute: 60); + $gravity = new Gravity(specificGravity: 1.080); + $volume = new Volume(gallon: 0); + Beer::internationalBitternessUnits($alphaAcid, $weight, $time, $gravity, $volume); + } + + public function testAlphaAcidUnitCalculatesCorrectly(): void + { + $alphaAcid = 6.4; + $weight = new Weight(ounce: 1.5); + $expected = 9.600000000000001; + $actual = Beer::alphaAcidUnit($alphaAcid, $weight); + $this->assertEquals($expected, $actual); + } + + public function testHopUtilizationCalculatesCorrectly(): void + { + $time = new Time(minute: 120); + $gravity = new Gravity(specificGravity: 1.030); + $expected = 0.30113013986478654; + $actual = Beer::hopUtilization($time, $gravity); + $this->assertEquals($expected, $actual); + } + + public function testCaloriesCalculatesCorrectly(): void + { + $originalGravity = new Gravity(specificGravity: 1.070); + $finalGravity = new Gravity(specificGravity: 1.015); + $expected = 235.00333730524883; + $actual = Beer::calories($originalGravity, $finalGravity); + $this->assertEquals($expected, $actual); + } + + public function testAlcoholByWeightCalculatesCorrectly(): void + { + $originalGravity = new Gravity(specificGravity: 1.055); + $finalGravity = new Gravity(specificGravity: 1); + $expected = 5.782388748950455; + $actual = Beer::alcoholByWeight($originalGravity, $finalGravity); + $this->assertEquals($expected, $actual); + } + + public function testAlcoholByWeightThrowsRuntimeException(): void + { + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('Final Gravity cannot be zero'); + + $originalGravity = new Gravity(specificGravity: 1.055); + $finalGravity = new Gravity(specificGravity: 0); + Beer::alcoholByWeight($originalGravity, $finalGravity); + } + + public function testAlcoholByVolumeCalculatesCorrectly(): void + { + $originalGravity = new Gravity(specificGravity: 1.055); + $finalGravity = new Gravity(specificGravity: 1); + $expected = 7.319479429051208; + $actual = Beer::alcoholByVolume($originalGravity, $finalGravity); + $this->assertEquals($expected, $actual); + } + + public function testRealExtractCalculatesCorrectly(): void + { + $originalGravity = new Gravity(specificGravity: 1.070); + $finalGravity = new Gravity(specificGravity: 1.015); + $expected = 6.218109887422394; + $actual = Beer::realExtract($originalGravity, $finalGravity); + $this->assertEquals($expected, $actual); + } + + public function testAttenuationCalculatesCorrectly(): void + { + $originalGravity = new Gravity(specificGravity: 1.054); + $finalGravity = new Gravity(specificGravity: 1.012); + $expected = 0.7777777777777778; + $actual = Beer::apparentDegreeOfFermentation($originalGravity, $finalGravity); + $this->assertEquals($expected, $actual); + } + + public function testAttenuationThrowsRuntimeException(): void + { + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('Original Gravity cannot be less than 1.0'); + + $originalGravity = new Gravity(specificGravity: 1); + $finalGravity = new Gravity(specificGravity: 1.012); + Beer::apparentDegreeOfFermentation($originalGravity, $finalGravity); + } + + public function testGravityCorrectionCalculatesCorrectly(): void + { + $temperature = new Temperature(fahrenheit: 100.4); + $specificGravity = new Gravity(specificGravity: 1.050); + $calibrateTemperature = new Temperature(fahrenheit: 60); + $expected = new Gravity(specificGravity: 1.0562227410996516); + $actual = Beer::gravityCorrection($temperature, $specificGravity, $calibrateTemperature); + $this->assertEquals($expected, $actual); + } +} \ No newline at end of file diff --git a/tests/GravityTest.php b/tests/GravityTest.php index ad74371..0079c6a 100644 --- a/tests/GravityTest.php +++ b/tests/GravityTest.php @@ -8,9 +8,9 @@ final class GravityTest extends TestCase { - public const TEST_PLATO = 12.152961955125761; - public const TEST_SPECIFIC_GRAVITY = 1.0492327639471877; - public const TEST_BRIX = 12.204818625308235; + public const TEST_PLATO = 12.155178526444615; + public const TEST_SPECIFIC_GRAVITY = 1.0490215002286123; + public const TEST_BRIX = 12.154604415669382; public function testSetPlatoWillReturnPlatoWithGetValueAndDefaultPreferences(): void { @@ -34,7 +34,7 @@ public function testSetPlatoWillReturnSpecificGravityWithGetSpecificGravity(): v { $gravity = new Gravity(plato: self::TEST_PLATO); $actual = $gravity->getSpecificGravity(); - $expected = self::TEST_SPECIFIC_GRAVITY; + $expected = 1.0490308268117239; // TODO: This is a slightly different value than plato -> SG conversion $this->assertEquals($expected, $actual); } @@ -43,7 +43,7 @@ public function testSetPlatoWillReturnBrixWithGetBrix(): void { $gravity = new Gravity(plato: self::TEST_PLATO); $actual = $gravity->getBrix(); - $expected = self::TEST_BRIX; + $expected = 12.156821583620058; // TODO: this is a slightly different value than plato -> brix conversion; $this->assertEquals($expected, $actual); } diff --git a/tests/TimeTest.php b/tests/TimeTest.php index 8b0f4de..55f1ba5 100644 --- a/tests/TimeTest.php +++ b/tests/TimeTest.php @@ -14,11 +14,12 @@ final class TimeTest extends TestCase public const TEST_DAY = 42; public const TEST_WEEK = 6; public const TEST_MONTH = 1.4; + public const TEST_YEAR = 0.11506849315068493; public function testSetMinuteWillReturnMinuteWithGetValueAndDefaultPreferences(): void { - $gravity = new Time(minute: self::TEST_MINUTE); - $actual = $gravity->getValue(); + $time = new Time(minute: self::TEST_MINUTE); + $actual = $time->getValue(); $expected = self::TEST_MINUTE; $this->assertEquals($expected, $actual); @@ -28,8 +29,8 @@ public function testSetMinuteWillReturnMinuteWithGetValueAndDefaultPreferences() public function testSetMillisecondWillReturnMillisecondWithGetMillisecond(): void { - $gravity = new Time(millisecond: self::TEST_MILLISECOND); - $actual = $gravity->getMillisecond(); + $time = new Time(millisecond: self::TEST_MILLISECOND); + $actual = $time->getMillisecond(); $expected = self::TEST_MILLISECOND; $this->assertEquals($expected, $actual); @@ -37,8 +38,8 @@ public function testSetMillisecondWillReturnMillisecondWithGetMillisecond(): voi public function testSetMillisecondWillReturnMinuteWithGetMinute(): void { - $gravity = new Time(millisecond: self::TEST_MILLISECOND); - $actual = $gravity->getMinute(); + $time = new Time(millisecond: self::TEST_MILLISECOND); + $actual = $time->getMinute(); $expected = self::TEST_MINUTE; $this->assertEquals($expected, $actual); @@ -46,8 +47,8 @@ public function testSetMillisecondWillReturnMinuteWithGetMinute(): void public function testSetMillisecondWillReturnSecondWithGetSecond(): void { - $gravity = new Time(millisecond: self::TEST_MILLISECOND); - $actual = $gravity->getSecond(); + $time = new Time(millisecond: self::TEST_MILLISECOND); + $actual = $time->getSecond(); $expected = self::TEST_SECOND; $this->assertEquals($expected, $actual); @@ -55,8 +56,8 @@ public function testSetMillisecondWillReturnSecondWithGetSecond(): void public function testSetMillisecondWillReturnHourWithGetHour(): void { - $gravity = new Time(millisecond: self::TEST_MILLISECOND); - $actual = $gravity->getHour(); + $time = new Time(millisecond: self::TEST_MILLISECOND); + $actual = $time->getHour(); $expected = self::TEST_HOUR; $this->assertEquals($expected, $actual); @@ -64,17 +65,26 @@ public function testSetMillisecondWillReturnHourWithGetHour(): void public function testSetMillisecondWillReturnDayWithGetDay(): void { - $gravity = new Time(millisecond: self::TEST_MILLISECOND); - $actual = $gravity->getDay(); + $time = new Time(millisecond: self::TEST_MILLISECOND); + $actual = $time->getDay(); $expected = self::TEST_DAY; $this->assertEquals($expected, $actual); } + public function testSetMillisecondWillReturnWeekWithGetWeek(): void + { + $time = new Time(millisecond: self::TEST_MILLISECOND); + $actual = $time->getWeek(); + $expected = self::TEST_WEEK; + + $this->assertEquals($expected, $actual); + } + public function testSetMillisecondWillReturnMonthWithGetMonth(): void { - $gravity = new Time(millisecond: self::TEST_MILLISECOND); - $actual = $gravity->getMonth(); + $time = new Time(millisecond: self::TEST_MILLISECOND); + $actual = $time->getMonth(); $expected = self::TEST_MONTH; $this->assertEquals($expected, $actual); @@ -82,9 +92,9 @@ public function testSetMillisecondWillReturnMonthWithGetMonth(): void public function testSetMillisecondWillReturnYearWithGetYear(): void { - $gravity = new Time(millisecond: self::TEST_MILLISECOND); - $actual = $gravity->getMonth(); - $expected = self::TEST_MONTH; + $time = new Time(millisecond: self::TEST_MILLISECOND); + $actual = $time->getYear(); + $expected = self::TEST_YEAR; $this->assertEquals($expected, $actual); } @@ -93,8 +103,8 @@ public function testSetMillisecondWillReturnYearWithGetYear(): void public function testSetSecondWillReturnMillisecondWithGetMillisecond(): void { - $gravity = new Time(second: self::TEST_SECOND); - $actual = $gravity->getMillisecond(); + $time = new Time(second: self::TEST_SECOND); + $actual = $time->getMillisecond(); $expected = self::TEST_MILLISECOND; $this->assertEquals($expected, $actual); @@ -102,8 +112,8 @@ public function testSetSecondWillReturnMillisecondWithGetMillisecond(): void public function testSetSecondWillReturnMinuteWithGetMinute(): void { - $gravity = new Time(second: self::TEST_SECOND); - $actual = $gravity->getMinute(); + $time = new Time(second: self::TEST_SECOND); + $actual = $time->getMinute(); $expected = self::TEST_MINUTE; $this->assertEquals($expected, $actual); @@ -111,8 +121,8 @@ public function testSetSecondWillReturnMinuteWithGetMinute(): void public function testSetSecondWillReturnSecondWithGetSecond(): void { - $gravity = new Time(second: self::TEST_SECOND); - $actual = $gravity->getSecond(); + $time = new Time(second: self::TEST_SECOND); + $actual = $time->getSecond(); $expected = self::TEST_SECOND; $this->assertEquals($expected, $actual); @@ -120,8 +130,8 @@ public function testSetSecondWillReturnSecondWithGetSecond(): void public function testSetSecondWillReturnHourWithGetHour(): void { - $gravity = new Time(second: self::TEST_SECOND); - $actual = $gravity->getHour(); + $time = new Time(second: self::TEST_SECOND); + $actual = $time->getHour(); $expected = self::TEST_HOUR; $this->assertEquals($expected, $actual); @@ -129,17 +139,26 @@ public function testSetSecondWillReturnHourWithGetHour(): void public function testSetSecondWillReturnDayWithGetDay(): void { - $gravity = new Time(second: self::TEST_SECOND); - $actual = $gravity->getDay(); + $time = new Time(second: self::TEST_SECOND); + $actual = $time->getDay(); $expected = self::TEST_DAY; $this->assertEquals($expected, $actual); } + public function testSetSecondWillReturnWeekWithGetWeek(): void + { + $time = new Time(second: self::TEST_SECOND); + $actual = $time->getWeek(); + $expected = self::TEST_WEEK; + + $this->assertEquals($expected, $actual); + } + public function testSetSecondWillReturnMonthWithGetMonth(): void { - $gravity = new Time(second: self::TEST_SECOND); - $actual = $gravity->getMonth(); + $time = new Time(second: self::TEST_SECOND); + $actual = $time->getMonth(); $expected = self::TEST_MONTH; $this->assertEquals($expected, $actual); @@ -147,9 +166,9 @@ public function testSetSecondWillReturnMonthWithGetMonth(): void public function testSetSecondWillReturnYearWithGetYear(): void { - $gravity = new Time(second: self::TEST_SECOND); - $actual = $gravity->getMonth(); - $expected = self::TEST_MONTH; + $time = new Time(second: self::TEST_SECOND); + $actual = $time->getYear(); + $expected = self::TEST_YEAR; $this->assertEquals($expected, $actual); } @@ -158,8 +177,8 @@ public function testSetSecondWillReturnYearWithGetYear(): void public function testSetMinuteWillReturnMinuteWithGetMinute(): void { - $gravity = new Time(minute: self::TEST_MINUTE); - $actual = $gravity->getMinute(); + $time = new Time(minute: self::TEST_MINUTE); + $actual = $time->getMinute(); $expected = self::TEST_MINUTE; $this->assertEquals($expected, $actual); @@ -167,8 +186,8 @@ public function testSetMinuteWillReturnMinuteWithGetMinute(): void public function testSetMinuteWillReturnMillisecondWithGetMillisecond(): void { - $gravity = new Time(minute: self::TEST_MINUTE); - $actual = $gravity->getMillisecond(); + $time = new Time(minute: self::TEST_MINUTE); + $actual = $time->getMillisecond(); $expected = self::TEST_MILLISECOND; $this->assertEquals($expected, $actual); @@ -176,8 +195,8 @@ public function testSetMinuteWillReturnMillisecondWithGetMillisecond(): void public function testSetMinuteWillReturnSecondWithGetSecond(): void { - $gravity = new Time(minute: self::TEST_MINUTE); - $actual = $gravity->getSecond(); + $time = new Time(minute: self::TEST_MINUTE); + $actual = $time->getSecond(); $expected = self::TEST_SECOND; $this->assertEquals($expected, $actual); @@ -185,8 +204,8 @@ public function testSetMinuteWillReturnSecondWithGetSecond(): void public function testSetMinuteWillReturnHourWithGetHour(): void { - $gravity = new Time(minute: self::TEST_MINUTE); - $actual = $gravity->getHour(); + $time = new Time(minute: self::TEST_MINUTE); + $actual = $time->getHour(); $expected = self::TEST_HOUR; $this->assertEquals($expected, $actual); @@ -194,17 +213,26 @@ public function testSetMinuteWillReturnHourWithGetHour(): void public function testSetMinuteWillReturnDayWithGetDay(): void { - $gravity = new Time(minute: self::TEST_MINUTE); - $actual = $gravity->getDay(); + $time = new Time(minute: self::TEST_MINUTE); + $actual = $time->getDay(); $expected = self::TEST_DAY; $this->assertEquals($expected, $actual); } + public function testSetMinuteWillReturnWeekWithGetWeek(): void + { + $time = new Time(minute: self::TEST_MINUTE); + $actual = $time->getWeek(); + $expected = self::TEST_WEEK; + + $this->assertEquals($expected, $actual); + } + public function testSetMinuteWillReturnMonthWithGetMonth(): void { - $gravity = new Time(minute: self::TEST_MINUTE); - $actual = $gravity->getMonth(); + $time = new Time(minute: self::TEST_MINUTE); + $actual = $time->getMonth(); $expected = self::TEST_MONTH; $this->assertEquals($expected, $actual); @@ -212,9 +240,9 @@ public function testSetMinuteWillReturnMonthWithGetMonth(): void public function testSetMinuteWillReturnYearWithGetYear(): void { - $gravity = new Time(minute: self::TEST_MINUTE); - $actual = $gravity->getMonth(); - $expected = self::TEST_MONTH; + $time = new Time(minute: self::TEST_MINUTE); + $actual = $time->getYear(); + $expected = self::TEST_YEAR; $this->assertEquals($expected, $actual); } @@ -223,8 +251,8 @@ public function testSetMinuteWillReturnYearWithGetYear(): void public function testSetHourWillReturnMinuteWithGetMinute(): void { - $gravity = new Time(hour: self::TEST_HOUR); - $actual = $gravity->getMinute(); + $time = new Time(hour: self::TEST_HOUR); + $actual = $time->getMinute(); $expected = self::TEST_MINUTE; $this->assertEquals($expected, $actual); @@ -232,8 +260,8 @@ public function testSetHourWillReturnMinuteWithGetMinute(): void public function testSetHourWillReturnMillisecondWithGetMillisecond(): void { - $gravity = new Time(hour: self::TEST_HOUR); - $actual = $gravity->getMillisecond(); + $time = new Time(hour: self::TEST_HOUR); + $actual = $time->getMillisecond(); $expected = self::TEST_MILLISECOND; $this->assertEquals($expected, $actual); @@ -241,8 +269,8 @@ public function testSetHourWillReturnMillisecondWithGetMillisecond(): void public function testSetHourWillReturnSecondWithGetSecond(): void { - $gravity = new Time(hour: self::TEST_HOUR); - $actual = $gravity->getSecond(); + $time = new Time(hour: self::TEST_HOUR); + $actual = $time->getSecond(); $expected = self::TEST_SECOND; $this->assertEquals($expected, $actual); @@ -250,8 +278,8 @@ public function testSetHourWillReturnSecondWithGetSecond(): void public function testSetHourWillReturnHourWithGetHour(): void { - $gravity = new Time(hour: self::TEST_HOUR); - $actual = $gravity->getHour(); + $time = new Time(hour: self::TEST_HOUR); + $actual = $time->getHour(); $expected = self::TEST_HOUR; $this->assertEquals($expected, $actual); @@ -259,17 +287,26 @@ public function testSetHourWillReturnHourWithGetHour(): void public function testSetHourWillReturnDayWithGetDay(): void { - $gravity = new Time(hour: self::TEST_HOUR); - $actual = $gravity->getDay(); + $time = new Time(hour: self::TEST_HOUR); + $actual = $time->getDay(); $expected = self::TEST_DAY; $this->assertEquals($expected, $actual); } + public function testSetHourWillReturnWeekWithGetWeek(): void + { + $time = new Time(hour: self::TEST_HOUR); + $actual = $time->getWeek(); + $expected = self::TEST_WEEK; + + $this->assertEquals($expected, $actual); + } + public function testSetHourWillReturnMonthWithGetMonth(): void { - $gravity = new Time(hour: self::TEST_HOUR); - $actual = $gravity->getMonth(); + $time = new Time(hour: self::TEST_HOUR); + $actual = $time->getMonth(); $expected = self::TEST_MONTH; $this->assertEquals($expected, $actual); @@ -277,9 +314,9 @@ public function testSetHourWillReturnMonthWithGetMonth(): void public function testSetHourWillReturnYearWithGetYear(): void { - $gravity = new Time(hour: self::TEST_HOUR); - $actual = $gravity->getMonth(); - $expected = self::TEST_MONTH; + $time = new Time(hour: self::TEST_HOUR); + $actual = $time->getYear(); + $expected = self::TEST_YEAR; $this->assertEquals($expected, $actual); } @@ -288,8 +325,8 @@ public function testSetHourWillReturnYearWithGetYear(): void public function testSetDayWillReturnMinuteWithGetMinute(): void { - $gravity = new Time(day: self::TEST_DAY); - $actual = $gravity->getMinute(); + $time = new Time(day: self::TEST_DAY); + $actual = $time->getMinute(); $expected = self::TEST_MINUTE; $this->assertEquals($expected, $actual); @@ -297,8 +334,8 @@ public function testSetDayWillReturnMinuteWithGetMinute(): void public function testSetDayWillReturnMillisecondWithGetMillisecond(): void { - $gravity = new Time(day: self::TEST_DAY); - $actual = $gravity->getMillisecond(); + $time = new Time(day: self::TEST_DAY); + $actual = $time->getMillisecond(); $expected = self::TEST_MILLISECOND; $this->assertEquals($expected, $actual); @@ -306,8 +343,8 @@ public function testSetDayWillReturnMillisecondWithGetMillisecond(): void public function testSetDayWillReturnSecondWithGetSecond(): void { - $gravity = new Time(day: self::TEST_DAY); - $actual = $gravity->getSecond(); + $time = new Time(day: self::TEST_DAY); + $actual = $time->getSecond(); $expected = self::TEST_SECOND; $this->assertEquals($expected, $actual); @@ -315,8 +352,8 @@ public function testSetDayWillReturnSecondWithGetSecond(): void public function testSetDayWillReturnHourWithGetHour(): void { - $gravity = new Time(day: self::TEST_DAY); - $actual = $gravity->getHour(); + $time = new Time(day: self::TEST_DAY); + $actual = $time->getHour(); $expected = self::TEST_HOUR; $this->assertEquals($expected, $actual); @@ -324,17 +361,26 @@ public function testSetDayWillReturnHourWithGetHour(): void public function testSetDayWillReturnDayWithGetDay(): void { - $gravity = new Time(day: self::TEST_DAY); - $actual = $gravity->getDay(); + $time = new Time(day: self::TEST_DAY); + $actual = $time->getDay(); $expected = self::TEST_DAY; $this->assertEquals($expected, $actual); } + public function testSetDayWillReturnWeekWithGetWeek(): void + { + $time = new Time(day: self::TEST_DAY); + $actual = $time->getWeek(); + $expected = self::TEST_WEEK; + + $this->assertEquals($expected, $actual); + } + public function testSetDayWillReturnMonthWithGetMonth(): void { - $gravity = new Time(day: self::TEST_DAY); - $actual = $gravity->getMonth(); + $time = new Time(day: self::TEST_DAY); + $actual = $time->getMonth(); $expected = self::TEST_MONTH; $this->assertEquals($expected, $actual); @@ -342,9 +388,9 @@ public function testSetDayWillReturnMonthWithGetMonth(): void public function testSetDayWillReturnYearWithGetYear(): void { - $gravity = new Time(day: self::TEST_DAY); - $actual = $gravity->getMonth(); - $expected = self::TEST_MONTH; + $time = new Time(day: self::TEST_DAY); + $actual = $time->getYear(); + $expected = self::TEST_YEAR; $this->assertEquals($expected, $actual); } @@ -353,8 +399,8 @@ public function testSetDayWillReturnYearWithGetYear(): void public function testSetWeekWillReturnMinuteWithGetMinute(): void { - $gravity = new Time(week: self::TEST_WEEK); - $actual = $gravity->getMinute(); + $time = new Time(week: self::TEST_WEEK); + $actual = $time->getMinute(); $expected = self::TEST_MINUTE; $this->assertEquals($expected, $actual); @@ -362,8 +408,8 @@ public function testSetWeekWillReturnMinuteWithGetMinute(): void public function testSetWeekWillReturnMillisecondWithGetMillisecond(): void { - $gravity = new Time(week: self::TEST_WEEK); - $actual = $gravity->getMillisecond(); + $time = new Time(week: self::TEST_WEEK); + $actual = $time->getMillisecond(); $expected = self::TEST_MILLISECOND; $this->assertEquals($expected, $actual); @@ -371,8 +417,8 @@ public function testSetWeekWillReturnMillisecondWithGetMillisecond(): void public function testSetWeekWillReturnSecondWithGetSecond(): void { - $gravity = new Time(week: self::TEST_WEEK); - $actual = $gravity->getSecond(); + $time = new Time(week: self::TEST_WEEK); + $actual = $time->getSecond(); $expected = self::TEST_SECOND; $this->assertEquals($expected, $actual); @@ -380,8 +426,8 @@ public function testSetWeekWillReturnSecondWithGetSecond(): void public function testSetWeekWillReturnHourWithGetHour(): void { - $gravity = new Time(week: self::TEST_WEEK); - $actual = $gravity->getHour(); + $time = new Time(week: self::TEST_WEEK); + $actual = $time->getHour(); $expected = self::TEST_HOUR; $this->assertEquals($expected, $actual); @@ -389,17 +435,26 @@ public function testSetWeekWillReturnHourWithGetHour(): void public function testSetWeekWillReturnDayWithGetDay(): void { - $gravity = new Time(week: self::TEST_WEEK); - $actual = $gravity->getDay(); + $time = new Time(week: self::TEST_WEEK); + $actual = $time->getDay(); $expected = self::TEST_DAY; $this->assertEquals($expected, $actual); } + public function testSetWeekWillReturnWeekWithGetWeek(): void + { + $time = new Time(week: self::TEST_WEEK); + $actual = $time->getWeek(); + $expected = self::TEST_WEEK; + + $this->assertEquals($expected, $actual); + } + public function testSetWeekWillReturnMonthWithGetMonth(): void { - $gravity = new Time(week: self::TEST_WEEK); - $actual = $gravity->getMonth(); + $time = new Time(week: self::TEST_WEEK); + $actual = $time->getMonth(); $expected = self::TEST_MONTH; $this->assertEquals($expected, $actual); @@ -407,9 +462,9 @@ public function testSetWeekWillReturnMonthWithGetMonth(): void public function testSetWeekWillReturnYearWithGetYear(): void { - $gravity = new Time(week: self::TEST_WEEK); - $actual = $gravity->getMonth(); - $expected = self::TEST_MONTH; + $time = new Time(week: self::TEST_WEEK); + $actual = $time->getYear(); + $expected = self::TEST_YEAR; $this->assertEquals($expected, $actual); } @@ -418,8 +473,8 @@ public function testSetWeekWillReturnYearWithGetYear(): void public function testSetMonthWillReturnMinuteWithGetMinute(): void { - $gravity = new Time(month: self::TEST_MONTH); - $actual = $gravity->getMinute(); + $time = new Time(month: self::TEST_MONTH); + $actual = $time->getMinute(); $expected = self::TEST_MINUTE; $this->assertEquals($expected, $actual); @@ -427,8 +482,8 @@ public function testSetMonthWillReturnMinuteWithGetMinute(): void public function testSetMonthWillReturnMillisecondWithGetMillisecond(): void { - $gravity = new Time(month: self::TEST_MONTH); - $actual = $gravity->getMillisecond(); + $time = new Time(month: self::TEST_MONTH); + $actual = $time->getMillisecond(); $expected = self::TEST_MILLISECOND; $this->assertEquals($expected, $actual); @@ -436,8 +491,8 @@ public function testSetMonthWillReturnMillisecondWithGetMillisecond(): void public function testSetMonthWillReturnSecondWithGetSecond(): void { - $gravity = new Time(month: self::TEST_MONTH); - $actual = $gravity->getSecond(); + $time = new Time(month: self::TEST_MONTH); + $actual = $time->getSecond(); $expected = self::TEST_SECOND; $this->assertEquals($expected, $actual); @@ -445,8 +500,8 @@ public function testSetMonthWillReturnSecondWithGetSecond(): void public function testSetMonthWillReturnHourWithGetHour(): void { - $gravity = new Time(month: self::TEST_MONTH); - $actual = $gravity->getHour(); + $time = new Time(month: self::TEST_MONTH); + $actual = $time->getHour(); $expected = self::TEST_HOUR; $this->assertEquals($expected, $actual); @@ -454,17 +509,26 @@ public function testSetMonthWillReturnHourWithGetHour(): void public function testSetMonthWillReturnDayWithGetDay(): void { - $gravity = new Time(month: self::TEST_MONTH); - $actual = $gravity->getDay(); + $time = new Time(month: self::TEST_MONTH); + $actual = $time->getDay(); $expected = self::TEST_DAY; $this->assertEquals($expected, $actual); } + public function testSetMonthWillReturnWeekWithGetWeek(): void + { + $time = new Time(month: self::TEST_MONTH); + $actual = $time->getWeek(); + $expected = self::TEST_WEEK; + + $this->assertEquals($expected, $actual); + } + public function testSetMonthWillReturnMonthWithGetMonth(): void { - $gravity = new Time(month: self::TEST_MONTH); - $actual = $gravity->getMonth(); + $time = new Time(month: self::TEST_MONTH); + $actual = $time->getMonth(); $expected = self::TEST_MONTH; $this->assertEquals($expected, $actual); @@ -472,10 +536,84 @@ public function testSetMonthWillReturnMonthWithGetMonth(): void public function testSetMonthWillReturnYearWithGetYear(): void { - $gravity = new Time(month: self::TEST_MONTH); - $actual = $gravity->getMonth(); + $time = new Time(month: self::TEST_MONTH); + $actual = $time->getYear(); + $expected = self::TEST_YEAR; + + $this->assertEquals($expected, $actual); + } + + // Year Conversions + + public function testSetYearWillReturnMinuteWithGetMinute(): void + { + $time = new Time(year: self::TEST_YEAR); + $actual = $time->getMinute(); + $expected = self::TEST_MINUTE; + + $this->assertEquals($expected, $actual); + } + + public function testSetYearWillReturnMillisecondWithGetMillisecond(): void + { + $time = new Time(year: self::TEST_YEAR); + $actual = $time->getMillisecond(); + $expected = self::TEST_MILLISECOND; + + $this->assertEquals($expected, $actual); + } + + public function testSetYearWillReturnSecondWithGetSecond(): void + { + $time = new Time(year: self::TEST_YEAR); + $actual = $time->getSecond(); + $expected = self::TEST_SECOND; + + $this->assertEquals($expected, $actual); + } + + public function testSetYearWillReturnHourWithGetHour(): void + { + $time = new Time(year: self::TEST_YEAR); + $actual = $time->getHour(); + $expected = self::TEST_HOUR; + + $this->assertEquals($expected, $actual); + } + + public function testSetYearWillReturnDayWithGetDay(): void + { + $time = new Time(year: self::TEST_YEAR); + $actual = $time->getDay(); + $expected = self::TEST_DAY; + + $this->assertEquals($expected, $actual); + } + + public function testSetYearWillReturnWeekWithGetWeek(): void + { + $time = new Time(year: self::TEST_YEAR); + $actual = $time->getWeek(); + $expected = self::TEST_WEEK; + + $this->assertEquals($expected, $actual); + } + + public function testSetYearWillReturnMonthWithGetMonth(): void + { + $time = new Time(year: self::TEST_YEAR); + $actual = $time->getMonth(); $expected = self::TEST_MONTH; $this->assertEquals($expected, $actual); } + + public function testSetYearWillReturnYearWithGetYear(): void + { + $time = new Time(year: self::TEST_YEAR); + $actual = $time->getYear(); + $expected = self::TEST_YEAR; + + $this->assertEquals($expected, $actual); + } } \ No newline at end of file