Explorar o código

merged branch eriksencosta/locale-fixes-2.0 (PR #3955)

Commits
-------

fab1b5a [Locale] changed inequality operator to strict checking and updated some assertions
09d30d3 [Locale] refactored some code
e4cbbf3 [Locale] fixed StubNumberFormatter::format() to behave like the NumberFormatter::parse() regarding to error flagging
f16ff89 [Locale] fixed StubNumberFormatter::parse() to behave like the NumberFormatter::parse() regarding to error flagging
0a60664 [Locale] updated StubIntlDateFormatter::format() exception message when timestamp argument is an array for PHP >= 5.3.4
e4769d9 [Locale] reordered test methods
312a5a4 [Locale] fixed StubIntlDateFormatter::format() to set the right error for PHP >= 5.3.4 and to behave like the intl when formatting successfully

Discussion
----------

[2.0][Locale] some fixes

Bug fix: yes
Feature addition: no
Backwards compatibility break: no
Symfony2 tests pass: yes
Todo: -

Fixed some inconsistencies between the stub and the intl implementation:

 - `StubIntlDateFormatter::format()` to set the right error for PHP >= 5.3.4 and to behave like the intl when formatting successfully
 - updated `StubIntlDateFormatter::format()` exception message when timestamp argument is an array for PHP >= 5.3.4
 - `StubNumberFormatter::parse()` to behave like the NumberFormatter::parse() regarding to error flagging
 - `StubNumberFormatter::format()` to behave like the NumberFormatter::parse() regarding to error flagging
Fabien Potencier %!s(int64=13) %!d(string=hai) anos
pai
achega
44ea9495a3

+ 1 - 1
src/Symfony/Component/Locale/Exception/MethodArgumentValueNotImplementedException.php

@@ -33,7 +33,7 @@ class MethodArgumentValueNotImplementedException extends NotImplementedException
             $methodName,
             $argName,
             var_export($argValue, true),
-            $additionalMessage != '' ? ' '.$additionalMessage.'. ' : ''
+            $additionalMessage !== '' ? ' '.$additionalMessage.'. ' : ''
         );
 
         parent::__construct($message);

+ 1 - 1
src/Symfony/Component/Locale/Stub/DateFormat/TimeZoneTransformer.php

@@ -88,7 +88,7 @@ class TimeZoneTransformer extends Transformer
                 ));
             }
 
-            return 'Etc/GMT'.($hours != 0 ? $signal.$hours : '');
+            return 'Etc/GMT'.($hours !== 0 ? $signal.$hours : '');
         }
 
         throw new \InvalidArgumentException('The GMT time zone \'%s\' does not match with the supported formats GMT[+-]HH:MM or GMT[+-]HHMM.');

+ 2 - 12
src/Symfony/Component/Locale/Stub/StubCollator.php

@@ -21,16 +21,6 @@ use Symfony\Component\Locale\Exception\MethodArgumentValueNotImplementedExceptio
  */
 class StubCollator
 {
-    /**
-     * Constants defined by the intl extension, not class constants in IntlDateFormatter
-     * TODO: remove if the Form component drop the call to the intl_is_failure() function
-     *
-     * @see StubIntlDateFormatter::getErrorCode()
-     * @see StubIntlDateFormatter::getErrorMessage()
-     */
-    const U_ZERO_ERROR = 0;
-    const U_ZERO_ERROR_MESSAGE = 'U_ZERO_ERROR';
-
     /** Attribute constants */
     const FRENCH_COLLATION = 0;
     const ALTERNATE_HANDLING = 1;
@@ -158,7 +148,7 @@ class StubCollator
      */
     public function getErrorCode()
     {
-        return self::U_ZERO_ERROR;
+        return StubIntl::U_ZERO_ERROR;
     }
 
     /**
@@ -168,7 +158,7 @@ class StubCollator
      */
     public function getErrorMessage()
     {
-        return self::U_ZERO_ERROR_MESSAGE;
+        return 'U_ZERO_ERROR';
     }
 
     /**

+ 25 - 6
src/Symfony/Component/Locale/Stub/StubIntlDateFormatter.php

@@ -124,11 +124,11 @@ class StubIntlDateFormatter
      */
     public function __construct($locale, $datetype, $timetype, $timezone = null, $calendar = self::GREGORIAN, $pattern = null)
     {
-        if ('en' != $locale) {
+        if ('en' !== $locale) {
             throw new MethodArgumentValueNotImplementedException(__METHOD__, 'locale', $locale, 'Only the \'en\' locale is supported');
         }
 
-        if (self::GREGORIAN != $calendar) {
+        if (self::GREGORIAN !== $calendar) {
             throw new MethodArgumentValueNotImplementedException(__METHOD__, 'calendar', $calendar, 'Only the GREGORIAN calendar is supported');
         }
 
@@ -175,24 +175,42 @@ class StubIntlDateFormatter
     {
         // intl allows timestamps to be passed as arrays - we don't
         if (is_array($timestamp)) {
-            throw new MethodArgumentValueNotImplementedException(__METHOD__, 'timestamp', $timestamp, 'Only integer unix timestamps are supported');
+            $message = version_compare(\PHP_VERSION, '5.3.4', '>=') ?
+                'Only integer unix timestamps and DateTime objects are supported' :
+                'Only integer unix timestamps are supported';
+
+            throw new MethodArgumentValueNotImplementedException(__METHOD__, 'timestamp', $timestamp, $message);
         }
 
         // behave like the intl extension
-        if (!is_int($timestamp) && version_compare(\PHP_VERSION, '5.3.4', '<')) {
-            StubIntl::setError(StubIntl::U_ILLEGAL_ARGUMENT_ERROR, 'datefmt_format: takes either an array  or an integer timestamp value ');
+        $argumentError = null;
+        if (version_compare(\PHP_VERSION, '5.3.4', '<') && !is_int($timestamp)) {
+            $argumentError = 'datefmt_format: takes either an array  or an integer timestamp value ';
+        } elseif (version_compare(\PHP_VERSION, '5.3.4', '>=') && !is_int($timestamp) && !$timestamp instanceOf \DateTime) {
+            $argumentError = 'datefmt_format: takes either an array or an integer timestamp value or a DateTime object';
+        }
+
+        if (null !== $argumentError) {
+            StubIntl::setError(StubIntl::U_ILLEGAL_ARGUMENT_ERROR, $argumentError);
+            $this->errorCode = StubIntl::getErrorCode();
+            $this->errorMessage = StubIntl::getErrorMessage();
 
             return false;
         }
 
         // As of PHP 5.3.4, IntlDateFormatter::format() accepts DateTime instances
-        if ($timestamp instanceOf \DateTime && version_compare(\PHP_VERSION, '5.3.4', '>=')) {
+        if (version_compare(\PHP_VERSION, '5.3.4', '>=') && $timestamp instanceOf \DateTime) {
             $timestamp = $timestamp->getTimestamp();
         }
 
         $transformer = new FullTransformer($this->getPattern(), $this->getTimeZoneId());
         $formatted = $transformer->format($this->createDateTime($timestamp));
 
+        // behave like the intl extension
+        StubIntl::setError(StubIntl::U_ZERO_ERROR);
+        $this->errorCode = StubIntl::getErrorCode();
+        $this->errorMessage = StubIntl::getErrorMessage();
+
         return $formatted;
     }
 
@@ -359,6 +377,7 @@ class StubIntlDateFormatter
 
         $timestamp = $transformer->parse($dateTime, $value);
 
+        // behave like the intl extension. FullTransformer::parse() set the proper error
         if (false === $timestamp) {
             $this->errorCode = StubIntl::getErrorCode();
             $this->errorMessage = StubIntl::getErrorMessage();

+ 1 - 1
src/Symfony/Component/Locale/Stub/StubLocale.php

@@ -480,7 +480,7 @@ class StubLocale
      */
     static private function getStubData($locale, $cacheVariable, $stubDataDir)
     {
-        if ('en' != $locale) {
+        if ('en' !== $locale) {
             throw new \InvalidArgumentException(sprintf('Only the \'en\' locale is supported. %s', NotImplementedException::INTL_INSTALL_MESSAGE));
         }
 

+ 45 - 27
src/Symfony/Component/Locale/Stub/StubNumberFormatter.php

@@ -24,20 +24,6 @@ use Symfony\Component\Locale\Exception\MethodArgumentValueNotImplementedExceptio
  */
 class StubNumberFormatter
 {
-    /**
-     * The error code from the last operation
-     *
-     * @var integer
-     */
-    protected $errorCode = StubIntl::U_ZERO_ERROR;
-
-    /**
-     * The error message from the last operation
-     *
-     * @var string
-     */
-    protected $errorMessage = 'U_ZERO_ERROR';
-
     /** Format style constants */
     const PATTERN_DECIMAL   = 0;
     const DECIMAL           = 1;
@@ -125,6 +111,30 @@ class StubNumberFormatter
     const PAD_BEFORE_SUFFIX = 2;
     const PAD_AFTER_SUFFIX  = 3;
 
+    /**
+     * The error code from the last operation
+     *
+     * @var integer
+     */
+    protected $errorCode = StubIntl::U_ZERO_ERROR;
+
+    /**
+     * The error message from the last operation
+     *
+     * @var string
+     */
+    protected $errorMessage = 'U_ZERO_ERROR';
+
+    /**
+     * @var string
+     */
+    private $locale;
+
+    /**
+     * @var int
+     */
+    private $style;
+
     /**
      * Default values for the en locale
      *
@@ -211,16 +221,6 @@ class StubNumberFormatter
         'negative' => -9223372036854775808
     );
 
-    /**
-     * @var string
-     */
-    private $locale = null;
-
-    /**
-     * @var int
-     */
-    private $style = null;
-
     /**
      * Constructor
      *
@@ -351,8 +351,12 @@ class StubNumberFormatter
         $fractionDigits = $this->getAttribute(self::FRACTION_DIGITS);
 
         $value = $this->round($value, $fractionDigits);
+        $value = $this->formatNumber($value, $fractionDigits);
 
-        return $this->formatNumber($value, $fractionDigits);
+        // behave like the intl extension
+        $this->resetError();
+
+        return $value;
     }
 
     /**
@@ -501,7 +505,7 @@ class StubNumberFormatter
 
         // Any string before the numeric value causes error in the parsing
         if (isset($matches[1]) && !empty($matches[1])) {
-            StubIntl::setError(StubIntl::U_PARSE_ERROR);
+            StubIntl::setError(StubIntl::U_PARSE_ERROR, 'Number parsing failed');
             $this->errorCode = StubIntl::getErrorCode();
             $this->errorMessage = StubIntl::getErrorMessage();
 
@@ -510,8 +514,12 @@ class StubNumberFormatter
 
         // Remove everything that is not number or dot (.)
         $value = preg_replace('/[^0-9\.\-]/', '', $value);
+        $value = $this->convertValueDataType($value, $type);
+
+        // behave like the intl extension
+        $this->resetError();
 
-        return $this->convertValueDataType($value, $type);
+        return $value;
     }
 
     /**
@@ -612,6 +620,16 @@ class StubNumberFormatter
         throw new MethodNotImplementedException(__METHOD__);
     }
 
+    /**
+     * Set the error to the default U_ZERO_ERROR
+     */
+    protected function resetError()
+    {
+        StubIntl::setError(StubIntl::U_ZERO_ERROR);
+        $this->errorCode = StubIntl::getErrorCode();
+        $this->errorMessage = StubIntl::getErrorMessage();
+    }
+
     /**
      * Rounds a currency value, applying increment rounding if applicable
      *

+ 3 - 2
tests/Symfony/Tests/Component/Locale/Stub/StubCollatorTest.php

@@ -15,6 +15,7 @@ require_once __DIR__.'/../TestCase.php';
 
 use Symfony\Component\Locale\Locale;
 use Symfony\Component\Locale\Stub\StubCollator;
+use Symfony\Component\Locale\Stub\StubIntl;
 use Symfony\Tests\Component\Locale\TestCase as LocaleTestCase;
 
 class StubCollatorTest extends LocaleTestCase
@@ -91,13 +92,13 @@ class StubCollatorTest extends LocaleTestCase
     public function testGetErrorCode()
     {
         $collator = $this->createStubCollator();
-        $this->assertEquals(StubCollator::U_ZERO_ERROR, $collator->getErrorCode());
+        $this->assertEquals(StubIntl::U_ZERO_ERROR, $collator->getErrorCode());
     }
 
     public function testGetErrorMessage()
     {
         $collator = $this->createStubCollator();
-        $this->assertEquals(StubCollator::U_ZERO_ERROR_MESSAGE, $collator->getErrorMessage());
+        $this->assertEquals('U_ZERO_ERROR', $collator->getErrorMessage());
     }
 
     public function testGetLocale()

+ 87 - 32
tests/Symfony/Tests/Component/Locale/Stub/StubIntlDateFormatterTest.php

@@ -53,52 +53,69 @@ class StubIntlDateFormatterTest extends LocaleTestCase
         $this->assertNull($formatter->getTimeZoneId());
     }
 
+    public function testFormatWithUnsupportedTimestampArgument()
+    {
+        $formatter = $this->createStubFormatter();
+
+        $localtime = array(
+            'tm_sec'   => 59,
+            'tm_min'   => 3,
+            'tm_hour'  => 15,
+            'tm_mday'  => 15,
+            'tm_mon'   => 3,
+            'tm_year'  => 112,
+            'tm_wday'  => 0,
+            'tm_yday'  => 105,
+            'tm_isdst' => 0
+        );
+
+        try {
+            $formatter->format($localtime);
+        } catch (\Exception $e) {
+            $this->assertInstanceOf('Symfony\Component\Locale\Exception\MethodArgumentValueNotImplementedException', $e);
+
+            if ($this->isGreaterOrEqualThanPhpVersion('5.3.4')) {
+                $this->assertStringEndsWith('Only integer unix timestamps and DateTime objects are supported.  Please install the \'intl\' extension for full localization capabilities.', $e->getMessage());
+            } else {
+                $this->assertStringEndsWith('Only integer unix timestamps are supported.  Please install the \'intl\' extension for full localization capabilities.', $e->getMessage());
+            }
+        }
+    }
+
     /**
      * @dataProvider formatProvider
      */
-    public function testFormatStub($pattern, $timestamp, $expected, $errorCode = 0, $errorMessage = 'U_ZERO_ERROR')
+    public function testFormatStub($pattern, $timestamp, $expected)
     {
+        $errorCode = StubIntl::U_ZERO_ERROR;
+        $errorMessage = 'U_ZERO_ERROR';
+
         $formatter = $this->createStubFormatter($pattern);
         $this->assertSame($expected, $formatter->format($timestamp));
         $this->assertSame($errorMessage, StubIntl::getErrorMessage());
         $this->assertSame($errorCode, StubIntl::getErrorCode());
-        $this->assertSame($errorCode != 0, StubIntl::isFailure(StubIntl::getErrorCode()));
+        $this->assertFalse(StubIntl::isFailure(StubIntl::getErrorCode()));
         $this->assertSame($errorMessage, $formatter->getErrorMessage());
         $this->assertSame($errorCode, $formatter->getErrorCode());
-        $this->assertSame($errorCode != 0, StubIntl::isFailure($formatter->getErrorCode()));
+        $this->assertFalse(StubIntl::isFailure($formatter->getErrorCode()));
     }
 
     /**
      * @dataProvider formatProvider
      */
-    public function testFormatIntl($pattern, $timestamp, $expected, $errorCode = 0, $errorMessage = 'U_ZERO_ERROR')
+    public function testFormatIntl($pattern, $timestamp, $expected)
     {
         $this->skipIfIntlExtensionIsNotLoaded();
         $this->skipIfICUVersionIsTooOld();
-        $formatter = $this->createIntlFormatter($pattern);
-        $this->assertSame($expected, $formatter->format($timestamp));
-        $this->assertSame($errorMessage, intl_get_error_message());
-        $this->assertSame($errorCode, intl_get_error_code());
-        $this->assertSame($errorCode != 0, intl_is_failure(intl_get_error_code()));
-    }
 
-    /**
-     * @dataProvider formatErrorProvider
-     */
-    public function testFormatErrorIntl($pattern, $timestamp, $expected, $errorCode = 0, $errorMessage = 'U_ZERO_ERROR')
-    {
-        $this->skipIfIntlExtensionIsNotLoaded();
-        $this->skipIfICUVersionIsTooOld();
-
-        if (version_compare(PHP_VERSION, '5.3.3') > 0) {
-            $this->markTestSkipped('The intl error messages were change in PHP 5.3.3.');
-        }
+        $errorCode = StubIntl::U_ZERO_ERROR;
+        $errorMessage = 'U_ZERO_ERROR';
 
         $formatter = $this->createIntlFormatter($pattern);
         $this->assertSame($expected, $formatter->format($timestamp));
         $this->assertSame($errorMessage, intl_get_error_message());
         $this->assertSame($errorCode, intl_get_error_code());
-        $this->assertSame($errorCode != 0, intl_is_failure(intl_get_error_code()));
+        $this->assertFalse(intl_is_failure(intl_get_error_code()));
     }
 
     public function formatProvider()
@@ -280,7 +297,7 @@ class StubIntlDateFormatterTest extends LocaleTestCase
         );
 
         // As of PHP 5.3.4, IntlDateFormatter::format() accepts DateTime instances
-        if (version_compare(\PHP_VERSION, '5.3.4', '>=')) {
+        if ($this->isGreaterOrEqualThanPhpVersion('5.3.4')) {
             $dateTime = new \DateTime('@0');
 
             /* general, DateTime */
@@ -295,13 +312,51 @@ class StubIntlDateFormatterTest extends LocaleTestCase
         return $formatData;
     }
 
+    /**
+     * @dataProvider formatErrorProvider
+     */
+    public function testFormatIllegalArgumentErrorStub($pattern, $timestamp, $errorMessage)
+    {
+        $errorCode = StubIntl::U_ILLEGAL_ARGUMENT_ERROR;
+
+        $formatter = $this->createStubFormatter($pattern);
+        $this->assertFalse($formatter->format($timestamp));
+        $this->assertSame($errorMessage, StubIntl::getErrorMessage());
+        $this->assertSame($errorCode, StubIntl::getErrorCode());
+        $this->assertTrue(StubIntl::isFailure(StubIntl::getErrorCode()));
+        $this->assertSame($errorMessage, $formatter->getErrorMessage());
+        $this->assertSame($errorCode, $formatter->getErrorCode());
+        $this->assertTrue(StubIntl::isFailure($formatter->getErrorCode()));
+    }
+
+    /**
+     * @dataProvider formatErrorProvider
+     */
+    public function testFormatIllegalArgumentErrorIntl($pattern, $timestamp, $errorMessage)
+    {
+        $this->skipIfIntlExtensionIsNotLoaded();
+        $this->skipIfICUVersionIsTooOld();
+
+        $errorCode = StubIntl::U_ILLEGAL_ARGUMENT_ERROR;
+
+        $formatter = $this->createIntlFormatter($pattern);
+        $this->assertFalse($formatter->format($timestamp));
+        $this->assertSame($errorMessage, intl_get_error_message());
+        $this->assertSame($errorCode, intl_get_error_code());
+        $this->assertTrue(intl_is_failure(intl_get_error_code()));
+    }
+
     public function formatErrorProvider()
     {
-        /* errors */
+        $message = 'datefmt_format: takes either an array  or an integer timestamp value : U_ILLEGAL_ARGUMENT_ERROR';
+
+        if ($this->isGreaterOrEqualThanPhpVersion('5.3.4')) {
+            $message = 'datefmt_format: takes either an array or an integer timestamp value or a DateTime object: U_ILLEGAL_ARGUMENT_ERROR';
+        }
 
         return array(
-            array('y-M-d', '0', false, 1, 'datefmt_format: takes either an array  or an integer timestamp value : U_ILLEGAL_ARGUMENT_ERROR'),
-            array('y-M-d', 'foobar', false, 1, 'datefmt_format: takes either an array  or an integer timestamp value : U_ILLEGAL_ARGUMENT_ERROR'),
+            array('y-M-d', '0', $message),
+            array('y-M-d', 'foobar', $message),
         );
     }
 
@@ -543,7 +598,7 @@ class StubIntlDateFormatterTest extends LocaleTestCase
         $this->assertSame($expected, $formatter->parse($value));
         $this->assertSame($errorMessage, intl_get_error_message());
         $this->assertSame($errorCode, intl_get_error_code());
-        $this->assertSame($errorCode != 0, intl_is_failure(intl_get_error_code()));
+        $this->assertFalse(intl_is_failure(intl_get_error_code()));
     }
 
     /**
@@ -558,10 +613,10 @@ class StubIntlDateFormatterTest extends LocaleTestCase
         $this->assertSame($expected, $formatter->parse($value));
         $this->assertSame($errorMessage, StubIntl::getErrorMessage());
         $this->assertSame($errorCode, StubIntl::getErrorCode());
-        $this->assertSame($errorCode != 0, StubIntl::isFailure(StubIntl::getErrorCode()));
+        $this->assertFalse(StubIntl::isFailure(StubIntl::getErrorCode()));
         $this->assertSame($errorMessage, $formatter->getErrorMessage());
         $this->assertSame($errorCode, $formatter->getErrorCode());
-        $this->assertSame($errorCode != 0, StubIntl::isFailure($formatter->getErrorCode()));
+        $this->assertFalse(StubIntl::isFailure($formatter->getErrorCode()));
     }
 
     public function parseProvider()
@@ -720,7 +775,7 @@ class StubIntlDateFormatterTest extends LocaleTestCase
         $this->assertFalse($formatter->parse($value));
         $this->assertSame($errorMessage, intl_get_error_message());
         $this->assertSame($errorCode, intl_get_error_code());
-        $this->assertSame($errorCode != 0, intl_is_failure(intl_get_error_code()));
+        $this->assertTrue(intl_is_failure(intl_get_error_code()));
     }
 
     /**
@@ -735,10 +790,10 @@ class StubIntlDateFormatterTest extends LocaleTestCase
         $this->assertFalse($formatter->parse($value));
         $this->assertSame($errorMessage, StubIntl::getErrorMessage());
         $this->assertSame($errorCode, StubIntl::getErrorCode());
-        $this->assertSame($errorCode != 0, StubIntl::isFailure(StubIntl::getErrorCode()));
+        $this->assertTrue(StubIntl::isFailure(StubIntl::getErrorCode()));
         $this->assertSame($errorMessage, $formatter->getErrorMessage());
         $this->assertSame($errorCode, $formatter->getErrorCode());
-        $this->assertSame($errorCode != 0, StubIntl::isFailure($formatter->getErrorCode()));
+        $this->assertTrue(StubIntl::isFailure($formatter->getErrorCode()));
     }
 
     public function parseErrorProvider()

+ 44 - 4
tests/Symfony/Tests/Component/Locale/Stub/StubNumberFormatterTest.php

@@ -225,15 +225,36 @@ class StubNumberFormatterTest extends LocaleTestCase
 
     public function testFormatStub()
     {
+        $errorCode = StubIntl::U_ZERO_ERROR;
+        $errorMessage = 'U_ZERO_ERROR';
+
         $formatter = $this->getStubFormatterWithDecimalStyle();
         $this->assertSame('9.555', $formatter->format(9.555));
+
+        $this->assertSame($errorMessage, StubIntl::getErrorMessage());
+        $this->assertSame($errorCode, StubIntl::getErrorCode());
+        $this->assertFalse(StubIntl::isFailure(StubIntl::getErrorCode()));
+        $this->assertSame($errorMessage, $formatter->getErrorMessage());
+        $this->assertSame($errorCode, $formatter->getErrorCode());
+        $this->assertFalse(StubIntl::isFailure($formatter->getErrorCode()));
     }
 
     public function testFormatIntl()
     {
         $this->skipIfIntlExtensionIsNotLoaded();
+
+        $errorCode = StubIntl::U_ZERO_ERROR;
+        $errorMessage = 'U_ZERO_ERROR';
+
         $formatter = $this->getIntlFormatterWithDecimalStyle();
         $this->assertSame('9.555', $formatter->format(9.555));
+
+        $this->assertSame($errorMessage, intl_get_error_message());
+        $this->assertSame($errorCode, intl_get_error_code());
+        $this->assertFalse(intl_is_failure(intl_get_error_code()));
+        $this->assertSame($errorMessage, $formatter->getErrorMessage());
+        $this->assertSame($errorCode, $formatter->getErrorCode());
+        $this->assertFalse(intl_is_failure($formatter->getErrorCode()));
     }
 
     /**
@@ -669,10 +690,19 @@ class StubNumberFormatterTest extends LocaleTestCase
         $this->assertSame($expected, $parsedValue, $message);
 
         if ($expected === false) {
-            $this->assertSame(StubIntl::U_PARSE_ERROR, $formatter->getErrorCode());
+            $errorCode = StubIntl::U_PARSE_ERROR;
+            $errorMessage = 'Number parsing failed: U_PARSE_ERROR';
         } else {
-            $this->assertEquals(StubIntl::U_ZERO_ERROR, $formatter->getErrorCode());
+            $errorCode = StubIntl::U_ZERO_ERROR;
+            $errorMessage = 'U_ZERO_ERROR';
         }
+
+        $this->assertSame($errorMessage, StubIntl::getErrorMessage());
+        $this->assertSame($errorCode, StubIntl::getErrorCode());
+        $this->assertSame($errorCode !== 0, StubIntl::isFailure(StubIntl::getErrorCode()));
+        $this->assertSame($errorMessage, $formatter->getErrorMessage());
+        $this->assertSame($errorCode, $formatter->getErrorCode());
+        $this->assertSame($errorCode !== 0, StubIntl::isFailure($formatter->getErrorCode()));
     }
 
     /**
@@ -682,15 +712,25 @@ class StubNumberFormatterTest extends LocaleTestCase
     {
         $this->skipIfIntlExtensionIsNotLoaded();
         $this->skipIfICUVersionIsTooOld();
+
         $formatter = $this->getIntlFormatterWithDecimalStyle();
         $parsedValue = $formatter->parse($value, \NumberFormatter::TYPE_DOUBLE);
         $this->assertSame($expected, $parsedValue, $message);
 
         if ($expected === false) {
-            $this->assertSame(U_PARSE_ERROR, $formatter->getErrorCode());
+            $errorCode = StubIntl::U_PARSE_ERROR;
+            $errorMessage = 'Number parsing failed: U_PARSE_ERROR';
         } else {
-            $this->assertEquals(U_ZERO_ERROR, $formatter->getErrorCode());
+            $errorCode = StubIntl::U_ZERO_ERROR;
+            $errorMessage = 'U_ZERO_ERROR';
         }
+
+        $this->assertSame($errorMessage, intl_get_error_message());
+        $this->assertSame($errorCode, intl_get_error_code());
+        $this->assertSame($errorCode > 0, intl_is_failure(intl_get_error_code()));
+        $this->assertSame($errorMessage, $formatter->getErrorMessage());
+        $this->assertSame($errorCode, $formatter->getErrorCode());
+        $this->assertSame($errorCode > 0, intl_is_failure($formatter->getErrorCode()));
     }
 
     public function parseProvider()

+ 5 - 0
tests/Symfony/Tests/Component/Locale/TestCase.php

@@ -58,6 +58,11 @@ abstract class TestCase extends \PHPUnit_Framework_TestCase
         }
     }
 
+    protected function isGreaterOrEqualThanPhpVersion($version)
+    {
+        return version_compare(\PHP_VERSION, $version, '>=');
+    }
+
     protected function isGreaterOrEqualThanIcuVersion($version)
     {
         $version = $this->normalizeIcuVersion($version);