MDL-47494 ddimageortext: Fix @package names and PHPdoc layout.
[moodle.git] / question / type / ddimageortext / simpletest / testquestiontype.php
CommitLineData
a2bb148a
TH
1<?php
2
3// This file is part of Moodle - http://moodle.org/
4//
5// Moodle is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// Moodle is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17
a2bb148a
TH
18/**
19 * Unit tests for the drag-and-drop words into sentences question definition class.
20 *
5b4602d2
TH
21 * @package qtype
22 * @subpackage ddwtos
23 * @copyright 2010 The Open University
24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
a2bb148a
TH
25 */
26
27
28require_once($CFG->dirroot . '/question/engine/simpletest/helpers.php');
29require_once($CFG->dirroot . '/question/type/ddwtos/simpletest/helper.php');
30
31
32/**
33 * Unit tests for the drag-and-drop words into sentences question definition class.
34 *
5b4602d2
TH
35 * @copyright 2010 The Open University
36 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
a2bb148a
TH
37 */
38class qtype_ddwtos_test extends UnitTestCase {
39 /** @var qtype_ddwtos instance of the question type class to test. */
40 protected $qtype;
41
42 public function setUp() {
43 $this->qtype = question_bank::get_qtype('ddwtos');;
44 }
45
46 public function tearDown() {
47 $this->qtype = null;
48 }
49
50 public function assert_same_xml($expectedxml, $xml) {
51 $this->assertEqual(str_replace("\r\n", "\n", $expectedxml),
52 str_replace("\r\n", "\n", $xml));
53 }
54
55 /**
56 * @return object the data to construct a question like
57 * {@link qtype_ddwtos_test_helper::make_a_ddwtos_question()}.
58 */
59 protected function get_test_question_data() {
60 global $USER;
61
3919f482 62 $dd = new stdClass();
a2bb148a
TH
63 $dd->id = 0;
64 $dd->category = 0;
7368987a 65 $dd->contextid = 0;
a2bb148a
TH
66 $dd->parent = 0;
67 $dd->questiontextformat = FORMAT_HTML;
77e268e1 68 $dd->generalfeedbackformat = FORMAT_HTML;
a2bb148a
TH
69 $dd->defaultmark = 1;
70 $dd->penalty = 0.3333333;
71 $dd->length = 1;
72 $dd->stamp = make_unique_id_code();
73 $dd->version = make_unique_id_code();
74 $dd->hidden = 0;
75 $dd->timecreated = time();
76 $dd->timemodified = time();
77 $dd->createdby = $USER->id;
78 $dd->modifiedby = $USER->id;
79
80 $dd->name = 'Drag-and-drop words into sentences question';
81 $dd->questiontext = 'The [[1]] brown [[2]] jumped over the [[3]] dog.';
82 $dd->generalfeedback = 'This sentence uses each letter of the alphabet.';
83 $dd->qtype = 'ddwtos';
84
85 $dd->options->shuffleanswers = true;
86
87 test_question_maker::set_standard_combined_feedback_fields($dd->options);
88
89 $dd->options->answers = array(
90 (object) array('answer' => 'quick', 'feedback' => 'O:8:"stdClass":2:{s:9:"draggroup";s:1:"1";s:8:"infinite";i:0;}'),
91 (object) array('answer' => 'fox', 'feedback' => 'O:8:"stdClass":2:{s:9:"draggroup";s:1:"2";s:8:"infinite";i:0;}'),
92 (object) array('answer' => 'lazy', 'feedback' => 'O:8:"stdClass":2:{s:9:"draggroup";s:1:"3";s:8:"infinite";i:0;}'),
93 (object) array('answer' => 'assiduous', 'feedback' => 'O:8:"stdClass":2:{s:9:"draggroup";s:1:"3";s:8:"infinite";i:0;}'),
94 (object) array('answer' => 'dog', 'feedback' => 'O:8:"stdClass":2:{s:9:"draggroup";s:1:"2";s:8:"infinite";i:0;}'),
95 (object) array('answer' => 'slow', 'feedback' => 'O:8:"stdClass":2:{s:9:"draggroup";s:1:"1";s:8:"infinite";i:0;}'),
96 );
97
98 return $dd;
99 }
100
101 public function test_name() {
102 $this->assertEqual($this->qtype->name(), 'ddwtos');
103 }
104
105 public function test_can_analyse_responses() {
106 $this->assertTrue($this->qtype->can_analyse_responses());
107 }
108
109 public function test_initialise_question_instance() {
110 $qdata = $this->get_test_question_data();
111
112 $expected = qtype_ddwtos_test_helper::make_a_ddwtos_question();
113 $expected->stamp = $qdata->stamp;
114 $expected->version = $qdata->version;
115
116 $q = $this->qtype->make_question($qdata);
117
118 $this->assertEqual($expected, $q);
119 }
120
121 public function test_get_random_guess_score() {
122 $q = $this->get_test_question_data();
123 $this->assertWithinMargin(0.5, $this->qtype->get_random_guess_score($q), 0.0000001);
124 }
125
126 public function test_get_possible_responses() {
127 $q = $this->get_test_question_data();
128
129 $this->assertEqual(array(
130 1 => array(
131 1 => new question_possible_response('quick', 1),
132 2 => new question_possible_response('slow', 0),
133 null => question_possible_response::no_response()),
134 2 => array(
135 1 => new question_possible_response('fox', 1),
136 2 => new question_possible_response('dog', 0),
137 null => question_possible_response::no_response()),
138 3 => array(
139 1 => new question_possible_response('lazy', 1),
140 2 => new question_possible_response('assiduous', 0),
141 null => question_possible_response::no_response()),
142 ), $this->qtype->get_possible_responses($q));
143 }
144
145 public function test_xml_import() {
146 $xml = ' <question type="ddwtos">
147 <name>
148 <text>A drag-and-drop question</text>
149 </name>
150 <questiontext format="moodle_auto_format">
151 <text>Put these in order: [[1]], [[2]], [[3]].</text>
152 </questiontext>
153 <generalfeedback>
154 <text>The answer is Alpha, Beta, Gamma.</text>
155 </generalfeedback>
156 <defaultgrade>3</defaultgrade>
157 <penalty>0.3333333</penalty>
158 <hidden>0</hidden>
159 <shuffleanswers>1</shuffleanswers>
160 <correctfeedback>
161 <text><![CDATA[<p>Your answer is correct.</p>]]></text>
162 </correctfeedback>
163 <partiallycorrectfeedback>
164 <text><![CDATA[<p>Your answer is partially correct.</p>]]></text>
165 </partiallycorrectfeedback>
166 <incorrectfeedback>
167 <text><![CDATA[<p>Your answer is incorrect.</p>]]></text>
168 </incorrectfeedback>
169 <shownumcorrect/>
170 <dragbox>
171 <text>Alpha</text>
172 <group>1</group>
173 </dragbox>
174 <dragbox>
175 <text>Beta</text>
176 <group>1</group>
177 </dragbox>
178 <dragbox>
179 <text>Gamma</text>
180 <group>1</group>
181 <infinite/>
182 </dragbox>
183 <hint>
184 <text>Try again.</text>
185 <shownumcorrect />
186 </hint>
187 <hint>
188 <text>These are the first three letters of the Greek alphabet.</text>
189 <shownumcorrect />
190 <clearwrong />
191 </hint>
192 </question>';
193 $xmldata = xmlize($xml);
194
195 $importer = new qformat_xml();
196 $q = $importer->try_importing_using_qtypes(
197 $xmldata['question'], null, null, 'ddwtos');
198
3919f482 199 $expectedq = new stdClass();
a2bb148a
TH
200 $expectedq->qtype = 'ddwtos';
201 $expectedq->name = 'A drag-and-drop question';
202 $expectedq->questiontext = 'Put these in order: [[1]], [[2]], [[3]].';
203 $expectedq->questiontextformat = FORMAT_MOODLE;
204 $expectedq->generalfeedback = 'The answer is Alpha, Beta, Gamma.';
205 $expectedq->defaultmark = 3;
206 $expectedq->length = 1;
207 $expectedq->penalty = 0.3333333;
208
209 $expectedq->shuffleanswers = 1;
77e268e1
TH
210 $expectedq->correctfeedback = array('text' => '<p>Your answer is correct.</p>', 'format' => FORMAT_MOODLE, 'files' => array());
211 $expectedq->partiallycorrectfeedback = array('text' => '<p>Your answer is partially correct.</p>', 'format' => FORMAT_MOODLE, 'files' => array());
a2bb148a 212 $expectedq->shownumcorrect = true;
77e268e1 213 $expectedq->incorrectfeedback = array('text' => '<p>Your answer is incorrect.</p>', 'format' => FORMAT_MOODLE, 'files' => array());
a2bb148a
TH
214
215 $expectedq->choices = array(
216 array('answer' => 'Alpha', 'draggroup' => 1, 'infinite' => false),
217 array('answer' => 'Beta', 'draggroup' => 1, 'infinite' => false),
218 array('answer' => 'Gamma', 'draggroup' => 1, 'infinite' => true),
219 );
220
221 $expectedq->hint = array('Try again.', 'These are the first three letters of the Greek alphabet.');
222 $expectedq->hintshownumcorrect = array(true, true);
223 $expectedq->hintclearwrong = array(false, true);
224
225 $this->assert(new CheckSpecifiedFieldsExpectation($expectedq), $q);
226 }
227
228 public function test_xml_import_legacy() {
229 $xml = ' <question type="ddwtos">
230 <name>
231 <text>QDandD1 Base definition</text>
232 </name>
233 <questiontext format="html">
234 <text>&lt;p&gt;Drag and drop the words from the list below to fill the blank spaces and correctly complete the sentence.&lt;/p&gt; &lt;p&gt;At 25°C all aqueous basic solutions have [[1]]&#160;ion concentrations less than [[8]]&lt;br /&gt;mol litre&lt;sup&gt;-1&lt;/sup&gt; and pH values [[9]] than [[6]].&lt;/p&gt; &lt;!--DONOTCLEAN--&gt;</text>
235 </questiontext>
236 <image></image>
237 <generalfeedback>
238 <text>&lt;p&gt;At 25 &amp;#xB0;C all aqueous basic solutions have hydrogen ion concentrations less than 10&lt;sup&gt;&amp;#x2212;7&lt;/sup&gt; mol litre&lt;sup&gt;&amp;#x2212;1&lt;/sup&gt; and pH values greater than 7.&lt;/p&gt; &lt;p&gt;See Section 9 of S103 &lt;em class="italic"&gt;Discovering Science&lt;/em&gt; Block 8.&lt;/p&gt;</text>
239 </generalfeedback>
240 <defaultgrade>1</defaultgrade>
241 <penalty>0.33</penalty>
242 <hidden>0</hidden>
243 <shuffleanswers>0</shuffleanswers>
244 <shuffleanswers>false</shuffleanswers>
245 <answer>
246 <correctanswer>1</correctanswer>
247 <text>hydrogen</text>
248 <feedback>
249 <text>O:8:"stdClass":2:{s:9:"draggroup";s:1:"1";s:8:"infinite";i:0;}</text>
250 </feedback>
251 </answer>
252 <answer>
253 <correctanswer>0</correctanswer>
254 <text>positive</text>
255 <feedback>
256 <text>O:8:"stdClass":2:{s:9:"draggroup";s:1:"1";s:8:"infinite";i:0;}</text>
257 </feedback>
258 </answer>
259 <answer>
260 <correctanswer>0</correctanswer>
261 <text>hydroxide</text>
262 <feedback>
263 <text>O:8:"stdClass":2:{s:9:"draggroup";s:1:"1";s:8:"infinite";i:0;}</text>
264 </feedback>
265 </answer>
266 <answer>
267 <correctanswer>0</correctanswer>
268 <text>negative</text>
269 <feedback>
270 <text>O:8:"stdClass":2:{s:9:"draggroup";s:1:"1";s:8:"infinite";i:0;}</text>
271 </feedback>
272 </answer>
273 <answer>
274 <correctanswer>0</correctanswer>
275 <text>10&lt;sup&gt;7&lt;/sup&gt;</text>
276 <feedback>
277 <text>O:8:"stdClass":2:{s:9:"draggroup";s:1:"2";s:8:"infinite";i:0;}</text>
278 </feedback>
279 </answer>
280 <answer>
281 <correctanswer>1</correctanswer>
282 <text>7</text>
283 <feedback>
284 <text>O:8:"stdClass":2:{s:9:"draggroup";s:1:"2";s:8:"infinite";i:0;}</text>
285 </feedback>
286 </answer>
287 <answer>
288 <correctanswer>0</correctanswer>
289 <text>1</text>
290 <feedback>
291 <text>O:8:"stdClass":2:{s:9:"draggroup";s:1:"2";s:8:"infinite";i:0;}</text>
292 </feedback>
293 </answer>
294 <answer>
295 <correctanswer>1</correctanswer>
296 <text>10&lt;sup&gt;-7&lt;/sup&gt;</text>
297 <feedback>
298 <text>O:8:"stdClass":2:{s:9:"draggroup";s:1:"2";s:8:"infinite";i:0;}</text>
299 </feedback>
300 </answer>
301 <answer>
302 <correctanswer>1</correctanswer>
303 <text>greater</text>
304 <feedback>
305 <text>O:8:"stdClass":2:{s:9:"draggroup";s:1:"3";s:8:"infinite";i:0;}</text>
306 </feedback>
307 </answer>
308 <answer>
309 <correctanswer>0</correctanswer>
310 <text>less</text>
311 <feedback>
312 <text>O:8:"stdClass":2:{s:9:"draggroup";s:1:"3";s:8:"infinite";i:0;}</text>
313 </feedback>
314 </answer>
315 <correctfeedback>
316 <text>Your answer is correct.</text>
317 </correctfeedback>
318 <correctresponsesfeedback>1</correctresponsesfeedback>
319 <partiallycorrectfeedback>
320 <text>Your answer is partially correct.</text>
321 </partiallycorrectfeedback>
322 <incorrectfeedback>
323 <text>Your answer is incorrect.</text>
324 </incorrectfeedback>
325 <unlimited>0</unlimited>
326 <penalty>0.33</penalty>
327 <hint>
328 <statenumberofcorrectresponses>1</statenumberofcorrectresponses>
329 <clearincorrectresponses>0</clearincorrectresponses>
330 <hintcontent>
331 <text>You may wish to read&#160;Section 9 of&#160;&lt;em class="italic"&gt;Discovering Science&lt;/em&gt; Block 8.</text>
332 </hintcontent>
333 </hint>
334 <hint>
335 <statenumberofcorrectresponses>1</statenumberofcorrectresponses>
336 <clearincorrectresponses>1</clearincorrectresponses>
337 <hintcontent>
338 <text>Any incorrect choices&#160;will be removed before your final try.</text>
339 </hintcontent>
340 </hint>
341 </question>';
342 $xmldata = xmlize($xml);
343
344 $importer = new qformat_xml();
345 $q = $importer->try_importing_using_qtypes(
346 $xmldata['question'], null, null, 'ddwtos');
347
3919f482 348 $expectedq = new stdClass();
a2bb148a
TH
349 $expectedq->qtype = 'ddwtos';
350 $expectedq->name = 'QDandD1 Base definition';
351 $expectedq->questiontext = '<p>Drag and drop the words from the list below to fill the blank spaces and correctly complete the sentence.</p><p>At 25°C all aqueous basic solutions have [[1]] ion concentrations less than [[8]]<br />mol litre<sup>-1</sup> and pH values [[9]] than [[6]].</p><!--DONOTCLEAN-->';
352 $expectedq->questiontextformat = FORMAT_HTML;
77e268e1 353 $expectedq->generalfeedback = '<p>At 25 &#xB0;C all aqueous basic solutions have hydrogen ion concentrations less than 10<sup>&#x2212;7</sup> mol litre<sup>&#x2212;1</sup> and pH values greater than 7.</p><p>See Section 9 of S103 <em class="italic">Discovering Science</em> Block 8.</p>';
a2bb148a
TH
354 $expectedq->defaultmark = 1;
355 $expectedq->length = 1;
356 $expectedq->penalty = 0.3333333;
357
358 $expectedq->shuffleanswers = 0;
77e268e1
TH
359 $expectedq->correctfeedback = array('text' => 'Your answer is correct.', 'format' => FORMAT_MOODLE, 'files' => array());
360 $expectedq->partiallycorrectfeedback = array('text' => 'Your answer is partially correct.', 'format' => FORMAT_MOODLE, 'files' => array());
a2bb148a 361 $expectedq->shownumcorrect = true;
77e268e1 362 $expectedq->incorrectfeedback = array('text' => 'Your answer is incorrect.', 'format' => FORMAT_MOODLE, 'files' => array());
a2bb148a
TH
363
364 $expectedq->choices = array(
77e268e1
TH
365 array('answer' => array('text' => 'hydrogen', 'format' => FORMAT_MOODLE, 'files' => array()), 'draggroup' => 1, 'infinite' => false),
366 array('answer' => array('text' => 'positive', 'format' => FORMAT_MOODLE, 'files' => array()), 'draggroup' => 1, 'infinite' => false),
367 array('answer' => array('text' => 'hydroxide', 'format' => FORMAT_MOODLE, 'files' => array()), 'draggroup' => 1, 'infinite' => false),
368 array('answer' => array('text' => 'negative', 'format' => FORMAT_MOODLE, 'files' => array()), 'draggroup' => 1, 'infinite' => false),
369 array('answer' => array('text' => '10<sup>7</sup>', 'format' => FORMAT_MOODLE, 'files' => array()), 'draggroup' => 2, 'infinite' => false),
370 array('answer' => array('text' => '7', 'format' => FORMAT_MOODLE, 'files' => array()), 'draggroup' => 2, 'infinite' => false),
371 array('answer' => array('text' => '1', 'format' => FORMAT_MOODLE, 'files' => array()), 'draggroup' => 2, 'infinite' => false),
372 array('answer' => array('text' => '10<sup>-7</sup>', 'format' => FORMAT_MOODLE, 'files' => array()), 'draggroup' => 2, 'infinite' => false),
373 array('answer' => array('text' => 'greater', 'format' => FORMAT_MOODLE, 'files' => array()), 'draggroup' => 3, 'infinite' => false),
374 array('answer' => array('text' => 'less', 'format' => FORMAT_MOODLE, 'files' => array()), 'draggroup' => 3, 'infinite' => false),
a2bb148a
TH
375 );
376
377 $expectedq->hint = array(
77e268e1 378 'You may wish to read Section 9 of <em class="italic">Discovering Science</em> Block 8.',
a2bb148a
TH
379 'Any incorrect choices will be removed before your final try.'
380 );
381 $expectedq->hintshownumcorrect = array(true, true);
382 $expectedq->hintclearwrong = array(false, true);
383
384 $this->assert(new CheckSpecifiedFieldsExpectation($expectedq), $q);
385 }
386
387 public function test_xml_export() {
3919f482 388 $qdata = new stdClass();
a2bb148a 389 $qdata->id = 123;
77e268e1 390 $qdata->contextid = 0;
a2bb148a
TH
391 $qdata->qtype = 'ddwtos';
392 $qdata->name = 'A drag-and-drop question';
393 $qdata->questiontext = 'Put these in order: [[1]], [[2]], [[3]].';
394 $qdata->questiontextformat = FORMAT_MOODLE;
395 $qdata->generalfeedback = 'The answer is Alpha, Beta, Gamma.';
77e268e1 396 $qdata->generalfeedbackformat = FORMAT_MOODLE;
a2bb148a
TH
397 $qdata->defaultmark = 3;
398 $qdata->length = 1;
399 $qdata->penalty = 0.3333333;
400 $qdata->hidden = 0;
401
402 $qdata->options->shuffleanswers = 1;
403 $qdata->options->correctfeedback = '<p>Your answer is correct.</p>';
77e268e1 404 $qdata->options->correctfeedbackformat = FORMAT_MOODLE;
a2bb148a 405 $qdata->options->partiallycorrectfeedback = '<p>Your answer is partially correct.</p>';
77e268e1
TH
406 $qdata->options->partiallycorrectfeedbackformat = FORMAT_MOODLE;
407 $qdata->options->shownumcorrect = 1;
a2bb148a 408 $qdata->options->incorrectfeedback = '<p>Your answer is incorrect.</p>';
77e268e1 409 $qdata->options->incorrectfeedbackformat = FORMAT_MOODLE;
a2bb148a
TH
410
411 $qdata->options->answers = array(
77e268e1
TH
412 13 => new question_answer(13, 'Alpha', 0, 'O:8:"stdClass":2:{s:9:"draggroup";s:1:"1";s:8:"infinite";b:0;}', FORMAT_MOODLE),
413 14 => new question_answer(14, 'Beta', 0, 'O:8:"stdClass":2:{s:9:"draggroup";s:1:"1";s:8:"infinite";b:0;}', FORMAT_MOODLE),
414 15 => new question_answer(15, 'Gamma', 0, 'O:8:"stdClass":2:{s:9:"draggroup";s:1:"1";s:8:"infinite";b:1;}', FORMAT_MOODLE),
a2bb148a
TH
415 );
416
417 $qdata->hints = array(
77e268e1
TH
418 1 => new question_hint_with_parts(1, 'Try again.', FORMAT_MOODLE, true, false),
419 2 => new question_hint_with_parts(2, 'These are the first three letters of the Greek alphabet.', FORMAT_MOODLE, true, true),
a2bb148a
TH
420 );
421
422 $exporter = new qformat_xml();
423 $xml = $exporter->writequestion($qdata);
424
425 $expectedxml = '<!-- question: 123 -->
426 <question type="ddwtos">
427 <name>
428 <text>A drag-and-drop question</text>
429 </name>
430 <questiontext format="moodle_auto_format">
431 <text>Put these in order: [[1]], [[2]], [[3]].</text>
432 </questiontext>
77e268e1 433 <generalfeedback format="moodle_auto_format">
a2bb148a
TH
434 <text>The answer is Alpha, Beta, Gamma.</text>
435 </generalfeedback>
436 <defaultgrade>3</defaultgrade>
437 <penalty>0.3333333</penalty>
438 <hidden>0</hidden>
439 <shuffleanswers>1</shuffleanswers>
77e268e1 440 <correctfeedback format="moodle_auto_format">
a2bb148a
TH
441 <text><![CDATA[<p>Your answer is correct.</p>]]></text>
442 </correctfeedback>
77e268e1 443 <partiallycorrectfeedback format="moodle_auto_format">
a2bb148a
TH
444 <text><![CDATA[<p>Your answer is partially correct.</p>]]></text>
445 </partiallycorrectfeedback>
77e268e1 446 <incorrectfeedback format="moodle_auto_format">
a2bb148a
TH
447 <text><![CDATA[<p>Your answer is incorrect.</p>]]></text>
448 </incorrectfeedback>
449 <shownumcorrect/>
450 <dragbox>
451 <text>Alpha</text>
452 <group>1</group>
453 </dragbox>
454 <dragbox>
455 <text>Beta</text>
456 <group>1</group>
457 </dragbox>
458 <dragbox>
459 <text>Gamma</text>
460 <group>1</group>
461 <infinite/>
462 </dragbox>
77e268e1 463 <hint format="moodle_auto_format">
a2bb148a
TH
464 <text>Try again.</text>
465 <shownumcorrect/>
466 </hint>
77e268e1 467 <hint format="moodle_auto_format">
a2bb148a
TH
468 <text>These are the first three letters of the Greek alphabet.</text>
469 <shownumcorrect/>
470 <clearwrong/>
471 </hint>
472 </question>
473';
474
475 $this->assert_same_xml($expectedxml, $xml);
476 }
477}