From bb68f56d42386e9859d6d3ca8e8372bb2272f7c1 Mon Sep 17 00:00:00 2001 From: Stefan Neufeind Date: Sat, 15 Jun 2013 03:38:21 +0200 Subject: [PATCH] [FEATURE] MathUtility: Add canBeInterpretedAsFloat Like canBeInterpretedAsInteger but for float. Change-Id: I9a44f2505f3702ef754a45f876a8197d2b6e2afb Resolves: #49144 Releases: 6.2 Reviewed-on: https://review.typo3.org/21447 Reviewed-by: Philipp Gampe Tested-by: Philipp Gampe Reviewed-by: Christian Kuhn Tested-by: Christian Kuhn --- .../core/Classes/Utility/MathUtility.php | 22 +++++ .../Tests/Unit/Utility/MathUtilityTest.php | 83 ++++++++++++++++++- 2 files changed, 102 insertions(+), 3 deletions(-) diff --git a/typo3/sysext/core/Classes/Utility/MathUtility.php b/typo3/sysext/core/Classes/Utility/MathUtility.php index 9b147f8ef56..d4959f59029 100644 --- a/typo3/sysext/core/Classes/Utility/MathUtility.php +++ b/typo3/sysext/core/Classes/Utility/MathUtility.php @@ -89,6 +89,28 @@ class MathUtility { return (string) intval($var) === (string) $var; } + /** + * Tests if the input can be interpreted as float. + * + * Note: Float casting from objects or arrays is considered undefined and thus will return false. + * + * @see http://www.php.net/manual/en/language.types.float.php, section "Formally" for the notation + * @param mixed $var Any input variable to test + * @return boolean Returns TRUE if string is a float + */ + static public function canBeInterpretedAsFloat($var) { + $pattern_lnum = '[0-9]+'; + $pattern_dnum = '([0-9]*[\.]' . $pattern_lnum . ')|(' . $pattern_lnum . '[\.][0-9]*)'; + $pattern_exp_dnum = '[+-]?((' . $pattern_lnum . '|' . $pattern_dnum . ')([eE][+-]?' . $pattern_lnum . ')?)'; + + if ($var === '' || is_object($var) || is_array($var)) { + return FALSE; + } + + $matches = preg_match('/^' . $pattern_exp_dnum . '$/', $var); + return $matches === 1; + } + /** * Calculates the input by +,-,*,/,%,^ with priority to + and - * diff --git a/typo3/sysext/core/Tests/Unit/Utility/MathUtilityTest.php b/typo3/sysext/core/Tests/Unit/Utility/MathUtilityTest.php index 51efb5f2dfb..b1830343944 100644 --- a/typo3/sysext/core/Tests/Unit/Utility/MathUtilityTest.php +++ b/typo3/sysext/core/Tests/Unit/Utility/MathUtilityTest.php @@ -84,7 +84,7 @@ class MathUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase { } /////////////////////////////// - // Tests concerning testInt + // Tests concerning canBeInterpretedAsInteger /////////////////////////////// /** * Data provider for canBeInterpretedAsIntegerReturnsTrue @@ -107,12 +107,12 @@ class MathUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase { * @test * @dataProvider functionCanBeInterpretedAsIntegerValidDataProvider */ - public function testIntReturnsTrue($int) { + public function canBeInterpretedAsIntegerReturnsTrue($int) { $this->assertTrue(\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($int)); } /** - * Data provider for testIntReturnsFalse + * Data provider for canBeInterpretedAsIntegerReturnsFalse * * @return array Data sets */ @@ -158,6 +158,83 @@ class MathUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase { $this->assertFalse(\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($int)); } + /////////////////////////////// + // Tests concerning canBeInterpretedAsFloat + /////////////////////////////// + /** + * Data provider for canBeInterpretedAsFloatReturnsTrue + * + * @return array Data sets + */ + public function functionCanBeInterpretedAsFloatValidDataProvider() { + // testcases for Integer apply for float as well + $intTestcases = $this->functionCanBeInterpretedAsIntegerValidDataProvider(); + $floatTestcases = array( + 'zero as float' => array((float) 0), + 'negative float' => array((float) -7.5), + 'negative float as string with exp #1' => array('-7.5e3'), + 'negative float as string with exp #2' => array('-7.5e03'), + 'negative float as string with exp #3' => array('-7.5e-3'), + 'float' => array(3.14159), + 'float as string' => array('3.14159'), + 'float as string only a dot' => array('10.'), + 'float as string trailing zero' => array('10.0'), + 'float as string trailing zeros' => array('10.00'), + ); + return array_merge($intTestcases, $floatTestcases); + } + + /** + * @test + * @dataProvider functionCanBeInterpretedAsFloatValidDataProvider + */ + public function canBeInterpretedAsFloatReturnsTrue($val) { + $this->assertTrue(\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsFloat($val)); + } + + /** + * Data provider for canBeInterpretedAsFloatReturnsFalse + * + * @return array Data sets + */ + public function functionCanBeInterpretedAsFloatInvalidDataProvider() { + $objectWithNumericalStringRepresentation = new \TYPO3\CMS\Core\Tests\Unit\Utility\Fixtures\MathUtilityTestClassWithStringRepresentationFixture(); + $objectWithNumericalStringRepresentation->setString('1234'); + $objectWithNonNumericalStringRepresentation = new \TYPO3\CMS\Core\Tests\Unit\Utility\Fixtures\MathUtilityTestClassWithStringRepresentationFixture(); + $objectWithNonNumericalStringRepresentation->setString('foo'); + $objectWithEmptyStringRepresentation = new \TYPO3\CMS\Core\Tests\Unit\Utility\Fixtures\MathUtilityTestClassWithStringRepresentationFixture(); + $objectWithEmptyStringRepresentation->setString(''); + return array( + // 'int as string with leading zero' => array('01234'), + // 'positive int as string with plus modifier' => array('+1234'), + // 'negative int as string with leading zero' => array('-01234'), + // 'largest int plus one' => array(PHP_INT_MAX + 1), + 'string' => array('testInt'), + 'empty string' => array(''), + 'int in string' => array('5 times of testInt'), + 'int as string with space after' => array('5 '), + 'int as string with space before' => array(' 5'), + 'int as string with many spaces before' => array(' 5'), + 'null' => array(NULL), + 'empty array' => array(array()), + 'int in array' => array(array(32425)), + 'int as string in array' => array(array('32425')), + 'negative float as string with invalid chars in exponent' => array('-7.5eX3'), + 'object without string representation' => array(new \stdClass()), + 'object with numerical string representation' => array($objectWithNumericalStringRepresentation), + 'object without numerical string representation' => array($objectWithNonNumericalStringRepresentation), + 'object with empty string representation' => array($objectWithEmptyStringRepresentation) + ); + } + + /** + * @test + * @dataProvider functionCanBeInterpretedAsFloatInvalidDataProvider + */ + public function canBeInterpretedAsFloatReturnsFalse($int) { + $this->assertFalse(\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsFloat($int)); + } + ////////////////////////////////// // Tests concerning calculateWithPriorityToAdditionAndSubtraction ////////////////////////////////// -- 2.20.1