aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Michel Vedrine <vedrine@vedrine.org>2018-01-29 16:18:00 +0100
committerJean-Michel Vedrine <vedrine@vedrine.org>2018-01-29 16:18:00 +0100
commit5e12f43961b92ea152d9ede1200faaa4ee1dc5c9 (patch)
tree06e2a68d9f9ccf825cd661073e08f5fa334c859c
parent70f3702b5d5addcd029488d5194e8d6855c1a45f (diff)
Test parser exceptions
-rw-r--r--lang/en/qtype_algebra.php1
-rw-r--r--parser.php46
-rw-r--r--tests/parser_exception_test.php51
3 files changed, 79 insertions, 19 deletions
diff --git a/lang/en/qtype_algebra.php b/lang/en/qtype_algebra.php
index 26b6fe1..819e14b 100644
--- a/lang/en/qtype_algebra.php
+++ b/lang/en/qtype_algebra.php
@@ -27,6 +27,7 @@ $string['badclosebracket'] = 'Invalid close bracket found';
$string['badequivtype'] = 'Invalid type: can only compare parser terms with other parser terms';
$string['badfuncargs'] = 'Invalid arguments for the function \'{$a}\'';
$string['decimal'] = '.';
+$string['exceptionmessage'] = '{$a}';
$string['illegalplusminus'] = 'Found a + or - in an invalid location';
$string['mismatchedbracket'] = 'Mismatched brackets: Open and close bracket pair not of same type \'{$a}\'';
$string['mismatchedcloseb'] = 'Mismatched brackets: Close bracket without an open bracket found';
diff --git a/parser.php b/parser.php
index f86771b..f53d0c3 100644
--- a/parser.php
+++ b/parser.php
@@ -21,7 +21,7 @@
defined('MOODLE_INTERNAL') || die();
-require_once(__DIR__.'/../../../config.php');
+// require_once(__DIR__.'/../../../config.php');
/**
* Helper function which will compare two strings using their length only.
@@ -49,6 +49,14 @@ function qtype_algebra_parser_strlen_sort($a, $b) {
}
/**
+ * Base class for all the types of exception we throw.
+ */
+class parser_exception extends moodle_exception {
+ public function __construct($error) {
+ parent::__construct('exceptionmessage', 'qtype_algebra', '', $error);
+ }
+}
+/**
* Class which represents a single term in an algebraic expression.
*
* A single algebraic term is considered to be either an operation, for example addition,
@@ -204,7 +212,7 @@ class qtype_algebra_parser_term {
*/
public function set_arguments($args) {
if (count($args) != $this->_nargs) {
- throw new Exception(get_string('nargswrong', 'qtype_algebra', $this->_value));
+ throw new parser_exception(get_string('nargswrong', 'qtype_algebra', $this->_value));
}
$this->_arguments = $args;
}
@@ -223,7 +231,7 @@ class qtype_algebra_parser_term {
public function check_arguments($exc = true) {
$retval = (count($this->_arguments) == $this->_nargs);
if ($exc && !$retval) {
- throw new Exception(get_string('nargswrong', 'qtype_algebra', $this->_value));
+ throw new parser_exception(get_string('nargswrong', 'qtype_algebra', $this->_value));
} else {
return $retval;
}
@@ -317,7 +325,7 @@ class qtype_algebra_parser_term {
public function equivalent($expr) {
// Check that the argument is also a term.
if (!is_a($expr, 'qtype_algebra_parser_term')) {
- throw new Exception(get_string('badequivtype', 'qtype_algebra'));
+ throw new parser_exception(get_string('badequivtype', 'qtype_algebra'));
}
// Now check that this term is the same as the given term.
if (!$this->equals($expr)) {
@@ -349,7 +357,7 @@ class qtype_algebra_parser_term {
return false;
}
default:
- throw new Exception(get_string('morethantwoargs', 'qtype_algebra'));
+ throw new parser_exception(get_string('morethantwoargs', 'qtype_algebra'));
}
}
@@ -374,7 +382,7 @@ class qtype_algebra_parser_term {
* @return the numerical value of the term given the provided values for the variables
*/
public function evaluate($params) {
- throw new Exception(get_string('noevaluate', 'qtype_algebra', $this->_value));
+ throw new parser_exception(get_string('noevaluate', 'qtype_algebra', $this->_value));
}
/**
@@ -714,7 +722,7 @@ class qtype_algebra_parser_variable extends qtype_algebra_parser_term {
return $mult * doubleval($params[$this->_value]);
} else {
// Found an indefined variable. Cannot evaluate numerically so throw exception.
- throw new Exception(get_string('undefinedvariable', 'qtype_algebra', $this->_value));
+ throw new parser_exception(get_string('undefinedvariable', 'qtype_algebra', $this->_value));
}
}
@@ -1153,7 +1161,7 @@ class qtype_algebra_parser_function extends qtype_algebra_parser_term {
*/
public function __construct($text) {
if (!function_exists($text) and !array_key_exists($text, self::$fnmap)) {
- throw new Exception(get_string('undefinedfunction', 'qtype_algebra', $text));
+ throw new parser_exception(get_string('undefinedfunction', 'qtype_algebra', $text));
}
$formats = array( 'str' => '%s'.$text.'%s');
if (array_key_exists($text, self::$texmap)) {
@@ -1188,7 +1196,7 @@ class qtype_algebra_parser_function extends qtype_algebra_parser_term {
*/
public function set_arguments($args) {
if (count($args) != $this->_nargs) {
- throw new Exception(get_string('badfuncargs', 'qtype_algebra', $this->_value));
+ throw new parser_exception(get_string('badfuncargs', 'qtype_algebra', $this->_value));
}
if (!is_a($args[0], 'qtype_algebra_parser_bracket')) {
// Check to see if this function requires a special bracket.
@@ -1541,14 +1549,14 @@ class qtype_algebra_parser {
if (preg_match(self::$closeb, substr($text, $i), $m)) {
// First check that the current parse tree has at least one term.
if (count($tree) == 0) {
- throw new Exception(get_string('badclosebracket', 'qtype_algebra'));
+ throw new parser_exception(get_string('badclosebracket', 'qtype_algebra'));
}
// Now check that the current tree started with a bracket.
if (!is_a($tree[0], 'qtype_algebra_parser_bracket')) {
- throw new Exception(get_string('mismatchedcloseb', 'qtype_algebra'));
+ throw new parser_exception(get_string('mismatchedcloseb', 'qtype_algebra'));
} else if ($tree[0]->_value != self::$bramap[$m[0]]) {
// Check that the open and close bracket are of the same type.
- throw new Exception(get_string('mismatchedbracket', 'qtype_algebra', $tree[0]->_value.$m[0]));
+ throw new parser_exception(get_string('mismatchedbracket', 'qtype_algebra', $tree[0]->_value.$m[0]));
}
// Append the current tree to the tree one level up on the stack.
array_push($stack[count($stack) - 1], $tree);
@@ -1578,7 +1586,7 @@ class qtype_algebra_parser {
// Check for a variable and throw an exception if undeclared variables are
// not allowed and a list of defined variables was passed.
if (!empty($revar) and !$undecvars and $token[1] == 'qtype_algebra_parser_variable') {
- throw new Exception(get_string('undeclaredvar', 'qtype_algebra', $m[0]));
+ throw new parser_exception(get_string('undeclaredvar', 'qtype_algebra', $m[0]));
}
// Check for a zero argument term preceding a variable, function or special and then
// add the implicit multiplication.
@@ -1594,12 +1602,12 @@ class qtype_algebra_parser {
continue 2;
}
}
- throw new Exception(get_string('unknownterm', 'qtype_algebra', substr($text, $i)));
+ throw new parser_exception(get_string('unknownterm', 'qtype_algebra', substr($text, $i)));
} // End while loop over tokens.
// If all the open brackets have been closed then the stack will be empty and the
// tree will contain the entire parsed expression.
if (count($stack) > 0) {
- throw new Exception(get_string('mismatchedopenb', 'qtype_algebra'));
+ throw new parser_exception(get_string('mismatchedopenb', 'qtype_algebra'));
}
return $this->interpret($tree);
}
@@ -1655,7 +1663,7 @@ class qtype_algebra_parser {
// Otherwise we have found a minus sign indicating a positive or negative quantity...
// Check that we do have a number following otherwise generate an exception...
if ($i == (count($tree) - 1) or !method_exists($tree[$i + 1], 'set_negative')) {
- throw new Exception(get_string('illegalplusminus', 'qtype_algebra'));
+ throw new parser_exception(get_string('illegalplusminus', 'qtype_algebra'));
}
// If we have a subtract operation then we need to make the following number negative.
if (is_a($tree[$i], 'qtype_algebra_parser_subtract')) {
@@ -1681,7 +1689,7 @@ class qtype_algebra_parser {
$i++;
continue;
} else {
- throw new Exception(get_string('missingonearg', 'qtype_algebra', $tree[$i]->_value));
+ throw new parser_exception(get_string('missingonearg', 'qtype_algebra', $tree[$i]->_value));
}
} else if ($tree[$i]->n_args() == 2) {
if ($i > 0 and $i < (count($tree) - 1)) {
@@ -1691,7 +1699,7 @@ class qtype_algebra_parser {
array_splice($tree, $i - 1, 1);
continue;
} else {
- throw new Exception(get_string('missingtwoargs', 'qtype_algebra', $tree[$i]->_value));
+ throw new parser_exception(get_string('missingtwoargs', 'qtype_algebra', $tree[$i]->_value));
}
}
} else {
@@ -1704,7 +1712,7 @@ class qtype_algebra_parser {
if (count($tree) == 0) {
return new qtype_algebra_parser_nullterm;
} else if (count($tree) != 1) {
- throw new Exception(get_string('notopterm', 'qtype_algebra'));
+ throw new parser_exception(get_string('notopterm', 'qtype_algebra'));
}
if ($bracket) {
$bracket->set_arguments(array($tree[0]));
diff --git a/tests/parser_exception_test.php b/tests/parser_exception_test.php
new file mode 100644
index 0000000..d73f766
--- /dev/null
+++ b/tests/parser_exception_test.php
@@ -0,0 +1,51 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Unit tests for the short answer question definition class.
+ *
+ * @package qtype_algebra
+ * @copyright 2017 Jean-Michel Vedrine
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+
+defined('MOODLE_INTERNAL') || die();
+
+global $CFG;
+require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
+require_once($CFG->dirroot . '/question/type/algebra/tests/helper.php');
+require_once($CFG->dirroot . '/question/type/algebra/parser.php');
+
+
+/**
+ * Unit tests for the algebra question parser.
+ *
+ * @copyright 2017 Jean-Michel Vedrine
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+class qtype_algebra_parser_exception_test extends advanced_testcase {
+ /**
+ * Test parsing an invalid exprssion
+ */
+ public function test_parser_invalid() {
+ $this->expectException('parser_exception');
+ $this->expectExceptionMessage('Mismatched brackets: Open bracket without a close bracket found');
+ $p = new qtype_algebra_parser;
+ $expr = $p->parse('sin(2x) + cos(');
+ }
+}