[Locale] StubNumberFormatter allow to parse 64bit number in 64bit mode
This commit is contained in:
parent
83894be6c8
commit
3759ff0777
@ -203,11 +203,20 @@ class StubNumberFormatter
|
||||
* The maximum values of the integer type in 32 bit platforms.
|
||||
* @var array
|
||||
*/
|
||||
static private $intRange = array(
|
||||
static private $int32Range = array(
|
||||
'positive' => 2147483647,
|
||||
'negative' => -2147483648
|
||||
);
|
||||
|
||||
/**
|
||||
* The maximum values of the integer type in 64 bit platforms.
|
||||
* @var array
|
||||
*/
|
||||
static private $int64Range = array(
|
||||
'positive' => 9223372036854775807,
|
||||
'negative' => -9223372036854775808
|
||||
);
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
@ -450,7 +459,6 @@ class StubNumberFormatter
|
||||
* @param int $position Offset to begin the parsing on return this value will hold the offset at which the parsing ended
|
||||
* @return Boolean|string The parsed value of false on error
|
||||
* @see http://www.php.net/manual/en/numberformatter.parse.php
|
||||
* @throws MethodArgumentValueNotImplementedException When $type equals to TYPE_INT64, behavior not implemented
|
||||
* @throws MethodArgumentNotImplementedException When $position different than null, behavior not implemented
|
||||
*/
|
||||
public function parse($value, $type = self::TYPE_DOUBLE, &$position = null)
|
||||
@ -461,11 +469,6 @@ class StubNumberFormatter
|
||||
return false;
|
||||
}
|
||||
|
||||
// Not implemented, the NumberFormatter behavior is inconsistency
|
||||
if ($type == self::TYPE_INT64) {
|
||||
throw new MethodArgumentValueNotImplementedException(__METHOD__, 'type', $type);
|
||||
}
|
||||
|
||||
// We don't calculate the position when parsing the value
|
||||
if (null !== $position) {
|
||||
throw new MethodArgumentNotImplementedException(__METHOD__, 'position');
|
||||
@ -719,9 +722,10 @@ class StubNumberFormatter
|
||||
{
|
||||
if ($type == self::TYPE_DOUBLE) {
|
||||
$value = (float) $value;
|
||||
}
|
||||
elseif ($type == self::TYPE_INT32) {
|
||||
$value = $this->getIntValue($value);
|
||||
} elseif ($type == self::TYPE_INT32) {
|
||||
$value = $this->getInt32Value($value);
|
||||
} elseif ($type == self::TYPE_INT64) {
|
||||
$value = $this->getInt64Value($value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
@ -733,15 +737,38 @@ class StubNumberFormatter
|
||||
* @param mixed $value The value to be converted
|
||||
* @return int The converted value
|
||||
*/
|
||||
private function getIntValue($value)
|
||||
private function getInt32Value($value)
|
||||
{
|
||||
if ($value > self::$intRange['positive'] || $value < self::$intRange['negative']) {
|
||||
if ($value > self::$int32Range['positive'] || $value < self::$int32Range['negative']) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (int) $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the value data type to int or returns false if the value is out of the integer value range.
|
||||
*
|
||||
* @param mixed $value The value to be converted
|
||||
* @return int|float The converted value
|
||||
*/
|
||||
private function getInt64Value($value)
|
||||
{
|
||||
if ($value > self::$int64Range['positive'] || $value < self::$int64Range['negative']) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (PHP_INT_SIZE !== 8 && ($value > self::$int32Range['positive'] || $value <= self::$int32Range['negative'])) {
|
||||
return (float) $value;
|
||||
}
|
||||
|
||||
if (PHP_INT_SIZE === 8 && ($value > self::$int32Range['positive'] || $value < self::$int32Range['negative'])) {
|
||||
$value = (-2147483648 - ($value % -2147483648)) * ($value / abs($value));
|
||||
}
|
||||
|
||||
return (int) $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the rounding mode is invalid.
|
||||
*
|
||||
|
@ -752,28 +752,84 @@ class StubNumberFormatterTest extends LocaleTestCase
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* There are a lot of hard behaviors with TYPE_INT64, see the intl tests
|
||||
*
|
||||
* @expectedException Symfony\Component\Locale\Exception\MethodArgumentValueNotImplementedException
|
||||
* @see testParseTypeInt64IntlWith32BitIntegerInPhp32Bit
|
||||
* @see testParseTypeInt64IntlWith32BitIntegerInPhp64Bit
|
||||
* @see testParseTypeInt64IntlWith64BitIntegerInPhp32Bit
|
||||
* @see testParseTypeInt64IntlWith64BitIntegerInPhp64Bit
|
||||
*/
|
||||
public function testParseTypeInt64Stub()
|
||||
// Stub Tests
|
||||
|
||||
public function testParseTypeInt64StubWith32BitIntegerInPhp32Bit()
|
||||
{
|
||||
$this->skipIfIntlExtensionIsNotLoaded();
|
||||
$this->skipIfNot32Bit();
|
||||
|
||||
$formatter = $this->getStubFormatterWithDecimalStyle();
|
||||
$formatter->parse('1', StubNumberFormatter::TYPE_INT64);
|
||||
|
||||
$parsedValue = $formatter->parse('2,147,483,647', \NumberFormatter::TYPE_INT64);
|
||||
$this->assertInternalType('integer', $parsedValue);
|
||||
$this->assertEquals(2147483647, $parsedValue);
|
||||
|
||||
// Look that the parsing of '-2,147,483,648' results in a float like the literal -2147483648
|
||||
$parsedValue = $formatter->parse('-2,147,483,648', \NumberFormatter::TYPE_INT64);
|
||||
$this->assertInternalType('float', $parsedValue);
|
||||
$this->assertEquals(((float) -2147483647 - 1), $parsedValue);
|
||||
}
|
||||
|
||||
public function testParseTypeInt64StubWith32BitIntegerInPhp64Bit()
|
||||
{
|
||||
$this->skipIfNot64Bit();
|
||||
|
||||
$formatter = $this->getStubFormatterWithDecimalStyle();
|
||||
|
||||
$parsedValue = $formatter->parse('2,147,483,647', \NumberFormatter::TYPE_INT64);
|
||||
$this->assertInternalType('integer', $parsedValue);
|
||||
$this->assertEquals(2147483647, $parsedValue);
|
||||
|
||||
$parsedValue = $formatter->parse('-2,147,483,648', \NumberFormatter::TYPE_INT64);
|
||||
$this->assertInternalType('integer', $parsedValue);
|
||||
$this->assertEquals(-2147483647 - 1, $parsedValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* If PHP is compiled in 32bit mode, the returned value for a 64bit integer are float numbers.
|
||||
*/
|
||||
public function testParseTypeInt64StubWith64BitIntegerInPhp32Bit()
|
||||
{
|
||||
$this->skipIfNot32Bit();
|
||||
|
||||
$formatter = $this->getStubFormatterWithDecimalStyle();
|
||||
|
||||
// int 64 using only 32 bit range strangeness
|
||||
$parsedValue = $formatter->parse('2,147,483,648', \NumberFormatter::TYPE_INT64);
|
||||
$this->assertInternalType('float', $parsedValue);
|
||||
$this->assertEquals(2147483648, $parsedValue, '->parse() TYPE_INT64 does not use true 64 bit integers, using only the 32 bit range.');
|
||||
|
||||
$parsedValue = $formatter->parse('-2,147,483,649', \NumberFormatter::TYPE_INT64);
|
||||
$this->assertInternalType('float', $parsedValue);
|
||||
$this->assertEquals(-2147483649, $parsedValue, '->parse() TYPE_INT64 does not use true 64 bit integers, using only the 32 bit range.');
|
||||
}
|
||||
|
||||
/**
|
||||
* If PHP is compiled in 64bit mode, the returned value for a 64bit integer are 32bit integer numbers.
|
||||
*/
|
||||
public function testParseTypeInt64StubWith64BitIntegerInPhp64Bit()
|
||||
{
|
||||
$this->skipIfNot64Bit();
|
||||
|
||||
$formatter = $this->getStubFormatterWithDecimalStyle();
|
||||
|
||||
$parsedValue = $formatter->parse('2,147,483,648', \NumberFormatter::TYPE_INT64);
|
||||
$this->assertInternalType('integer', $parsedValue);
|
||||
$this->assertEquals(-2147483647 - 1, $parsedValue, '->parse() TYPE_INT64 does not use true 64 bit integers, using only the 32 bit range.');
|
||||
|
||||
$parsedValue = $formatter->parse('-2,147,483,649', \NumberFormatter::TYPE_INT64);
|
||||
$this->assertInternalType('integer', $parsedValue);
|
||||
$this->assertEquals(2147483647, $parsedValue, '->parse() TYPE_INT64 does not use true 64 bit integers, using only the 32 bit range.');
|
||||
}
|
||||
|
||||
// Intl Tests
|
||||
|
||||
public function testParseTypeInt64IntlWith32BitIntegerInPhp32Bit()
|
||||
{
|
||||
$this->skipIfIntlExtensionIsNotLoaded();
|
||||
if (!$this->is32Bit()) {
|
||||
// the PHP must be compiled in 32 bit mode to run this test (64 bits test will be run instead).
|
||||
return;
|
||||
}
|
||||
$this->skipIfNot32Bit();
|
||||
|
||||
$formatter = $this->getIntlFormatterWithDecimalStyle();
|
||||
|
||||
$parsedValue = $formatter->parse('2,147,483,647', \NumberFormatter::TYPE_INT64);
|
||||
@ -789,10 +845,8 @@ class StubNumberFormatterTest extends LocaleTestCase
|
||||
public function testParseTypeInt64IntlWith32BitIntegerInPhp64Bit()
|
||||
{
|
||||
$this->skipIfIntlExtensionIsNotLoaded();
|
||||
if (!$this->is64Bit()) {
|
||||
// the PHP must be compiled in 64 bit mode to run this test (32 bits test will be run instead).
|
||||
return;
|
||||
}
|
||||
$this->skipIfNot64Bit();
|
||||
|
||||
$formatter = $this->getIntlFormatterWithDecimalStyle();
|
||||
|
||||
$parsedValue = $formatter->parse('2,147,483,647', \NumberFormatter::TYPE_INT64);
|
||||
@ -810,10 +864,8 @@ class StubNumberFormatterTest extends LocaleTestCase
|
||||
public function testParseTypeInt64IntlWith64BitIntegerInPhp32Bit()
|
||||
{
|
||||
$this->skipIfIntlExtensionIsNotLoaded();
|
||||
if (!$this->is32Bit()) {
|
||||
// the PHP must be compiled in 32 bit mode to run this test (64 bits test will be run instead).
|
||||
return;
|
||||
}
|
||||
$this->skipIfNot32Bit();
|
||||
|
||||
$formatter = $this->getIntlFormatterWithDecimalStyle();
|
||||
|
||||
// int 64 using only 32 bit range strangeness
|
||||
@ -832,10 +884,8 @@ class StubNumberFormatterTest extends LocaleTestCase
|
||||
public function testParseTypeInt64IntlWith64BitIntegerInPhp64Bit()
|
||||
{
|
||||
$this->skipIfIntlExtensionIsNotLoaded();
|
||||
if (!$this->is64Bit()) {
|
||||
// the PHP must be compiled in 64 bit mode to run this test (32 bits test will be run instead).
|
||||
return;
|
||||
}
|
||||
$this->skipIfNot64Bit();
|
||||
|
||||
$formatter = $this->getIntlFormatterWithDecimalStyle();
|
||||
|
||||
$parsedValue = $formatter->parse('2,147,483,648', \NumberFormatter::TYPE_INT64);
|
||||
|
@ -44,6 +44,20 @@ abstract class TestCase extends \PHPUnit_Framework_TestCase
|
||||
}
|
||||
}
|
||||
|
||||
protected function skipIfNot32Bit()
|
||||
{
|
||||
if (!$this->is32Bit()) {
|
||||
$this->markTestSkipped('PHP must be compiled in 32 bit mode to run this test');
|
||||
}
|
||||
}
|
||||
|
||||
protected function skipIfNot64Bit()
|
||||
{
|
||||
if (!$this->is64Bit()) {
|
||||
$this->markTestSkipped('PHP must be compiled in 64 bit mode to run this test');
|
||||
}
|
||||
}
|
||||
|
||||
protected function isGreaterOrEqualThanIcuVersion($version)
|
||||
{
|
||||
$version = $this->normalizeIcuVersion($version);
|
||||
|
Reference in New Issue
Block a user