mirror of
https://github.com/moodle/moodle.git
synced 2025-08-04 16:36:37 +02:00
Merge branch 'MDL-75464-master' of https://github.com/meirzamoodle/moodle
This commit is contained in:
commit
95c5001ddb
4 changed files with 115 additions and 7 deletions
|
@ -210,14 +210,14 @@ class EvalMath {
|
||||||
$output = array(); // postfix form of expression, to be passed to pfx()
|
$output = array(); // postfix form of expression, to be passed to pfx()
|
||||||
$expr = trim(strtolower($expr));
|
$expr = trim(strtolower($expr));
|
||||||
// MDL-14274: new operators for comparison added.
|
// MDL-14274: new operators for comparison added.
|
||||||
$ops = array('+', '-', '*', '/', '^', '_', '>', '<', '<=', '>=', '==');
|
$ops = array('+', '-', '*', '/', '^', '_', '>', '<', '<=', '>=', '==', '%');
|
||||||
$ops_r = array('+'=>0,'-'=>0,'*'=>0,'/'=>0,'^'=>1); // right-associative operator?
|
$ops_r = array('+'=>0,'-'=>0,'*'=>0,'/'=>0,'^'=>1, '%' => 0); // right-associative operator?
|
||||||
$ops_p = array('+'=>0,'-'=>0,'*'=>1,'/'=>1,'_'=>1,'^'=>2, '>'=>3, '<'=>3, '<='=>3, '>='=>3, '=='=>3); // operator precedence
|
$ops_p = array('+'=>0,'-'=>0,'*'=>1,'/'=>1,'_'=>1,'^'=>2, '>'=>3, '<'=>3, '<='=>3, '>='=>3, '=='=>3, '%'=>1); // operator precedence
|
||||||
|
|
||||||
$expecting_op = false; // we use this in syntax-checking the expression
|
$expecting_op = false; // we use this in syntax-checking the expression
|
||||||
// and determining when a - is a negation
|
// and determining when a - is a negation
|
||||||
|
|
||||||
if (preg_match("/[^\w\s+*^\/()\.,-<>=]/", $expr, $matches)) { // make sure the characters are all good
|
if (preg_match("/[^\%\w\s+*^\/()\.,-<>=]/", $expr, $matches)) { // make sure the characters are all good
|
||||||
return $this->trigger(get_string('illegalcharactergeneral', 'mathslib', $matches[0]));
|
return $this->trigger(get_string('illegalcharactergeneral', 'mathslib', $matches[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -433,7 +433,7 @@ class EvalMath {
|
||||||
$stack->push($this->pfx($this->f[$fnn]['func'], $args)); // yay... recursion!!!!
|
$stack->push($this->pfx($this->f[$fnn]['func'], $args)); // yay... recursion!!!!
|
||||||
}
|
}
|
||||||
// if the token is a binary operator, pop two values off the stack, do the operation, and push the result back on
|
// if the token is a binary operator, pop two values off the stack, do the operation, and push the result back on
|
||||||
} elseif (in_array($token, array('+', '-', '*', '/', '^', '>', '<', '==', '<=', '>='), true)) {
|
} elseif (in_array($token, array('+', '-', '*', '/', '^', '>', '<', '==', '<=', '>=', '%'), true)) {
|
||||||
if (is_null($op2 = $stack->pop())) return $this->trigger(get_string('internalerror', 'mathslib'));
|
if (is_null($op2 = $stack->pop())) return $this->trigger(get_string('internalerror', 'mathslib'));
|
||||||
if (is_null($op1 = $stack->pop())) return $this->trigger(get_string('internalerror', 'mathslib'));
|
if (is_null($op1 = $stack->pop())) return $this->trigger(get_string('internalerror', 'mathslib'));
|
||||||
switch ($token) {
|
switch ($token) {
|
||||||
|
@ -458,6 +458,8 @@ class EvalMath {
|
||||||
$stack->push((int)($op1 <= $op2)); break;
|
$stack->push((int)($op1 <= $op2)); break;
|
||||||
case '>=':
|
case '>=':
|
||||||
$stack->push((int)($op1 >= $op2)); break;
|
$stack->push((int)($op1 >= $op2)); break;
|
||||||
|
case '%':
|
||||||
|
$stack->push($op1%$op2); break;
|
||||||
}
|
}
|
||||||
// if the token is a unary operator, pop one value off the stack, do the operation, and push it back on
|
// if the token is a unary operator, pop one value off the stack, do the operation, and push it back on
|
||||||
} elseif ($token == "_") {
|
} elseif ($token == "_") {
|
||||||
|
|
|
@ -32,4 +32,21 @@ e.g. if (and(condition_1, condition_2, ... condition_n))
|
||||||
|
|
||||||
Changes by Raquel Ortega (MDL-76413)
|
Changes by Raquel Ortega (MDL-76413)
|
||||||
* Avoid PHP 8.2: Partially-supported callable deprecations
|
* Avoid PHP 8.2: Partially-supported callable deprecations
|
||||||
* eg: call_user_func_array(array('self', 'sum'), $args to call_user_func_array(array(self::class, 'sum'), $args)
|
* eg: call_user_func_array(array('self', 'sum'), $args to call_user_func_array(array(self::class, 'sum'), $args)
|
||||||
|
|
||||||
|
Changes by Meirza (MDL-75464)
|
||||||
|
* EvalMath has unit tests in lib/tests/mathslib_test.php,
|
||||||
|
since version 1.0.1, there are two additional tests:
|
||||||
|
- shouldSupportModuloOperator()
|
||||||
|
- shouldConsiderDoubleMinusAsPlus()
|
||||||
|
To pass the test, some modifications must be made:
|
||||||
|
- Adjust the test code so it can run properly by using \calc_formula.
|
||||||
|
Please see the differences between the code in MDL-75464 and the upstream code.
|
||||||
|
- In the dataprovider for both tests, add the formula in the first array with "=" at the first character.
|
||||||
|
Before:
|
||||||
|
```
|
||||||
|
'a%b', // 9%3 => 0
|
||||||
|
```
|
||||||
|
After:
|
||||||
|
```
|
||||||
|
'=a%b', // 9%3 => 0
|
|
@ -317,4 +317,93 @@ class mathslib_test extends \basic_testcase {
|
||||||
$result = $formula->evaluate();
|
$result = $formula->evaluate();
|
||||||
$this->assertTrue(is_float($result));
|
$this->assertTrue(is_float($result));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the modulo operator.
|
||||||
|
*
|
||||||
|
* @covers calc_formula::evaluate
|
||||||
|
* @dataProvider moduloOperatorData
|
||||||
|
*
|
||||||
|
* @param string $formula
|
||||||
|
* @param array $values
|
||||||
|
* @param int|float $expectedResult
|
||||||
|
*/
|
||||||
|
public function shouldSupportModuloOperator($formula, $values, $expectedResult)
|
||||||
|
{
|
||||||
|
$formula = new calc_formula($formula);
|
||||||
|
$formula->set_params($values);
|
||||||
|
$this->assertEquals($expectedResult, $formula->evaluate());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data provider for shouldSupportModuloOperator
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function moduloOperatorData() {
|
||||||
|
return array(
|
||||||
|
array(
|
||||||
|
'=a%b', // 9%3 => 0
|
||||||
|
array('a' => 9, 'b' => 3),
|
||||||
|
0
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'=a%b', // 10%3 => 1
|
||||||
|
array('a' => 10, 'b' => 3),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'=10-a%(b+c*d)', // 10-10%(7-2*2) => 9
|
||||||
|
array('a' => '10', 'b' => 7, 'c' => -2, 'd' => 2),
|
||||||
|
9
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the double minus as plus.
|
||||||
|
*
|
||||||
|
* @covers calc_formula::evaluate
|
||||||
|
* @dataProvider doubleMinusData
|
||||||
|
*
|
||||||
|
* @param string $formula
|
||||||
|
* @param array $values
|
||||||
|
* @param int|float $expectedResult
|
||||||
|
*/
|
||||||
|
public function shouldConsiderDoubleMinusAsPlus($formula, $values, $expectedResult)
|
||||||
|
{
|
||||||
|
$formula = new calc_formula($formula);
|
||||||
|
$formula->set_params($values);
|
||||||
|
$this->assertEquals($expectedResult, $formula->evaluate());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data provider for shouldConsiderDoubleMinusAsPlus
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function doubleMinusData() {
|
||||||
|
return array(
|
||||||
|
array(
|
||||||
|
'=a+b*c--d', // 1+2*3--4 => 1+6+4 => 11
|
||||||
|
array(
|
||||||
|
'a' => 1,
|
||||||
|
'b' => 2,
|
||||||
|
'c' => 3,
|
||||||
|
'd' => 4
|
||||||
|
),
|
||||||
|
11
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'=a+b*c--d', // 1+2*3---4 => 1+6-4 => 3
|
||||||
|
array(
|
||||||
|
'a' => 1,
|
||||||
|
'b' => 2,
|
||||||
|
'c' => 3,
|
||||||
|
'd' => -4
|
||||||
|
),
|
||||||
|
3
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
<location>evalmath</location>
|
<location>evalmath</location>
|
||||||
<name>EvalMath</name>
|
<name>EvalMath</name>
|
||||||
<description>Class to safely evaluate math expressions.</description>
|
<description>Class to safely evaluate math expressions.</description>
|
||||||
<version>1.0.0</version>
|
<version>1.0.1</version>
|
||||||
<license>BSD</license>
|
<license>BSD</license>
|
||||||
<repository>https://github.com/dbojdo/eval-math</repository>
|
<repository>https://github.com/dbojdo/eval-math</repository>
|
||||||
<copyrights>
|
<copyrights>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue