View source
<?php
class CtoolsMathExpressionTestCase extends DrupalWebTestCase {
public static function getInfo() {
return array(
'name' => 'Math expressions',
'description' => 'Test the math expression library of ctools.',
'group' => 'ctools',
'dependencies' => array(
'ctools',
),
);
}
public function setUp(array $modules = array()) {
$modules[] = 'ctools';
$modules[] = 'ctools_plugin_test';
parent::setUp($modules);
}
protected static function sign($n) {
return ($n > 0) - ($n < 0);
}
protected function rand01() {
return mt_rand(0, PHP_INT_MAX) / PHP_INT_MAX;
}
protected function assertFloat($first, $second, $message = '', $delta = 1.0E-8, $group = 'Other') {
$equal = FALSE || is_infinite($first) && is_infinite($second) || is_nan($first) && is_nan($second) || abs($first - $second) <= $delta && self::sign($first) === self::sign($second);
if (empty($message)) {
$default = t('Value !first is equal to value !second.', array(
'!first' => var_export($first, TRUE),
'!second' => var_export($second, TRUE),
));
$message = $default;
}
return $this
->assert($equal, $message, $group);
}
public function testArithmetic() {
$math_expr = new ctools_math_expr();
$this
->assertEqual($math_expr
->evaluate('2'), 2, 'Check Literal 2');
$this
->assertEqual($math_expr
->e('2+1'), $math_expr
->evaluate('2+1'), 'Check that e() and evaluate() are equivalent.');
foreach (range(1, 4) as $n) {
$random_number = mt_rand(0, 20);
$this
->assertEqual($random_number, $math_expr
->evaluate((string) $random_number), "Literal {$random_number}");
$number_a = mt_rand(-55, 777);
$number_b = mt_rand(-555, 77);
$this
->assertEqual($number_a + $number_b, $math_expr
->evaluate("{$number_a} + {$number_b}"), "Addition: {$number_a} + {$number_b}");
$this
->assertEqual($number_a - $number_b, $math_expr
->evaluate("{$number_a} - {$number_b}"), "Subtraction: {$number_a} + {$number_b}");
$this
->assertFloat($number_a * $number_b, $math_expr
->evaluate("{$number_a} * {$number_b}"), "Multiplication: {$number_a} * {$number_b} = " . $number_a * $number_b);
$this
->assertFloat($number_a / $number_b, $math_expr
->evaluate("{$number_a} / {$number_b}"), "Division: {$number_a} / {$number_b} = " . $number_a / $number_b);
$number_c = mt_rand(-99, 77);
$this
->assertEqual($math_expr
->evaluate("{$number_a} + ({$number_b} + {$number_c})"), $math_expr
->evaluate("({$number_a} + {$number_b}) + {$number_c}"), "Associative: {$number_a} + ({$number_b} + {$number_c})");
$this
->assertEqual($math_expr
->evaluate("{$number_a} * ({$number_b} * {$number_c})"), $math_expr
->evaluate("({$number_a} * {$number_b}) * {$number_c}"), "Associative: {$number_a} * ({$number_b} * {$number_c})");
$this
->assertEqual($math_expr
->evaluate("{$number_a} + {$number_b}"), $math_expr
->evaluate("{$number_b} + {$number_a}"), "Commutative: {$number_a} + {$number_b}");
$this
->assertEqual($math_expr
->evaluate("{$number_a} * {$number_b}"), $math_expr
->evaluate("{$number_b} * {$number_a}"), "Commutative: {$number_a} * {$number_b}");
$this
->assertEqual($math_expr
->evaluate("({$number_a} + {$number_b}) * {$number_c}"), $math_expr
->evaluate("({$number_a} * {$number_c} + {$number_b} * {$number_c})"), "Distributive: ({$number_a} + {$number_b}) * {$number_c}");
$random_number = mt_rand(1, 15);
$random_power = mt_rand(-15, 15);
$this
->assertFloat(pow($random_number, $random_power), $math_expr
->evaluate("{$random_number} ^ {$random_power}"), "{$random_number} ^ {$random_power}");
$this
->assertFloat(pow($random_number, $random_power), $math_expr
->evaluate("pow({$random_number}, {$random_power})"), "pow({$random_number}, {$random_power})");
}
}
public function testBuildInFunctions() {
$math_expr = new ctools_math_expr();
foreach (range(1, 4) as $n) {
$random_double = $this
->rand01();
$random_int = mt_rand(-65535, 65535);
$this
->assertFloat(sin($random_double), $math_expr
->evaluate("sin({$random_double})"), "sin({$random_double})");
$this
->assertFloat(cos($random_double), $math_expr
->evaluate("cos({$random_double})"), "cos({$random_double})");
$this
->assertFloat(tan($random_double), $math_expr
->evaluate("tan({$random_double})"), "tan({$random_double})");
$this
->assertFloat(exp($random_double), $math_expr
->evaluate("exp({$random_double})"), "exp({$random_double})");
$this
->assertFloat(sqrt($random_double), $math_expr
->evaluate("sqrt({$random_double})"), "sqrt({$random_double})");
$this
->assertFloat(log($random_double), $math_expr
->evaluate("ln({$random_double})"), "ln({$random_double})");
$this
->assertFloat(round($random_double), $math_expr
->evaluate("round({$random_double})"), "round({$random_double})");
$random_real = $random_double + $random_int;
$this
->assertFloat(abs($random_real), $math_expr
->evaluate('abs(' . $random_real . ')'), "abs({$random_real})");
$this
->assertEqual(round($random_real), $math_expr
->evaluate('round(' . $random_real . ')'), "round({$random_real})");
$this
->assertEqual(ceil($random_real), $math_expr
->evaluate('ceil(' . $random_real . ')'), "ceil({$random_real})");
$this
->assertEqual(floor($random_real), $math_expr
->evaluate('floor(' . $random_real . ')'), "floor({$random_real})");
}
$this
->assertFloat(time(), $math_expr
->evaluate('time()'), "time()");
$random_double_a = $this
->rand01();
$random_double_b = $this
->rand01();
$this
->assertFloat(max($random_double_a, $random_double_b), $math_expr
->evaluate("max({$random_double_a}, {$random_double_b})"), "max({$random_double_a}, {$random_double_b})");
$this
->assertFloat(min($random_double_a, $random_double_b), $math_expr
->evaluate("min({$random_double_a}, {$random_double_b})"), "min({$random_double_a}, {$random_double_b})");
}
public function testVariables() {
$math_expr = new ctools_math_expr();
$this
->assertFloat(pi(), $math_expr
->evaluate('pi'));
$this
->assertFloat(exp(1), $math_expr
->evaluate('e'));
$number_a = 5;
$number_b = 10;
$math_expr
->evaluate("var = {$number_a}");
$this
->assertEqual($number_a + $number_b, $math_expr
->evaluate("var + {$number_b}"));
$math_expr
->evaluate("var = {$number_b}");
$this
->assertEqual($number_b + $number_b, $math_expr
->evaluate("var + {$number_b}"), "var + {$number_b}");
$math_expr
->evaluate("var = {$number_a}");
$math_expr
->evaluate("newvar = {$number_a}");
$this
->assertEqual($number_a + $number_a, $math_expr
->evaluate('var + newvar'), 'var + newvar');
$this
->assertFloat($number_a / $number_b, $math_expr
->evaluate("var / {$number_b}"), "var / {$number_b}");
}
public function testCustomFunctions() {
$math_expr = new ctools_math_expr();
$number_a = mt_rand(5, 10);
$number_b = mt_rand(5, 10);
$math_expr
->evaluate("f(x) = 2 * x");
$this
->assertEqual($number_a * 2, $math_expr
->evaluate("f({$number_a})"));
$this
->assertEqual($number_b * 2, $math_expr
->evaluate("f({$number_b})"));
$math_expr
->evaluate("g(x, y) = 2 * x + y");
$this
->assertEqual($number_a * 2 + $number_b, $math_expr
->evaluate("g({$number_a}, {$number_b})"), "g({$number_a}, {$number_b})");
$this
->assertEqual(($number_a * 2 + $number_b) * 2, $math_expr
->evaluate("f(g({$number_a}, {$number_b}))"), "f(g({$number_a}, {$number_b}))");
}
public function testIf() {
$math_expr = new ctools_math_expr();
$number_a = mt_rand(1, 10);
$number_b = mt_rand(11, 20);
foreach (range(1, 4) as $n) {
if ($n == 2 || $n == 4) {
}
if ($n == 3 || $n == 4) {
}
$this
->assertEqual($number_a, $math_expr
->evaluate("if(1, {$number_a}, {$number_b})"), "if(1, {$number_a}, {$number_b})");
$this
->assertEqual($number_a, $math_expr
->evaluate("if(1, {$number_a})", "if(1, {$number_a})"));
$this
->assertEqual($number_b, $math_expr
->evaluate("if(0, {$number_a}, {$number_b})"), "if(0, {$number_a}, {$number_b})");
$this
->assertEqual($number_b, $math_expr
->evaluate("if({$number_a} > {$number_b}, {$number_a}, {$number_b})"), "if({$number_a} > {$number_b}, {$number_a}, {$number_b})");
$this
->assertEqual($number_b, $math_expr
->evaluate("if({$number_a} < {$number_b}, {$number_b}, {$number_a})"), "if({$number_a} < {$number_b}, {$number_b}, {$number_a})");
}
}
}