[TASK] Move and rename testInt, calcPriority, calcParenthesis
authorSusanne Moog <typo3@susannemoog.de>
Sat, 9 Jul 2011 23:58:44 +0000 (01:58 +0200)
committerAndreas Wolf <andreas.wolf@ikt-werk.de>
Mon, 11 Jul 2011 17:52:27 +0000 (19:52 +0200)
Move and rename testInt, calcPriority, calcParenthesis to
t3lib_utility_Math. Also add corresponding unit tests.

Change-Id: I095b24794e15e16d02e4761c69c8e1e65510bd0c
Resolves: #28064
Reviewed-on: http://review.typo3.org/3235
Reviewed-by: Philipp Gampe
Tested-by: Philipp Gampe
Reviewed-by: Georg Ringer
Tested-by: Georg Ringer
Reviewed-by: Xavier Perseguers
Tested-by: Xavier Perseguers
Reviewed-by: Andreas Wolf
Tested-by: Andreas Wolf
t3lib/class.t3lib_div.php
t3lib/utility/class.t3lib_utility_math.php
tests/t3lib/class.t3lib_divTest.php
tests/t3lib/utility/class.t3lib_utility_mathTest.php

index d267b13..1df596f 100644 (file)
@@ -972,12 +972,12 @@ final class t3lib_div {
         *
         * @param mixed $var Any input variable to test
         * @return boolean Returns TRUE if string is an integer
+        * @deprecated since TYPO3 4.6, will be removed in TYPO3 4.8 - Use t3lib_utility_Math::canBeInterpretedAsInteger() instead
         */
        public static function testInt($var) {
-               if ($var === '') {
-                       return FALSE;
-               }
-               return (string) intval($var) === (string) $var;
+               self::logDeprecatedFunction();
+
+               return t3lib_utility_Math::canBeInterpretedAsInteger($var);
        }
 
        /**
@@ -1065,55 +1065,12 @@ final class t3lib_div {
         * @param string $string Input string, eg "123 + 456 / 789 - 4"
         * @return integer Calculated value. Or error string.
         * @see calcParenthesis()
+        * @deprecated since TYPO3 4.6, will be removed in TYPO3 4.8 - Use t3lib_utility_Math::calculateWithPriorityToAdditionAndSubtraction() instead
         */
        public static function calcPriority($string) {
-               $string = preg_replace('/[[:space:]]*/', '', $string); // removing all whitespace
-               $string = '+' . $string; // Ensuring an operator for the first entrance
-               $qm = '\*\/\+-^%';
-               $regex = '([' . $qm . '])([' . $qm . ']?[0-9\.]*)';
-                       // split the expression here:
-               $reg = array();
-               preg_match_all('/' . $regex . '/', $string, $reg);
-
-               reset($reg[2]);
-               $number = 0;
-               $Msign = '+';
-               $err = '';
-               $buffer = doubleval(current($reg[2]));
-               next($reg[2]); // Advance pointer
-
-               while (list($k, $v) = each($reg[2])) {
-                       $v = doubleval($v);
-                       $sign = $reg[1][$k];
-                       if ($sign == '+' || $sign == '-') {
-                               $number = $Msign == '-' ? $number -= $buffer : $number += $buffer;
-                               $Msign = $sign;
-                               $buffer = $v;
-                       } else {
-                               if ($sign == '/') {
-                                       if ($v) {
-                                               $buffer /= $v;
-                                       } else {
-                                               $err = 'dividing by zero';
-                                       }
-                               }
-                               if ($sign == '%') {
-                                       if ($v) {
-                                               $buffer %= $v;
-                                       } else {
-                                               $err = 'dividing by zero';
-                                       }
-                               }
-                               if ($sign == '*') {
-                                       $buffer *= $v;
-                               }
-                               if ($sign == '^') {
-                                       $buffer = pow($buffer, $v);
-                               }
-                       }
-               }
-               $number = $Msign == '-' ? $number -= $buffer : $number += $buffer;
-               return $err ? 'ERROR: ' . $err : $number;
+               self::logDeprecatedFunction();
+
+               return t3lib_utility_Math::calculateWithPriorityToAdditionAndSubtraction($string);
        }
 
        /**
@@ -1122,26 +1079,12 @@ final class t3lib_div {
         * @param string $string Input string, eg "(123 + 456) / 789 - 4"
         * @return integer Calculated value. Or error string.
         * @see calcPriority(), tslib_cObj::stdWrap()
+        * @deprecated since TYPO3 4.6, will be removed in TYPO3 4.8 - Use t3lib_utility_Math::calculateWithParentheses() instead
         */
        public static function calcParenthesis($string) {
-               $securC = 100;
-               do {
-                       $valueLenO = strcspn($string, '(');
-                       $valueLenC = strcspn($string, ')');
-                       if ($valueLenC == strlen($string) || $valueLenC < $valueLenO) {
-                               $value = self::calcPriority(substr($string, 0, $valueLenC));
-                               $string = $value . substr($string, $valueLenC + 1);
-                               return $string;
-                       } else {
-                               $string = substr($string, 0, $valueLenO) . self::calcParenthesis(substr($string, $valueLenO + 1));
-                       }
-                               // Security:
-                       $securC--;
-                       if ($securC <= 0) {
-                               break;
-                       }
-               } while ($valueLenO < strlen($string));
-               return $string;
+               self::logDeprecatedFunction();
+
+               return t3lib_utility_Math::calculateWithParentheses($string);
        }
 
        /**
index 619a6f6..276613d 100644 (file)
@@ -71,6 +71,104 @@ final class t3lib_utility_Math {
                }
                return $theInt;
        }
+
+       /**
+        * Tests if the input can be interpreted as integer.
+        *
+        * @param $var mixed Any input variable to test
+        * @return boolean Returns TRUE if string is an integer
+        */
+       public static function canBeInterpretedAsInteger($var) {
+               if ($var === '') {
+                       return FALSE;
+               }
+               return (string) intval($var) === (string) $var;
+       }
+
+       /**
+        * Calculates the input by +,-,*,/,%,^ with priority to + and -
+        *
+        * @param $string string Input string, eg "123 + 456 / 789 - 4"
+        * @return integer Calculated value. Or error string.
+        * @see calcParenthesis()
+        */
+       public static function calculateWithPriorityToAdditionAndSubtraction($string) {
+               $string = preg_replace('/[[:space:]]*/', '', $string); // removing all whitespace
+               $string = '+' . $string; // Ensuring an operator for the first entrance
+               $qm = '\*\/\+-^%';
+               $regex = '([' . $qm . '])([' . $qm . ']?[0-9\.]*)';
+                       // split the expression here:
+               $reg = array();
+               preg_match_all('/' . $regex . '/', $string, $reg);
+
+               reset($reg[2]);
+               $number = 0;
+               $Msign = '+';
+               $err = '';
+               $buffer = doubleval(current($reg[2]));
+               next($reg[2]); // Advance pointer
+
+               while (list($k, $v) = each($reg[2])) {
+                       $v = doubleval($v);
+                       $sign = $reg[1][$k];
+                       if ($sign == '+' || $sign == '-') {
+                               $Msign == '-' ? $number -= $buffer : $number += $buffer;
+                               $Msign = $sign;
+                               $buffer = $v;
+                       } else {
+                               if ($sign == '/') {
+                                       if ($v) {
+                                               $buffer /= $v;
+                                       } else {
+                                               $err = 'dividing by zero';
+                                       }
+                               }
+                               if ($sign == '%') {
+                                       if ($v) {
+                                               $buffer %= $v;
+                                       } else {
+                                               $err = 'dividing by zero';
+                                       }
+                               }
+                               if ($sign == '*') {
+                                       $buffer *= $v;
+                               }
+                               if ($sign == '^') {
+                                       $buffer = pow($buffer, $v);
+                               }
+                       }
+               }
+               $number = $Msign == '-' ? $number -= $buffer : $number += $buffer;
+               return $err ? 'ERROR: ' . $err : $number;
+       }
+
+       /**
+        * Calculates the input with parenthesis levels
+        *
+        * @param $string string Input string, eg "(123 + 456) / 789 - 4"
+        * @return integer Calculated value. Or error string.
+        * @see calcPriority(), tslib_cObj::stdWrap()
+        */
+       public static function calculateWithParentheses($string) {
+               $securC = 100;
+               do {
+                       $valueLenO = strcspn($string, '(');
+                       $valueLenC = strcspn($string, ')');
+                       if ($valueLenC == strlen($string) || $valueLenC < $valueLenO) {
+                               $value = self::calculateWithPriorityToAdditionAndSubtraction(substr($string, 0, $valueLenC));
+                               $string = $value . substr($string, $valueLenC + 1);
+                               return $string;
+                       } else {
+                               $string = substr($string, 0, $valueLenO) . self::calculateWithParentheses(substr($string, $valueLenO + 1));
+                       }
+                               // Security:
+                       $securC--;
+                       if ($securC <= 0) {
+                               break;
+                       }
+               } while ($valueLenO < strlen($string));
+               return $string;
+       }
 }
 
 ?>
\ No newline at end of file
index 78753b0..c6bab23 100644 (file)
@@ -420,6 +420,8 @@ class t3lib_divTest extends tx_phpunit_testcase {
                        'three operands with power' => array(14, '5 + 3 ^ 2'),
                        'three operads with modulus' => array(4, '5 % 2 + 3'),
                        'four operands' => array(3, '2 + 6 / 2 - 2'),
+                       'division by zero when dividing' => array('ERROR: dividing by zero', '2 / 0'),
+                       'division by zero with modulus' => array('ERROR: dividing by zero', '2 % 0')
                );
        }
 
@@ -431,6 +433,32 @@ class t3lib_divTest extends tx_phpunit_testcase {
                $this->assertEquals($expected, t3lib_div::calcPriority($expression));
        }
 
+       //////////////////////////////////
+       // Tests concerning calcParenthesis
+       //////////////////////////////////
+
+       /**
+        * Data provider for calcParenthesis
+        *
+        * @return array expected values, arithmetic expression
+        */
+       public function calcParenthesisDataProvider() {
+               return array(
+                       'starts with parenthesis' => array(18, '(6 + 3) * 2'),
+                       'ends with parenthesis' => array(6, '2 * (6 - 3)'),
+                       'multiple parentheses' => array(-6, '(3 - 6) * (4 - 2)'),
+                       'nested parentheses' => array(22, '2 * (3 + 2 + (3 * 2))'),
+                       'parenthesis with division' => array(15, '5 / 2 * (3 * 2)'),
+               );
+       }
+
+       /**
+        * @test
+        * @dataProvider calcParenthesisDataProvider
+        */
+       public function calcParenthesisCorrectlyCalculatesExpression($expected, $expression) {
+               $this->assertEquals($expected, t3lib_div::calcParenthesis($expression));
+       }
 
        //////////////////////////////////
        // Tests concerning calcPriority
@@ -3055,4 +3083,4 @@ class t3lib_divTest extends tx_phpunit_testcase {
                );
        }
 }
-?>
\ No newline at end of file
+?>
index 0dfd1db..d2076b7 100644 (file)
@@ -83,6 +83,134 @@ class t3lib_utility_MathTest extends tx_phpunit_testcase {
                $this->assertEquals(123, t3lib_utility_Math::convertToPositiveInteger(123));
        }
 
+       ///////////////////////////////
+       // Tests concerning testInt
+       ///////////////////////////////
+
+       /**
+        * Data provider for canBeInterpretedAsIntegerReturnsTrue
+        *
+        * @return array Data sets
+        */
+       public function functionCanBeInterpretedAsIntegerValidDataProvider() {
+               return array(
+                       'int' => array(32425),
+                       'negative int' => array(-32425),
+                       'largest int' => array(PHP_INT_MAX),
+                       'int as string' => array('32425'),
+                       'negative int as string' => array('-32425'),
+                       'zero' => array(0),
+                       'zero as string' => array('0'),
+               );
+       }
+
+       /**
+        * @test
+        * @dataProvider functionCanBeInterpretedAsIntegerValidDataProvider
+        */
+       public function testIntReturnsTrue($int) {
+               $this->assertTrue(t3lib_utility_Math::canBeInterpretedAsInteger($int));
+       }
+
+       /**
+        * Data provider for testIntReturnsFalse
+        *
+        * @return array Data sets
+        */
+       public function functionCanBeInterpretedAsIntegerInvalidDataProvider() {
+               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'),
+                       'float' => array(3.14159),
+                       'float as string' => array('3.14159'),
+                       'float as string only a dot' => array('10.'),
+                       'float as string trailing zero would evaluate to int 10' => array('10.0'),
+                       'float as string trailing zeros  would evaluate to int 10' => array('10.00'),
+                       'null' => array(NULL),
+                       'empty array' => array(array()),
+                       'int in array' => array(array(32425)),
+                       'int as string in array' => array(array('32425')),
+               );
+       }
+
+       /**
+        * @test
+        * @dataProvider functionCanBeInterpretedAsIntegerInvalidDataProvider
+        */
+       public function canBeInterpretedAsIntegerReturnsFalse($int) {
+               $this->assertFalse(t3lib_utility_Math::canBeInterpretedAsInteger($int));
+       }
+
+       //////////////////////////////////
+       // Tests concerning calculateWithPriorityToAdditionAndSubtraction
+       //////////////////////////////////
+
+       /**
+        * Data provider for calculateWithPriorityToAdditionAndSubtraction
+        *
+        * @return array expected values, arithmetic expression
+        */
+       public function calculateWithPriorityToAdditionAndSubtractionDataProvider() {
+               return array(
+                       'add' => array(9, '6 + 3'),
+                       'substract with positive result' => array(3, '6 - 3'),
+                       'substract with negative result' => array(-3, '3 - 6'),
+                       'multiply' => array(6, '2 * 3'),
+                       'divide' => array(2.5, '5 / 2'),
+                       'modulus' => array(1, '5 % 2'),
+                       'power' => array(8, '2 ^ 3'),
+                       'three operands with non integer result' => array(6.5, '5 + 3 / 2'),
+                       'three operands with power' => array(14, '5 + 3 ^ 2'),
+                       'three operads with modulus' => array(4, '5 % 2 + 3'),
+                       'four operands' => array(3, '2 + 6 / 2 - 2'),
+                       'division by zero when dividing' => array('ERROR: dividing by zero', '2 / 0'),
+                       'division by zero with modulus' => array('ERROR: dividing by zero', '2 % 0')
+               );
+       }
+
+       /**
+        * @test
+        * @dataProvider calculateWithPriorityToAdditionAndSubtractionDataProvider
+        */
+       public function calculateWithPriorityToAdditionAndSubtractionCorrectlyCalculatesExpression($expected, $expression) {
+               $this->assertEquals($expected, t3lib_utility_Math::calculateWithPriorityToAdditionAndSubtraction($expression));
+       }
+
+
+       //////////////////////////////////
+       // Tests concerning calcParenthesis
+       //////////////////////////////////
+
+       /**
+        * Data provider for calcParenthesis
+        *
+        * @return array expected values, arithmetic expression
+        */
+       public function calculateWithParenthesesDataProvider() {
+               return array(
+                       'starts with parenthesis' => array(18, '(6 + 3) * 2'),
+                       'ends with parenthesis' => array(6, '2 * (6 - 3)'),
+                       'multiple parentheses' => array(-6, '(3 - 6) * (4 - 2)'),
+                       'nested parentheses' => array(22, '2 * (3 + 2 + (3 * 2))'),
+                       'parenthesis with division' => array(15, '5 / 2 * (3 * 2)'),
+               );
+       }
+
+       /**
+        * @test
+        * @dataProvider calculateWithParenthesesDataProvider
+        */
+       public function calculateWithParenthesesCorrectlyCalculatesExpression($expected, $expression) {
+               $this->assertEquals($expected, t3lib_utility_Math::calculateWithParentheses($expression));
+       }
 }
 
 ?>
\ No newline at end of file