183 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			PHP
		
	
	
			
		
		
	
	
			183 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			PHP
		
	
	
| <?php
 | ||
| 
 | ||
| namespace CommerceGuys\Intl\Tests\Formatter;
 | ||
| 
 | ||
| use CommerceGuys\Intl\Currency\Currency;
 | ||
| use CommerceGuys\Intl\Exception\InvalidArgumentException;
 | ||
| use CommerceGuys\Intl\Formatter\NumberFormatter;
 | ||
| use CommerceGuys\Intl\NumberFormat\NumberFormat;
 | ||
| use CommerceGuys\Intl\NumberFormat\NumberFormatRepository;
 | ||
| use PHPUnit\Framework\TestCase;
 | ||
| 
 | ||
| /**
 | ||
|  * @coversDefaultClass \CommerceGuys\Intl\Formatter\NumberFormatter
 | ||
|  */
 | ||
| final class NumberFormatterTest extends TestCase
 | ||
| {
 | ||
|     /**
 | ||
|      * @covers ::format
 | ||
|      */
 | ||
|     public function testFormatWithInvalidOptions()
 | ||
|     {
 | ||
|         $formatter = new NumberFormatter(new NumberFormatRepository());
 | ||
|         $data = [
 | ||
|             'Unrecognized option "unknown".' => [
 | ||
|                 'unknown' => '123',
 | ||
|             ],
 | ||
|             'The option "use_grouping" must be a boolean.' => [
 | ||
|               'use_grouping' => 'INVALID',
 | ||
|             ],
 | ||
|             'The option "minimum_fraction_digits" must be numeric.' => [
 | ||
|                 'minimum_fraction_digits' => 'INVALID',
 | ||
|             ],
 | ||
|             'The option "maximum_fraction_digits" must be numeric.' => [
 | ||
|                 'maximum_fraction_digits' => 'INVALID',
 | ||
|             ],
 | ||
|             'Unrecognized rounding mode "INVALID".' => [
 | ||
|                 'rounding_mode' => 'INVALID',
 | ||
|             ],
 | ||
|             'Unrecognized style "INVALID".' => [
 | ||
|                 'style' => 'INVALID',
 | ||
|             ],
 | ||
|         ];
 | ||
| 
 | ||
|         foreach ($data as $expectedError => $options) {
 | ||
|             $message = '';
 | ||
|             try {
 | ||
|                 $formatter->format('9.99', $options);
 | ||
|             } catch (InvalidArgumentException $e) {
 | ||
|                 $message = $e->getMessage();
 | ||
|             }
 | ||
|             $this->assertEquals($expectedError, $message);
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * @covers ::format
 | ||
|      */
 | ||
|     public function testFormatWithInvalidNumber()
 | ||
|     {
 | ||
|         $this->expectExceptionMessage('The provided value "a12.34" is not a valid number or numeric string.');
 | ||
|         $this->expectException(InvalidArgumentException::class);
 | ||
|         $formatter = new NumberFormatter(new NumberFormatRepository());
 | ||
|         $formatter->format('a12.34');
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * @covers ::format
 | ||
|      */
 | ||
|     public function testFormatWithFloat()
 | ||
|     {
 | ||
|         $formatter = new NumberFormatter(new NumberFormatRepository());
 | ||
|         $formattedNumber = $formatter->format(12.34);
 | ||
|         $this->assertSame('12.34', $formattedNumber);
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * @covers ::format
 | ||
|      *
 | ||
|      * @dataProvider numberValueProvider
 | ||
|      */
 | ||
|     public function testBasicFormat($locale, $style, $number, $expectedNumber)
 | ||
|     {
 | ||
|         $formatter = new NumberFormatter(new NumberFormatRepository(), [
 | ||
|             'locale' => $locale,
 | ||
|             'style' => $style,
 | ||
|         ]);
 | ||
|         $formattedNumber = $formatter->format($number);
 | ||
|         $this->assertSame($expectedNumber, $formattedNumber);
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * @covers ::format
 | ||
|      */
 | ||
|     public function testAdvancedFormat()
 | ||
|     {
 | ||
|         $formatter = new NumberFormatter(new NumberFormatRepository(), [
 | ||
|             'maximum_fraction_digits' => 2,
 | ||
|             'rounding_mode' => 'none',
 | ||
|         ]);
 | ||
| 
 | ||
|         $formattedNumber = $formatter->format('12.999');
 | ||
|         $this->assertSame('12.99', $formattedNumber);
 | ||
| 
 | ||
|         $formattedNumber = $formatter->format('12.5', [
 | ||
|            'minimum_fraction_digits' => 2,
 | ||
|         ]);
 | ||
|         $this->assertSame('12.50', $formattedNumber);
 | ||
| 
 | ||
|         $formattedNumber = $formatter->format('12', [
 | ||
|             'minimum_fraction_digits' => 1,
 | ||
|         ]);
 | ||
|         $this->assertSame('12.0', $formattedNumber);
 | ||
| 
 | ||
|         // Format with and without grouping.
 | ||
|         $formattedNumber = $formatter->format('10000.90');
 | ||
|         $this->assertSame('10,000.9', $formattedNumber);
 | ||
|         $formattedNumber = $formatter->format('10000.90', [
 | ||
|             'use_grouping' => false,
 | ||
|         ]);
 | ||
|         $this->assertSame('10000.9', $formattedNumber);
 | ||
| 
 | ||
|         // Test secondary groups.
 | ||
|         $formattedNumber = $formatter->format('12345678.90', ['locale' => 'bn']);
 | ||
|         $this->assertSame('১,২৩,৪৫,৬৭৮.৯', $formattedNumber);
 | ||
| 
 | ||
|         // No grouping needed.
 | ||
|         $formattedNumber = $formatter->format('123.90', ['locale' => 'bn']);
 | ||
|         $this->assertSame('১২৩.৯', $formattedNumber);
 | ||
| 
 | ||
|         // Rounding.
 | ||
|         $formattedNumber = $formatter->format('12.555', [
 | ||
|             'rounding_mode' => PHP_ROUND_HALF_UP,
 | ||
|         ]);
 | ||
|         $this->assertSame('12.56', $formattedNumber);
 | ||
| 
 | ||
|         $formattedNumber = $formatter->format('12.555', [
 | ||
|             'rounding_mode' => PHP_ROUND_HALF_DOWN,
 | ||
|         ]);
 | ||
|         $this->assertSame('12.55', $formattedNumber);
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * @covers ::parse
 | ||
|      *
 | ||
|      * @dataProvider formattedValueProvider
 | ||
|      */
 | ||
|     public function testParse($locale, $number, $expectedNumber)
 | ||
|     {
 | ||
|         $formatter = new NumberFormatter(new NumberFormatRepository());
 | ||
|         $parsedNumber = $formatter->parse($number, ['locale' => $locale]);
 | ||
|         $this->assertSame($expectedNumber, $parsedNumber);
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * Provides the locale, number style, value and expected formatted value.
 | ||
|      */
 | ||
|     public static function numberValueProvider()
 | ||
|     {
 | ||
|         return [
 | ||
|             ['en', 'decimal', '-50.00', '-50'],
 | ||
|             ['en', 'percent', '0.50', '50%'],
 | ||
|             ['en', 'decimal', '5000000.5', '5,000,000.5'],
 | ||
|             ['bn', 'decimal', '-50.5', '-৫০.৫'],
 | ||
|             ['bn', 'decimal', '5000000.5', '৫০,০০,০০০.৫'],
 | ||
|             ['de-AT', 'decimal', '-5000.00', '-5 000'],
 | ||
|             ['fr-CH', 'decimal', '-5000.12', '-5 000,12'],
 | ||
|         ];
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * Provides values for the formatted value parser.
 | ||
|      */
 | ||
|     public static function formattedValueProvider()
 | ||
|     {
 | ||
|         return [
 | ||
|             ['en', '500,100.05', '500100.05'],
 | ||
|             ['en', '-1,059.59', '-1059.59'],
 | ||
|             ['en', '50%', '0.5'],
 | ||
|             ['bn', '৫,০০,১০০.০৫', '500100.05'],
 | ||
|         ];
 | ||
|     }
 | ||
| }
 |