1ba3408e5ce2720c644143b3d0048f44506c9abf
[moodle.git] / question / type / multianswer / tests / helper.php
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17 /**
18  * Test helpers for the multianswer question type.
19  *
20  * @package    qtype_multianswer
21  * @copyright  2013 The Open University
22  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
26 defined('MOODLE_INTERNAL') || die();
28 global $CFG;
29 require_once($CFG->dirroot . '/question/type/multianswer/question.php');
32 /**
33  * Test helper class for the multianswer question type.
34  *
35  * @copyright  2013 The Open University
36  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37  */
38 class qtype_multianswer_test_helper extends question_test_helper {
39     public function get_test_questions() {
40         return array('twosubq', 'fourmc', 'numericalzero', 'dollarsigns');
41     }
43     /**
44      * Makes a multianswer question about completing two blanks in some text.
45      * @return qtype_multianswer_question
46      */
47     public function make_multianswer_question_twosubq() {
48         question_bank::load_question_definition_classes('multianswer');
49         $q = new qtype_multianswer_question();
50         test_question_maker::initialise_a_question($q);
51         $q->name = 'Simple multianswer';
52         $q->questiontext =
53                 'Complete this opening line of verse: "The {#1} and the {#2} went to sea".';
54         $q->generalfeedback = 'General feedback: It\'s from "The Owl and the Pussy-cat" by Lear: ' .
55                 '"The owl and the pussycat went to sea';
56         $q->qtype = question_bank::get_qtype('multianswer');
58         $q->textfragments = array(
59             'Complete this opening line of verse: "The ',
60             ' and the ',
61             ' went to sea".',
62         );
63         $q->places = array('1' => '1', '2' => '2');
65         // Shortanswer subquestion.
66         question_bank::load_question_definition_classes('shortanswer');
67         $sa = new qtype_shortanswer_question();
68         test_question_maker::initialise_a_question($sa);
69         $sa->name = 'Simple multianswer';
70         $sa->questiontext = '{1:SHORTANSWER:Dog#Wrong, silly!~=Owl#Well done!~*#Wrong answer}';
71         $sa->questiontextformat = FORMAT_HTML;
72         $sa->generalfeedback = '';
73         $sa->generalfeedbackformat = FORMAT_HTML;
74         $sa->usecase = true;
75         $sa->answers = array(
76             13 => new question_answer(13, 'Dog', 0.0, 'Wrong, silly!', FORMAT_HTML),
77             14 => new question_answer(14, 'Owl', 1.0, 'Well done!', FORMAT_HTML),
78             15 => new question_answer(15, '*', 0.0, 'Wrong answer', FORMAT_HTML),
79         );
80         $sa->qtype = question_bank::get_qtype('shortanswer');
81         $sa->maxmark = 1;
83         // Multiple-choice subquestion.
84         question_bank::load_question_definition_classes('multichoice');
85         $mc = new qtype_multichoice_single_question();
86         test_question_maker::initialise_a_question($mc);
87         $mc->name = 'Simple multianswer';
88         $mc->questiontext = '{1:MULTICHOICE:Bow-wow#You seem to have a dog obsessions!' .
89                 '~Wiggly worm#Now you are just being rediculous!~=Pussy-cat#Well done!}';
90         $mc->questiontextformat = FORMAT_HTML;
91         $mc->generalfeedback = '';
92         $mc->generalfeedbackformat = FORMAT_HTML;
94         $mc->shuffleanswers = 0;
95         $mc->answernumbering = 'none';
96         $mc->layout = qtype_multichoice_base::LAYOUT_DROPDOWN;
98         $mc->answers = array(
99             13 => new question_answer(13, 'Bow-wow', 0,
100                     'You seem to have a dog obsessions!', FORMAT_HTML),
101             14 => new question_answer(14, 'Wiggly worm', 0,
102                     'Now you are just being rediculous!', FORMAT_HTML),
103             15 => new question_answer(15, 'Pussy-cat', 1,
104                     'Well done!', FORMAT_HTML),
105         );
106         $mc->qtype = question_bank::get_qtype('multichoice');
107         $mc->maxmark = 1;
109         $q->subquestions = array(
110             1 => $sa,
111             2 => $mc,
112         );
114         return $q;
115     }
117     /**
118      * Makes a multianswer question about completing two blanks in some text.
119      * @return object the question definition data, as it might be returned from
120      * get_question_options.
121      */
122     public function get_multianswer_question_data_twosubq() {
123         $qdata = new stdClass();
124         test_question_maker::initialise_question_data($qdata);
126         $qdata->name = 'Simple multianswer';
127         $qdata->questiontext =
128                         'Complete this opening line of verse: "The {#1} and the {#2} went to sea".';
129         $qdata->generalfeedback = 'General feedback: It\'s from "The Owl and the Pussy-cat" by Lear: ' .
130                         '"The owl and the pussycat went to sea';
132         $qdata->defaultmark = 2.0;
133         $qdata->qtype = 'multianswer';
135         $sa = new stdClass();
136         test_question_maker::initialise_question_data($sa);
138         $sa->name = 'Simple multianswer';
139         $sa->questiontext = '{1:SHORTANSWER:Dog#Wrong, silly!~=Owl#Well done!~*#Wrong answer}';
140         $sa->generalfeedback = '';
141         $sa->penalty = 0.0;
142         $sa->qtype = 'shortanswer';
144         $sa->options = new stdClass();
145         $sa->options->usecase = 0;
147         $sa->options->answers = array(
148             13 => new question_answer(13, 'Dog', 0, 'Wrong, silly!', FORMAT_HTML),
149             14 => new question_answer(14, 'Owl', 1, 'Well done!',    FORMAT_HTML),
150             15 => new question_answer(15, '*',   0, 'Wrong answer',  FORMAT_HTML),
151         );
153         $mc = new stdClass();
154         test_question_maker::initialise_question_data($mc);
156         $mc->name = 'Simple multianswer';
157         $mc->questiontext = '{1:MULTICHOICE:Bow-wow#You seem to have a dog obsessions!~' .
158                 'Wiggly worm#Now you are just being ridiculous!~=Pussy-cat#Well done!}';
159         $mc->generalfeedback = '';
160         $mc->penalty = 0.0;
161         $mc->qtype = 'multichoice';
163         $mc->options = new stdClass();
164         $mc->options->layout = 0;
165         $mc->options->single = 1;
166         $mc->options->shuffleanswers = 0;
167         $mc->options->correctfeedback = '';
168         $mc->options->correctfeedbackformat = 1;
169         $mc->options->partiallycorrectfeedback = '';
170         $mc->options->partiallycorrectfeedbackformat = 1;
171         $mc->options->incorrectfeedback = '';
172         $mc->options->incorrectfeedbackformat = 1;
173         $mc->options->answernumbering = 0;
174         $mc->options->shownumcorrect = 0;
176         $mc->options->answers = array(
177             23 => new question_answer(23, 'Bow-wow',     0,
178                     'You seem to have a dog obsessions!', FORMAT_HTML),
179             24 => new question_answer(24, 'Wiggly worm', 0,
180                     'Now you are just being ridiculous!', FORMAT_HTML),
181             25 => new question_answer(25, 'Pussy-cat',   1,
182                     'Well done!',                         FORMAT_HTML),
183         );
185         $qdata->options = new stdClass();
186         $qdata->options->questions = array(
187             1 => $sa,
188             2 => $mc,
189         );
191         $qdata->hints = array(
192             new question_hint_with_parts(0, 'Hint 1', FORMAT_HTML, 0, 0),
193             new question_hint_with_parts(0, 'Hint 2', FORMAT_HTML, 0, 0),
194         );
196         return $qdata;
197     }
199     /**
200      * Makes a multianswer question onetaining one blank in some text.
201      * This question has no hints.
202      *
203      * @return object the question definition data, as it might be returned from
204      * get_question_options.
205      */
206     public function get_multianswer_question_data_dollarsigns() {
207         $qdata = new stdClass();
208         test_question_maker::initialise_question_data($qdata);
210         $qdata->name = 'Multianswer with $s';
211         $qdata->questiontext =
212                         'Which is the right order? {#1}';
213         $qdata->generalfeedback = '';
215         $qdata->defaultmark = 1.0;
216         $qdata->qtype = 'multianswer';
218         $mc = new stdClass();
219         test_question_maker::initialise_question_data($mc);
221         $mc->name = 'Multianswer with $s';
222         $mc->questiontext = '{1:MULTICHOICE:=y,y,$3~$3,y,y}';
223         $mc->generalfeedback = '';
224         $mc->penalty = 0.0;
225         $mc->qtype = 'multichoice';
227         $mc->options = new stdClass();
228         $mc->options->layout = 0;
229         $mc->options->single = 1;
230         $mc->options->shuffleanswers = 0;
231         $mc->options->correctfeedback = '';
232         $mc->options->correctfeedbackformat = 1;
233         $mc->options->partiallycorrectfeedback = '';
234         $mc->options->partiallycorrectfeedbackformat = 1;
235         $mc->options->incorrectfeedback = '';
236         $mc->options->incorrectfeedbackformat = 1;
237         $mc->options->answernumbering = 0;
238         $mc->options->shownumcorrect = 0;
240         $mc->options->answers = array(
241             23 => new question_answer(23, 'y,y,$3', 0, '', FORMAT_HTML),
242             24 => new question_answer(24, '$3,y,y', 0, '', FORMAT_HTML),
243         );
245         $qdata->options = new stdClass();
246         $qdata->options->questions = array(
247             1 => $mc,
248         );
250         $qdata->hints = array(
251         );
253         return $qdata;
254     }
256     /**
257      * Makes a multianswer question about completing two blanks in some text.
258      * @return object the question definition data, as it might be returned from
259      *      the question editing form.
260      */
261     public function get_multianswer_question_form_data_twosubq() {
262         $formdata = new stdClass();
263         $formdata->name = 'Simple multianswer';
264         $formdata->questiontext = array('text' => 'Complete this opening line of verse: "The ' .
265                 '{1:SHORTANSWER:Dog#Wrong, silly!~=Owl#Well done!~*#Wrong answer} ' .
266                 'and the {1:MULTICHOICE:Bow-wow#You seem to have a dog obsessions!' .
267                 '~Wiggly worm#Now you are just being ridiculous!~=Pussy-cat#Well done!}' .
268                 ' went to sea".', 'format' => FORMAT_HTML);
269         $formdata->generalfeedback = array('text' => 'General feedback: It\'s from "The Owl and the Pussy-cat" ' .
270                 'by Lear: "The owl and the pussycat went to sea', 'format' => FORMAT_HTML);
272         $formdata->hint = array(
273             0 => array('text' => 'Hint 1', 'format' => FORMAT_HTML, 'itemid' => 0),
274             1 => array('text' => 'Hint 2', 'format' => FORMAT_HTML, 'itemid' => 0),
275         );
277         return $formdata;
278     }
280     /**
281      * Makes a multianswer question about completing two blanks in some text.
282      * @return qtype_multianswer_question
283      */
284     public function make_multianswer_question_fourmc() {
285         question_bank::load_question_definition_classes('multianswer');
286         $q = new qtype_multianswer_question();
287         test_question_maker::initialise_a_question($q);
288         $q->name = 'Multianswer four multi-choice';
289         $q->questiontext = '<p>Match the following cities with the correct state:</p>
290                 <ul>
291                 <li>San Francisco: {#1}</li>
292                 <li>Tucson: {#2}</li>
293                 <li>Los Angeles: {#3}</li>
294                 <li>Phoenix: {#4}</li>
295                 </ul>';
296         $q->questiontextformat = FORMAT_HTML;
297         $q->generalfeedback = '';
298         $q->qtype = question_bank::get_qtype('multianswer');
300         $q->textfragments = array('<p>Match the following cities with the correct state:</p>
301                 <ul>
302                 <li>San Francisco: ', '</li>
303                 <li>Tucson: ', '</li>
304                 <li>Los Angeles: ', '</li>
305                 <li>Phoenix: ', '</li>
306                 </ul>');
307         $q->places = array('1' => '1', '2' => '2', '3' => '3', '4' => '4');
309         $subqdata = array(
310             1 => array('qt' => '{1:MULTICHOICE:=California#OK~Arizona#Wrong}', 'California' => 'OK', 'Arizona' => 'Wrong'),
311             2 => array('qt' => '{1:MULTICHOICE:%0%California#Wrong~=Arizona#OK}', 'California' => 'Wrong', 'Arizona' => 'OK'),
312             3 => array('qt' => '{1:MULTICHOICE:=California#OK~Arizona#Wrong}', 'California' => 'OK', 'Arizona' => 'Wrong'),
313             4 => array('qt' => '{1:MULTICHOICE:%0%California#Wrong~=Arizona#OK}', 'California' => 'Wrong', 'Arizona' => 'OK'),
314         );
315         foreach ($subqdata as $i => $data) {
316                 // Multiple-choice subquestion.
317             question_bank::load_question_definition_classes('multichoice');
318             $mc = new qtype_multichoice_single_question();
319             test_question_maker::initialise_a_question($mc);
320             $mc->name = 'Multianswer four multi-choice';
321             $mc->questiontext = $data['qt'];
322             $mc->questiontextformat = FORMAT_HTML;
323             $mc->generalfeedback = '';
324             $mc->generalfeedbackformat = FORMAT_HTML;
326             $mc->shuffleanswers = 0; // TODO this is a cheat to make the unit tests easier to write.
327             // In reality, multianswer questions always shuffle.
328             $mc->answernumbering = 'none';
329             $mc->layout = qtype_multichoice_base::LAYOUT_DROPDOWN;
331             $mc->answers = array(
332                 10 * $i     => new question_answer(13, 'California', (float) ($data['California'] == 'OK'),
333                         $data['California'], FORMAT_HTML),
334                 10 * $i + 1 => new question_answer(14, 'Arizona', (float) ($data['Arizona'] == 'OK'),
335                          $data['Arizona'], FORMAT_HTML),
336             );
337             $mc->qtype = question_bank::get_qtype('multichoice');
338             $mc->maxmark = 1;
340             $q->subquestions[$i] = $mc;
341         }
343         return $q;
344     }
346     /**
347      * Makes a multianswer question with one numerical subquestion, right answer 0.
348      * This is used for testing the MDL-35370 bug.
349      * @return qtype_multianswer_question
350      */
351     public function make_multianswer_question_numericalzero() {
352         question_bank::load_question_definition_classes('multianswer');
353         $q = new qtype_multianswer_question();
354         test_question_maker::initialise_a_question($q);
355         $q->name = 'Numerical zero';
356         $q->questiontext =
357                 'Enter zero: {#1}.';
358         $q->generalfeedback = '';
359         $q->qtype = question_bank::get_qtype('multianswer');
361         $q->textfragments = array(
362             'Enter zero: ',
363             '.',
364         );
365         $q->places = array('1' => '1');
367         // Numerical subquestion.
368         question_bank::load_question_definition_classes('numerical');
369         $sub = new qtype_numerical_question();
370         test_question_maker::initialise_a_question($sub);
371         $sub->name = 'Numerical zero';
372         $sub->questiontext = '{1:NUMERICAL:=0:0}';
373         $sub->questiontextformat = FORMAT_HTML;
374         $sub->generalfeedback = '';
375         $sub->generalfeedbackformat = FORMAT_HTML;
376         $sub->answers = array(
377             13 => new qtype_numerical_answer(13, '0', 1.0, '', FORMAT_HTML, 0),
378         );
379         $sub->qtype = question_bank::get_qtype('numerical');
380         $sub->ap = new qtype_numerical_answer_processor(array());
381         $sub->maxmark = 1;
383         $q->subquestions = array(
384             1 => $sub,
385         );
387         return $q;
388     }