From cfd2337ed52f64bd7a1e802e45b91d360edbcad3 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Fri, 18 Oct 2019 18:55:17 +0800 Subject: [PATCH] Support complex calculation. Signed-off-by: Mior Muhammad Zaki --- src/Distance.php | 56 ++++++++++++++++++++++---------- src/Metric.php | 74 ++++++++++++++++++++++++++++++++++++++++++ src/Speed.php | 57 ++++++++++++++++++++++---------- tests/DistanceTest.php | 26 ++++++++++----- tests/SpeedTest.php | 26 ++++++++++----- 5 files changed, 187 insertions(+), 52 deletions(-) create mode 100644 src/Metric.php diff --git a/src/Distance.php b/src/Distance.php index f115dcb..ac36457 100644 --- a/src/Distance.php +++ b/src/Distance.php @@ -4,23 +4,52 @@ use InvalidArgumentException; -class Distance +class Distance extends Metric { /** - * Speed value in METER. + * List of supported formats. * - * @var int + * @var array */ - protected $value; + protected $supportedFormats = [ + 'm' => [ + 'from' => 1, + 'to' => 1, + ], + 'km' => [ + 'from' => 0.001, + 'to' => 1000.0, + ], + 'mi' => [ + 'from' => 0.000621371, + 'to' => 1609.34, + ], + ]; /** * Construct a new Speed from METER. * - * @param int $value + * @param float $value */ - public function __construct(int $value) + public function __construct(float $value, string $format = 'm') { - $this->value = $value; + $value = \is_numeric($value) ? $value : 0; + + $this->format = $format; + $this->value = $this->convertTo($value, $format, 'to'); + } + + /** + * Convert to Speed with new format. + * + * @param string $format + * @return static + */ + public function to(string $format = 'km') + { + return new static( + $this->convertTo($this->value, $format, 'from'), $format + ); } /** @@ -32,15 +61,8 @@ public function __construct(int $value) */ public function humanize(string $format = 'km'): float { - $value = \is_numeric($this->value) ? $this->value : 0; - - switch ($format) { - case 'km': - return \round($value * 0.001, 2); - case 'mi': - return \round($value * 0.000621371, 2); - default: - throw new InvalidArgumentException("Unvalid given {$format} format."); - } + return \round( + $this->convertTo($this->value, $format, 'from'), 2 + ); } } diff --git a/src/Metric.php b/src/Metric.php new file mode 100644 index 0000000..9879dc2 --- /dev/null +++ b/src/Metric.php @@ -0,0 +1,74 @@ +humanize($this->format), 0, '.', ','); + } + + /** + * Convert to new format. + * + * @param string $format + * @return static + */ + abstract public function to(string $format); + + /** + * Convert to humanize. + * + * @param string $format + * @return float|int + * + * @throws \InvalidArgumentException + */ + abstract public function humanize(string $format); + + /** + * Convert value to. + * + * @param float|int $value + * @param string $format + * @param string $type + * @return float|int + */ + protected function convertTo($value, string $format, string $type = 'from') + { + if (! \array_key_exists($format, $this->supportedFormats)) { + throw new InvalidArgumentException("Unvalid use unsupported {$format} format."); + } + + $conversion = $this->supportedFormats[$format]; + + return ($value * $conversion[$type]); + } +} diff --git a/src/Speed.php b/src/Speed.php index 4334373..483ef1a 100644 --- a/src/Speed.php +++ b/src/Speed.php @@ -4,23 +4,53 @@ use InvalidArgumentException; -class Speed +class Speed extends Metric { /** - * Speed value in KNOT. + * List of supported formats. * - * @var float + * @var array */ - protected $value; + protected $supportedFormats = [ + 'kn' => [ + 'from' => 1, + 'to' => 1, + ], + 'kmh' => [ + 'from' => 1.85200, + 'to' => 0.539957, + ], + 'mph' => [ + 'from' => 1.15078, + 'to' => 0.868976, + ], + ]; /** - * Construct a new Speed from KNOT. + * Construct a new Speed. * * @param float $value + * @param string $format */ - public function __construct(float $value) + public function __construct(float $value, string $format = 'kn') { - $this->value = $value; + $value = \is_numeric($value) ? $value : 0; + + $this->format = $format; + $this->value = $this->convertTo($value, $format, 'to'); + } + + /** + * Convert to Speed with new format. + * + * @param string $format + * @return static + */ + public function to(string $format = 'kmh') + { + return new static( + $this->convertTo($this->value, $format, 'from'), $format + ); } /** @@ -32,15 +62,8 @@ public function __construct(float $value) */ public function humanize(string $format = 'kmh'): float { - $value = \is_numeric($this->value) ? $this->value : 0; - - switch ($format) { - case 'kmh': - return \round($value * 1.85200, 2); - case 'mph': - return \round($value * 1.15078, 2); - default: - throw new InvalidArgumentException("Unvalid given {$format} format."); - } + return \round( + $this->convertTo($this->value, $format, 'from'), 2 + ); } } diff --git a/tests/DistanceTest.php b/tests/DistanceTest.php index 6bb9d61..4e92a75 100644 --- a/tests/DistanceTest.php +++ b/tests/DistanceTest.php @@ -7,6 +7,15 @@ class DistanceTest extends TestCase { + /** @test */ + public function it_can_display_formatted_distance() + { + $this->assertSame('60', (string) (new Distance(60000))->to('km')); + $this->assertSame('7', (string) (new Distance(6812))->to('km')); + $this->assertSame('0', (string) (new Distance(12))->to('km')); + $this->assertSame('0', (string) (new Distance(0))->to('km')); + } + /** @test */ public function it_can_convert_distance_from_meter_to_km() { @@ -14,11 +23,6 @@ public function it_can_convert_distance_from_meter_to_km() $this->assertSame(6.81, (new Distance(6812))->humanize()); $this->assertSame(0.01, (new Distance(12))->humanize()); $this->assertSame(0.0, (new Distance(0))->humanize()); - - $this->assertSame(60.0, (new Distance('60000'))->humanize()); - $this->assertSame(6.81, (new Distance('6812'))->humanize()); - $this->assertSame(0.01, (new Distance('12'))->humanize()); - $this->assertSame(0.0, (new Distance('0'))->humanize()); } /** @test */ @@ -28,10 +32,14 @@ public function it_can_convert_distance_from_meter_to_miles() $this->assertSame(4.23, (new Distance(6812))->humanize('mi')); $this->assertSame(0.01, (new Distance(12))->humanize('mi')); $this->assertSame(0.0, (new Distance(0))->humanize('mi')); + } - $this->assertSame(37.28, (new Distance('60000'))->humanize('mi')); - $this->assertSame(4.23, (new Distance('6812'))->humanize('mi')); - $this->assertSame(0.01, (new Distance('12'))->humanize('mi')); - $this->assertSame(0.0, (new Distance('0'))->humanize('mi')); + /** @test */ + public function it_can_convert_distance_from_meter_to_miles_via_km() + { + $this->assertSame(37.28, (new Distance(60000))->to('km')->humanize('mi')); + $this->assertSame(4.23, (new Distance(6812))->to('km')->humanize('mi')); + $this->assertSame(0.01, (new Distance(12))->to('km')->humanize('mi')); + $this->assertSame(0.0, (new Distance(0))->to('km')->humanize('mi')); } } diff --git a/tests/SpeedTest.php b/tests/SpeedTest.php index 5c1e8f2..5537c46 100644 --- a/tests/SpeedTest.php +++ b/tests/SpeedTest.php @@ -7,6 +7,15 @@ class SpeedTest extends TestCase { + /** @test */ + public function it_can_display_formatted_speed() + { + $this->assertSame('111', (string) (new Speed(60))->to('kmh')); + $this->assertSame('126', (string) (new Speed(68.12))->to('kmh')); + $this->assertSame('2', (string) (new Speed(1.2))->to('kmh')); + $this->assertSame('0', (string) (new Speed(0))->to('kmh')); + } + /** @test */ public function it_can_convert_speed_from_knot_to_kmh() { @@ -14,11 +23,6 @@ public function it_can_convert_speed_from_knot_to_kmh() $this->assertSame(126.16, (new Speed(68.12))->humanize()); $this->assertSame(2.22, (new Speed(1.2))->humanize()); $this->assertSame(0.0, (new Speed(0))->humanize()); - - $this->assertSame(111.12, (new Speed('60'))->humanize()); - $this->assertSame(126.16, (new Speed('68.12'))->humanize()); - $this->assertSame(2.22, (new Speed('1.2'))->humanize()); - $this->assertSame(0.0, (new Speed('0'))->humanize()); } /** @test */ @@ -28,10 +32,14 @@ public function it_can_convert_speed_from_knot_to_mph() $this->assertSame(78.39, (new Speed(68.12))->humanize('mph')); $this->assertSame(1.38, (new Speed(1.2))->humanize('mph')); $this->assertSame(0.0, (new Speed(0))->humanize('mph')); + } - $this->assertSame(69.05, (new Speed('60'))->humanize('mph')); - $this->assertSame(78.39, (new Speed('68.12'))->humanize('mph')); - $this->assertSame(1.38, (new Speed('1.2'))->humanize('mph')); - $this->assertSame(0.0, (new Speed('0'))->humanize('mph')); + /** @test */ + public function it_can_convert_speed_from_knot_to_mph_via_kmh() + { + $this->assertSame(69.05, (new Speed(60))->to('kmh')->humanize('mph')); + $this->assertSame(78.39, (new Speed(68.12))->to('kmh')->humanize('mph')); + $this->assertSame(1.38, (new Speed(1.2))->to('kmh')->humanize('mph')); + $this->assertSame(0.0, (new Speed(0))->to('kmh')->humanize('mph')); } }