Skip to content

Commit

Permalink
Merge pull request #47 from mostertb/master
Browse files Browse the repository at this point in the history
Support for optional explicit BinarySuffix precision
  • Loading branch information
Norbert Orzechowicz committed Nov 5, 2015
2 parents a4d68a9 + 84b8863 commit 9d17321
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 3 deletions.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -128,6 +130,24 @@ 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')`
The precision parameter must be between 0 and 3.

```php
use Coduo\PHPHumanizer\Number;

echo Number::preciseBinarySuffix(1024, 2); // "1.00 kB"
echo Number::preciseBinarySuffix(1325899906842624, 3); // "1.178 PB"
```

This function also supports locale

```php
use Coduo\PHPHumanizer\Number;

echo Number::preciseBinarySuffix(1325899906842624, 3, 'pl'); // "1,178 PB"
```

**Metric Suffix**

```php
Expand Down
7 changes: 7 additions & 0 deletions src/Coduo/PHPHumanizer/Number.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ public static function binarySuffix($number, $locale = 'en')
return $binarySuffix->convert();
}

public static function preciseBinarySuffix($number, $precision, $locale = 'en')
{
$binarySuffix = new BinarySuffix($number, $locale, $precision);

return $binarySuffix->convert();
}

public static function metricSuffix($number, $locale = 'en')
{
$binarySuffix = new MetricSuffix($number, $locale);
Expand Down
42 changes: 39 additions & 3 deletions src/Coduo/PHPHumanizer/String/BinarySuffix.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,57 @@ 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 = '#';
if($precision > 0){
$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);
Expand Down
71 changes: 71 additions & 0 deletions tests/Coduo/PHPHumanizer/Tests/NumberTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,35 @@ public function test_statically_throw_exception_when_converting_to_string_with_b
Number::binarySuffix('as12');
}

/**
* @dataProvider preciseBinarySuffixDataProvider
*
* @param $expected
* @param $number
* @param string $locale
* @param integer $precision
*/
public function test_convert_number_to_string_with_precise_binary_suffix($expected, $number, $precision, $locale = 'en')
{
$this->assertEquals($expected, Number::preciseBinarySuffix($number, $precision, $locale));
}

/**
* @expectedException \InvalidArgumentException
*/
public function test_statically_throw_exception_when_converting_to_string_with_precise_binary_suffix_negative_precision()
{
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);
}

/**
* @dataProvider metricSuffixDataProvider
*
Expand Down Expand Up @@ -163,6 +192,48 @@ public function binarySuffixDataProvider()
);
}

/**
* @return array
*/
public function preciseBinarySuffixDataProvider()
{
return array(
// Negative case
array(-1, -1, 3),

// Byte Cases
array("0 bytes", 0, 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'),
);
}

/**
* @return array
*/
Expand Down

0 comments on commit 9d17321

Please sign in to comment.