MDL-32464 qformat multianswer: fix missing include.
authorTim Hunt <T.J.Hunt@open.ac.uk>
Fri, 24 Aug 2012 13:19:27 +0000 (14:19 +0100)
committerTim Hunt <T.J.Hunt@open.ac.uk>
Fri, 24 Aug 2012 15:56:18 +0000 (16:56 +0100)
Also, add a sample file that can be used for testing, and add a unit
test to verify this is working.

question/format/multianswer/format.php
question/format/multianswer/tests/fixtures/questions.multianswer.txt [new file with mode: 0644]
question/format/multianswer/tests/multianswerformat_test.php [new file with mode: 0644]
question/type/multianswer/questiontype.php

index 45179d8..d7a7ac7 100644 (file)
 /**
  * Embedded answer (Cloze) question importer.
  *
- * @package    qformat
- * @subpackage multianswer
- * @copyright  2003 Henrik Kaipe
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @package   qformat_multianswer
+ * @copyright 2003 Henrik Kaipe
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
 
@@ -31,32 +30,36 @@ defined('MOODLE_INTERNAL') || die();
  * Importer that imports a text file containing a single Multianswer question
  * from a text file.
  *
- * @copyright  2003 Henrik Kaipe
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @copyright 2003 Henrik Kaipe
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 class qformat_multianswer extends qformat_default {
 
     public function provide_import() {
-      return true;
+        return true;
     }
 
-    protected function readquestions($lines) {
+    public function readquestions($lines) {
+        question_bank::get_qtype('multianswer'); // Ensure the multianswer code is loaded.
+
         // For this class the method has been simplified as
         // there can never be more than one question for a
-        // multianswer import
+        // multianswer import.
         $questions = array();
 
         $questiontext = array();
         $questiontext['text'] = implode('', $lines);
-        $questiontext['format'] = ;
+        $questiontext['format'] = FORMAT_MOODLE;
         $questiontext['itemid'] = '';
         $question = qtype_multianswer_extract_question($questiontext);
-        $question->questiontext = $question->questiontext['text'] ;
-        $question->questiontextformat = 0 ;
+        $question->questiontext = $question->questiontext['text'];
+        $question->questiontextformat = 0;
 
-        $question->qtype = MULTIANSWER;
+        $question->qtype = 'multianswer';
         $question->generalfeedback = '';
-        $question->course = $this->course;
+        $question->generalfeedbackformat = FORMAT_MOODLE;
+        $question->length = 1;
+        $question->penalty = 0.3333333;
 
         if (!empty($question)) {
             $name = html_to_text(implode(' ', $lines));
diff --git a/question/format/multianswer/tests/fixtures/questions.multianswer.txt b/question/format/multianswer/tests/fixtures/questions.multianswer.txt
new file mode 100644 (file)
index 0000000..57a56a9
--- /dev/null
@@ -0,0 +1,8 @@
+Match the following cities with the correct state:
+* San Francisco: {1:MULTICHOICE:=California#OK~Arizona#Wrong}
+* Tucson: {1:MULTICHOICE:California#Wrong~%100%Arizona#OK}
+* Los Angeles: {1:MULTICHOICE:=California#OK~Arizona#Wrong}
+* Phoenix: {1:MULTICHOICE:%0%California#Wrong~=Arizona#OK}
+The capital of France is {1:SHORTANSWER:%100%Paris#Congratulations!
+~%50%Marseille#No, that is the second largest city in France (after
+Paris).~*#Wrong answer. The capital of France is Paris, of course.}.
diff --git a/question/format/multianswer/tests/multianswerformat_test.php b/question/format/multianswer/tests/multianswerformat_test.php
new file mode 100644 (file)
index 0000000..29c3224
--- /dev/null
@@ -0,0 +1,76 @@
+<?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 Embedded answer (Cloze) question importer.
+ *
+ * @package   qformat_multianswer
+ * @copyright 2012 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->libdir . '/questionlib.php');
+require_once($CFG->dirroot . '/question/format.php');
+require_once($CFG->dirroot . '/question/format/multianswer/format.php');
+require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
+
+
+/**
+ * Unit tests for the Embedded answer (Cloze) question importer.
+ *
+ * @copyright 2012 The Open University
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class qformat_multianswer_test extends question_testcase {
+
+    public function test_import() {
+        $lines = file(__DIR__ . '/fixtures/questions.multianswer.txt');
+
+        $importer = new qformat_multianswer();
+        $qs = $importer->readquestions($lines);
+
+        $expectedq = (object) array(
+            'name' => 'Match the following cities with the ...',
+            'questiontext' => 'Match the following cities with the correct state:
+* San Francisco: {#1}
+* Tucson: {#2}
+* Los Angeles: {#3}
+* Phoenix: {#4}
+The capital of France is {#5}.
+',
+            'questiontextformat' => FORMAT_MOODLE,
+            'generalfeedback' => '',
+            'generalfeedbackformat' => FORMAT_MOODLE,
+            'qtype' => 'multianswer',
+            'defaultmark' => 5,
+            'penalty' => 0.3333333,
+            'length' => 1,
+        );
+
+        $this->assertEquals(1, count($qs));
+        $this->assert(new question_check_specified_fields_expectation($expectedq), $qs[0]);
+
+        $this->assertEquals('multichoice', $qs[0]->options->questions[1]->qtype);
+        $this->assertEquals('multichoice', $qs[0]->options->questions[2]->qtype);
+        $this->assertEquals('multichoice', $qs[0]->options->questions[3]->qtype);
+        $this->assertEquals('multichoice', $qs[0]->options->questions[4]->qtype);
+        $this->assertEquals('shortanswer', $qs[0]->options->questions[5]->qtype);
+    }
+}
index c87e8e7..b39848d 100644 (file)
@@ -304,7 +304,7 @@ function qtype_multianswer_extract_question($text) {
     $question->defaultmark = 0; // Will be increased for each answer norm
 
     for ($positionkey = 1;
-            preg_match('/'.ANSWER_REGEX.'/', $question->questiontext['text'], $answerregs);
+            preg_match('/'.ANSWER_REGEX.'/s', $question->questiontext['text'], $answerregs);
             ++$positionkey) {
         $wrapped = new stdClass();
         $wrapped->generalfeedback['text'] = '';
@@ -390,7 +390,7 @@ function qtype_multianswer_extract_question($text) {
         $answerindex = 0;
 
         $remainingalts = $answerregs[ANSWER_REGEX_ALTERNATIVES];
-        while (preg_match('/~?'.ANSWER_ALTERNATIVE_REGEX.'/', $remainingalts, $altregs)) {
+        while (preg_match('/~?'.ANSWER_ALTERNATIVE_REGEX.'/s', $remainingalts, $altregs)) {
             if ('=' == $altregs[ANSWER_ALTERNATIVE_REGEX_FRACTION]) {
                 $wrapped->fraction["$answerindex"] = '1';
             } else if ($percentile = $altregs[ANSWER_ALTERNATIVE_REGEX_PERCENTILE_FRACTION]) {
@@ -412,7 +412,7 @@ function qtype_multianswer_extract_question($text) {
 
             }
             if (!empty($answerregs[ANSWER_REGEX_ANSWER_TYPE_NUMERICAL])
-                    && preg_match('~'.NUMERICAL_ALTERNATIVE_REGEX.'~',
+                    && preg_match('~'.NUMERICAL_ALTERNATIVE_REGEX.'~s',
                             $altregs[ANSWER_ALTERNATIVE_REGEX_ANSWER], $numregs)) {
                 $wrapped->answer[] = $numregs[NUMERICAL_CORRECT_ANSWER];
                 if (array_key_exists(NUMERICAL_ABS_ERROR_MARGIN, $numregs)) {