diff options
Diffstat (limited to 'library/intl/tests/Formatter/NumberFormatterTest.php')
-rw-r--r-- | library/intl/tests/Formatter/NumberFormatterTest.php | 378 |
1 files changed, 378 insertions, 0 deletions
diff --git a/library/intl/tests/Formatter/NumberFormatterTest.php b/library/intl/tests/Formatter/NumberFormatterTest.php new file mode 100644 index 000000000..83574873b --- /dev/null +++ b/library/intl/tests/Formatter/NumberFormatterTest.php @@ -0,0 +1,378 @@ +<?php + +namespace CommerceGuys\Intl\Tests\Formatter; + +use CommerceGuys\Intl\Currency\Currency; +use CommerceGuys\Intl\Formatter\NumberFormatter; +use CommerceGuys\Intl\NumberFormat\NumberFormat; + +/** + * @coversDefaultClass \CommerceGuys\Intl\Formatter\NumberFormatter + */ +class NumberFormatterTest extends \PHPUnit_Framework_TestCase +{ + /** + * Prepare two number formats. + */ + protected $numberFormats = array( + 'latn' => array( + 'numbering_system' => 'latn', + 'decimal_pattern' => '#,##0.###', + 'percent_pattern' => '#,##0%', + 'currency_pattern' => '¤#,##0.00', + 'accounting_currency_pattern' => '¤#,##0.00;(¤#,##0.00)', + ), + 'beng' => array( + 'numbering_system' => 'beng', + 'decimal_pattern' => '#,##,##0.###', + 'percent_pattern' => '#,##,##0%', + 'currency_pattern' => '#,##,##0.00¤', + 'accounting_currency_pattern' => '#,##,##0.00¤;(#,##,##0.00¤)', + ), + ); + + /** + * Prepare two currency formats. + */ + protected $currencies = array( + 'USD' => array( + 'code' => 'USD', + 'name' => 'US Dollar', + 'numeric_code' => '840', + 'symbol' => '$', + ), + 'BND' => array( + 'code' => 'BND', + 'name' => 'dollar Brunei', + 'numeric_code' => '096', + 'symbol' => 'BND', + ), + ); + + /** + * @covers ::__construct + * @uses \CommerceGuys\Intl\Formatter\NumberFormatter::getNumberFormat + * @uses \CommerceGuys\Intl\NumberFormat\NumberFormat + */ + public function testConstructor() + { + $numberFormat = new NumberFormat(); + $formatter = new NumberFormatter($numberFormat, NumberFormatter::DECIMAL); + $this->assertSame($numberFormat, $formatter->getNumberFormat()); + } + + /** + * @covers ::__construct + * @uses \CommerceGuys\Intl\NumberFormat\NumberFormat + * + * @expectedException \CommerceGuys\Intl\Exception\InvalidArgumentException + * @expectedExceptionMessage Unknown format style provided to NumberFormatter::__construct(). + */ + public function testConstructorWithInvalidStyle() + { + $numberFormat = new NumberFormat(); + new NumberFormatter($numberFormat, 'foo'); + } + + /** + * @covers ::format + * @covers ::replaceDigits + * @covers ::replaceSymbols + * @uses \CommerceGuys\Intl\Formatter\NumberFormatter::__construct + * @uses \CommerceGuys\Intl\NumberFormat\NumberFormat + * + * @dataProvider numberValueProvider + */ + public function testFormat($number_format, $style, $value, $expected_value) + { + $formatter = new NumberFormatter($number_format, $style); + + $formattedNumber = $formatter->format($value); + $this->assertSame($expected_value, $formattedNumber); + } + + /** + * @covers ::SetMinimumFractionDigits + * @covers ::SetMaximumFractionDigits + * @covers ::format + * @uses \CommerceGuys\Intl\Formatter\NumberFormatter::__construct + * @uses \CommerceGuys\Intl\Formatter\NumberFormatter::replaceDigits + * @uses \CommerceGuys\Intl\Formatter\NumberFormatter::replaceSymbols + * @uses \CommerceGuys\Intl\NumberFormat\NumberFormat + */ + public function testFormatFractionDigits() + { + $numberFormat = $this->createNumberFormat($this->numberFormats['latn']); + + $formatter = new NumberFormatter($numberFormat); + $formatter->setMinimumFractionDigits(2); + $formattedNumber = $formatter->format('12.5'); + $this->assertSame('12.50', $formattedNumber); + + $formatter = new NumberFormatter($numberFormat); + $formatter->setMaximumFractionDigits(1); + $formattedNumber = $formatter->format('12.50'); + $this->assertSame('12.5', $formattedNumber); + + $formatter = new NumberFormatter($numberFormat); + $formatter->setMinimumFractionDigits(4); + $formatter->setMaximumFractionDigits(5); + $formattedNumber = $formatter->format('12.50000'); + $this->assertSame('12.5000', $formattedNumber); + } + + /** + * @covers ::format + * @uses \CommerceGuys\Intl\Formatter\NumberFormatter::__construct + * @uses \CommerceGuys\Intl\Formatter\NumberFormatter::format + * @uses \CommerceGuys\Intl\NumberFormat\NumberFormat + * + * @expectedException \CommerceGuys\Intl\Exception\InvalidArgumentException + */ + public function testFormatOnlyAllowsNumbers() + { + $numberFormat = $this->createNumberFormat($this->numberFormats['latn']); + $formatter = new NumberFormatter($numberFormat); + $formatter->format('a12.34'); + } + + /** + * @covers ::formatCurrency + * @covers ::replaceSymbols + * @uses \CommerceGuys\Intl\Currency\Currency + * @uses \CommerceGuys\Intl\Formatter\NumberFormatter::__construct + * @uses \CommerceGuys\Intl\Formatter\NumberFormatter::format + * @uses \CommerceGuys\Intl\Formatter\NumberFormatter::replaceDigits + * @uses \CommerceGuys\Intl\NumberFormat\NumberFormat + * + * @dataProvider currencyValueProvider + */ + public function testFormatCurrency($number_format, $currency, $style, $value, $expected_value) + { + $formatter = new NumberFormatter($number_format, $style); + + $formattedNumber = $formatter->formatCurrency($value, $currency); + $this->assertSame($expected_value, $formattedNumber); + } + + /** + * @covers ::parseCurrency + * @uses \CommerceGuys\Intl\Currency\Currency + * @uses \CommerceGuys\Intl\Formatter\NumberFormatter::__construct + * @uses \CommerceGuys\Intl\NumberFormat\NumberFormat + * + * @dataProvider formattedCurrencyProvider + */ + public function testParseCurrency($number_format, $currency, $style, $value, $expected_value) + { + $formatter = new NumberFormatter($number_format, $style); + + $parsedNumber = $formatter->parseCurrency($value, $currency); + $this->assertSame($expected_value, $parsedNumber); + } + + /** + * @covers ::getNumberFormat + * @uses \CommerceGuys\Intl\Formatter\NumberFormatter::__construct + * @uses \CommerceGuys\Intl\NumberFormat\NumberFormat + */ + public function testGetNumberFormat() + { + $numberFormat = $this->createNumberFormat($this->numberFormats['latn']); + $formatter = new NumberFormatter($numberFormat, NumberFormatter::DECIMAL); + $this->assertSame($numberFormat, $formatter->getNumberFormat()); + } + + /** + * @covers ::getMinimumFractionDigits + * @uses \CommerceGuys\Intl\Formatter\NumberFormatter::__construct + * @uses \CommerceGuys\Intl\NumberFormat\NumberFormat + */ + public function testMinimumFractionDigits() + { + $numberFormat = $this->createNumberFormat($this->numberFormats['latn']); + + // Defaults to 0 for decimal and percentage formats. + $formatter = new NumberFormatter($numberFormat, NumberFormatter::DECIMAL); + $this->assertEquals(0, $formatter->getMinimumFractionDigits()); + $formatter = new NumberFormatter($numberFormat, NumberFormatter::PERCENT); + $this->assertEquals(0, $formatter->getMinimumFractionDigits()); + + // Should default to null for currency formats. + $formatter = new NumberFormatter($numberFormat, NumberFormatter::CURRENCY); + $this->assertNull($formatter->getMinimumFractionDigits()); + $formatter = new NumberFormatter($numberFormat, NumberFormatter::CURRENCY_ACCOUNTING); + $this->assertNull($formatter->getMinimumFractionDigits()); + } + + /** + * @covers ::getMaximumFractionDigits + * @uses \CommerceGuys\Intl\Formatter\NumberFormatter::__construct + * @uses \CommerceGuys\Intl\NumberFormat\NumberFormat + */ + public function testMaximumFractionDigits() + { + $numberFormat = $this->createNumberFormat($this->numberFormats['latn']); + + // Defaults to 3 for decimal and percentage formats. + $formatter = new NumberFormatter($numberFormat, NumberFormatter::DECIMAL); + $this->assertEquals(3, $formatter->getMaximumFractionDigits()); + $formatter = new NumberFormatter($numberFormat, NumberFormatter::PERCENT); + $this->assertEquals(3, $formatter->getMaximumFractionDigits()); + + // Should default to null for currency formats. + $formatter = new NumberFormatter($numberFormat, NumberFormatter::CURRENCY); + $this->assertNull($formatter->getMaximumFractionDigits()); + $formatter = new NumberFormatter($numberFormat, NumberFormatter::CURRENCY_ACCOUNTING); + $this->assertNull($formatter->getMaximumFractionDigits()); + } + + /** + * @covers ::isGroupingUsed + * @covers ::setGroupingUsed + * @uses \CommerceGuys\Intl\Formatter\NumberFormatter::__construct + * @uses \CommerceGuys\Intl\Formatter\NumberFormatter::format + * @uses \CommerceGuys\Intl\Formatter\NumberFormatter::replaceDigits + * @uses \CommerceGuys\Intl\Formatter\NumberFormatter::replaceSymbols + * @uses \CommerceGuys\Intl\NumberFormat\NumberFormat + */ + public function testGroupingUsed() + { + $numberFormat = $this->createNumberFormat($this->numberFormats['latn']); + + // The formatter groups correctly. + $formatter = new NumberFormatter($numberFormat, NumberFormatter::DECIMAL); + $this->assertTrue($formatter->isGroupingUsed()); + $this->assertSame('10,000.9', $formatter->format('10000.90')); + + // The formatter respects grouping turned off. + $formatter = new NumberFormatter($numberFormat, NumberFormatter::DECIMAL); + $formatter->setGroupingUsed(false); + $this->assertFalse($formatter->isGroupingUsed()); + $this->assertSame('10000.9', $formatter->format('10000.90')); + } + + /** + * @covers ::getCurrencyDisplay + * @covers ::setCurrencyDisplay + * @covers ::formatCurrency + * @uses \CommerceGuys\Intl\Currency\Currency + * @uses \CommerceGuys\Intl\Formatter\NumberFormatter::__construct + * @uses \CommerceGuys\Intl\Formatter\NumberFormatter::format + * @uses \CommerceGuys\Intl\Formatter\NumberFormatter::replaceDigits + * @uses \CommerceGuys\Intl\Formatter\NumberFormatter::replaceSymbols + * @uses \CommerceGuys\Intl\NumberFormat\NumberFormat + */ + public function testCurrencyDisplay() + { + $numberFormat = $this->createNumberFormat($this->numberFormats['latn']); + $currency = $this->createCurrency($this->currencies['USD']); + + // Currency display defaults to symbol. + $formatter = new NumberFormatter($numberFormat, NumberFormatter::CURRENCY); + $this->assertSame(NumberFormatter::CURRENCY_DISPLAY_SYMBOL, $formatter->getCurrencyDisplay()); + $formattedNumber = $formatter->formatCurrency('100', $currency); + $this->assertSame('$100.00', $formattedNumber); + + // Currency display respects setting the value to currency code. + $formatter = new NumberFormatter($numberFormat, NumberFormatter::CURRENCY); + $formatter->setCurrencyDisplay(NumberFormatter::CURRENCY_DISPLAY_CODE); + $this->assertSame(NumberFormatter::CURRENCY_DISPLAY_CODE, $formatter->getCurrencyDisplay()); + $formattedNumber = $formatter->formatCurrency('100', $currency); + $this->assertSame('USD100.00', $formattedNumber); + } + + /** + * Provides the number format, number style, value and expected formatted value. + */ + public function numberValueProvider() + { + return array( + array($this->createNumberFormat($this->numberFormats['latn']), NumberFormatter::DECIMAL, '-50.5', '-50.5'), + array($this->createNumberFormat($this->numberFormats['latn']), NumberFormatter::PERCENT, '50.5', '50.5%'), + array($this->createNumberFormat($this->numberFormats['latn']), NumberFormatter::DECIMAL, '5000000.5', '5,000,000.5'), + array($this->createNumberFormat($this->numberFormats['beng'], 'bn'), NumberFormatter::DECIMAL, '-50.5', '-৫০.৫'), + array($this->createNumberFormat($this->numberFormats['beng'], 'bn'), NumberFormatter::PERCENT, '50.5', '৫০.৫%'), + array($this->createNumberFormat($this->numberFormats['beng'], 'bn'), NumberFormatter::DECIMAL, '5000000.5', '৫০,০০,০০০.৫') + ); + } + + /** + * Provides the number format, currency format, number style, value and expected formatted value. + */ + public function currencyValueProvider() + { + return array( + array($this->createNumberFormat($this->numberFormats['latn']), $this->createCurrency($this->currencies['USD']), NumberFormatter::CURRENCY, '-5.05', '-$5.05'), + array($this->createNumberFormat($this->numberFormats['latn']), $this->createCurrency($this->currencies['USD']), NumberFormatter::CURRENCY_ACCOUNTING, '-5.05', '($5.05)'), + array($this->createNumberFormat($this->numberFormats['latn']), $this->createCurrency($this->currencies['USD']), NumberFormatter::CURRENCY, '500100.05', '$500,100.05'), + array($this->createNumberFormat($this->numberFormats['beng'], 'bn'), $this->createCurrency($this->currencies['BND'], 'bn'), NumberFormatter::CURRENCY, '-50.5', '-৫০.৫০BND'), + array($this->createNumberFormat($this->numberFormats['beng'], 'bn'), $this->createCurrency($this->currencies['BND'], 'bn'), NumberFormatter::CURRENCY_ACCOUNTING, '-50.5', '(৫০.৫০BND)'), + array($this->createNumberFormat($this->numberFormats['beng'], 'bn'), $this->createCurrency($this->currencies['BND'], 'bn'), NumberFormatter::CURRENCY, '500100.05', '৫,০০,১০০.০৫BND'), + ); + } + + /** + * Provides values for the formatted currency parser. + */ + public function formattedCurrencyProvider() + { + return array( + array($this->createNumberFormat($this->numberFormats['latn']), $this->createCurrency($this->currencies['USD']), NumberFormatter::CURRENCY, '$500,100.05', '500100.05'), + array($this->createNumberFormat($this->numberFormats['latn']), $this->createCurrency($this->currencies['USD']), NumberFormatter::CURRENCY, '-$1,059.59', '-1059.59'), + array($this->createNumberFormat($this->numberFormats['latn']), $this->createCurrency($this->currencies['USD']), NumberFormatter::CURRENCY_ACCOUNTING, '($1,059.59)', '-1059.59'), + array($this->createNumberFormat($this->numberFormats['beng'], 'bn'), $this->createCurrency($this->currencies['BND'], 'bn'), NumberFormatter::CURRENCY, '৫,০০,১০০.০৫BND', '500100.05'), + ); + } + + /** + * Helper for initiating a new NumberFormat object. + */ + protected function createNumberFormat(array $definition, $locale = 'en') + { + $default = array( + 'decimal_separator' => '.', + 'grouping_separator' => ',', + 'plus_sign' => '+', + 'minus_sign' => '-', + 'percent_sign' => '%' + ); + $format = array_merge($default, $definition); + + $numberFormat = new NumberFormat(); + $numberFormat->setLocale($locale); + $numberFormat->setNumberingSystem($format['numbering_system']); + $numberFormat->setDecimalSeparator($format['decimal_separator']); + $numberFormat->setGroupingSeparator($format['grouping_separator']); + $numberFormat->setPlusSign($format['plus_sign']); + $numberFormat->setMinusSign($format['minus_sign']); + $numberFormat->setPercentSign($format['percent_sign']); + $numberFormat->setDecimalPattern($format['decimal_pattern']); + $numberFormat->setPercentPattern($format['percent_pattern']); + $numberFormat->setCurrencyPattern($format['currency_pattern']); + $numberFormat->setAccountingCurrencyPattern($format['accounting_currency_pattern']); + + return $numberFormat; + } + + /** + * Helper for initiating a new Currency object. + */ + protected function createCurrency(array $definition, $locale = 'en') + { + $default = array( + 'fraction_digits' => 2 + ); + $format = array_merge($default, $definition); + + $currency = new Currency(); + $currency->setCurrencyCode($format['code']); + $currency->setName($format['name']); + $currency->setNumericCode($format['numeric_code']); + $currency->setFractionDigits($format['fraction_digits']); + $currency->setSymbol($format['symbol']); + $currency->setLocale($locale); + + return $currency; + } +} |