-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feat: add unit converter class to actually convert values from/to units
- Loading branch information
1 parent
4e241a1
commit 3a84d07
Showing
3 changed files
with
261 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
<?php | ||
|
||
/** | ||
* This file is part of the jordanbrauer/unit-converter PHP package. | ||
* | ||
* @copyright 2017 Jordan Brauer <[email protected]> | ||
* @license MIT | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
declare(strict_types = 1); | ||
|
||
namespace UnitConverter; | ||
|
||
use UnitConverter\Measure; | ||
use UnitConverter\Unit\UnitInterface; | ||
use UnitConverter\Registry\UnitRegistryInterface; | ||
|
||
/** | ||
* The actual unit converter object. | ||
* | ||
* @version 1.0.0 | ||
* @since 1.0.0 | ||
* @author Jordan Brauer <[email protected]> | ||
*/ | ||
class UnitConverter implements UnitConverterInterface | ||
{ | ||
/** | ||
* @var UnitRegistryInterface The registry that the unit converter accesses available units from. | ||
*/ | ||
protected $registry; | ||
|
||
/** | ||
* @var float $convert The value being converted. | ||
*/ | ||
protected $convert; | ||
|
||
/** | ||
* @var string $from The unit of measure being converted **from**. | ||
*/ | ||
protected $from; | ||
|
||
/** | ||
* @var string $to The unit of measure being converted **to**. | ||
*/ | ||
protected $to; | ||
|
||
/** | ||
* Public constructor function for the UnitConverter class. | ||
* | ||
* @param UnitInterface[] A two-dimensional array of UnitInterface objects. | ||
* @return self | ||
*/ | ||
public function __construct (UnitRegistryInterface $registry = null) | ||
{ | ||
$this->setRegistry($registry); | ||
} | ||
|
||
/** | ||
* Determine whether or not the converter has an active registry. | ||
* | ||
* @internal | ||
* @return bool | ||
*/ | ||
protected function registryExists () : bool | ||
{ | ||
if ($this->registry instanceof UnitRegistryInterface) | ||
return true; | ||
|
||
return false; | ||
} | ||
|
||
/** | ||
* Load a unit from the unit converter registry. | ||
* | ||
* @internal | ||
* @uses UnitConverter\UnitRegistry::loadUnit | ||
* @throws ErrorException An error exceptino will be thrown if no registry exits | ||
* @return UnitInterface | ||
*/ | ||
protected function loadUnit(string $symbol) : UnitInterface | ||
{ | ||
if ($this->registryExists() === false) | ||
throw new \ErrorException("No unit registry was found to load units from."); | ||
|
||
return $this->registry->loadUnit($symbol); | ||
} | ||
|
||
/** | ||
* Calculate the conversion from one unit to another. | ||
* | ||
* @internal | ||
* @param float $value The initial value being converted. | ||
* @param UnitInterface $from The unit of measure being converted **from**. | ||
* @param UnitInterface $to The unit of measure being converted **to**. | ||
* @return float | ||
*/ | ||
protected function calculate (float $value, UnitInterface $from, UnitInterface $to): float | ||
{ | ||
return ($value * $from->getUnits()) / $to->getUnits(); | ||
} | ||
|
||
|
||
public function setRegistry ($registry) : UnitConverterInterface | ||
{ | ||
$this->registry = $registry; | ||
return $this; | ||
} | ||
|
||
public function convert (float $value) | ||
{ | ||
$this->convert = $value; | ||
return $this; | ||
} | ||
|
||
public function from (string $unit) | ||
{ | ||
$this->from = $this->loadUnit($unit); | ||
return $this; | ||
} | ||
|
||
public function to (string $unit) | ||
{ | ||
$this->to = $this->loadUnit($unit); | ||
return $this->calculate($this->convert, $this->from, $this->to); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
<?php | ||
|
||
/** | ||
* This file is part of the jordanbrauer/unit-converter PHP package. | ||
* | ||
* @copyright 2017 Jordan Brauer <[email protected]> | ||
* @license MIT | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
declare(strict_types = 1); | ||
|
||
namespace UnitConverter; | ||
|
||
use UnitConverter\Unit\UnitInterface; | ||
|
||
/** | ||
* The interface for any and all unit converter classes. If you want | ||
* a custom converter, implement this interface and you are good to | ||
* go! | ||
* | ||
* @version 1.0.0 | ||
* @since 1.0.0 | ||
* @author Jordan Brauer <[email protected]> | ||
*/ | ||
interface UnitConverterInterface | ||
{ | ||
/** | ||
* Set the unit converter registry for storing units of measure to convert values with. | ||
* | ||
* @api | ||
* @param UnitRegistryInterface $registry An instance of UnitRegistry. | ||
*/ | ||
public function setRegistry ($registry) : UnitConverterInterface; | ||
|
||
/** | ||
* Set the unit converters' value to be converted. This method is the first | ||
* method to be called in the chain of conversion methods. | ||
* | ||
* @api | ||
* @example $converter->convert(1)->from("in")->to("cm"); | ||
* @param float $value The numerical value being converted. | ||
*/ | ||
public function convert (float $value); | ||
|
||
/** | ||
* Set the unit converters' unit to be converted **from**. This method is the | ||
* second to be called in the chain of conversion methods. | ||
* | ||
* @api | ||
* @example $converter->convert(1)->from("in")->to("cm"); | ||
* @param string $unit The unit being conerted **from**. The unit must first be registered to the UnitRegistry. | ||
*/ | ||
public function from (string $unit); | ||
|
||
/** | ||
* Set the unit converters' unit to be converted **to**. This method is the | ||
* third to be called in the chain of conversion methods. | ||
* | ||
* @api | ||
* @example $converter->convert(1)->from("in")->to("cm"); | ||
* @param string $unit The unit being converted **to**. The unit must first be registered to the UnitRegistry. | ||
*/ | ||
public function to (string $unit); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
<?php | ||
|
||
/** | ||
* This file is part of the jordanbrauer/unit-converter PHP package. | ||
* | ||
* @copyright 2017 Jordan Brauer <[email protected]> | ||
* @license MIT | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
declare(strict_types = 1); | ||
|
||
namespace UnitConverter\Tests\Unit; | ||
|
||
use PHPUnit\Framework\TestCase; | ||
use UnitConverter\UnitConverter; | ||
use UnitConverter\Registry\UnitRegistry; | ||
use UnitConverter\Unit\Length\{ | ||
Centimeter, | ||
Inch | ||
}; | ||
|
||
/** | ||
* @coversDefaultClass UnitConverter\UnitConverter | ||
* @author Jordan Brauer <[email protected]> | ||
*/ | ||
class UnitConverterSpec extends TestCase | ||
{ | ||
protected function setUp () | ||
{ | ||
$this->converter = new UnitConverter( | ||
new UnitRegistry(array( | ||
new Centimeter, | ||
new Inch, | ||
)) | ||
); | ||
} | ||
|
||
protected function tearDown () | ||
{ | ||
unset($this->converter); | ||
} | ||
|
||
/** | ||
* @test | ||
* @covers ::convert | ||
* @covers ::from | ||
* @covers ::to | ||
* @covers ::calculate | ||
*/ | ||
public function assertCalculateMethodReturnsCorrectCalculation () | ||
{ | ||
$expected = 2.54; # = (1 * 0.0254) / 0.01 | ||
$actual = $this->converter | ||
->convert(1) | ||
->from("in") | ||
->to("cm") | ||
; | ||
|
||
$this->assertEquals($expected, $actual); | ||
$this->assertInternalType("float", $actual); | ||
} | ||
} |