MDL-40171 question saving test
authorJamie Pratt <me@jamiep.org>
Mon, 24 Jun 2013 07:06:01 +0000 (14:06 +0700)
committerDamyon Wiese <damyon@moodle.com>
Tue, 9 Jul 2013 07:08:01 +0000 (15:08 +0800)
18 files changed:
question/engine/tests/helpers.php
question/type/calculatedsimple/tests/helper.php
question/type/calculatedsimple/tests/questiontype_test.php [new file with mode: 0644]
question/type/description/tests/helper.php
question/type/description/tests/questiontype_test.php
question/type/match/tests/helper.php [new file with mode: 0644]
question/type/match/tests/questiontype_test.php
question/type/multianswer/tests/helper.php
question/type/multianswer/tests/questiontype_test.php
question/type/multichoice/tests/helper.php [new file with mode: 0644]
question/type/multichoice/tests/questiontype_test.php
question/type/numerical/tests/helper.php
question/type/numerical/tests/questiontype_test.php
question/type/questionbase.php
question/type/shortanswer/tests/helper.php
question/type/shortanswer/tests/questiontype_test.php
question/type/truefalse/tests/helper.php
question/type/truefalse/tests/questiontype_test.php

index ece0ed7..a55c6c8 100644 (file)
@@ -96,6 +96,29 @@ abstract class question_test_helper {
      * this question type.
      */
     abstract public function get_test_questions();
+
+    /**
+     * Set up a form to create a question in $cat. This method also sets cat and contextid on $questiondata object.
+     * @param object $cat the category
+     * @param object $questiondata form initialisation requires question data.
+     * @return moodleform
+     */
+    public static function get_question_editing_form($cat, $questiondata) {
+        $catcontext = context::instance_by_id($cat->contextid, MUST_EXIST);
+        $contexts = new question_edit_contexts($catcontext);
+        $dataforformconstructor = new stdClass();
+        $dataforformconstructor->qtype = $questiondata->qtype;
+        $dataforformconstructor->contextid = $questiondata->contextid = $catcontext->id;
+        $dataforformconstructor->category = $questiondata->category = $cat->id;
+        $dataforformconstructor->formoptions = new stdClass();
+        $dataforformconstructor->formoptions->canmove = true;
+        $dataforformconstructor->formoptions->cansaveasnew = true;
+        $dataforformconstructor->formoptions->movecontext = false;
+        $dataforformconstructor->formoptions->canedit = true;
+        $dataforformconstructor->formoptions->repeatelements = true;
+        $qtype = question_bank::get_qtype($questiondata->qtype);
+        return  $qtype->create_editing_form('question.php', $dataforformconstructor, $cat, $contexts, true);
+    }
 }
 
 
@@ -172,18 +195,6 @@ class test_question_maker {
         $qdata->hints = array();
     }
 
-    public static function initialise_question_form_data($qdata) {
-        $formdata = new stdClass();
-        $formdata->id = 0;
-        $formdata->category = '0,0';
-        $formdata->usecurrentcat = 1;
-        $formdata->categorymoveto = '0,0';
-        $formdata->tags = array();
-        $formdata->penalty = 0.3333333;
-        $formdata->questiontextformat = FORMAT_HTML;
-        $formdata->generalfeedbackformat = FORMAT_HTML;
-    }
-
     /**
      * Get the test helper class for a particular question type.
      * @param $qtype the question type name, e.g. 'multichoice'.
@@ -413,6 +424,19 @@ class test_question_maker {
         $q->incorrectfeedback = self::STANDARD_OVERALL_INCORRECT_FEEDBACK;
         $q->incorrectfeedbackformat = FORMAT_HTML;
     }
+
+    /**
+     * Add some standard overall feedback to a question's form data.
+     */
+    public static function set_standard_combined_feedback_form_data($form) {
+        $form->correctfeedback = array('text' => self::STANDARD_OVERALL_CORRECT_FEEDBACK,
+                                    'format' => FORMAT_HTML);
+        $form->partiallycorrectfeedback = array('text' => self::STANDARD_OVERALL_PARTIALLYCORRECT_FEEDBACK,
+                                             'format' => FORMAT_HTML);
+        $form->shownumcorrect = true;
+        $form->incorrectfeedback = array('text' => self::STANDARD_OVERALL_INCORRECT_FEEDBACK,
+                                    'format' => FORMAT_HTML);
+    }
 }
 
 
index 4cd72a3..53cb8e4 100644 (file)
@@ -38,7 +38,7 @@ require_once($CFG->dirroot . '/question/type/calculated/tests/helper.php');
  */
 class qtype_calculatedsimple_test_helper extends question_test_helper {
     public function get_test_questions() {
-        return array('sum');
+        return array('sum', 'sumwithvariants');
     }
 
     /**
@@ -77,4 +77,184 @@ class qtype_calculatedsimple_test_helper extends question_test_helper {
 
         return $q;
     }
+
+
+    public function get_calculatedsimple_question_form_data_sumwithvariants() {
+        $form = new stdClass();
+
+        $form->name = 'Calculated simple';
+
+        $form->qtype = 'calculatedsimple';
+
+        $form->questiontext = array();
+        $form->questiontext['text'] = '<p>This is a simple sum of two variables.</p>';
+        $form->questiontext['format'] = '1';
+
+        $form->defaultmark = 1;
+        $form->generalfeedback = array();
+        $form->generalfeedback['text'] = '<p>The answer is  {a} + {b}</p>';
+        $form->generalfeedback['format'] = '1';
+
+        $form->synchronize = 0;
+        $form->initialcategory = 1;
+        $form->reload = 1;
+        $form->mform_isexpanded_id_answerhdr = 1;
+        $form->noanswers = 1;
+        $form->answer = array('{a} + {b}');
+
+        $form->fraction = array('1.0');
+
+        $form->tolerance = array(0.01);
+        $form->tolerancetype = array('1');
+
+        $form->correctanswerlength = array('2');
+        $form->correctanswerformat = array('1');
+
+        $form->feedback = array();
+        $form->feedback[0] = array();
+        $form->feedback[0]['text'] = '';
+        $form->feedback[0]['format'] = '1';
+
+        $form->unitrole = '3';
+        $form->unitpenalty = 0.1;
+        $form->unitgradingtypes = '1';
+        $form->unitsleft = '0';
+        $form->nounits = 1;
+        $form->multiplier = array('1.0');
+
+        $form->penalty = '0.3333333';
+        $form->numhints = 2;
+        $form->hint = array();
+        $form->hint[0] = array();
+        $form->hint[0]['text'] = '';
+        $form->hint[0]['format'] = '1';
+
+        $form->hint[1] = array();
+        $form->hint[1]['text'] = '';
+        $form->hint[1]['format'] = '1';
+
+        $form->calcmin = array();
+        $form->calcmin[1] = 1;
+        $form->calcmin[2] = 1;
+
+        $form->calcmax = array();
+        $form->calcmax[1] = 10;
+        $form->calcmax[2] = 10;
+
+        $form->calclength = array();
+        $form->calclength[1] = '1';
+        $form->calclength[2] = '1';
+
+        $form->calcdistribution = array();
+        $form->calcdistribution[1] = 0;
+        $form->calcdistribution[2] = 0;
+
+        $form->datasetdef = array();
+        $form->datasetdef[1] = '1-0-a';
+        $form->datasetdef[2] = '1-0-b';
+
+        $form->defoptions = array();
+        $form->defoptions[1] = '';
+        $form->defoptions[2] = '';
+
+        $form->selectadd = '10';
+        $form->selectshow = '10';
+        $form->number = array();
+        $form->number[1] = '2.3';
+        $form->number[2] = '7.6';
+        $form->number[3] = '2.1';
+        $form->number[4] = '6.4';
+        $form->number[5] = '1.4';
+        $form->number[6] = '1.9';
+        $form->number[7] = '9.9';
+        $form->number[8] = '9.5';
+        $form->number[9] = '9.0';
+        $form->number[10] = '5.2';
+        $form->number[11] = '2.1';
+        $form->number[12] = '7.3';
+        $form->number[13] = '7.9';
+        $form->number[14] = '1.2';
+        $form->number[15] = '2.3';
+        $form->number[16] = '3.4';
+        $form->number[17] = '1.9';
+        $form->number[18] = '5.2';
+        $form->number[19] = '3.4';
+        $form->number[20] = '3.4';
+
+        $form->itemid = array_fill(1, 20, 0);
+
+        $form->definition = array();
+        $form->definition[1] = '1-0-b';
+        $form->definition[2] = '1-0-a';
+        $form->definition[3] = '1-0-b';
+        $form->definition[4] = '1-0-a';
+        $form->definition[5] = '1-0-b';
+        $form->definition[6] = '1-0-a';
+        $form->definition[7] = '1-0-b';
+        $form->definition[8] = '1-0-a';
+        $form->definition[9] = '1-0-b';
+        $form->definition[10] = '1-0-a';
+        $form->definition[11] = '1-0-b';
+        $form->definition[12] = '1-0-a';
+        $form->definition[13] = '1-0-b';
+        $form->definition[14] = '1-0-a';
+        $form->definition[15] = '1-0-b';
+        $form->definition[16] = '1-0-a';
+        $form->definition[17] = '1-0-b';
+        $form->definition[18] = '1-0-a';
+        $form->definition[19] = '1-0-b';
+        $form->definition[20] = '1-0-a';
+
+        return $form;
+    }
+
+    public function get_calculatedsimple_question_data_sumwithvariants() {
+        $q = new stdClass();
+
+        $q->name = 'Calculated simple';
+        $q->questiontext = '<p>This is a simple sum of two variables.</p>';
+        $q->questiontextformat = '1';
+        $q->generalfeedback = '<p>The answer is  {a} + {b}</p>';
+        $q->generalfeedbackformat = '1';
+        $q->defaultmark = 1;
+        $q->penalty = 0.3333333;
+        $q->qtype = 'calculatedsimple';
+        $q->length = '1';
+        $q->hidden = '0';
+        $q->options = new stdClass();
+        $q->options->synchronize = 0;
+        $q->options->single = 0;
+        $q->options->answernumbering = 'abc';
+        $q->options->shuffleanswers = 0;
+        $q->options->correctfeedback = '';
+        $q->options->partiallycorrectfeedback = '';
+        $q->options->incorrectfeedback = '';
+        $q->options->correctfeedbackformat = 0;
+        $q->options->partiallycorrectfeedbackformat = 0;
+        $q->options->incorrectfeedbackformat = 0;
+        $q->options->answers = array();
+        $q->options->answers[0] = new stdClass();
+        $q->options->answers[0]->id = '6977';
+        $q->options->answers[0]->question = '3379';
+        $q->options->answers[0]->answer = '{a} + {b}';
+        $q->options->answers[0]->answerformat = '0';
+        $q->options->answers[0]->fraction = '1.0000000';
+        $q->options->answers[0]->feedback = '';
+        $q->options->answers[0]->feedbackformat = '1';
+        $q->options->answers[0]->tolerance = '0.01';
+        $q->options->answers[0]->tolerancetype = '1';
+        $q->options->answers[0]->correctanswerlength = '2';
+        $q->options->answers[0]->correctanswerformat = '1';
+
+        $q->options->units = array();
+
+        $q->options->unitgradingtype = '0';
+        $q->options->unitpenalty = '0.1000000';
+        $q->options->showunits = '3';
+        $q->options->unitsleft = '0';
+
+        $q->hints = array();
+
+        return $q;
+    }
 }
diff --git a/question/type/calculatedsimple/tests/questiontype_test.php b/question/type/calculatedsimple/tests/questiontype_test.php
new file mode 100644 (file)
index 0000000..1b9771a
--- /dev/null
@@ -0,0 +1,122 @@
+<?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 calculatedsimple question type class.
+ *
+ * @package    qtype_calculatedsimple
+ * @copyright  2013 The Open University
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+
+defined('MOODLE_INTERNAL') || die();
+
+global $CFG;
+require_once($CFG->dirroot . '/question/type/calculatedsimple/questiontype.php');
+require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
+require_once($CFG->dirroot . '/question/type/edit_question_form.php');
+require_once($CFG->dirroot . '/question/type/calculatedsimple/edit_calculatedsimple_form.php');
+
+
+/**
+ * Unit tests for the calculatedsimple question type class.
+ *
+ * @copyright  2007 The Open University
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class qtype_calculatedsimple_test extends advanced_testcase {
+    public static $includecoverage = array(
+        'question/type/questiontypebase.php',
+        'question/type/calculatedsimple/questiontype.php',
+        'question/type/edit_question_form.php',
+        'question/type/calculatedsimple/edit_calculatedsimple_form.php'
+    );
+
+    protected $qtype;
+
+    protected function setUp() {
+        $this->qtype = new qtype_calculatedsimple();
+    }
+
+    protected function tearDown() {
+        $this->qtype = null;
+    }
+
+    public function test_name() {
+        $this->assertEquals($this->qtype->name(), 'calculatedsimple');
+    }
+
+    public function test_can_analyse_responses() {
+        $this->assertTrue($this->qtype->can_analyse_responses());
+    }
+
+
+    public function test_question_saving_sumwithvariants() {
+        $this->resetAfterTest(true);
+        $this->setAdminUser();
+
+        $questiondata = test_question_maker::get_question_data('calculatedsimple', 'sumwithvariants');
+        $formdata = test_question_maker::get_question_form_data('calculatedsimple', 'sumwithvariants');
+
+        $generator = $this->getDataGenerator()->get_plugin_generator('core_question');
+        $cat = $generator->create_question_category(array());
+
+        $formdata->category = "{$cat->id},{$cat->contextid}";
+        qtype_calculatedsimple_edit_form::mock_submit((array)$formdata);
+
+        $form = qtype_calculatedsimple_test_helper::get_question_editing_form($cat, $questiondata);
+
+        $this->assertTrue($form->is_validated());
+
+        $fromform = $form->get_data();
+
+        $returnedfromsave = $this->qtype->save_question($questiondata, $fromform);
+        $actualquestionsdata = question_load_questions(array($returnedfromsave->id));
+        $actualquestiondata = end($actualquestionsdata);
+
+        foreach ($questiondata as $property => $value) {
+            if (!in_array($property, array('id', 'version', 'timemodified', 'timecreated', 'options'))) {
+                $this->assertAttributeEquals($value, $property, $actualquestiondata);
+            }
+        }
+
+        foreach ($questiondata->options as $optionname => $value) {
+            if ($optionname != 'answers') {
+                $this->assertAttributeEquals($value, $optionname, $actualquestiondata->options);
+            }
+        }
+
+        foreach ($questiondata->options->answers as $answer) {
+            $actualanswer = array_shift($actualquestiondata->options->answers);
+            foreach ($answer as $ansproperty => $ansvalue) {
+                if (!in_array($ansproperty, array('id', 'question', 'answerformat'))) {
+                    $this->assertAttributeEquals($ansvalue, $ansproperty, $actualanswer);
+                }
+            }
+        }
+
+        $datasetloader = new qtype_calculated_dataset_loader($actualquestiondata->id);
+
+        $this->assertEquals(10, $datasetloader->get_number_of_items());
+
+        for ($itemno = 1; $itemno <= 10; $itemno++) {
+            $item = $datasetloader->get_values($itemno);
+            $this->assertEquals($formdata->number[($itemno -1)*2 + 2], $item['a']);
+            $this->assertEquals($formdata->number[($itemno -1)*2 + 1], $item['b']);
+        }
+    }
+}
index d571b5d..a8c68ff 100644 (file)
@@ -17,9 +17,8 @@
 /**
  * Test helper code for the description question type.
  *
- * @package    qtype
- * @subpackage description
- * @copyright  2010 The Open University
+ * @package    qtype_description
+ * @copyright  2013 The Open University
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
@@ -30,7 +29,7 @@ defined('MOODLE_INTERNAL') || die();
 /**
  * Test helper class for the description question type.
  *
- * @copyright  2010 The Open University
+ * @copyright  2013 The Open University
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 class qtype_description_test_helper extends question_test_helper {
@@ -59,11 +58,10 @@ class qtype_description_test_helper extends question_test_helper {
     }
 
     /**
-     * Get the question data, as it would be loaded by get_question_options, for
-     * the question returned by {@link make_an_oumultiresponse_two_of_four()}.
+     * Get the question data, as it would be loaded by get_question_options.
      * @return object
      */
-    public static function get_question_data() {
+    public static function get_description_question_data_info() {
         global $USER;
 
         $qdata = new stdClass();
@@ -87,7 +85,28 @@ class qtype_description_test_helper extends question_test_helper {
         $qdata->length = 0;
         $qdata->penalty = 0;
         $qdata->hidden = 0;
+        $qdata->hints = array();
+        $qdata->options = new stdClass();
+        $qdata->options->answers = array();
 
         return $qdata;
     }
+
+
+    /**
+     * Get the question form data.
+     * @return object
+     */
+    public static function get_description_question_form_data_info() {
+        $form = new stdClass();
+
+        $form->name = 'Description';
+        $form->questiontext = array('text' => 'Here is some information about the questions you are about to attempt.',
+                                    'format' => FORMAT_HTML);
+        $form->generalfeedback = array('text' => 'And here is some more text shown only on the review page.',
+                                       'format' => FORMAT_HTML);
+
+        return $form;
+    }
+
 }
index ae97ed8..60da13e 100644 (file)
@@ -17,9 +17,8 @@
 /**
  * Unit tests for the description question type class.
  *
- * @package    qtype
- * @subpackage description
- * @copyright  2010 The Open University
+ * @package    qtype_description
+ * @copyright  2013 The Open University
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
@@ -28,12 +27,15 @@ defined('MOODLE_INTERNAL') || die();
 
 global $CFG;
 require_once($CFG->dirroot . '/question/type/description/questiontype.php');
+require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
+require_once($CFG->dirroot . '/question/type/edit_question_form.php');
+require_once($CFG->dirroot . '/question/type/description/edit_description_form.php');
 
 
 /**
  * Unit tests for the description question type class.
  *
- * @copyright  2010 The Open University
+ * @copyright  2013 The Open University
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 class qtype_description_test extends advanced_testcase {
@@ -66,4 +68,35 @@ class qtype_description_test extends advanced_testcase {
     public function test_get_possible_responses() {
         $this->assertEquals(array(), $this->qtype->get_possible_responses(null));
     }
+
+
+    public function test_question_saving() {
+        $this->resetAfterTest(true);
+        $this->setAdminUser();
+
+        $questiondata = test_question_maker::get_question_data('description');
+        $formdata = test_question_maker::get_question_form_data('description');
+
+        $generator = $this->getDataGenerator()->get_plugin_generator('core_question');
+        $cat = $generator->create_question_category(array());
+
+        $formdata->category = "{$cat->id},{$cat->contextid}";
+        qtype_description_edit_form::mock_submit((array)$formdata);
+
+        $form = qtype_description_test_helper::get_question_editing_form($cat, $questiondata);
+
+        $this->assertTrue($form->is_validated());
+
+        $fromform = $form->get_data();
+
+        $returnedfromsave = $this->qtype->save_question($questiondata, $fromform);
+        $actualquestionsdata = question_load_questions(array($returnedfromsave->id));
+        $actualquestiondata = end($actualquestionsdata);
+
+        foreach ($questiondata as $property => $value) {
+            if (!in_array($property, array('id', 'version', 'timemodified', 'timecreated'))) {
+                $this->assertAttributeEquals($value, $property, $actualquestiondata);
+            }
+        }
+    }
 }
diff --git a/question/type/match/tests/helper.php b/question/type/match/tests/helper.php
new file mode 100644 (file)
index 0000000..d69b9ee
--- /dev/null
@@ -0,0 +1,131 @@
+<?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 match question type.
+ *
+ * @package    qtype_match
+ * @copyright  2013 The Open University
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+
+defined('MOODLE_INTERNAL') || die();
+
+global $CFG;
+require_once($CFG->dirroot . '/question/type/match/question.php');
+
+
+/**
+ * Test helper class for the match question type.
+ *
+ * @copyright  2013 The Open University
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class qtype_match_test_helper extends question_test_helper {
+    public function get_test_questions() {
+        return array('foursubq');
+    }
+
+
+    /**
+     * Makes a match question about completing two blanks in some text.
+     * @return object the question definition data, as it might be returned from
+     * get_question_options.
+     */
+    public function get_match_question_data_foursubq() {
+        global $USER;
+        $q = new stdClass();
+        test_question_maker::initialise_question_data($q);
+        $q->name = 'Matching question';
+        $q->qtype = 'match';
+        $q->parent = 0;
+        $q->questiontext = 'Classify the animals.';
+        $q->questiontextformat = FORMAT_HTML;
+        $q->generalfeedback = 'General feedback.';
+        $q->generalfeedbackformat = FORMAT_HTML;
+        $q->defaultmark = 1;
+        $q->penalty = 0.3333333;
+        $q->length = 1;
+        $q->hidden = 0;
+        $q->createdby = $USER->id;
+        $q->modifiedby = $USER->id;
+
+        $q->options = new stdClass();
+        $q->options->shuffleanswers = 0;
+        test_question_maker::set_standard_combined_feedback_fields($q->options);
+
+        $q->options->subquestions = array(
+            14 => (object) array(
+                'id' => 14,
+                'questiontext' => 'frog',
+                'questiontextformat' => FORMAT_HTML,
+                'answertext' => 'amphibian'),
+            15 => (object) array(
+                'id' => 15,
+                'questiontext' => 'cat',
+                'questiontextformat' => FORMAT_HTML,
+                'answertext' => 'mammal'),
+            16 => (object) array(
+                'id' => 16,
+                'questiontext' => 'newt',
+                'questiontextformat' => FORMAT_HTML,
+                'answertext' => 'amphibian'),
+            17 => (object) array(
+                'id' => 17,
+                'questiontext' => '',
+                'questiontextformat' => FORMAT_HTML,
+                'answertext' => 'insect'),
+        );
+
+        return $q;
+    }
+
+    /**
+     * Makes a match question about completing two blanks in some text.
+     * @return object the question definition data, as it might be returned from
+     *      the question editing form.
+     */
+    public function get_match_question_form_data_foursubq() {
+        $q = new stdClass();
+        $q->name = 'Matching question';
+        $q->questiontext = array('text' => 'Classify the animals.', 'format' => FORMAT_HTML);
+        $q->generalfeedback = array('text' => 'General feedback.', 'format' => FORMAT_HTML);
+        $q->defaultmark = 1;
+        $q->penalty = 0.3333333;
+
+        $q->shuffleanswers = 0;
+        test_question_maker::set_standard_combined_feedback_form_data($q);
+
+        $q->subquestions = array(
+            0 => array('text' => 'frog', 'format' => FORMAT_HTML),
+            1 => array('text' => 'cat', 'format' => FORMAT_HTML),
+            2 => array('text' => 'newt', 'format' => FORMAT_HTML),
+            3 => array('text' => '', 'format' => FORMAT_HTML));
+
+        $q->subanswers = array(
+            0 => 'amphibian',
+            1 => 'mammal',
+            2 => 'amphibian',
+            3 => 'insect'
+        );
+
+        $q->noanswers = 4;
+
+        return $q;
+    }
+
+}
index 4ec6f4e..2a8af38 100644 (file)
@@ -28,6 +28,8 @@ defined('MOODLE_INTERNAL') || die();
 global $CFG;
 require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
 require_once($CFG->dirroot . '/question/type/match/questiontype.php');
+require_once($CFG->dirroot . '/question/type/edit_question_form.php');
+require_once($CFG->dirroot . '/question/type/match/edit_match_form.php');
 
 
 /**
@@ -135,4 +137,53 @@ class qtype_match_test extends advanced_testcase {
                 null => question_possible_response::no_response()),
         ), $this->qtype->get_possible_responses($q));
     }
+
+
+    public function test_question_saving_foursubq() {
+        $this->resetAfterTest(true);
+        $this->setAdminUser();
+
+        $questiondata = test_question_maker::get_question_data('match');
+        $formdata = test_question_maker::get_question_form_data('match');
+
+        $generator = $this->getDataGenerator()->get_plugin_generator('core_question');
+        $cat = $generator->create_question_category(array());
+
+        $formdata->category = "{$cat->id},{$cat->contextid}";
+
+        qtype_match_edit_form::mock_submit((array)$formdata);
+
+        $form = qtype_match_test_helper::get_question_editing_form($cat, $questiondata);
+        $this->assertTrue($form->is_validated());
+
+        $fromform = $form->get_data();
+
+        $returnedfromsave = $this->qtype->save_question($questiondata, $fromform);
+        $actualquestionsdata = question_load_questions(array($returnedfromsave->id));
+        $actualquestiondata = end($actualquestionsdata);
+
+        foreach ($questiondata as $property => $value) {
+            if (!in_array($property, array('id', 'version', 'timemodified', 'timecreated', 'options', 'stamp'))) {
+                $this->assertAttributeEquals($value, $property, $actualquestiondata);
+            }
+        }
+
+        foreach ($questiondata->options as $optionname => $value) {
+            if ($optionname != 'subquestions') {
+                $this->assertAttributeEquals($value, $optionname, $actualquestiondata->options);
+            }
+        }
+
+        $this->assertObjectHasAttribute('subquestions', $actualquestiondata->options);
+
+        $subqpropstoignore = array('id');
+        foreach ($questiondata->options->subquestions as $subq) {
+            $actualsubq = array_shift($actualquestiondata->options->subquestions);
+            foreach ($subq as $subqproperty => $subqvalue) {
+                if (!in_array($subqproperty, $subqpropstoignore)) {
+                    $this->assertAttributeEquals($subqvalue, $subqproperty, $actualsubq);
+                }
+            }
+        }
+    }
 }
index 743058e..92a51e4 100644 (file)
@@ -17,9 +17,8 @@
 /**
  * Test helpers for the multianswer question type.
  *
- * @package    qtype
- * @subpackage multianswer
- * @copyright  2011 The Open University
+ * @package    qtype_multianswer
+ * @copyright  2013 The Open University
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
@@ -33,7 +32,7 @@ require_once($CFG->dirroot . '/question/type/multianswer/question.php');
 /**
  * Test helper class for the multianswer question type.
  *
- * @copyright  2011 The Open University
+ * @copyright  2013 The Open University
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 class qtype_multianswer_test_helper extends question_test_helper {
@@ -171,7 +170,7 @@ class qtype_multianswer_test_helper extends question_test_helper {
         $mc->options->partiallycorrectfeedbackformat = 1;
         $mc->options->incorrectfeedback = '';
         $mc->options->incorrectfeedbackformat = 1;
-        $mc->options->answernumbering = '';
+        $mc->options->answernumbering = 0;
         $mc->options->shownumcorrect = 0;
 
         $mc->options->answers = array(
@@ -190,8 +189,8 @@ class qtype_multianswer_test_helper extends question_test_helper {
         );
 
         $qdata->hints = array(
-            new question_hint(0, 'Hint 1', FORMAT_HTML),
-            new question_hint(0, 'Hint 2', FORMAT_HTML),
+            new question_hint_with_parts(0, 'Hint 1', FORMAT_HTML, 0, 0),
+            new question_hint_with_parts(0, 'Hint 2', FORMAT_HTML, 0, 0),
         );
 
         return $qdata;
@@ -204,16 +203,14 @@ class qtype_multianswer_test_helper extends question_test_helper {
      */
     public function get_multianswer_question_form_data_twosubq() {
         $formdata = new stdClass();
-        test_question_maker::initialise_question_form_data($formdata);
-
         $formdata->name = 'Simple multianswer';
-        $formdata->questiontext = 'Complete this opening line of verse: "The ' .
+        $formdata->questiontext = array('text' => 'Complete this opening line of verse: "The ' .
                 '{1:SHORTANSWER:Dog#Wrong, silly!~=Owl#Well done!~*#Wrong answer} ' .
                 'and the {1:MULTICHOICE:Bow-wow#You seem to have a dog obsessions!' .
                 '~Wiggly worm#Now you are just being ridiculous!~=Pussy-cat#Well done!}' .
-                ' went to sea".';
-        $formdata->generalfeedback = 'General feedback: It\'s from "The Owl and the Pussy-cat" ' .
-                'by Lear: "The owl and the pussycat went to sea';
+                ' went to sea".', 'format' => FORMAT_HTML);
+        $formdata->generalfeedback = array('text' => 'General feedback: It\'s from "The Owl and the Pussy-cat" ' .
+                'by Lear: "The owl and the pussycat went to sea', 'format' => FORMAT_HTML);
 
         $formdata->hint = array(
             0 => array('text' => 'Hint 1', 'format' => FORMAT_HTML, 'itemid' => 0),
index 9caffbf..241742d 100644 (file)
@@ -29,6 +29,8 @@ defined('MOODLE_INTERNAL') || die();
 global $CFG;
 require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
 require_once($CFG->dirroot . '/question/type/multianswer/questiontype.php');
+require_once($CFG->dirroot . '/question/type/edit_question_form.php');
+require_once($CFG->dirroot . '/question/type/multianswer/edit_multianswer_form.php');
 
 
 /**
@@ -112,4 +114,77 @@ class qtype_multianswer_test extends advanced_testcase {
         $q = test_question_maker::get_question_data('multianswer', 'twosubq');
         $this->assertEquals(0.1666667, $this->qtype->get_random_guess_score($q), '', 0.0000001);
     }
+
+    public function test_question_saving_twosubq() {
+        $this->resetAfterTest(true);
+        $this->setAdminUser();
+
+        $questiondata = test_question_maker::get_question_data('multianswer');
+        $formdata = test_question_maker::get_question_form_data('multianswer');
+
+        $generator = $this->getDataGenerator()->get_plugin_generator('core_question');
+        $cat = $generator->create_question_category(array());
+
+        $formdata->category = "{$cat->id},{$cat->contextid}";
+        qtype_multianswer_edit_form::mock_submit((array)$formdata);
+
+        $form = qtype_multianswer_test_helper::get_question_editing_form($cat, $questiondata);
+
+        $this->assertTrue($form->is_validated());
+
+        $fromform = $form->get_data();
+
+        $returnedfromsave = $this->qtype->save_question($questiondata, $fromform);
+        $actualquestionsdata = question_load_questions(array($returnedfromsave->id));
+        $actualquestiondata = end($actualquestionsdata);
+
+        foreach ($questiondata as $property => $value) {
+            if (!in_array($property, array('id', 'version', 'timemodified', 'timecreated', 'options', 'hints', 'stamp'))) {
+                $this->assertAttributeEquals($value, $property, $actualquestiondata);
+            }
+        }
+
+        foreach ($questiondata->options as $optionname => $value) {
+            if ($optionname != 'questions') {
+                $this->assertAttributeEquals($value, $optionname, $actualquestiondata->options);
+            }
+        }
+
+        foreach ($questiondata->hints as $hint) {
+            $actualhint = array_shift($actualquestiondata->hints);
+            foreach ($hint as $property => $value) {
+                if (!in_array($property, array('id', 'questionid', 'options'))) {
+                    $this->assertAttributeEquals($value, $property, $actualhint);
+                }
+            }
+        }
+
+        $this->assertObjectHasAttribute('questions', $actualquestiondata->options);
+
+        $subqpropstoignore =
+            array('id', 'category', 'parent', 'contextid', 'question', 'options', 'stamp', 'version', 'timemodified',
+                'timecreated');
+        foreach ($questiondata->options->questions as $subqno => $subq) {
+            $actualsubq = $actualquestiondata->options->questions[$subqno];
+            foreach ($subq as $subqproperty => $subqvalue) {
+                if (!in_array($subqproperty, $subqpropstoignore)) {
+                    $this->assertAttributeEquals($subqvalue, $subqproperty, $actualsubq);
+                }
+            }
+            foreach ($subq->options as $optionname => $value) {
+                if (!in_array($optionname, array('answers'))) {
+                    $this->assertAttributeEquals($value, $optionname, $actualsubq->options);
+                }
+            }
+            foreach ($subq->options->answers as $answer) {
+                $actualanswer = array_shift($actualsubq->options->answers);
+                foreach ($answer as $ansproperty => $ansvalue) {
+                    // These questions do not use 'answerformat', will ignore it.
+                    if (!in_array($ansproperty, array('id', 'question', 'answerformat'))) {
+                        $this->assertAttributeEquals($ansvalue, $ansproperty, $actualanswer);
+                    }
+                }
+            }
+        }
+    }
 }
diff --git a/question/type/multichoice/tests/helper.php b/question/type/multichoice/tests/helper.php
new file mode 100644 (file)
index 0000000..0746b51
--- /dev/null
@@ -0,0 +1,219 @@
+<?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 helper code for the multiple choice question type.
+ *
+ * @package    qtype_multichoice
+ * @copyright  2013 The Open University
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+
+defined('MOODLE_INTERNAL') || die();
+
+
+/**
+ * Test helper class for the multiple choice question type.
+ *
+ * @copyright  2013 The Open University
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class qtype_multichoice_test_helper extends question_test_helper {
+    public function get_test_questions() {
+        return array('two_of_four');
+    }
+
+    /**
+     * Get the question data, as it would be loaded by get_question_options.
+     * @return object
+     */
+    public static function get_multichoice_question_data_two_of_four() {
+        global $USER;
+
+        $qdata = new stdClass();
+
+        $qdata->createdby = $USER->id;
+        $qdata->modifiedby = $USER->id;
+        $qdata->qtype = 'multichoice';
+        $qdata->name = 'Multiple choice question';
+        $qdata->questiontext = 'Which are the odd numbers?';
+        $qdata->questiontextformat = FORMAT_HTML;
+        $qdata->generalfeedback = 'The odd numbers are One and Three.';
+        $qdata->generalfeedbackformat = FORMAT_HTML;
+        $qdata->defaultmark = 1;
+        $qdata->length = 1;
+        $qdata->penalty = 0.3333333;
+        $qdata->hidden = 0;
+
+        $qdata->options = new stdClass();
+        $qdata->options->shuffleanswers = 1;
+        $qdata->options->answernumbering = '123';
+        $qdata->options->layout = 0;
+        $qdata->options->single = 0;
+        $qdata->options->correctfeedback =
+                test_question_maker::STANDARD_OVERALL_CORRECT_FEEDBACK;
+        $qdata->options->correctfeedbackformat = FORMAT_HTML;
+        $qdata->options->partiallycorrectfeedback =
+                test_question_maker::STANDARD_OVERALL_PARTIALLYCORRECT_FEEDBACK;
+        $qdata->options->partiallycorrectfeedbackformat = FORMAT_HTML;
+        $qdata->options->shownumcorrect = 1;
+        $qdata->options->incorrectfeedback =
+                test_question_maker::STANDARD_OVERALL_INCORRECT_FEEDBACK;
+        $qdata->options->incorrectfeedbackformat = FORMAT_HTML;
+
+        $qdata->options->answers = array(
+            13 => (object) array(
+                'id' => 13,
+                'answer' => 'One',
+                'answerformat' => FORMAT_PLAIN,
+                'fraction' => '0.5',
+                'feedback' => 'One is odd.',
+                'feedbackformat' => FORMAT_HTML,
+            ),
+            14 => (object) array(
+                'id' => 14,
+                'answer' => 'Two',
+                'answerformat' => FORMAT_PLAIN,
+                'fraction' => '0.0',
+                'feedback' => 'Two is even.',
+                'feedbackformat' => FORMAT_HTML,
+            ),
+            15 => (object) array(
+                'id' => 15,
+                'answer' => 'Three',
+                'answerformat' => FORMAT_PLAIN,
+                'fraction' => '0.5',
+                'feedback' => 'Three is odd.',
+                'feedbackformat' => FORMAT_HTML,
+            ),
+            16 => (object) array(
+                'id' => 16,
+                'answer' => 'Four',
+                'answerformat' => FORMAT_PLAIN,
+                'fraction' => '0.0',
+                'feedback' => 'Four is even.',
+                'feedbackformat' => FORMAT_HTML,
+            ),
+        );
+
+        $qdata->hints = array(
+            1 => (object) array(
+                'hint' => 'Hint 1.',
+                'hintformat' => FORMAT_HTML,
+                'shownumcorrect' => 1,
+                'clearwrong' => 0,
+                'options' => 0,
+            ),
+            2 => (object) array(
+                'hint' => 'Hint 2.',
+                'hintformat' => FORMAT_HTML,
+                'shownumcorrect' => 1,
+                'clearwrong' => 1,
+                'options' => 1,
+            ),
+        );
+
+        return $qdata;
+    }
+    /**
+     * Get the question data, as it would be loaded by get_question_options.
+     * @return object
+     */
+    public static function get_multichoice_question_form_data_two_of_four() {
+        $qdata = new stdClass();
+
+        $qdata->name = 'multiple choice question';
+        $qdata->questiontext = array('text' => 'Which are the odd numbers?', 'format' => FORMAT_HTML);
+        $qdata->generalfeedback = array('text' => 'The odd numbers are One and Three.', 'format' => FORMAT_HTML);
+        $qdata->defaultmark = 1;
+        $qdata->noanswers = 5;
+        $qdata->numhints = 2;
+        $qdata->penalty = 0.3333333;
+
+        $qdata->shuffleanswers = 1;
+        $qdata->answernumbering = '123';
+        $qdata->single = '0';
+        $qdata->correctfeedback = array('text' => test_question_maker::STANDARD_OVERALL_CORRECT_FEEDBACK,
+                                                 'format' => FORMAT_HTML);
+        $qdata->partiallycorrectfeedback = array('text' => test_question_maker::STANDARD_OVERALL_PARTIALLYCORRECT_FEEDBACK,
+                                                          'format' => FORMAT_HTML);
+        $qdata->shownumcorrect = 1;
+        $qdata->incorrectfeedback = array('text' => test_question_maker::STANDARD_OVERALL_INCORRECT_FEEDBACK,
+                                                   'format' => FORMAT_HTML);
+        $qdata->fraction = array('0.5', '0.0', '0.5', '0.0', '0.0');
+        $qdata->answer = array(
+            0 => array(
+                'text' => 'One',
+                'format' => FORMAT_PLAIN
+            ),
+            1 => array(
+                'text' => 'Two',
+                'format' => FORMAT_PLAIN
+            ),
+            2 => array(
+                'text' => 'Three',
+                'format' => FORMAT_PLAIN
+            ),
+            3 => array(
+                'text' => 'Four',
+                'format' => FORMAT_PLAIN
+            ),
+            4 => array(
+                'text' => '',
+                'format' => FORMAT_PLAIN
+            )
+        );
+
+        $qdata->feedback = array(
+            0 => array(
+                'text' => 'One is odd.',
+                'format' => FORMAT_HTML
+            ),
+            1 => array(
+                'text' => 'Two is even.',
+                'format' => FORMAT_HTML
+            ),
+            2 => array(
+                'text' => 'Three is odd.',
+                'format' => FORMAT_HTML
+            ),
+            3 => array(
+                'text' => 'Four is even.',
+                'format' => FORMAT_HTML
+            ),
+            4 => array(
+                'text' => '',
+                'format' => FORMAT_HTML
+            )
+        );
+
+        $qdata->hint = array(
+            0 => array(
+                'text' => 'Hint 1.',
+                'format' => FORMAT_HTML
+            ),
+            1 => array(
+                'text' => 'Hint 2.',
+                'format' => FORMAT_HTML
+            )
+        );
+        $qdata->hintclearwrong = array(0, 1);
+        $qdata->hintshownumcorrect = array(1, 1);
+
+        return $qdata;
+    }
+}
index 17e50db..1f1f100 100644 (file)
@@ -17,9 +17,8 @@
 /**
  * Unit tests for the mulitple choice question definition class.
  *
- * @package    qtype
- * @subpackage multichoice
- * @copyright  2009 The Open University
+ * @package    qtype_multichoice
+ * @copyright  2013 The Open University
  * @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/multichoice/questiontype.php');
-
+require_once($CFG->dirroot . '/question/type/edit_question_form.php');
+require_once($CFG->dirroot . '/question/type/multichoice/edit_multichoice_form.php');
 
 /**
  * Unit tests for the multiple choice question definition class.
@@ -100,4 +101,59 @@ class qtype_multichoice_test extends advanced_testcase {
             2 => array(2 => new question_possible_response('toad', 0)),
         ), $this->qtype->get_possible_responses($q));
     }
+
+    public function test_question_saving_two_of_four() {
+        $this->resetAfterTest(true);
+        $this->setAdminUser();
+
+        $questiondata = test_question_maker::get_question_data('multichoice');
+        $formdata = test_question_maker::get_question_form_data('multichoice');
+
+        $generator = $this->getDataGenerator()->get_plugin_generator('core_question');
+        $cat = $generator->create_question_category(array());
+
+        $formdata->category = "{$cat->id},{$cat->contextid}";
+        qtype_multichoice_edit_form::mock_submit((array)$formdata);
+
+        $form = qtype_multichoice_test_helper::get_question_editing_form($cat, $questiondata);
+
+        $this->assertTrue($form->is_validated());
+
+        $fromform = $form->get_data();
+
+        $returnedfromsave = $this->qtype->save_question($questiondata, $fromform);
+        $actualquestionsdata = question_load_questions(array($returnedfromsave->id));
+        $actualquestiondata = end($actualquestionsdata);
+
+        foreach ($questiondata as $property => $value) {
+            if (!in_array($property, array('id', 'version', 'timemodified', 'timecreated', 'options', 'hints', 'stamp'))) {
+                $this->assertAttributeEquals($value, $property, $actualquestiondata);
+            }
+        }
+
+        foreach ($questiondata->options as $optionname => $value) {
+            if (!in_array($optionname, array('answers'))) {
+                $this->assertAttributeEquals($value, $optionname, $actualquestiondata->options);
+            }
+        }
+
+        foreach ($questiondata->hints as $hint) {
+            $actualhint = array_shift($actualquestiondata->hints);
+            foreach ($hint as $property => $value) {
+                if (!in_array($property, array('id', 'questionid', 'options'))) {
+                    $this->assertAttributeEquals($value, $property, $actualhint);
+                }
+            }
+        }
+
+        foreach ($questiondata->options->answers as $answer) {
+            $actualanswer = array_shift($actualquestiondata->options->answers);
+            foreach ($answer as $ansproperty => $ansvalue) {
+                // This question does not use 'answerformat', will ignore it.
+                if (!in_array($ansproperty, array('id', 'question', 'answerformat'))) {
+                    $this->assertAttributeEquals($ansvalue, $ansproperty, $actualanswer);
+                }
+            }
+        }
+    }
 }
index ffd15bb..7157dfb 100644 (file)
@@ -71,7 +71,155 @@ class qtype_numerical_test_helper extends question_test_helper {
         return $num;
     }
 
-    /**
+    public function get_numerical_question_form_data_pi() {
+        $form = new stdClass();
+        $form->name = 'Pi to two d.p.';
+        $form->questiontext = array();
+        $form->questiontext['format'] = '1';
+        $form->questiontext['text'] = 'What is pi to two d.p.?';
+
+        $form->defaultmark = 1;
+        $form->generalfeedback = array();
+        $form->generalfeedback['format'] = '1';
+        $form->generalfeedback['text'] = 'Generalfeedback: 3.14 is the right answer.';
+
+        $form->noanswers = 6;
+        $form->answer = array();
+        $form->answer[0] = '3.14';
+        $form->answer[1] = '3.142';
+        $form->answer[2] = '3.1';
+        $form->answer[3] = '3';
+        $form->answer[4] = '*';
+        $form->answer[5] = '';
+
+        $form->tolerance = array();
+        $form->tolerance[0] = 0;
+        $form->tolerance[1] = 0;
+        $form->tolerance[2] = 0;
+        $form->tolerance[3] = 0;
+        $form->tolerance[4] = 0;
+        $form->tolerance[5] = 0;
+
+        $form->fraction = array();
+        $form->fraction[0] = '1.0';
+        $form->fraction[1] = '0.0';
+        $form->fraction[2] = '0.0';
+        $form->fraction[3] = '0.0';
+        $form->fraction[4] = '0.0';
+        $form->fraction[5] = '0.0';
+
+        $form->feedback = array();
+        $form->feedback[0] = array();
+        $form->feedback[0]['format'] = '1';
+        $form->feedback[0]['text'] = 'Very good.';
+
+        $form->feedback[1] = array();
+        $form->feedback[1]['format'] = '1';
+        $form->feedback[1]['text'] = 'Too accurate.';
+
+        $form->feedback[2] = array();
+        $form->feedback[2]['format'] = '1';
+        $form->feedback[2]['text'] = 'Not accurate enough.';
+
+        $form->feedback[3] = array();
+        $form->feedback[3]['format'] = '1';
+        $form->feedback[3]['text'] = 'Not accurate enough.';
+
+        $form->feedback[4] = array();
+        $form->feedback[4]['format'] = '1';
+        $form->feedback[4]['text'] = 'Completely wrong.';
+
+        $form->feedback[5] = array();
+        $form->feedback[5]['format'] = '1';
+        $form->feedback[5]['text'] = '';
+
+        $form->unitrole = '3';
+        $form->unitpenalty = 0.1;
+        $form->unitgradingtypes = '1';
+        $form->unitsleft = '0';
+        $form->nounits = 1;
+        $form->multiplier = array();
+        $form->multiplier[0] = '1.0';
+
+        $form->penalty = '0.3333333';
+        $form->numhints = 2;
+        $form->hint = array();
+        $form->hint[0] = array();
+        $form->hint[0]['format'] = '1';
+        $form->hint[0]['text'] = '';
+
+        $form->hint[1] = array();
+        $form->hint[1]['format'] = '1';
+        $form->hint[1]['text'] = '';
+
+        $form->qtype = 'numerical';
+        return $form;
+    }
+
+    public function get_numerical_question_data_pi() {
+        $q = new stdClass();
+        $q->name = 'Pi to two d.p.';
+        $q->questiontext = 'What is pi to two d.p.?';
+        $q->questiontextformat = FORMAT_HTML;
+        $q->generalfeedback = 'Generalfeedback: 3.14 is the right answer.';
+        $q->generalfeedbackformat = FORMAT_HTML;
+        $q->defaultmark = 1;
+        $q->penalty = 0.3333333;
+        $q->qtype = 'numerical';
+        $q->length = '1';
+        $q->hidden = '0';
+        $q->createdby = '2';
+        $q->modifiedby = '2';
+        $q->options = new stdClass();
+        $q->options->answers = array();
+        $q->options->answers[0] = new stdClass();
+        $q->options->answers[0]->answer = '3.14';
+        $q->options->answers[0]->fraction = '1.0000000';
+        $q->options->answers[0]->feedback = 'Very good.';
+        $q->options->answers[0]->feedbackformat = FORMAT_HTML;
+        $q->options->answers[0]->tolerance = '0';
+
+        $q->options->answers[1] = new stdClass();
+        $q->options->answers[1]->answer = '3.142';
+        $q->options->answers[1]->fraction = '0.0000000';
+        $q->options->answers[1]->feedback = 'Too accurate.';
+        $q->options->answers[1]->feedbackformat = FORMAT_HTML;
+        $q->options->answers[1]->tolerance = '0';
+
+        $q->options->answers[2] = new stdClass();
+        $q->options->answers[2]->answer = '3.1';
+        $q->options->answers[2]->fraction = '0.0000000';
+        $q->options->answers[2]->feedback = 'Not accurate enough.';
+        $q->options->answers[2]->feedbackformat = FORMAT_HTML;
+        $q->options->answers[2]->tolerance = '0';
+
+        $q->options->answers[3] = new stdClass();
+        $q->options->answers[3]->answer = '3';
+        $q->options->answers[3]->answerformat = '0';
+        $q->options->answers[3]->fraction = '0.0000000';
+        $q->options->answers[3]->feedback = 'Not accurate enough.';
+        $q->options->answers[3]->feedbackformat = FORMAT_HTML;
+        $q->options->answers[3]->tolerance = '0';
+
+        $q->options->answers[4] = new stdClass();
+        $q->options->answers[4]->answer = '*';
+        $q->options->answers[4]->answerformat = '0';
+        $q->options->answers[4]->fraction = '0.0000000';
+        $q->options->answers[4]->feedback = 'Completely wrong.';
+        $q->options->answers[4]->feedbackformat = FORMAT_HTML;
+        $q->options->answers[4]->tolerance = '0';
+
+        $q->options->units = array();
+
+        $q->options->unitgradingtype = '0';
+        $q->options->unitpenalty = '0.1000000';
+        $q->options->showunits = '3';
+        $q->options->unitsleft = '0';
+
+        return $q;
+    }
+
+        /**
      * Makes a numerical question with a choice (select menu) of units.
      * @return qtype_numerical_question
      */
index d54408a..1d19a2f 100644 (file)
@@ -28,7 +28,9 @@ defined('MOODLE_INTERNAL') || die();
 
 global $CFG;
 require_once($CFG->dirroot . '/question/type/numerical/questiontype.php');
-
+require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
+require_once($CFG->dirroot . '/question/type/edit_question_form.php');
+require_once($CFG->dirroot . '/question/type/numerical/edit_numerical_form.php');
 
 /**
  * Unit tests for question/type/numerical/questiontype.php.
@@ -121,4 +123,50 @@ class qtype_numerical_test extends advanced_testcase {
             ),
         ), $this->qtype->get_possible_responses($q));
     }
+
+    public function test_question_saving_pi() {
+        $this->resetAfterTest(true);
+        $this->setAdminUser();
+
+        $questiondata = test_question_maker::get_question_data('numerical');
+        $formdata = test_question_maker::get_question_form_data('numerical');
+
+        $generator = $this->getDataGenerator()->get_plugin_generator('core_question');
+        $cat = $generator->create_question_category(array());
+
+        $formdata->category = "{$cat->id},{$cat->contextid}";
+        qtype_numerical_edit_form::mock_submit((array)$formdata);
+
+        $form = qtype_numerical_test_helper::get_question_editing_form($cat, $questiondata);
+
+        $this->assertTrue($form->is_validated());
+
+        $fromform = $form->get_data();
+
+        $returnedfromsave = $this->qtype->save_question($questiondata, $fromform);
+        $actualquestionsdata = question_load_questions(array($returnedfromsave->id));
+        $actualquestiondata = end($actualquestionsdata);
+
+        foreach ($questiondata as $property => $value) {
+            if (!in_array($property, array('options'))) {
+                $this->assertAttributeEquals($value, $property, $actualquestiondata);
+            }
+        }
+
+        foreach ($questiondata->options as $optionname => $value) {
+            if (!in_array($optionname, array('answers'))) {
+                $this->assertAttributeEquals($value, $optionname, $actualquestiondata->options);
+            }
+        }
+
+        foreach ($questiondata->options->answers as $ansindex => $answer) {
+            $actualanswer = array_shift($actualquestiondata->options->answers);
+            foreach ($answer as $ansproperty => $ansvalue) {
+                // This question does not use 'answerformat', will ignore it.
+                if (!in_array($ansproperty, array('id', 'question', 'answerformat'))) {
+                    $this->assertAttributeEquals($ansvalue, $ansproperty, $actualanswer);
+                }
+            }
+        }
+    }
 }
index 452b1a4..5b9c748 100644 (file)
@@ -768,7 +768,6 @@ class question_answer {
      * Constructor.
      * @param int $id the answer.
      * @param string $answer the answer.
-     * @param int $answerformat the format of the answer.
      * @param number $fraction the fraction this answer is worth.
      * @param string $feedback the feedback for this answer.
      * @param int $feedbackformat the format of the feedback.
@@ -966,4 +965,4 @@ class question_first_matching_answer_grading_strategy implements question_gradin
         }
         return null;
     }
-}
\ No newline at end of file
+}
index 40180a7..0889919 100644 (file)
@@ -77,7 +77,7 @@ class qtype_shortanswer_test_helper extends question_test_helper {
         $qdata->generalfeedback = 'Generalfeedback: frog or toad would have been OK.';
 
         $qdata->options = new stdClass();
-        $qdata->options->usecase = false;
+        $qdata->options->usecase = 0;
         $qdata->options->answers = array(
             13 => new question_answer(13, 'frog', 1.0, 'Frog is a very good answer.', FORMAT_HTML),
             14 => new question_answer(14, 'toad', 0.8, 'Toad is an OK good answer.', FORMAT_HTML),
@@ -88,29 +88,28 @@ class qtype_shortanswer_test_helper extends question_test_helper {
     }
 
     /**
-     * Gets the question data for a shortanswer question with with correct
-     * ansewer 'frog', partially correct answer 'toad' and defaultmark 1.
+     * Gets the question form data for a shortanswer question with with correct
+     * answer 'frog', partially correct answer 'toad' and defaultmark 1.
      * This question also has a '*' match anything answer.
      * @return stdClass
      */
     public function get_shortanswer_question_form_data_frogtoad() {
-        $fromform = new stdClass();
-        test_question_maker::initialise_question_form_data($fromform);
-
-        $fromform->qtype = 'shortanswer';
-        $fromform->name = 'Short answer question';
-        $fromform->questiontext = array('text' => 'Name an amphibian: __________', 'format' => FORMAT_HTML);
-        $fromform->generalfeedback = array('text' => 'Generalfeedback: frog or toad would have been OK.', 'format' => FORMAT_HTML);
-        $fromform->usecase = false;
-        $fromform->answer = array('frog', 'toad', '*');
-        $fromform->fraction = array(1.0, 0.8, 0.0);
-        $fromform->feedback = array(
+        $form = new stdClass();
+
+        $form->name = 'Short answer question';
+        $form->questiontext = array('text' => 'Name an amphibian: __________', 'format' => FORMAT_HTML);
+        $form->defaultmark = 1.0;
+        $form->generalfeedback = array('text' => 'Generalfeedback: frog or toad would have been OK.', 'format' => FORMAT_HTML);
+        $form->usecase = false;
+        $form->answer = array('frog', 'toad', '*');
+        $form->fraction = array('1.0', '0.8', '0.0');
+        $form->feedback = array(
             array('text' => 'Frog is a very good answer.', 'format' => FORMAT_HTML),
             array('text' => 'Toad is an OK good answer.', 'format' => FORMAT_HTML),
             array('text' => 'That is a bad answer.', 'format' => FORMAT_HTML),
         );
 
-        return $fromform;
+        return $form;
     }
 
     /**
index 512b635..91d2bcd 100644 (file)
@@ -17,9 +17,8 @@
 /**
  * Unit tests for the shortanswer question type class.
  *
- * @package    qtype
- * @subpackage shortanswer
- * @copyright  2007 The Open University
+ * @package    qtype_shortanswer
+ * @copyright  2013 The Open University
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
@@ -29,7 +28,8 @@ defined('MOODLE_INTERNAL') || die();
 global $CFG;
 require_once($CFG->dirroot . '/question/type/shortanswer/questiontype.php');
 require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
-
+require_once($CFG->dirroot . '/question/type/edit_question_form.php');
+require_once($CFG->dirroot . '/question/type/shortanswer/edit_shortanswer_form.php');
 
 /**
  * Unit tests for the shortanswer question type class.
@@ -95,4 +95,50 @@ class qtype_shortanswer_test extends advanced_testcase {
             ),
         ), $this->qtype->get_possible_responses($q));
     }
+
+    public function test_question_saving_frogtoad() {
+        $this->resetAfterTest(true);
+        $this->setAdminUser();
+
+        $questiondata = test_question_maker::get_question_data('shortanswer');
+        $formdata = test_question_maker::get_question_form_data('shortanswer');
+
+        $generator = $this->getDataGenerator()->get_plugin_generator('core_question');
+        $cat = $generator->create_question_category(array());
+
+        $formdata->category = "{$cat->id},{$cat->contextid}";
+        qtype_shortanswer_edit_form::mock_submit((array)$formdata);
+
+        $form = qtype_shortanswer_test_helper::get_question_editing_form($cat, $questiondata);
+
+        $this->assertTrue($form->is_validated());
+
+        $fromform = $form->get_data();
+
+        $returnedfromsave = $this->qtype->save_question($questiondata, $fromform);
+        $actualquestionsdata = question_load_questions(array($returnedfromsave->id));
+        $actualquestiondata = end($actualquestionsdata);
+
+        foreach ($questiondata as $property => $value) {
+            if (!in_array($property, array('id', 'version', 'timemodified', 'timecreated', 'options'))) {
+                $this->assertAttributeEquals($value, $property, $actualquestiondata);
+            }
+        }
+
+        foreach ($questiondata->options as $optionname => $value) {
+            if ($optionname != 'answers') {
+                $this->assertAttributeEquals($value, $optionname, $actualquestiondata->options);
+            }
+        }
+
+        foreach ($questiondata->options->answers as $answer) {
+            $actualanswer = array_shift($actualquestiondata->options->answers);
+            foreach ($answer as $ansproperty => $ansvalue) {
+                // This question does not use 'answerformat', will ignore it.
+                if (!in_array($ansproperty, array('id', 'question', 'answerformat'))) {
+                    $this->assertAttributeEquals($ansvalue, $ansproperty, $actualanswer);
+                }
+            }
+        }
+    }
 }
index 1ee7e8e..359ade0 100644 (file)
@@ -63,6 +63,67 @@ class qtype_truefalse_test_helper extends question_test_helper {
         return $tf;
     }
 
+    public function get_truefalse_question_form_data_true() {
+
+        $form = new stdClass();
+        $form->name = 'True/false question';
+        $form->questiontext = array();
+        $form->questiontext['format'] = '1';
+        $form->questiontext['text'] = 'The answer is true.';
+
+        $form->defaultmark = 1;
+        $form->generalfeedback = array();
+        $form->generalfeedback['format'] = '1';
+        $form->generalfeedback['text'] = 'You should have selected true.';
+
+        $form->correctanswer = '1';
+        $form->feedbacktrue = array();
+        $form->feedbacktrue['format'] = '1';
+        $form->feedbacktrue['text'] = 'This is the right answer.';
+
+        $form->feedbackfalse = array();
+        $form->feedbackfalse['format'] = '1';
+        $form->feedbackfalse['text'] = 'This is the wrong answer.';
+
+        $form->penalty = 1;
+
+        return $form;
+    }
+
+    function get_truefalse_question_data_true() {
+
+        $q = new stdClass();
+        $q->name = 'True/false question';
+        $q->questiontext = 'The answer is true.';
+        $q->questiontextformat = FORMAT_HTML;
+        $q->generalfeedback = 'You should have selected true.';
+        $q->generalfeedbackformat = FORMAT_HTML;
+        $q->defaultmark = 1;
+        $q->penalty = 1;
+        $q->qtype = 'truefalse';
+        $q->length = '1';
+        $q->hidden = '0';
+        $q->createdby = '2';
+        $q->modifiedby = '2';
+        $q->options = new stdClass();
+        $q->options->trueanswer = '0';
+        $q->options->falseanswer = '1';
+        $q->options->answers = array();
+        $q->options->answers[0] = new stdClass();
+        $q->options->answers[0]->answer = 'True';
+        $q->options->answers[0]->fraction = '1.0000000';
+        $q->options->answers[0]->feedback = 'This is the right answer.';
+        $q->options->answers[0]->feedbackformat = FORMAT_HTML;
+
+        $q->options->answers[1] = new stdClass();
+        $q->options->answers[1]->answer = 'False';
+        $q->options->answers[1]->fraction = '0.0000000';
+        $q->options->answers[1]->feedback = 'This is the wrong answer.';
+        $q->options->answers[1]->feedbackformat = FORMAT_HTML;
+
+        return $q;
+    }
+
     /**
      * Makes a truefalse question with correct answer false.
      * @return qtype_truefalse_question
index 57f6999..824f256 100644 (file)
@@ -28,7 +28,9 @@ defined('MOODLE_INTERNAL') || die();
 
 global $CFG;
 require_once($CFG->dirroot . '/question/type/truefalse/questiontype.php');
-
+require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
+require_once($CFG->dirroot . '/question/type/edit_question_form.php');
+require_once($CFG->dirroot . '/question/type/truefalse/edit_truefalse_form.php');
 
 /**
  * Unit tests for the true-false question definition class.
@@ -75,4 +77,55 @@ class qtype_truefalse_test extends advanced_testcase {
                 null => question_possible_response::no_response()),
         ), $this->qtype->get_possible_responses($q));
     }
+
+    public function test_question_saving_true() {
+        $this->resetAfterTest(true);
+        $this->setAdminUser();
+
+        $questiondata = test_question_maker::get_question_data('truefalse');
+        $formdata = test_question_maker::get_question_form_data('truefalse');
+
+        $generator = $this->getDataGenerator()->get_plugin_generator('core_question');
+        $cat = $generator->create_question_category(array());
+
+        $formdata->category = "{$cat->id},{$cat->contextid}";
+        qtype_truefalse_edit_form::mock_submit((array)$formdata);
+
+        $form = qtype_truefalse_test_helper::get_question_editing_form($cat, $questiondata);
+
+        $this->assertTrue($form->is_validated());
+
+        $fromform = $form->get_data();
+
+        $returnedfromsave = $this->qtype->save_question($questiondata, $fromform);
+        $actualquestionsdata = question_load_questions(array($returnedfromsave->id));
+        $actualquestiondata = end($actualquestionsdata);
+
+        foreach ($questiondata as $property => $value) {
+            if (!in_array($property, array('options'))) {
+                $this->assertAttributeEquals($value, $property, $actualquestiondata);
+            }
+        }
+
+        foreach ($questiondata->options as $optionname => $value) {
+            if (!in_array($optionname, array('trueanswer', 'falseanswer', 'answers'))) {
+                $this->assertAttributeEquals($value, $optionname, $actualquestiondata->options);
+            }
+        }
+
+        $answerindexes = array();
+        foreach ($questiondata->options->answers as $ansindex => $answer) {
+            $actualanswer = array_shift($actualquestiondata->options->answers);
+            foreach ($answer as $ansproperty => $ansvalue) {
+                // This question does not use 'answerformat', will ignore it.
+                if (!in_array($ansproperty, array('id', 'question', 'answerformat'))) {
+                    $this->assertAttributeEquals($ansvalue, $ansproperty, $actualanswer);
+                }
+            }
+            $answerindexes[$answer->answer] = $ansindex;
+        }
+
+        $this->assertEquals($questiondata->options->trueanswer, $answerindexes['True']);
+        $this->assertEquals($questiondata->options->falseanswer, $answerindexes['False']);
+    }
 }