diff --git a/UPGRADE-2.4.md b/UPGRADE-2.4.md new file mode 100644 index 0000000000..bd9ecc3c4d --- /dev/null +++ b/UPGRADE-2.4.md @@ -0,0 +1,9 @@ +UPGRADE FROM 2.3 to 2.4 +======================= + +Form +---- + + * The constructor parameter `$precision` in `IntegerToLocalizedStringTransformer` + is now ignored completely, because a precision does not make sense for + integers. diff --git a/UPGRADE-3.0.md b/UPGRADE-3.0.md index a2c1d74a1f..c806da2cd1 100644 --- a/UPGRADE-3.0.md +++ b/UPGRADE-3.0.md @@ -158,6 +158,10 @@ UPGRADE FROM 2.x to 3.0 * The `FormItegrationTestCase` and `FormPerformanceTestCase` classes were moved form the `Symfony\Component\Form\Tests` namespace to the `Symfony\Component\Form\Test` namespace. + * The constants `ROUND_HALFEVEN`, `ROUND_HALFUP` and `ROUND_HALFDOWN` in class + `NumberToLocalizedStringTransformer` were renamed to `ROUND_HALF_EVEN`, + `ROUND_HALF_UP` and `ROUND_HALF_DOWN`. + ### FrameworkBundle diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformer.php index 6bb48a9a03..c22dad5100 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformer.php @@ -11,8 +11,6 @@ namespace Symfony\Component\Form\Extension\Core\DataTransformer; -use Symfony\Component\Form\Exception\TransformationFailedException; - /** * Transforms between an integer and a localized number with grouping * (each thousand) and comma separators. @@ -21,33 +19,29 @@ use Symfony\Component\Form\Exception\TransformationFailedException; */ class IntegerToLocalizedStringTransformer extends NumberToLocalizedStringTransformer { + /** + * Constructs a transformer. + * + * @param integer $precision Unused. + * @param Boolean $grouping Whether thousands should be grouped. + * @param integer $roundingMode One of the ROUND_ constants in this class. + */ + public function __construct($precision = null, $grouping = null, $roundingMode = self::ROUND_DOWN) + { + if (null === $roundingMode) { + $roundingMode = self::ROUND_DOWN; + } + + parent::__construct(0, $grouping, $roundingMode); + } + /** * {@inheritDoc} */ public function reverseTransform($value) { - if (!is_string($value)) { - throw new TransformationFailedException('Expected a string.'); - } + $result = parent::reverseTransform($value); - if ('' === $value) { - return null; - } - - if ('NaN' === $value) { - throw new TransformationFailedException('"NaN" is not a valid integer'); - } - - $formatter = $this->getNumberFormatter(); - $value = $formatter->parse( - $value, - PHP_INT_SIZE == 8 ? $formatter::TYPE_INT64 : $formatter::TYPE_INT32 - ); - - if (intl_is_failure($formatter->getErrorCode())) { - throw new TransformationFailedException($formatter->getErrorMessage()); - } - - return $value; + return null !== $result ? (int) $result : null; } } diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php index b0c59b3ede..61f2f4441e 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php @@ -23,13 +23,75 @@ use Symfony\Component\Form\Exception\TransformationFailedException; */ class NumberToLocalizedStringTransformer implements DataTransformerInterface { - const ROUND_FLOOR = \NumberFormatter::ROUND_FLOOR; - const ROUND_DOWN = \NumberFormatter::ROUND_DOWN; - const ROUND_HALFDOWN = \NumberFormatter::ROUND_HALFDOWN; - const ROUND_HALFEVEN = \NumberFormatter::ROUND_HALFEVEN; - const ROUND_HALFUP = \NumberFormatter::ROUND_HALFUP; - const ROUND_UP = \NumberFormatter::ROUND_UP; - const ROUND_CEILING = \NumberFormatter::ROUND_CEILING; + /** + * Rounds a number towards positive infinity. + * + * Rounds 1.4 to 2 and -1.4 to -1. + */ + const ROUND_CEILING = \NumberFormatter::ROUND_CEILING; + + /** + * Rounds a number towards negative infinity. + * + * Rounds 1.4 to 1 and -1.4 to -2. + */ + const ROUND_FLOOR = \NumberFormatter::ROUND_FLOOR; + + /** + * Rounds a number away from zero. + * + * Rounds 1.4 to 2 and -1.4 to -2. + */ + const ROUND_UP = \NumberFormatter::ROUND_UP; + + /** + * Rounds a number towards zero. + * + * Rounds 1.4 to 1 and -1.4 to -1. + */ + const ROUND_DOWN = \NumberFormatter::ROUND_DOWN; + + /** + * Rounds to the nearest number and halves to the next even number. + * + * Rounds 2.5, 1.6 and 1.5 to 2 and 1.4 to 1. + */ + const ROUND_HALF_EVEN = \NumberFormatter::ROUND_HALFEVEN; + + /** + * Rounds to the nearest number and halves away from zero. + * + * Rounds 2.5 to 3, 1.6 and 1.5 to 2 and 1.4 to 1. + */ + const ROUND_HALF_UP = \NumberFormatter::ROUND_HALFUP; + + /** + * Rounds to the nearest number and halves towards zero. + * + * Rounds 2.5 and 1.6 to 2, 1.5 and 1.4 to 1. + */ + const ROUND_HALF_DOWN = \NumberFormatter::ROUND_HALFDOWN; + + /** + * Alias for {@link self::ROUND_HALF_EVEN}. + * + * @deprecated Deprecated as of Symfony 2.4, to be removed in Symfony 3.0. + */ + const ROUND_HALFEVEN = self::ROUND_HALF_EVEN; + + /** + * Alias for {@link self::ROUND_HALF_UP}. + * + * @deprecated Deprecated as of Symfony 2.4, to be removed in Symfony 3.0. + */ + const ROUND_HALFUP = self::ROUND_HALF_UP; + + /** + * Alias for {@link self::ROUND_HALF_DOWN}. + * + * @deprecated Deprecated as of Symfony 2.4, to be removed in Symfony 3.0. + */ + const ROUND_HALFDOWN = self::ROUND_HALF_DOWN; protected $precision; @@ -160,7 +222,8 @@ class NumberToLocalizedStringTransformer implements DataTransformerInterface } } - return $result; + // NumberFormatter::parse() does not round + return $this->round($result); } /** @@ -181,4 +244,48 @@ class NumberToLocalizedStringTransformer implements DataTransformerInterface return $formatter; } + + /** + * Rounds a number according to the configured precision and rounding mode. + * + * @param integer|float $number A number. + * + * @return integer|float The rounded number. + */ + private function round($number) + { + if (null !== $this->precision && null !== $this->roundingMode) { + // shift number to maintain the correct precision during rounding + $roundingCoef = pow(10, $this->precision); + $number *= $roundingCoef; + + switch ($this->roundingMode) { + case self::ROUND_CEILING: + $number = ceil($number); + break; + case self::ROUND_FLOOR: + $number = floor($number); + break; + case self::ROUND_UP: + $number = $number > 0 ? ceil($number) : floor($number); + break; + case self::ROUND_DOWN: + $number = $number > 0 ? floor($number) : ceil($number); + break; + case self::ROUND_HALF_EVEN: + $number = round($number, 0, PHP_ROUND_HALF_EVEN); + break; + case self::ROUND_HALF_UP: + $number = round($number, 0, PHP_ROUND_HALF_UP); + break; + case self::ROUND_HALF_DOWN: + $number = round($number, 0, PHP_ROUND_HALF_DOWN); + break; + } + + $number /= $roundingCoef; + } + + return $number; + } } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformerTest.php index a90fa91bb0..840134da95 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformerTest.php @@ -26,6 +26,67 @@ class IntegerToLocalizedStringTransformerTest extends \PHPUnit_Framework_TestCas \Locale::setDefault('de_AT'); } + public function transformWithRoundingProvider() + { + return array( + // towards positive infinity (1.6 -> 2, -1.6 -> -1) + array(1234.5, '1235', IntegerToLocalizedStringTransformer::ROUND_CEILING), + array(1234.4, '1235', IntegerToLocalizedStringTransformer::ROUND_CEILING), + array(-1234.5, '-1234', IntegerToLocalizedStringTransformer::ROUND_CEILING), + array(-1234.4, '-1234', IntegerToLocalizedStringTransformer::ROUND_CEILING), + // towards negative infinity (1.6 -> 1, -1.6 -> -2) + array(1234.5, '1234', IntegerToLocalizedStringTransformer::ROUND_FLOOR), + array(1234.4, '1234', IntegerToLocalizedStringTransformer::ROUND_FLOOR), + array(-1234.5, '-1235', IntegerToLocalizedStringTransformer::ROUND_FLOOR), + array(-1234.4, '-1235', IntegerToLocalizedStringTransformer::ROUND_FLOOR), + // away from zero (1.6 -> 2, -1.6 -> 2) + array(1234.5, '1235', IntegerToLocalizedStringTransformer::ROUND_UP), + array(1234.4, '1235', IntegerToLocalizedStringTransformer::ROUND_UP), + array(-1234.5, '-1235', IntegerToLocalizedStringTransformer::ROUND_UP), + array(-1234.4, '-1235', IntegerToLocalizedStringTransformer::ROUND_UP), + // towards zero (1.6 -> 1, -1.6 -> -1) + array(1234.5, '1234', IntegerToLocalizedStringTransformer::ROUND_DOWN), + array(1234.4, '1234', IntegerToLocalizedStringTransformer::ROUND_DOWN), + array(-1234.5, '-1234', IntegerToLocalizedStringTransformer::ROUND_DOWN), + array(-1234.4, '-1234', IntegerToLocalizedStringTransformer::ROUND_DOWN), + // round halves (.5) to the next even number + array(1234.6, '1235', IntegerToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(1234.5, '1234', IntegerToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(1234.4, '1234', IntegerToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(1233.5, '1234', IntegerToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(1232.5, '1232', IntegerToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(-1234.6, '-1235', IntegerToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(-1234.5, '-1234', IntegerToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(-1234.4, '-1234', IntegerToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(-1233.5, '-1234', IntegerToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(-1232.5, '-1232', IntegerToLocalizedStringTransformer::ROUND_HALF_EVEN), + // round halves (.5) away from zero + array(1234.6, '1235', IntegerToLocalizedStringTransformer::ROUND_HALF_UP), + array(1234.5, '1235', IntegerToLocalizedStringTransformer::ROUND_HALF_UP), + array(1234.4, '1234', IntegerToLocalizedStringTransformer::ROUND_HALF_UP), + array(-1234.6, '-1235', IntegerToLocalizedStringTransformer::ROUND_HALF_UP), + array(-1234.5, '-1235', IntegerToLocalizedStringTransformer::ROUND_HALF_UP), + array(-1234.4, '-1234', IntegerToLocalizedStringTransformer::ROUND_HALF_UP), + // round halves (.5) towards zero + array(1234.6, '1235', IntegerToLocalizedStringTransformer::ROUND_HALF_DOWN), + array(1234.5, '1234', IntegerToLocalizedStringTransformer::ROUND_HALF_DOWN), + array(1234.4, '1234', IntegerToLocalizedStringTransformer::ROUND_HALF_DOWN), + array(-1234.6, '-1235', IntegerToLocalizedStringTransformer::ROUND_HALF_DOWN), + array(-1234.5, '-1234', IntegerToLocalizedStringTransformer::ROUND_HALF_DOWN), + array(-1234.4, '-1234', IntegerToLocalizedStringTransformer::ROUND_HALF_DOWN), + ); + } + + /** + * @dataProvider transformWithRoundingProvider + */ + public function testTransformWithRounding($input, $output, $roundingMode) + { + $transformer = new IntegerToLocalizedStringTransformer(null, null, $roundingMode); + + $this->assertEquals($output, $transformer->transform($input)); + } + public function testReverseTransform() { $transformer = new IntegerToLocalizedStringTransformer(); @@ -53,6 +114,67 @@ class IntegerToLocalizedStringTransformerTest extends \PHPUnit_Framework_TestCas $this->assertEquals(12345, $transformer->reverseTransform('12345,912')); } + public function reverseTransformWithRoundingProvider() + { + return array( + // towards positive infinity (1.6 -> 2, -1.6 -> -1) + array('1234,5', 1235, IntegerToLocalizedStringTransformer::ROUND_CEILING), + array('1234,4', 1235, IntegerToLocalizedStringTransformer::ROUND_CEILING), + array('-1234,5', -1234, IntegerToLocalizedStringTransformer::ROUND_CEILING), + array('-1234,4', -1234, IntegerToLocalizedStringTransformer::ROUND_CEILING), + // towards negative infinity (1.6 -> 1, -1.6 -> -2) + array('1234,5', 1234, IntegerToLocalizedStringTransformer::ROUND_FLOOR), + array('1234,4', 1234, IntegerToLocalizedStringTransformer::ROUND_FLOOR), + array('-1234,5', -1235, IntegerToLocalizedStringTransformer::ROUND_FLOOR), + array('-1234,4', -1235, IntegerToLocalizedStringTransformer::ROUND_FLOOR), + // away from zero (1.6 -> 2, -1.6 -> 2) + array('1234,5', 1235, IntegerToLocalizedStringTransformer::ROUND_UP), + array('1234,4', 1235, IntegerToLocalizedStringTransformer::ROUND_UP), + array('-1234,5', -1235, IntegerToLocalizedStringTransformer::ROUND_UP), + array('-1234,4', -1235, IntegerToLocalizedStringTransformer::ROUND_UP), + // towards zero (1.6 -> 1, -1.6 -> -1) + array('1234,5', 1234, IntegerToLocalizedStringTransformer::ROUND_DOWN), + array('1234,4', 1234, IntegerToLocalizedStringTransformer::ROUND_DOWN), + array('-1234,5', -1234, IntegerToLocalizedStringTransformer::ROUND_DOWN), + array('-1234,4', -1234, IntegerToLocalizedStringTransformer::ROUND_DOWN), + // round halves (.5) to the next even number + array('1234,6', 1235, IntegerToLocalizedStringTransformer::ROUND_HALF_EVEN), + array('1234,5', 1234, IntegerToLocalizedStringTransformer::ROUND_HALF_EVEN), + array('1234,4', 1234, IntegerToLocalizedStringTransformer::ROUND_HALF_EVEN), + array('1233,5', 1234, IntegerToLocalizedStringTransformer::ROUND_HALF_EVEN), + array('1232,5', 1232, IntegerToLocalizedStringTransformer::ROUND_HALF_EVEN), + array('-1234,6', -1235, IntegerToLocalizedStringTransformer::ROUND_HALF_EVEN), + array('-1234,5', -1234, IntegerToLocalizedStringTransformer::ROUND_HALF_EVEN), + array('-1234,4', -1234, IntegerToLocalizedStringTransformer::ROUND_HALF_EVEN), + array('-1233,5', -1234, IntegerToLocalizedStringTransformer::ROUND_HALF_EVEN), + array('-1232,5', -1232, IntegerToLocalizedStringTransformer::ROUND_HALF_EVEN), + // round halves (.5) away from zero + array('1234,6', 1235, IntegerToLocalizedStringTransformer::ROUND_HALF_UP), + array('1234,5', 1235, IntegerToLocalizedStringTransformer::ROUND_HALF_UP), + array('1234,4', 1234, IntegerToLocalizedStringTransformer::ROUND_HALF_UP), + array('-1234,6', -1235, IntegerToLocalizedStringTransformer::ROUND_HALF_UP), + array('-1234,5', -1235, IntegerToLocalizedStringTransformer::ROUND_HALF_UP), + array('-1234,4', -1234, IntegerToLocalizedStringTransformer::ROUND_HALF_UP), + // round halves (.5) towards zero + array('1234,6', 1235, IntegerToLocalizedStringTransformer::ROUND_HALF_DOWN), + array('1234,5', 1234, IntegerToLocalizedStringTransformer::ROUND_HALF_DOWN), + array('1234,4', 1234, IntegerToLocalizedStringTransformer::ROUND_HALF_DOWN), + array('-1234,6', -1235, IntegerToLocalizedStringTransformer::ROUND_HALF_DOWN), + array('-1234,5', -1234, IntegerToLocalizedStringTransformer::ROUND_HALF_DOWN), + array('-1234,4', -1234, IntegerToLocalizedStringTransformer::ROUND_HALF_DOWN), + ); + } + + /** + * @dataProvider reverseTransformWithRoundingProvider + */ + public function testReverseTransformWithRounding($input, $output, $roundingMode) + { + $transformer = new IntegerToLocalizedStringTransformer(null, null, $roundingMode); + + $this->assertEquals($output, $transformer->reverseTransform($input)); + } + /** * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException */ diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/NumberToLocalizedStringTransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/NumberToLocalizedStringTransformerTest.php index c58e3f60e7..183935e7ab 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/NumberToLocalizedStringTransformerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/NumberToLocalizedStringTransformerTest.php @@ -82,14 +82,110 @@ class NumberToLocalizedStringTransformerTest extends \PHPUnit_Framework_TestCase $this->assertEquals('678,92', $transformer->transform(678.916)); } - public function testTransformWithRoundingMode() + public function transformWithRoundingProvider() + { + return array( + // towards positive infinity (1.6 -> 2, -1.6 -> -1) + array(0, 1234.5, '1235', NumberToLocalizedStringTransformer::ROUND_CEILING), + array(0, 1234.4, '1235', NumberToLocalizedStringTransformer::ROUND_CEILING), + array(0, -1234.5, '-1234', NumberToLocalizedStringTransformer::ROUND_CEILING), + array(0, -1234.4, '-1234', NumberToLocalizedStringTransformer::ROUND_CEILING), + array(1, 123.45, '123,5', NumberToLocalizedStringTransformer::ROUND_CEILING), + array(1, 123.44, '123,5', NumberToLocalizedStringTransformer::ROUND_CEILING), + array(1, -123.45, '-123,4', NumberToLocalizedStringTransformer::ROUND_CEILING), + array(1, -123.44, '-123,4', NumberToLocalizedStringTransformer::ROUND_CEILING), + // towards negative infinity (1.6 -> 1, -1.6 -> -2) + array(0, 1234.5, '1234', NumberToLocalizedStringTransformer::ROUND_FLOOR), + array(0, 1234.4, '1234', NumberToLocalizedStringTransformer::ROUND_FLOOR), + array(0, -1234.5, '-1235', NumberToLocalizedStringTransformer::ROUND_FLOOR), + array(0, -1234.4, '-1235', NumberToLocalizedStringTransformer::ROUND_FLOOR), + array(1, 123.45, '123,4', NumberToLocalizedStringTransformer::ROUND_FLOOR), + array(1, 123.44, '123,4', NumberToLocalizedStringTransformer::ROUND_FLOOR), + array(1, -123.45, '-123,5', NumberToLocalizedStringTransformer::ROUND_FLOOR), + array(1, -123.44, '-123,5', NumberToLocalizedStringTransformer::ROUND_FLOOR), + // away from zero (1.6 -> 2, -1.6 -> 2) + array(0, 1234.5, '1235', NumberToLocalizedStringTransformer::ROUND_UP), + array(0, 1234.4, '1235', NumberToLocalizedStringTransformer::ROUND_UP), + array(0, -1234.5, '-1235', NumberToLocalizedStringTransformer::ROUND_UP), + array(0, -1234.4, '-1235', NumberToLocalizedStringTransformer::ROUND_UP), + array(1, 123.45, '123,5', NumberToLocalizedStringTransformer::ROUND_UP), + array(1, 123.44, '123,5', NumberToLocalizedStringTransformer::ROUND_UP), + array(1, -123.45, '-123,5', NumberToLocalizedStringTransformer::ROUND_UP), + array(1, -123.44, '-123,5', NumberToLocalizedStringTransformer::ROUND_UP), + // towards zero (1.6 -> 1, -1.6 -> -1) + array(0, 1234.5, '1234', NumberToLocalizedStringTransformer::ROUND_DOWN), + array(0, 1234.4, '1234', NumberToLocalizedStringTransformer::ROUND_DOWN), + array(0, -1234.5, '-1234', NumberToLocalizedStringTransformer::ROUND_DOWN), + array(0, -1234.4, '-1234', NumberToLocalizedStringTransformer::ROUND_DOWN), + array(1, 123.45, '123,4', NumberToLocalizedStringTransformer::ROUND_DOWN), + array(1, 123.44, '123,4', NumberToLocalizedStringTransformer::ROUND_DOWN), + array(1, -123.45, '-123,4', NumberToLocalizedStringTransformer::ROUND_DOWN), + array(1, -123.44, '-123,4', NumberToLocalizedStringTransformer::ROUND_DOWN), + // round halves (.5) to the next even number + array(0, 1234.6, '1235', NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(0, 1234.5, '1234', NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(0, 1234.4, '1234', NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(0, 1233.5, '1234', NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(0, 1232.5, '1232', NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(0, -1234.6, '-1235', NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(0, -1234.5, '-1234', NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(0, -1234.4, '-1234', NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(0, -1233.5, '-1234', NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(0, -1232.5, '-1232', NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(1, 123.46, '123,5', NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(1, 123.45, '123,4', NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(1, 123.44, '123,4', NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(1, 123.35, '123,4', NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(1, 123.25, '123,2', NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(1, -123.46, '-123,5', NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(1, -123.45, '-123,4', NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(1, -123.44, '-123,4', NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(1, -123.35, '-123,4', NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(1, -123.25, '-123,2', NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + // round halves (.5) away from zero + array(0, 1234.6, '1235', NumberToLocalizedStringTransformer::ROUND_HALF_UP), + array(0, 1234.5, '1235', NumberToLocalizedStringTransformer::ROUND_HALF_UP), + array(0, 1234.4, '1234', NumberToLocalizedStringTransformer::ROUND_HALF_UP), + array(0, -1234.6, '-1235', NumberToLocalizedStringTransformer::ROUND_HALF_UP), + array(0, -1234.5, '-1235', NumberToLocalizedStringTransformer::ROUND_HALF_UP), + array(0, -1234.4, '-1234', NumberToLocalizedStringTransformer::ROUND_HALF_UP), + array(1, 123.46, '123,5', NumberToLocalizedStringTransformer::ROUND_HALF_UP), + array(1, 123.45, '123,5', NumberToLocalizedStringTransformer::ROUND_HALF_UP), + array(1, 123.44, '123,4', NumberToLocalizedStringTransformer::ROUND_HALF_UP), + array(1, -123.46, '-123,5', NumberToLocalizedStringTransformer::ROUND_HALF_UP), + array(1, -123.45, '-123,5', NumberToLocalizedStringTransformer::ROUND_HALF_UP), + array(1, -123.44, '-123,4', NumberToLocalizedStringTransformer::ROUND_HALF_UP), + // round halves (.5) towards zero + array(0, 1234.6, '1235', NumberToLocalizedStringTransformer::ROUND_HALF_DOWN), + array(0, 1234.5, '1234', NumberToLocalizedStringTransformer::ROUND_HALF_DOWN), + array(0, 1234.4, '1234', NumberToLocalizedStringTransformer::ROUND_HALF_DOWN), + array(0, -1234.6, '-1235', NumberToLocalizedStringTransformer::ROUND_HALF_DOWN), + array(0, -1234.5, '-1234', NumberToLocalizedStringTransformer::ROUND_HALF_DOWN), + array(0, -1234.4, '-1234', NumberToLocalizedStringTransformer::ROUND_HALF_DOWN), + array(1, 123.46, '123,5', NumberToLocalizedStringTransformer::ROUND_HALF_DOWN), + array(1, 123.45, '123,4', NumberToLocalizedStringTransformer::ROUND_HALF_DOWN), + array(1, 123.44, '123,4', NumberToLocalizedStringTransformer::ROUND_HALF_DOWN), + array(1, -123.46, '-123,5', NumberToLocalizedStringTransformer::ROUND_HALF_DOWN), + array(1, -123.45, '-123,4', NumberToLocalizedStringTransformer::ROUND_HALF_DOWN), + array(1, -123.44, '-123,4', NumberToLocalizedStringTransformer::ROUND_HALF_DOWN), + ); + } + + /** + * @dataProvider transformWithRoundingProvider + */ + public function testTransformWithRounding($precision, $input, $output, $roundingMode) + { + $transformer = new NumberToLocalizedStringTransformer($precision, null, $roundingMode); + + $this->assertEquals($output, $transformer->transform($input)); + } + + public function testTransformDoesNotRoundIfNoPrecision() { $transformer = new NumberToLocalizedStringTransformer(null, null, NumberToLocalizedStringTransformer::ROUND_DOWN); - $this->assertEquals('1234,547', $transformer->transform(1234.547), '->transform() only applies rounding mode if precision set'); - - $transformer = new NumberToLocalizedStringTransformer(2, null, NumberToLocalizedStringTransformer::ROUND_DOWN); - $this->assertEquals('1234,54', $transformer->transform(1234.547), '->transform() rounding-mode works'); + $this->assertEquals('1234,547', $transformer->transform(1234.547)); } /** @@ -139,6 +235,112 @@ class NumberToLocalizedStringTransformerTest extends \PHPUnit_Framework_TestCase $this->assertEquals(12345.912, $transformer->reverseTransform('12345,912')); } + public function reverseTransformWithRoundingProvider() + { + return array( + // towards positive infinity (1.6 -> 2, -1.6 -> -1) + array(0, '1234,5', 1235, NumberToLocalizedStringTransformer::ROUND_CEILING), + array(0, '1234,4', 1235, NumberToLocalizedStringTransformer::ROUND_CEILING), + array(0, '-1234,5', -1234, NumberToLocalizedStringTransformer::ROUND_CEILING), + array(0, '-1234,4', -1234, NumberToLocalizedStringTransformer::ROUND_CEILING), + array(1, '123,45', 123.5, NumberToLocalizedStringTransformer::ROUND_CEILING), + array(1, '123,44', 123.5, NumberToLocalizedStringTransformer::ROUND_CEILING), + array(1, '-123,45', -123.4, NumberToLocalizedStringTransformer::ROUND_CEILING), + array(1, '-123,44', -123.4, NumberToLocalizedStringTransformer::ROUND_CEILING), + // towards negative infinity (1.6 -> 1, -1.6 -> -2) + array(0, '1234,5', 1234, NumberToLocalizedStringTransformer::ROUND_FLOOR), + array(0, '1234,4', 1234, NumberToLocalizedStringTransformer::ROUND_FLOOR), + array(0, '-1234,5', -1235, NumberToLocalizedStringTransformer::ROUND_FLOOR), + array(0, '-1234,4', -1235, NumberToLocalizedStringTransformer::ROUND_FLOOR), + array(1, '123,45', 123.4, NumberToLocalizedStringTransformer::ROUND_FLOOR), + array(1, '123,44', 123.4, NumberToLocalizedStringTransformer::ROUND_FLOOR), + array(1, '-123,45', -123.5, NumberToLocalizedStringTransformer::ROUND_FLOOR), + array(1, '-123,44', -123.5, NumberToLocalizedStringTransformer::ROUND_FLOOR), + // away from zero (1.6 -> 2, -1.6 -> 2) + array(0, '1234,5', 1235, NumberToLocalizedStringTransformer::ROUND_UP), + array(0, '1234,4', 1235, NumberToLocalizedStringTransformer::ROUND_UP), + array(0, '-1234,5', -1235, NumberToLocalizedStringTransformer::ROUND_UP), + array(0, '-1234,4', -1235, NumberToLocalizedStringTransformer::ROUND_UP), + array(1, '123,45', 123.5, NumberToLocalizedStringTransformer::ROUND_UP), + array(1, '123,44', 123.5, NumberToLocalizedStringTransformer::ROUND_UP), + array(1, '-123,45', -123.5, NumberToLocalizedStringTransformer::ROUND_UP), + array(1, '-123,44', -123.5, NumberToLocalizedStringTransformer::ROUND_UP), + // towards zero (1.6 -> 1, -1.6 -> -1) + array(0, '1234,5', 1234, NumberToLocalizedStringTransformer::ROUND_DOWN), + array(0, '1234,4', 1234, NumberToLocalizedStringTransformer::ROUND_DOWN), + array(0, '-1234,5', -1234, NumberToLocalizedStringTransformer::ROUND_DOWN), + array(0, '-1234,4', -1234, NumberToLocalizedStringTransformer::ROUND_DOWN), + array(1, '123,45', 123.4, NumberToLocalizedStringTransformer::ROUND_DOWN), + array(1, '123,44', 123.4, NumberToLocalizedStringTransformer::ROUND_DOWN), + array(1, '-123,45', -123.4, NumberToLocalizedStringTransformer::ROUND_DOWN), + array(1, '-123,44', -123.4, NumberToLocalizedStringTransformer::ROUND_DOWN), + // round halves (.5) to the next even number + array(0, '1234,6', 1235, NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(0, '1234,5', 1234, NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(0, '1234,4', 1234, NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(0, '1233,5', 1234, NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(0, '1232,5', 1232, NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(0, '-1234,6', -1235, NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(0, '-1234,5', -1234, NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(0, '-1234,4', -1234, NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(0, '-1233,5', -1234, NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(0, '-1232,5', -1232, NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(1, '123,46', 123.5, NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(1, '123,45', 123.4, NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(1, '123,44', 123.4, NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(1, '123,35', 123.4, NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(1, '123,25', 123.2, NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(1, '-123,46', -123.5, NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(1, '-123,45', -123.4, NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(1, '-123,44', -123.4, NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(1, '-123,35', -123.4, NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + array(1, '-123,25', -123.2, NumberToLocalizedStringTransformer::ROUND_HALF_EVEN), + // round halves (.5) away from zero + array(0, '1234,6', 1235, NumberToLocalizedStringTransformer::ROUND_HALF_UP), + array(0, '1234,5', 1235, NumberToLocalizedStringTransformer::ROUND_HALF_UP), + array(0, '1234,4', 1234, NumberToLocalizedStringTransformer::ROUND_HALF_UP), + array(0, '-1234,6', -1235, NumberToLocalizedStringTransformer::ROUND_HALF_UP), + array(0, '-1234,5', -1235, NumberToLocalizedStringTransformer::ROUND_HALF_UP), + array(0, '-1234,4', -1234, NumberToLocalizedStringTransformer::ROUND_HALF_UP), + array(1, '123,46', 123.5, NumberToLocalizedStringTransformer::ROUND_HALF_UP), + array(1, '123,45', 123.5, NumberToLocalizedStringTransformer::ROUND_HALF_UP), + array(1, '123,44', 123.4, NumberToLocalizedStringTransformer::ROUND_HALF_UP), + array(1, '-123,46', -123.5, NumberToLocalizedStringTransformer::ROUND_HALF_UP), + array(1, '-123,45', -123.5, NumberToLocalizedStringTransformer::ROUND_HALF_UP), + array(1, '-123,44', -123.4, NumberToLocalizedStringTransformer::ROUND_HALF_UP), + // round halves (.5) towards zero + array(0, '1234,6', 1235, NumberToLocalizedStringTransformer::ROUND_HALF_DOWN), + array(0, '1234,5', 1234, NumberToLocalizedStringTransformer::ROUND_HALF_DOWN), + array(0, '1234,4', 1234, NumberToLocalizedStringTransformer::ROUND_HALF_DOWN), + array(0, '-1234,6', -1235, NumberToLocalizedStringTransformer::ROUND_HALF_DOWN), + array(0, '-1234,5', -1234, NumberToLocalizedStringTransformer::ROUND_HALF_DOWN), + array(0, '-1234,4', -1234, NumberToLocalizedStringTransformer::ROUND_HALF_DOWN), + array(1, '123,46', 123.5, NumberToLocalizedStringTransformer::ROUND_HALF_DOWN), + array(1, '123,45', 123.4, NumberToLocalizedStringTransformer::ROUND_HALF_DOWN), + array(1, '123,44', 123.4, NumberToLocalizedStringTransformer::ROUND_HALF_DOWN), + array(1, '-123,46', -123.5, NumberToLocalizedStringTransformer::ROUND_HALF_DOWN), + array(1, '-123,45', -123.4, NumberToLocalizedStringTransformer::ROUND_HALF_DOWN), + array(1, '-123,44', -123.4, NumberToLocalizedStringTransformer::ROUND_HALF_DOWN), + ); + } + + /** + * @dataProvider reverseTransformWithRoundingProvider + */ + public function testReverseTransformWithRounding($precision, $input, $output, $roundingMode) + { + $transformer = new NumberToLocalizedStringTransformer($precision, null, $roundingMode); + + $this->assertEquals($output, $transformer->reverseTransform($input)); + } + + public function testReverseTransformDoesNotRoundIfNoPrecision() + { + $transformer = new NumberToLocalizedStringTransformer(null, null, NumberToLocalizedStringTransformer::ROUND_DOWN); + + $this->assertEquals(1234.547, $transformer->reverseTransform('1234,547')); + } + public function testDecimalSeparatorMayBeDotIfGroupingSeparatorIsNotDot() { \Locale::setDefault('fr');