[Form] Fixed PercentToLocalizedStringTransformer to accept both comma and dot as decimal separator, if possible

This commit is contained in:
adev 2017-04-17 20:52:26 +02:00 committed by Fabien Potencier
parent ae7e2cd7a5
commit f96a7f81b8
2 changed files with 129 additions and 0 deletions

View File

@ -119,6 +119,18 @@ class PercentToLocalizedStringTransformer implements DataTransformerInterface
}
$formatter = $this->getNumberFormatter();
$groupSep = $formatter->getSymbol(\NumberFormatter::GROUPING_SEPARATOR_SYMBOL);
$decSep = $formatter->getSymbol(\NumberFormatter::DECIMAL_SEPARATOR_SYMBOL);
$grouping = $formatter->getAttribute(\NumberFormatter::GROUPING_USED);
if ('.' !== $decSep && (!$grouping || '.' !== $groupSep)) {
$value = str_replace('.', $decSep, $value);
}
if (',' !== $decSep && (!$grouping || ',' !== $groupSep)) {
$value = str_replace(',', $decSep, $value);
}
// replace normal spaces so that the formatter can read them
$value = $formatter->parse(str_replace(' ', "\xc2\xa0", $value));

View File

@ -119,4 +119,121 @@ class PercentToLocalizedStringTransformerTest extends TestCase
$transformer->reverseTransform(1);
}
public function testDecimalSeparatorMayBeDotIfGroupingSeparatorIsNotDot()
{
IntlTestHelper::requireFullIntl($this, '4.8.1.1');
\Locale::setDefault('fr');
$transformer = new PercentToLocalizedStringTransformer(1, 'integer');
// completely valid format
$this->assertEquals(1234.5, $transformer->reverseTransform('1 234,5'));
// accept dots
$this->assertEquals(1234.5, $transformer->reverseTransform('1 234.5'));
// omit group separator
$this->assertEquals(1234.5, $transformer->reverseTransform('1234,5'));
$this->assertEquals(1234.5, $transformer->reverseTransform('1234.5'));
}
/**
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
*/
public function testDecimalSeparatorMayNotBeDotIfGroupingSeparatorIsDot()
{
// Since we test against "de_AT", we need the full implementation
IntlTestHelper::requireFullIntl($this, '4.8.1.1');
\Locale::setDefault('de_AT');
$transformer = new PercentToLocalizedStringTransformer(1, 'integer');
$transformer->reverseTransform('1.234.5');
}
/**
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
*/
public function testDecimalSeparatorMayNotBeDotIfGroupingSeparatorIsDotWithNoGroupSep()
{
// Since we test against "de_DE", we need the full implementation
IntlTestHelper::requireFullIntl($this, '4.8.1.1');
\Locale::setDefault('de_DE');
$transformer = new PercentToLocalizedStringTransformer(1, 'integer');
$transformer->reverseTransform('1234.5');
}
public function testDecimalSeparatorMayBeDotIfGroupingSeparatorIsDotButNoGroupingUsed()
{
// Since we test against other locales, we need the full implementation
IntlTestHelper::requireFullIntl($this, false);
\Locale::setDefault('fr');
$transformer = new PercentToLocalizedStringTransformer(1, 'integer');
$this->assertEquals(1234.5, $transformer->reverseTransform('1234,5'));
$this->assertEquals(1234.5, $transformer->reverseTransform('1234.5'));
}
public function testDecimalSeparatorMayBeCommaIfGroupingSeparatorIsNotComma()
{
// Since we test against other locales, we need the full implementation
IntlTestHelper::requireFullIntl($this, '4.8.1.1');
\Locale::setDefault('bg');
$transformer = new PercentToLocalizedStringTransformer(1, 'integer');
// completely valid format
$this->assertEquals(1234.5, $transformer->reverseTransform('1 234.5'));
// accept commas
$this->assertEquals(1234.5, $transformer->reverseTransform('1 234,5'));
// omit group separator
$this->assertEquals(1234.5, $transformer->reverseTransform('1234.5'));
$this->assertEquals(1234.5, $transformer->reverseTransform('1234,5'));
}
/**
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
*/
public function testDecimalSeparatorMayNotBeCommaIfGroupingSeparatorIsComma()
{
IntlTestHelper::requireFullIntl($this, '4.8.1.1');
$transformer = new PercentToLocalizedStringTransformer(1, 'integer');
$transformer->reverseTransform('1,234,5');
}
/**
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
*/
public function testDecimalSeparatorMayNotBeCommaIfGroupingSeparatorIsCommaWithNoGroupSep()
{
IntlTestHelper::requireFullIntl($this, '4.8.1.1');
$transformer = new PercentToLocalizedStringTransformer(1, 'integer');
$transformer->reverseTransform('1234,5');
}
public function testDecimalSeparatorMayBeCommaIfGroupingSeparatorIsCommaButNoGroupingUsed()
{
$formatter = new \NumberFormatter(\Locale::getDefault(), \NumberFormatter::DECIMAL);
$formatter->setAttribute(\NumberFormatter::FRACTION_DIGITS, 1);
$formatter->setAttribute(\NumberFormatter::GROUPING_USED, false);
$transformer = $this->getMockBuilder('Symfony\Component\Form\Extension\Core\DataTransformer\PercentToLocalizedStringTransformer')
->setMethods(array('getNumberFormatter'))
->setConstructorArgs(array(1, 'integer'))
->getMock();
$transformer->expects($this->any())
->method('getNumberFormatter')
->willReturn($formatter);
$this->assertEquals(1234.5, $transformer->reverseTransform('1234,5'));
$this->assertEquals(1234.5, $transformer->reverseTransform('1234.5'));
}
}