From 149d4c391772392d17d4028e2023ef6b2835bd7b Mon Sep 17 00:00:00 2001 From: Brad Mostert Date: Fri, 30 Oct 2015 23:16:35 +0200 Subject: [PATCH 1/8] Added support for optional explicit BinarySuffix precision --- src/Coduo/PHPHumanizer/Number.php | 4 +- .../PHPHumanizer/String/BinarySuffix.php | 38 +++++++++++++++++-- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/Coduo/PHPHumanizer/Number.php b/src/Coduo/PHPHumanizer/Number.php index 560ed86..e77f561 100644 --- a/src/Coduo/PHPHumanizer/Number.php +++ b/src/Coduo/PHPHumanizer/Number.php @@ -19,9 +19,9 @@ public static function ordinal($number) return (string) new Ordinal($number); } - public static function binarySuffix($number, $locale = 'en') + public static function binarySuffix($number, $locale = 'en', $precision = null) { - $binarySuffix = new BinarySuffix($number, $locale); + $binarySuffix = new BinarySuffix($number, $locale, $precision); return $binarySuffix->convert(); } diff --git a/src/Coduo/PHPHumanizer/String/BinarySuffix.php b/src/Coduo/PHPHumanizer/String/BinarySuffix.php index 446f642..7ed216f 100644 --- a/src/Coduo/PHPHumanizer/String/BinarySuffix.php +++ b/src/Coduo/PHPHumanizer/String/BinarySuffix.php @@ -29,21 +29,53 @@ class BinarySuffix ); /** - * @param $number - * @param string $locale + * @param integer $number + * @param string $locale + * @param integer $precision * * @throws \InvalidArgumentException */ - public function __construct($number, $locale = 'en') + public function __construct($number, $locale = 'en', $precision = null) { if (!is_numeric($number)) { throw new \InvalidArgumentException('Binary suffix converter accept only numeric values.'); } + if(!is_null($precision)){ + $this->setSpecificPrecisionFormat($precision); + } + $this->number = (int) $number; $this->locale = $locale; } + /** + * Replaces the default ICU 56.1 decimal formats defined in $binaryPrefixes with ones that provide the same symbols + * but the provided number of decimal places + * + * @param integer $precision + * + * @throws \InvalidArgumentException + */ + protected function setSpecificPrecisionFormat($precision) + { + if($precision < 0){ + throw new \InvalidArgumentException('Precision must be positive'); + } + if($precision > 3){ + throw new \InvalidArgumentException('Invalid precision. Binary suffix converter can only represent values in '. + 'up to three decimal places'); + } + + $icuFormat = str_pad('#.', (2+$precision), '0'); + foreach ($this->binaryPrefixes as $size => $unitPattern) { + if($size >= 1024){ + $symbol = substr($unitPattern, strpos($unitPattern, ' ')); + $this->binaryPrefixes[$size] = $icuFormat.$symbol; + } + } + } + public function convert() { $formatter = new \NumberFormatter($this->locale, \NumberFormatter::PATTERN_DECIMAL); From 81a1073341afdc02c0d82ec0ff3f1152520b7e42 Mon Sep 17 00:00:00 2001 From: Brad Mostert Date: Fri, 30 Oct 2015 23:23:40 +0200 Subject: [PATCH 2/8] added a BinarySuffix precision example --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index f7ba58a..e226c02 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,14 @@ use Coduo\PHPHumanizer\Number; echo Number::binarySuffix(1536, 'pl'); // "1,5 kB" ``` +Number can also be humanized with a specific number of decimal places by providing a precision parameter + +```php +use Coduo\PHPHumanizer\Number; + +echo Number::binarySuffix(1325899906842624, 'en', 3); // "1.178 PB" +``` + **Metric Suffix** ```php From b0d1d533da19ba485bf616cf8a7147d5b77a6bde Mon Sep 17 00:00:00 2001 From: Brad Mostert Date: Fri, 30 Oct 2015 23:28:27 +0200 Subject: [PATCH 3/8] added another BinarySuffix example --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e226c02..1c613f6 100644 --- a/README.md +++ b/README.md @@ -112,11 +112,12 @@ use Coduo\PHPHumanizer\Number; echo Number::binarySuffix(1536, 'pl'); // "1,5 kB" ``` -Number can also be humanized with a specific number of decimal places by providing a precision parameter +Number can also be humanized with a specific number of decimal places by providing a precision parameter (between 0 and 3) ```php use Coduo\PHPHumanizer\Number; +echo Number::binarySuffix(1024, 'en', 3); // "1.000 kB" echo Number::binarySuffix(1325899906842624, 'en', 3); // "1.178 PB" ``` From 87618d4b71250326840476937debf3e65ffba407 Mon Sep 17 00:00:00 2001 From: Brad Mostert Date: Fri, 30 Oct 2015 23:33:43 +0200 Subject: [PATCH 4/8] added tests for BinarySuffix with precision --- spec/Coduo/PHPHumanizer/NumberSpec.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/spec/Coduo/PHPHumanizer/NumberSpec.php b/spec/Coduo/PHPHumanizer/NumberSpec.php index 6acaa24..8651a66 100644 --- a/spec/Coduo/PHPHumanizer/NumberSpec.php +++ b/spec/Coduo/PHPHumanizer/NumberSpec.php @@ -39,6 +39,20 @@ function it_convert_number_to_string_with_binary_suffix() $this->binarySuffix(1325899906842624)->shouldReturn("1.18 PB"); } + function it_convert_number_to_string_with_binary_suffix_with_precision() + { + $this->binarySuffix(-1, 'en', 3)->shouldReturn(-1); + $this->binarySuffix(0, 'en', 3)->shouldReturn("0 bytes"); + $this->binarySuffix(1, 'en', 3)->shouldReturn("1 bytes"); + $this->binarySuffix(1024, 'en', 3)->shouldReturn("1.000 kB"); + $this->binarySuffix(1025, 'en', 3)->shouldReturn("1.001 kB"); + $this->binarySuffix(1536, 'en', 3)->shouldReturn("1.500 kB"); + $this->binarySuffix(1048576 * 5, 'en', 3)->shouldReturn("5.000 MB"); + $this->binarySuffix(1073741824 * 2, 'en', 3)->shouldReturn("2.000 GB"); + $this->binarySuffix(1099511627776 * 3, 'en', 3)->shouldReturn("3.000 TB"); + $this->binarySuffix(1325899906842624, 'en', 3)->shouldReturn("1.178 PB"); + } + function it_convert_number_to_string_with_binary_suffix_for_specific_locale() { $this->binarySuffix(1536, 'pl')->shouldReturn("1,5 kB"); From fa73af33122a621b9caa1b8710fa5386cdaecabf Mon Sep 17 00:00:00 2001 From: Brad Mostert Date: Tue, 3 Nov 2015 08:28:05 +0200 Subject: [PATCH 5/8] moved optional precision parameter of binarySuffix in to its own function --- README.md | 17 ++++++++-- src/Coduo/PHPHumanizer/Number.php | 9 +++++- tests/Coduo/PHPHumanizer/Tests/NumberTest.php | 32 +++++++++---------- 3 files changed, 38 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 89d55fa..f9046f7 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,8 @@ echo Number::fromRoman("CXXV"); // 125 **Binary Suffix** +Convert a number of bytes in to the highest applicable data unit + ```php use Coduo\PHPHumanizer\Number; @@ -128,13 +130,22 @@ use Coduo\PHPHumanizer\Number; echo Number::binarySuffix(1536, 'pl'); // "1,5 kB" ``` -Number can also be humanized with a specific number of decimal places by providing a precision parameter (between 0 and 3) +Number can also be humanized with a specific number of decimal places with ```preciseBinarySuffix($number, $precision, $locale = 'en')``` +The precision parameter must be between 0 and 3. + +```php +use Coduo\PHPHumanizer\Number; + +echo Number::preciseBinarySuffix(1024, 2); // "1.00 kB" +echo Number::binarySuffix(1325899906842624, 3); // "1.178 PB" +``` + +This function also supports locale ```php use Coduo\PHPHumanizer\Number; -echo Number::binarySuffix(1024, 'en', 3); // "1.000 kB" -echo Number::binarySuffix(1325899906842624, 'en', 3); // "1.178 PB" +echo Number::binarySuffix(1325899906842624, 3, 'pl); // "1,178 PB" ``` **Metric Suffix** diff --git a/src/Coduo/PHPHumanizer/Number.php b/src/Coduo/PHPHumanizer/Number.php index f6877da..89caf87 100644 --- a/src/Coduo/PHPHumanizer/Number.php +++ b/src/Coduo/PHPHumanizer/Number.php @@ -19,7 +19,14 @@ public static function ordinal($number) return (string) new Ordinal($number); } - public static function binarySuffix($number, $locale = 'en', $precision = null) + public static function binarySuffix($number, $locale = 'en') + { + $binarySuffix = new BinarySuffix($number, $locale); + + return $binarySuffix->convert(); + } + + public static function preciseBinarySuffix($number, $precision, $locale = 'en') { $binarySuffix = new BinarySuffix($number, $locale, $precision); diff --git a/tests/Coduo/PHPHumanizer/Tests/NumberTest.php b/tests/Coduo/PHPHumanizer/Tests/NumberTest.php index 38c178f..c2ef873 100644 --- a/tests/Coduo/PHPHumanizer/Tests/NumberTest.php +++ b/tests/Coduo/PHPHumanizer/Tests/NumberTest.php @@ -42,16 +42,16 @@ public function test_convert_number_to_string_with_binary_suffix($expected, $num } /** - * @dataProvider binarySuffixWithPrecisionDataProvider + * @dataProvider preciseBinarySuffixDataProvider * * @param $expected * @param $number * @param string $locale * @param integer $precision */ - public function test_convert_number_to_string_with_binary_suffix_precision($expected, $number, $locale = 'en', $precision) + public function test_convert_number_to_string_with_precise_binary_suffix($expected, $number, $precision, $locale = 'en') { - $this->assertEquals($expected, Number::binarySuffix($number, $locale, $precision)); + $this->assertEquals($expected, Number::preciseBinarySuffix($number, $precision, $locale)); } /** @@ -179,22 +179,22 @@ public function binarySuffixDataProvider() /** * @return array */ - public function binarySuffixWithPrecisionDataProvider() + public function preciseBinarySuffixDataProvider() { return array( - array(-1, -1, 'en', 3), - array("0 bytes", 0, 'en', 3), - array("1 bytes", 1, 'en', 3), - array("1.000 kB", 1024, 'en', 3), - array("1.001 kB", 1025, 'en', 3), - array("1.500 kB", 1536, 'en', 3), - array("5.000 MB", 1048576 * 5, 'en', 3), - array("2.000 GB", 1073741824 * 2, 'en', 3), - array("3.000 TB", 1099511627776 * 3, 'en', 3), - array("1.178 PB", 1325899906842624, 'en', 3), + array(-1, -1, 3), + array("0 bytes", 0, 3), + array("1 bytes", 1, 3), + array("1.000 kB", 1024, 3), + array("1.001 kB", 1025, 3), + array("1.500 kB", 1536, 3), + array("5.000 MB", 1048576 * 5, 3), + array("2.000 GB", 1073741824 * 2, 3), + array("3.000 TB", 1099511627776 * 3, 3), + array("1.178 PB", 1325899906842624, 3), - array("1,500 kB", 1536, 'pl', 3), - array("1,178 PB", 1325899906842624, 'pl', 3), + array("1,500 kB", 1536, 3, 'pl'), + array("1,178 PB", 1325899906842624, 3, 'pl'), ); } From f4ee349676553df626a41f85b3db49678fd37d6d Mon Sep 17 00:00:00 2001 From: Brad Mostert Date: Tue, 3 Nov 2015 08:32:12 +0200 Subject: [PATCH 6/8] updated documentation for preciseBinarySuffix --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f9046f7..6e09e1b 100644 --- a/README.md +++ b/README.md @@ -130,14 +130,14 @@ use Coduo\PHPHumanizer\Number; echo Number::binarySuffix(1536, 'pl'); // "1,5 kB" ``` -Number can also be humanized with a specific number of decimal places with ```preciseBinarySuffix($number, $precision, $locale = 'en')``` +Number can also be humanized with a specific number of decimal places with `preciseBinarySuffix($number, $precision, $locale = 'en')` The precision parameter must be between 0 and 3. ```php use Coduo\PHPHumanizer\Number; echo Number::preciseBinarySuffix(1024, 2); // "1.00 kB" -echo Number::binarySuffix(1325899906842624, 3); // "1.178 PB" +echo Number::preciseBinarySuffix(1325899906842624, 3); // "1.178 PB" ``` This function also supports locale @@ -145,7 +145,7 @@ This function also supports locale ```php use Coduo\PHPHumanizer\Number; -echo Number::binarySuffix(1325899906842624, 3, 'pl); // "1,178 PB" +echo Number::preciseBinarySuffix(1325899906842624, 3, 'pl'); // "1,178 PB" ``` **Metric Suffix** From 27a65adb9be7ad787a26c218cc3fe4019d90f183 Mon Sep 17 00:00:00 2001 From: Brad Mostert Date: Wed, 4 Nov 2015 19:18:14 +0200 Subject: [PATCH 7/8] no longer showing decimal separator for zero precision --- src/Coduo/PHPHumanizer/String/BinarySuffix.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Coduo/PHPHumanizer/String/BinarySuffix.php b/src/Coduo/PHPHumanizer/String/BinarySuffix.php index 7ed216f..ab6ac36 100644 --- a/src/Coduo/PHPHumanizer/String/BinarySuffix.php +++ b/src/Coduo/PHPHumanizer/String/BinarySuffix.php @@ -67,7 +67,11 @@ protected function setSpecificPrecisionFormat($precision) 'up to three decimal places'); } - $icuFormat = str_pad('#.', (2+$precision), '0'); + $icuFormat = '#'; + if($precision > 0){ + $icuFormat .= str_pad('#.', (2+$precision), '0'); + } + foreach ($this->binaryPrefixes as $size => $unitPattern) { if($size >= 1024){ $symbol = substr($unitPattern, strpos($unitPattern, ' ')); From 84b88638bc1e4d29394aab0020c392f0b4eaa59f Mon Sep 17 00:00:00 2001 From: Brad Mostert Date: Wed, 4 Nov 2015 19:19:46 +0200 Subject: [PATCH 8/8] improved tests for preciseBinarySuffix() --- tests/Coduo/PHPHumanizer/Tests/NumberTest.php | 54 +++++++++++++++---- 1 file changed, 45 insertions(+), 9 deletions(-) diff --git a/tests/Coduo/PHPHumanizer/Tests/NumberTest.php b/tests/Coduo/PHPHumanizer/Tests/NumberTest.php index c2ef873..db31d65 100644 --- a/tests/Coduo/PHPHumanizer/Tests/NumberTest.php +++ b/tests/Coduo/PHPHumanizer/Tests/NumberTest.php @@ -41,6 +41,14 @@ public function test_convert_number_to_string_with_binary_suffix($expected, $num $this->assertEquals($expected, Number::binarySuffix($number, $locale)); } + /** + * @expectedException \InvalidArgumentException + */ + public function test_statically_throw_exception_when_converting_to_string_with_binary_suffix_non_numeric_values() + { + Number::binarySuffix('as12'); + } + /** * @dataProvider preciseBinarySuffixDataProvider * @@ -57,9 +65,17 @@ public function test_convert_number_to_string_with_precise_binary_suffix($expect /** * @expectedException \InvalidArgumentException */ - public function test_statically_throw_exception_when_converting_to_string_with_binary_suffix_non_numeric_values() + public function test_statically_throw_exception_when_converting_to_string_with_precise_binary_suffix_negative_precision() { - Number::binarySuffix('as12'); + Number::preciseBinarySuffix(1, -1); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function test_statically_throw_exception_when_converting_to_string_with_precise_binary_suffix_large_precision() + { + Number::preciseBinarySuffix(1, 4); } /** @@ -182,17 +198,37 @@ public function binarySuffixDataProvider() public function preciseBinarySuffixDataProvider() { return array( + // Negative case array(-1, -1, 3), + + // Byte Cases array("0 bytes", 0, 3), - array("1 bytes", 1, 3), - array("1.000 kB", 1024, 3), - array("1.001 kB", 1025, 3), - array("1.500 kB", 1536, 3), - array("5.000 MB", 1048576 * 5, 3), - array("2.000 GB", 1073741824 * 2, 3), - array("3.000 TB", 1099511627776 * 3, 3), + array("1 bytes", 1, 0), + array("1023 bytes", 1023, 3), + + // Kilobyte Cases + array('1.000 kB', 1024, 3), + array("2 kB", 1588, 0), + array("1.6 kB", 1588, 1), + array("1.55 kB", 1588, 2), + array("1.551 kB", 1588, 3), + + // Megabyte Cases + array("5.00 MB", (1048576 * 5), 2), + array("5.00 MB", (1048576 * 5) + 600, 2), + array("5.001 MB", (1048576 * 5) + 600, 3), + + // Gigabyte Cases + array("2 GB", 1073741824 * 2, 0), + array("2.0 GB", 1073741824 * 2, 1), + + // Terabyte Cases + array("3.00 TB", 1099511627776 * 3, 2), + + // Petabyte Case array("1.178 PB", 1325899906842624, 3), + // Locale Cases array("1,500 kB", 1536, 3, 'pl'), array("1,178 PB", 1325899906842624, 3, 'pl'), );