MDL-27411 upgrade the calculatedsimple qtype to the new question engine.

This commit is contained in:
Tim Hunt
2011-05-19 12:20:49 +01:00
parent 18f9b2d2cf
commit efe3e87b61
16 changed files with 393 additions and 336 deletions
+2
View File
@@ -121,6 +121,8 @@ class test_question_maker {
* @return question_test_helper the test helper class.
*/
public static function get_test_helper($qtype) {
global $CFG;
if (array_key_exists($qtype, self::$testhelpers)) {
return self::$testhelpers[$qtype];
}
+1 -1
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="question/type/calculated/db" VERSION="20100720" COMMENT="XMLDB file for Moodle question/type/calculated. This question type also relies on the question_numerical_units table created by the numerical question type, and the tables created by the datasetdependent question type base class."
<XMLDB PATH="question/type/calculated/db" VERSION="20100720" COMMENT="XMLDB file for Moodle question/type/calculated. This question type also relies on the question_numerical_units table created by the numerical question type, and the dataset tables created by lib/db/install.xml."
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../../lib/xmldb/xmldb.xsd"
>
+2 -2
View File
@@ -38,8 +38,8 @@ function xmldb_qtype_calculated_upgrade($oldversion) {
// MDL-16505.
if ($oldversion < 2008091700 ) { //New version in version.php
if (get_config('qtype_datasetdependent', 'version')) {
unset_config('version', 'qtype_datasetdependent');
if (get_config('qtype_calculated', 'version')) {
unset_config('version', 'qtype_calculated');
}
upgrade_plugin_savepoint(true, 2008091700, 'qtype', 'calculated');
}
@@ -266,7 +266,7 @@ class qtype_calculated_edit_form extends qtype_numerical_edit_form {
if (empty($mandatorydatasets)) {
foreach ($answers as $key => $answer) {
$errors['answer['.$key.']'] =
get_string('atleastonewildcard', 'qtype_datasetdependent');
get_string('atleastonewildcard', 'qtype_calculated');
}
}
-48
View File
@@ -1879,54 +1879,6 @@ class qtype_calculated extends question_type {
return question_bank::get_qtype('numerical');
}
/**
* Runs all the code required to set up and save an essay question for testing purposes.
* Alternate DB table prefix may be used to facilitate data deletion.
*/
public function generate_test($name, $courseid = null) {
global $DB;
list($form, $question) = parent::generate_test($name, $courseid);
$form->feedback = 1;
$form->multiplier = array(1, 1);
$form->shuffleanswers = 1;
$form->noanswers = 1;
$form->qtype = 'calculated';
$question->qtype = 'calculated';
$form->answers = array('{a} + {b}');
$form->fraction = array(1);
$form->tolerance = array(0.01);
$form->tolerancetype = array(1);
$form->correctanswerlength = array(2);
$form->correctanswerformat = array(1);
$form->questiontext = "What is {a} + {b}?";
if ($courseid) {
$course = $DB->get_record('course', array('id' => $courseid));
}
$newquestion = $this->save_question($question, $form);
$datasetform = new stdClass();
$datasetform->nextpageparam['forceregeneration']= 1;
$datasetform->calcmin = array(1 => 1.0, 2 => 1.0);
$datasetform->calcmax = array(1 => 10.0, 2 => 10.0);
$datasetform->calclength = array(1 => 1, 2 => 1);
$datasetform->number = array(1 => 5.4 , 2 => 4.9);
$datasetform->itemid = array(1 => '' , 2 => '');
$datasetform->calcdistribution = array(1 => 'uniform', 2 => 'uniform');
$datasetform->definition = array(1 => "1-0-a",
2 => "1-0-b");
$datasetform->nextpageparam = array('forceregeneration' => false);
$datasetform->addbutton = 1;
$datasetform->selectadd = 1;
$datasetform->courseid = $courseid;
$datasetform->cmid = 0;
$datasetform->id = $newquestion->id;
$this->save_dataset_items($newquestion, $datasetform);
return $newquestion;
}
function move_files($questionid, $oldcontextid, $newcontextid) {
$fs = get_file_storage();
@@ -26,6 +26,8 @@
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/question/type/calculated/question.php');
/**
* Test helper class for the calculated question type.
@@ -15,7 +15,7 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This file contains overall tests of numerical questions.
* This file contains overall tests of calculated questions.
*
* @package qtype
* @subpackage calculated
@@ -340,7 +340,7 @@ class qtype_calculatedmulti_edit_form extends question_edit_form {
if (count($mandatorydatasets) == 0) {
foreach ($answers as $key => $answer) {
$errors['answer['.$key.']'] =
get_string('atleastonewildcard', 'qtype_datasetdependent');
get_string('atleastonewildcard', 'qtype_calculated');
}
}
if ($data['multichoice'] == 1) {
@@ -280,54 +280,6 @@ class qtype_calculatedmulti extends qtype_calculated {
return true;
}
public function create_runtime_question($question, $form) {
$question = parent::create_runtime_question($question, $form);
$question->options->answers = array();
foreach ($form->answers as $key => $answer) {
$a->answer = trim($form->answer[$key]);
$a->fraction = $form->fraction[$key];//new
$a->tolerance = $form->tolerance[$key];
$a->tolerancetype = $form->tolerancetype[$key];
$a->correctanswerlength = $form->correctanswerlength[$key];
$a->correctanswerformat = $form->correctanswerformat[$key];
$question->options->answers[] = clone($a);
}
return $question;
}
public function convert_answers(&$question, &$state) {
foreach ($question->options->answers as $key => $answer) {
$answer->answer = $this->substitute_variables(
$answer->answer, $state->options->dataset);
//evaluate the equations i.e {=5+4)
$qtext = '';
$qtextremaining = $answer->answer;
while (preg_match('~\{=([^[:space:]}]*)}~', $qtextremaining, $regs1)) {
$qtextsplits = explode($regs1[0], $qtextremaining, 2);
$qtext = $qtext.$qtextsplits[0];
$qtextremaining = $qtextsplits[1];
if (empty($regs1[1])) {
$str = '';
} else {
if ($formulaerrors = qtype_calculated_find_formula_errors($regs1[1])) {
$str=$formulaerrors;
} else {
eval('$str = '.$regs1[1].';');
$texteval= qtype_calculated_calculate_answer(
$str, $state->options->dataset, $answer->tolerance,
$answer->tolerancetype, $answer->correctanswerlength,
$answer->correctanswerformat, '');
$str = $texteval->answer;
}
}
$qtext = $qtext.$str;
}
$answer->answer = $qtext.$qtextremaining;;
}
}
public function get_default_numerical_unit($question, $virtualqtype) {
$unit = '';
return $unit;
@@ -341,30 +293,6 @@ class qtype_calculatedmulti extends qtype_calculated {
return $virtualqtype->grade_responses($question, $state, $cmoptions);
}
// ULPGC ecastro
public function get_actual_response(&$question, &$state) {
// Substitute variables in questiontext before giving the data to the
// virtual type
$virtualqtype = $this->get_virtual_qtype($question);
$unit = '';
// We modify the question to look like a multichoice question
$numericalquestion = clone($question);
$this->convert_answers ($numericalquestion, $state);
$this->convert_questiontext ($numericalquestion, $state);
$responses = $virtualqtype->get_all_responses($numericalquestion, $state);
$response = reset($responses->responses);
$correct = $response->answer.' : ';
$responses = $virtualqtype->get_actual_response($numericalquestion, $state);
foreach ($responses as $key => $response) {
$responses[$key] = $correct . $response;
}
return $responses;
}
public function create_virtual_qtype() {
global $CFG;
require_once("$CFG->dirroot/question/type/multichoice/questiontype.php");
@@ -26,6 +26,8 @@
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/question/type/calculated/edit_calculated_form.php');
/**
* Editing form for the calculated simplequestion type.
@@ -33,7 +35,7 @@ defined('MOODLE_INTERNAL') || die();
* @copyright 2007 Jamie Pratt [email protected]
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class qtype_calculatedsimple_edit_form extends question_edit_form {
class qtype_calculatedsimple_edit_form extends qtype_calculated_edit_form {
/**
* Handle to the question type for this question.
*
@@ -72,7 +74,7 @@ class qtype_calculatedsimple_edit_form extends question_edit_form {
$this->regenerate = true;
$this->question = $question;
$this->qtypeobj = $QTYPES[$this->question->qtype];
$this->qtypeobj = question_bank::get_qtype($this->question->qtype);
// get the dataset definitions for this question
// coming here everytime even when using a NoSubmitButton
// so this will only set the values to the actual question database content
@@ -303,7 +305,7 @@ class qtype_calculatedsimple_edit_form extends question_edit_form {
$answerlengthformats = array(
'1' => get_string('decimalformat', 'qtype_numerical'),
'2' => get_string('significantfiguresformat', 'qtype_numerical')
'2' => get_string('significantfiguresformat', 'qtype_calculated')
);
$addrepeated[] = $mform->createElement('select', 'correctanswerformat',
get_string('correctanswershowsformat', 'qtype_calculated'), $answerlengthformats);
@@ -319,7 +321,6 @@ class qtype_calculatedsimple_edit_form extends question_edit_form {
* @param MoodleQuickForm $mform the form being built.
*/
protected function definition_inner($mform) {
$this->qtypeobj = $QTYPES[$this->qtype()];
$strquestionlabel = $this->qtypeobj->comment_header($this->nonemptyanswer);
$label = get_string("sharedwildcards", "qtype_calculated");
$mform->addElement('hidden', 'synchronize', 0);
@@ -335,9 +336,9 @@ class qtype_calculatedsimple_edit_form extends question_edit_form {
$this->add_per_answer_fields($mform, get_string('answerhdr', 'qtype_calculated', '{no}'),
$creategrades->gradeoptions, 1, 1);
$QTYPES['numerical']->add_units_options($mform, $this);
$this->add_unit_options($mform, $this);
$this->add_unit_fields($mform, $this);
$QTYPES['numerical']->add_units_elements($mform, $this);
$label = "<div class='mdl-align'></div><div class='mdl-align'>" .
get_string('wildcardrole', 'qtype_calculatedsimple') . "</div>";
$mform->addElement('html', "<div class='mdl-align'>&nbsp;</div>");
@@ -638,8 +639,6 @@ class qtype_calculatedsimple_edit_form extends question_edit_form {
}
}
$default_values['synchronize'] = 0;
$QTYPES['numerical']->set_numerical_unit_data($this, $question, $default_values);
$key = 0;
$formdata = array();
$fromform = new stdClass();
@@ -647,6 +646,9 @@ class qtype_calculatedsimple_edit_form extends question_edit_form {
//fill out all data sets and also the fields for the next item to add.
$question = (object)((array)$question + $default_values+$this->formdata);
$question = $this->data_preprocessing_units($question);
$question = $this->data_preprocessing_unit_options($question);
return $question;
}
@@ -656,109 +658,6 @@ class qtype_calculatedsimple_edit_form extends question_edit_form {
public function validation($data, $files) {
$errors = parent::validation($data, $files);
//verifying for errors in {=...} in question text;
$qtext = "";
$qtextremaining = $data['questiontext']['text'];
$possibledatasets = $this->qtypeobj->find_dataset_names($data['questiontext']['text']);
foreach ($possibledatasets as $name => $value) {
$qtextremaining = str_replace('{'.$name.'}', '1', $qtextremaining);
}
while (preg_match('~\{=([^[:space:]}]*)}~', $qtextremaining, $regs1)) {
$qtextsplits = explode($regs1[0], $qtextremaining, 2);
$qtext = $qtext . $qtextsplits[0];
$qtextremaining = $qtextsplits[1];
if (!empty($regs1[1]) && $formulaerrors =
qtype_calculated_find_formula_errors($regs1[1])) {
if (!isset($errors['questiontext'])) {
$errors['questiontext'] = $formulaerrors.':'.$regs1[1];
} else {
$errors['questiontext'] .= '<br/>'.$formulaerrors.':'.$regs1[1];
}
}
}
$answers = $data['answer'];
$answercount = 0;
$maxgrade = false;
$possibledatasets = $this->qtypeobj->find_dataset_names(
$data['questiontext']['text']);
$mandatorydatasets = array();
foreach ($answers as $key => $answer) {
$mandatorydatasets += $this->qtypeobj->find_dataset_names($answer);
}
if (count($mandatorydatasets) == 0) {
foreach ($answers as $key => $answer) {
$errors['answer['.$key.']'] =
get_string('atleastonewildcard', 'qtype_calculated');
}
}
foreach ($answers as $key => $answer) {
//check no of choices
// the * for everykind of answer not actually implemented
$trimmedanswer = trim($answer);
if ($trimmedanswer != '' || $answercount == 0) {
$eqerror = qtype_calculated_find_formula_errors($trimmedanswer);
if (false !== $eqerror) {
$errors['answer['.$key.']'] = $eqerror;
}
}
if ($trimmedanswer != '') {
if ('2' == $data['correctanswerformat'][$key]
&& '0' == $data['correctanswerlength'][$key]) {
$errors['correctanswerlength['.$key.']'] =
get_string('zerosignificantfiguresnotallowed', 'qtype_calculated');
}
if (!is_numeric($data['tolerance'][$key])) {
$errors['tolerance['.$key.']'] =
get_string('mustbenumeric', 'qtype_calculated');
}
if ($data['fraction'][$key] == 1) {
$maxgrade = true;
}
$answercount++;
}
//TODO how should grade checking work here??
}
$QTYPES['numerical']->validate_numerical_options($data, $errors);
$units = $data['unit'];
if (count($units)) {
foreach ($units as $key => $unit) {
if (is_numeric($unit)) {
$errors['unit['.$key.']'] =
get_string('mustnotbenumeric', 'qtype_calculated');
}
$trimmedunit = trim($unit);
$trimmedmultiplier = trim($data['multiplier'][$key]);
if (!empty($trimmedunit)) {
if (empty($trimmedmultiplier)) {
$errors['multiplier['.$key.']'] =
get_string('youmustenteramultiplierhere', 'qtype_calculated');
}
if (!is_numeric($trimmedmultiplier)) {
$errors['multiplier['.$key.']'] =
get_string('mustbenumeric', 'qtype_calculated');
}
}
}
}
if ($answercount == 0) {
$errors['answer[0]'] = get_string('atleastoneanswer', 'qtype_calculated');
}
if ($maxgrade == false) {
$errors['fraction[0]'] = get_string('fractionsnomax', 'question');
}
if (isset($data['savechanges']) && ($this->noofitems==0)) {
$errors['warning'] = get_string('warning', 'mnet');
}
if ($this->outsidelimit) {
$errors['outsidelimits'] =
get_string('oneanswertrueansweroutsidelimits', 'qtype_calculated');
}
if ($this->noofitems == 0) {
$errors['warning'] = get_string('warning', 'mnet');
}
return $errors;
}
@@ -0,0 +1,39 @@
<?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/>.
/**
* Calculated (simple) question definition class.
*
* @package qtype
* @subpackage calculatedsimple
* @copyright 2011 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/question/type/calculated/question.php');
/**
* Represents a simple calculated question.
*
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class qtype_calculatedsimple_question extends qtype_calculated_question {
}
@@ -26,6 +26,8 @@
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/question/type/calculated/questiontype.php');
/**
* The simple calculated question type.
@@ -37,7 +39,6 @@ class qtype_calculatedsimple extends qtype_calculated {
// Used by the function custom_generator_tools:
public $calcgenerateidhasbeenadded = false;
public $virtualqtype = false;
public $wizard_pages_number = 1;
public function save_question_options($question) {
@@ -61,8 +62,8 @@ class qtype_calculatedsimple extends qtype_calculated {
}
// Save the units.
$virtualqtype = $this->get_virtual_qtype($question);
$result = $virtualqtype->save_numerical_units($question);
$virtualqtype = $this->get_virtual_qtype();
$result = $virtualqtype->save_units($question);
if (isset($result->error)) {
return $result;
} else {
@@ -230,7 +231,8 @@ class qtype_calculatedsimple extends qtype_calculated {
if (!empty($question->makecopy) && !empty($question->convert)) {
$DB->set_field('question', 'qtype', 'calculated', array('id'=> $question->id));
}
$result = $QTYPES['numerical']->save_numerical_options($question);
$result = $virtualqtype->save_unit_options($question);
if (isset($result->error)) {
return $result;
}
@@ -249,7 +251,7 @@ class qtype_calculatedsimple extends qtype_calculated {
return 1;
}
public function custom_generator_tools_part(&$mform, $idx, $j) {
public function custom_generator_tools_part($mform, $idx, $j) {
$minmaxgrp = array();
$minmaxgrp[] = $mform->createElement('text', "calcmin[$idx]",
@@ -311,98 +313,4 @@ class qtype_calculatedsimple extends qtype_calculated {
}
return array($options, $selected);
}
/**
* Runs all the code required to set up and save an essay question for testing purposes.
* Alternate DB table prefix may be used to facilitate data deletion.
*/
public function generate_test($name, $courseid = null) {
global $DB;
list($form, $question) = parent::generate_test($name, $courseid);
$form->feedback = 1;
$form->multiplier = array(1, 1);
$form->shuffleanswers = 1;
$form->noanswers = 1;
$form->qtype = 'calculatedsimple';
$question->qtype = 'calculatedsimple';
$form->answers = array('{a} + {b}');
$form->fraction = array(1);
$form->tolerance = array(0.01);
$form->tolerancetype = array(1);
$form->correctanswerlength = array(2);
$form->correctanswerformat = array(1);
$form->questiontext = "What is {a} + {b}?";
if ($courseid) {
$course = $DB->get_record('course', array('id'=> $courseid));
}
$new_question = $this->save_question($question, $form);
$dataset_form = new stdClass();
$dataset_form->nextpageparam["forceregeneration"]= 1;
$dataset_form->calcmin = array(1 => 1.0, 2 => 1.0);
$dataset_form->calcmax = array(1 => 10.0, 2 => 10.0);
$dataset_form->calclength = array(1 => 1, 2 => 1);
$dataset_form->number = array(1 => 5.4, 2 => 4.9);
$dataset_form->itemid = array(1 => '', 2 => '');
$dataset_form->calcdistribution = array(1 => 'uniform', 2 => 'uniform');
$dataset_form->definition = array(1 => "1-0-a", 2 => "1-0-b");
$dataset_form->nextpageparam = array('forceregeneration' => false);
$dataset_form->addbutton = 1;
$dataset_form->selectadd = 1;
$dataset_form->courseid = $courseid;
$dataset_form->cmid = 0;
$dataset_form->id = $new_question->id;
$this->save_dataset_items($new_question, $dataset_form);
return $new_question;
}
public function move_files($questionid, $oldcontextid, $newcontextid) {
$fs = get_file_storage();
parent::move_files($questionid, $oldcontextid, $newcontextid);
$this->move_files_in_answers($questionid, $oldcontextid, $newcontextid);
$fs->move_area_files_to_new_context($oldcontextid,
$newcontextid, 'qtype_calculatedsimple', 'instruction', $questionid);
}
protected function delete_files($questionid, $contextid) {
$fs = get_file_storage();
parent::delete_files($questionid, $contextid);
$this->delete_files_in_answers($questionid, $contextid);
$fs->delete_area_files($contextid, 'qtype_calculatedsimple', 'instruction', $questionid);
}
public function check_file_access($question, $state, $options, $contextid, $component,
$filearea, $args) {
$itemid = reset($args);
if ($component == 'question' && $filearea == 'answerfeedback') {
// Check if answer id exists
$result = $options->feedback && array_key_exists($itemid, $question->options->answers);
if (!$result) {
return false;
}
// check response
if (!$this->check_response($question, $state)) {
return false;
}
return true;
} else if ($filearea == 'instruction') {
// Displayed all the time like the question text. Check if question id exists
if ($itemid != $question->id) {
return false;
} else {
return true;
}
} else {
return parent::check_file_access($question, $state, $options, $contextid, $component,
$filearea, $args);
}
return true;
}
}
@@ -0,0 +1,39 @@
<?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/>.
/**
* Calculated (simple) question renderer class.
*
* @package qtype
* @subpackage calculatedsimple
* @copyright 2011 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/question/type/calculated/renderer.php');
/**
* Generates the output for simple calculated questions.
*
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class qtype_calculatedsimple_renderer extends qtype_calculated_renderer {
}
@@ -0,0 +1,73 @@
<?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/>.
/**
* Test helpers for the simple calculated question type.
*
* @package qtype
* @subpackage calculatedsimple
* @copyright 2011 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/question/type/calculated/simpletest/helper.php');
/**
* Test helper class for the simple calculated question type.
*
* @copyright 2011 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class qtype_calculatedsimple_test_helper extends question_test_helper {
public function get_test_questions() {
return array('sum');
}
/**
* Makes a calculated question with correct ansewer 3.14, and various incorrect
* answers with different feedback.
* @return qtype_calculated_question
*/
public function make_calculatedsimple_question_sum() {
question_bank::load_question_definition_classes('calculatedsimple');
$q = new qtype_calculatedsimple_question();
test_question_maker::initialise_a_question($q);
$q->name = 'Simple sum';
$q->questiontext = 'What is {a} + {b}?';
$q->generalfeedback = 'Generalfeedback: {={a} + {b}} is the right answer.';
$q->answers = array(
13 => new qtype_numerical_answer(13, '{a} + {b}', 1.0, 'Very good.', FORMAT_HTML, 0),
14 => new qtype_numerical_answer(14, '{a} - {b}', 0.0, 'Add. not subtract!.', FORMAT_HTML, 0),
17 => new qtype_numerical_answer(17, '*', 0.0, 'Completely wrong.', FORMAT_HTML, 0),
);
$q->qtype = question_bank::get_qtype('calculated');
$q->unitdisplay = qtype_numerical::UNITNONE;
$q->unitgradingtype = 0;
$q->unitpenalty = 0;
$q->ap = new qtype_numerical_answer_processor(array());
$q->datasetloader = new qtype_calculated_test_dataset_loader(0, array(
array('a' => 1, 'b' => 5),
array('a' => 3, 'b' => 4),
));
return $q;
}
}
@@ -0,0 +1,111 @@
<?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 simple calculated question definition class.
*
* @package qtype
* @subpackage calculatedsimple
* @copyright 2011 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once($CFG->dirroot . '/question/engine/simpletest/helpers.php');
/**
* Unit tests for qtype_calculatedsimple_definition.
*
* @copyright 2011 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class qtype_calculatedsimple_question_test extends UnitTestCase {
public function test_is_complete_response() {
$question = test_question_maker::make_question('calculatedsimple');
$this->assertFalse($question->is_complete_response(array()));
$this->assertTrue($question->is_complete_response(array('answer' => '0')));
$this->assertTrue($question->is_complete_response(array('answer' => 0)));
$this->assertFalse($question->is_complete_response(array('answer' => 'test')));
}
public function test_is_gradable_response() {
$question = test_question_maker::make_question('calculatedsimple');
$this->assertFalse($question->is_gradable_response(array()));
$this->assertTrue($question->is_gradable_response(array('answer' => '0')));
$this->assertTrue($question->is_gradable_response(array('answer' => 0)));
$this->assertTrue($question->is_gradable_response(array('answer' => 'test')));
}
public function test_grading() {
$question = test_question_maker::make_question('calculatedsimple');
$question->start_attempt(new question_attempt_step());
$values = $question->vs->get_values();
$this->assertEqual(array(0, question_state::$gradedwrong),
$question->grade_response(array('answer' => $values['a'] - $values['b'])));
$this->assertEqual(array(1, question_state::$gradedright),
$question->grade_response(array('answer' => $values['a'] + $values['b'])));
}
public function test_get_correct_response() {
$question = test_question_maker::make_question('calculatedsimple');
$question->start_attempt(new question_attempt_step());
$values = $question->vs->get_values();
$this->assertEqual(array('answer' => $values['a'] + $values['b']),
$question->get_correct_response());
}
public function test_get_question_summary() {
$question = test_question_maker::make_question('calculatedsimple');
$question->start_attempt(new question_attempt_step());
$values = $question->vs->get_values();
$qsummary = $question->get_question_summary();
$this->assertEqual('What is ' . $values['a'] . ' + ' . $values['b'] . '?', $qsummary);
}
public function test_summarise_response() {
$question = test_question_maker::make_question('calculatedsimple');
$question->start_attempt(new question_attempt_step());
$values = $question->vs->get_values();
$this->assertEqual('3.1', $question->summarise_response(array('answer' => '3.1')));
}
public function test_classify_response() {
$question = test_question_maker::make_question('calculatedsimple');
$question->start_attempt(new question_attempt_step());
$values = $question->vs->get_values();
$this->assertEqual(array(
new question_classified_response(13, $values['a'] + $values['b'], 1.0)),
$question->classify_response(array('answer' => $values['a'] + $values['b'])));
$this->assertEqual(array(
new question_classified_response(14, $values['a'] - $values['b'], 0.0)),
$question->classify_response(array('answer' => $values['a'] - $values['b'])));
$this->assertEqual(array(
new question_classified_response(17, 7 * $values['a'], 0.0)),
$question->classify_response(array('answer' => 7 * $values['a'])));
$this->assertEqual(array(
question_classified_response::no_response()),
$question->classify_response(array('answer' => '')));
}
}
@@ -0,0 +1,104 @@
<?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/>.
/**
* This file contains overall tests of simple calculated questions.
*
* @package qtype
* @subpackage calculatedsimple
* @copyright 2011 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/question/engine/simpletest/helpers.php');
/**
* Unit tests for the simple calculated question type.
*
* @copyright 2011 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class qtype_calculatedsimple_walkthrough_test extends qbehaviour_walkthrough_test_base {
public function test_interactive() {
// Create a gapselect question.
$q = test_question_maker::make_question('calculatedsimple');
$q->hints = array(
new question_hint(1, 'This is the first hint.', FORMAT_HTML),
new question_hint(2, 'This is the second hint.', FORMAT_HTML),
);
$this->start_attempt_at_question($q, 'interactive', 3);
$values = $q->vs->get_values();
// Check the initial state.
$this->check_current_state(question_state::$todo);
$this->check_current_mark(null);
$this->check_current_output(
$this->get_contains_marked_out_of_summary(),
$this->get_contains_submit_button_expectation(true),
$this->get_does_not_contain_feedback_expectation(),
$this->get_does_not_contain_validation_error_expectation(),
$this->get_does_not_contain_try_again_button_expectation(),
$this->get_no_hint_visible_expectation());
// Submit blank.
$this->process_submission(array('-submit' => 1, 'answer' => ''));
// Verify.
$this->check_current_state(question_state::$invalid);
$this->check_current_mark(null);
$this->check_current_output(
$this->get_contains_marked_out_of_summary(),
$this->get_contains_submit_button_expectation(true),
$this->get_does_not_contain_feedback_expectation(),
$this->get_contains_validation_error_expectation(),
$this->get_does_not_contain_try_again_button_expectation(),
$this->get_no_hint_visible_expectation());
// Sumit something that does not look like a number.
$this->process_submission(array('-submit' => 1, 'answer' => 'newt'));
// Verify.
$this->check_current_state(question_state::$invalid);
$this->check_current_mark(null);
$this->check_current_output(
$this->get_contains_marked_out_of_summary(),
$this->get_contains_submit_button_expectation(true),
$this->get_does_not_contain_feedback_expectation(),
$this->get_contains_validation_error_expectation(),
new PatternExpectation('/' .
preg_quote(get_string('invalidnumber', 'qtype_numerical') . '/')),
$this->get_does_not_contain_try_again_button_expectation(),
$this->get_no_hint_visible_expectation());
// Now get it right.
$this->process_submission(array('-submit' => 1, 'answer' => $values['a'] + $values['b']));
// Verify.
$this->check_current_state(question_state::$gradedright);
$this->check_current_mark(3);
$this->check_current_output(
$this->get_contains_mark_summary(3),
$this->get_contains_submit_button_expectation(false),
$this->get_contains_correct_expectation(),
$this->get_does_not_contain_validation_error_expectation(),
$this->get_no_hint_visible_expectation());
}
}