Differences Between: [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403]
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/>. 16 17 namespace qtype_ddwtos; 18 19 use question_answer; 20 use question_bank; 21 use question_hint_with_parts; 22 use question_possible_response; 23 24 defined('MOODLE_INTERNAL') || die(); 25 global $CFG; 26 27 require_once($CFG->dirroot . '/question/engine/tests/helpers.php'); 28 require_once($CFG->dirroot . '/question/type/ddwtos/tests/helper.php'); 29 30 31 /** 32 * Unit tests for the drag-and-drop words into sentences question definition class. 33 * 34 * @package qtype_ddwtos 35 * @copyright 2012 The Open University 36 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 37 */ 38 class question_type_test extends \question_testcase { 39 /** @var qtype_ddwtos instance of the question type class to test. */ 40 protected $qtype; 41 42 protected function setUp(): void { 43 $this->qtype = question_bank::get_qtype('ddwtos');; 44 } 45 46 protected function tearDown(): void { 47 $this->qtype = null; 48 } 49 50 public function assert_same_xml($expectedxml, $xml) { 51 $this->assertEquals(str_replace("\r\n", "\n", $expectedxml), 52 str_replace("\r\n", "\n", $xml)); 53 } 54 55 /** 56 * Get some test question data. 57 * 58 * @return object the data to construct a question like 59 * {@link qtype_ddwtos_test_helper::make_ddwtos_question_fox()}. 60 */ 61 protected function get_test_question_data() { 62 global $USER; 63 64 $dd = new \stdClass(); 65 $dd->id = 0; 66 $dd->category = 0; 67 $dd->contextid = 0; 68 $dd->parent = 0; 69 $dd->questiontextformat = FORMAT_HTML; 70 $dd->generalfeedbackformat = FORMAT_HTML; 71 $dd->defaultmark = 1; 72 $dd->penalty = 0.3333333; 73 $dd->length = 1; 74 $dd->stamp = make_unique_id_code(); 75 $dd->version = make_unique_id_code(); 76 $dd->hidden = 0; 77 $dd->idnumber = null; 78 $dd->timecreated = time(); 79 $dd->timemodified = time(); 80 $dd->createdby = $USER->id; 81 $dd->modifiedby = $USER->id; 82 83 $dd->name = 'Drag-and-drop words into sentences question'; 84 $dd->questiontext = 'The [[1]] brown [[2]] jumped over the [[3]] dog.'; 85 $dd->generalfeedback = 'This sentence uses each letter of the alphabet.'; 86 $dd->qtype = 'ddwtos'; 87 88 $dd->options = new \stdClass(); 89 $dd->options->shuffleanswers = true; 90 91 \test_question_maker::set_standard_combined_feedback_fields($dd->options); 92 93 $dd->options->answers = array( 94 (object) array('answer' => 'quick', 'feedback' => 95 'O:8:"stdClass":2:{s:9:"draggroup";s:1:"1";s:8:"infinite";i:0;}'), 96 (object) array('answer' => 'fox', 'feedback' => 97 'O:8:"stdClass":2:{s:9:"draggroup";s:1:"2";s:8:"infinite";i:0;}'), 98 (object) array('answer' => 'lazy', 'feedback' => 99 'O:8:"stdClass":2:{s:9:"draggroup";s:1:"3";s:8:"infinite";i:0;}'), 100 (object) array('answer' => 'assiduous', 'feedback' => 101 'O:8:"stdClass":2:{s:9:"draggroup";s:1:"3";s:8:"infinite";i:0;}'), 102 (object) array('answer' => 'dog', 'feedback' => 103 'O:8:"stdClass":2:{s:9:"draggroup";s:1:"2";s:8:"infinite";i:0;}'), 104 (object) array('answer' => 'slow', 'feedback' => 105 'O:8:"stdClass":2:{s:9:"draggroup";s:1:"1";s:8:"infinite";i:0;}'), 106 ); 107 108 return $dd; 109 } 110 111 public function test_name() { 112 $this->assertEquals($this->qtype->name(), 'ddwtos'); 113 } 114 115 public function test_can_analyse_responses() { 116 $this->assertTrue($this->qtype->can_analyse_responses()); 117 } 118 119 public function test_save_question() { 120 $this->resetAfterTest(); 121 122 $syscontext = \context_system::instance(); 123 /** @var core_question_generator $generator */ 124 $generator = $this->getDataGenerator()->get_plugin_generator('core_question'); 125 $category = $generator->create_question_category(['contextid' => $syscontext->id]); 126 127 $fromform = \test_question_maker::get_question_form_data('ddwtos', 'missingchoiceno'); 128 $fromform->category = $category->id . ',' . $syscontext->id; 129 130 $question = new \stdClass(); 131 $question->category = $category->id; 132 $question->qtype = 'ddwtos'; 133 $question->createdby = 0; 134 135 $this->qtype->save_question($question, $fromform); 136 $q = question_bank::load_question($question->id); 137 // We just want to verify that this does not cause errors, 138 // but also verify some of the outcome. 139 $this->assertEquals('The [[1]] sat on the [[2]].', $q->questiontext); 140 $this->assertEquals([1 => 1, 2 => 1], $q->places); 141 $this->assertEquals([1 => 1, 2 => 2], $q->rightchoices); 142 } 143 144 public function test_initialise_question_instance() { 145 $qdata = $this->get_test_question_data(); 146 147 $expected = \test_question_maker::make_question('ddwtos'); 148 $expected->stamp = $qdata->stamp; 149 $expected->version = $qdata->version; 150 $expected->idnumber = null; 151 152 $q = $this->qtype->make_question($qdata); 153 154 $this->assertEquals($expected, $q); 155 } 156 157 public function test_get_random_guess_score() { 158 $q = $this->get_test_question_data(); 159 $this->assertEqualsWithDelta(0.5, $this->qtype->get_random_guess_score($q), 0.0000001); 160 } 161 162 public function test_get_possible_responses() { 163 $q = $this->get_test_question_data(); 164 165 $this->assertEquals(array( 166 1 => array( 167 1 => new question_possible_response('quick', 1 / 3), 168 2 => new question_possible_response('slow', 0), 169 null => question_possible_response::no_response()), 170 2 => array( 171 1 => new question_possible_response('fox', 1 / 3), 172 2 => new question_possible_response('dog', 0), 173 null => question_possible_response::no_response()), 174 3 => array( 175 1 => new question_possible_response('lazy', 1 / 3), 176 2 => new question_possible_response('assiduous', 0), 177 null => question_possible_response::no_response()), 178 ), $this->qtype->get_possible_responses($q)); 179 } 180 181 public function test_xml_import() { 182 $xml = ' <question type="ddwtos"> 183 <name> 184 <text>A drag-and-drop question</text> 185 </name> 186 <questiontext format="moodle_auto_format"> 187 <text>Put these in order: [[1]], [[2]], [[3]].</text> 188 </questiontext> 189 <generalfeedback> 190 <text>The answer is Alpha, Beta, Gamma.</text> 191 </generalfeedback> 192 <defaultgrade>3</defaultgrade> 193 <penalty>0.3333333</penalty> 194 <hidden>0</hidden> 195 <shuffleanswers>1</shuffleanswers> 196 <correctfeedback> 197 <text><![CDATA[<p>Your answer is correct.</p>]]></text> 198 </correctfeedback> 199 <partiallycorrectfeedback> 200 <text><![CDATA[<p>Your answer is partially correct.</p>]]></text> 201 </partiallycorrectfeedback> 202 <incorrectfeedback> 203 <text><![CDATA[<p>Your answer is incorrect.</p>]]></text> 204 </incorrectfeedback> 205 <shownumcorrect/> 206 <dragbox> 207 <text>Alpha</text> 208 <group>1</group> 209 </dragbox> 210 <dragbox> 211 <text>Beta</text> 212 <group>1</group> 213 </dragbox> 214 <dragbox> 215 <text>Gamma</text> 216 <group>1</group> 217 <infinite/> 218 </dragbox> 219 <hint> 220 <text>Try again.</text> 221 <shownumcorrect /> 222 </hint> 223 <hint> 224 <text>These are the first three letters of the Greek alphabet.</text> 225 <shownumcorrect /> 226 <clearwrong /> 227 </hint> 228 </question>'; 229 $xmldata = xmlize($xml); 230 231 $importer = new \qformat_xml(); 232 $q = $importer->try_importing_using_qtypes( 233 $xmldata['question'], null, null, 'ddwtos'); 234 235 $expectedq = new \stdClass(); 236 $expectedq->qtype = 'ddwtos'; 237 $expectedq->name = 'A drag-and-drop question'; 238 $expectedq->questiontext = 'Put these in order: [[1]], [[2]], [[3]].'; 239 $expectedq->questiontextformat = FORMAT_MOODLE; 240 $expectedq->generalfeedback = 'The answer is Alpha, Beta, Gamma.'; 241 $expectedq->defaultmark = 3; 242 $expectedq->length = 1; 243 $expectedq->penalty = 0.3333333; 244 245 $expectedq->shuffleanswers = 1; 246 $expectedq->correctfeedback = array('text' => '<p>Your answer is correct.</p>', 247 'format' => FORMAT_MOODLE); 248 $expectedq->partiallycorrectfeedback = array( 249 'text' => '<p>Your answer is partially correct.</p>', 250 'format' => FORMAT_MOODLE); 251 $expectedq->shownumcorrect = true; 252 $expectedq->incorrectfeedback = array('text' => '<p>Your answer is incorrect.</p>', 253 'format' => FORMAT_MOODLE); 254 255 $expectedq->choices = array( 256 array('answer' => 'Alpha', 'choicegroup' => 1, 'infinite' => false), 257 array('answer' => 'Beta', 'choicegroup' => 1, 'infinite' => false), 258 array('answer' => 'Gamma', 'choicegroup' => 1, 'infinite' => true), 259 ); 260 261 $expectedq->hint = array( 262 array('text' => 'Try again.', 'format' => FORMAT_MOODLE), 263 array('text' => 'These are the first three letters of the Greek alphabet.', 264 'format' => FORMAT_MOODLE)); 265 $expectedq->hintshownumcorrect = array(true, true); 266 $expectedq->hintclearwrong = array(false, true); 267 268 $this->assert(new \question_check_specified_fields_expectation($expectedq), $q); 269 $this->assertEquals($expectedq->hint, $q->hint); 270 } 271 272 public function test_xml_export() { 273 $qdata = new \stdClass(); 274 $qdata->id = 123; 275 $qdata->contextid = \context_system::instance()->id; 276 $qdata->idnumber = null; 277 $qdata->qtype = 'ddwtos'; 278 $qdata->name = 'A drag-and-drop question'; 279 $qdata->questiontext = 'Put these in order: [[1]], [[2]], [[3]].'; 280 $qdata->questiontextformat = FORMAT_MOODLE; 281 $qdata->generalfeedback = 'The answer is Alpha, Beta, Gamma.'; 282 $qdata->generalfeedbackformat = FORMAT_MOODLE; 283 $qdata->defaultmark = 3; 284 $qdata->length = 1; 285 $qdata->penalty = 0.3333333; 286 $qdata->hidden = 0; 287 288 $qdata->options = new \stdClass(); 289 $qdata->options->shuffleanswers = 1; 290 $qdata->options->correctfeedback = '<p>Your answer is correct.</p>'; 291 $qdata->options->correctfeedbackformat = FORMAT_MOODLE; 292 $qdata->options->partiallycorrectfeedback = '<p>Your answer is partially correct.</p>'; 293 $qdata->options->partiallycorrectfeedbackformat = FORMAT_MOODLE; 294 $qdata->options->shownumcorrect = 1; 295 $qdata->options->incorrectfeedback = '<p>Your answer is incorrect.</p>'; 296 $qdata->options->incorrectfeedbackformat = FORMAT_MOODLE; 297 298 $qdata->options->answers = array( 299 13 => new question_answer(13, 'Alpha', 0, 300 'O:8:"stdClass":2:{s:9:"draggroup";s:1:"1";s:8:"infinite";b:0;}', 301 FORMAT_MOODLE), 302 14 => new question_answer(14, 'Beta', 0, 303 'O:8:"stdClass":2:{s:9:"draggroup";s:1:"1";s:8:"infinite";b:0;}', 304 FORMAT_MOODLE), 305 15 => new question_answer(15, 'Gamma', 0, 306 'O:8:"stdClass":2:{s:9:"draggroup";s:1:"1";s:8:"infinite";b:1;}', 307 FORMAT_MOODLE), 308 ); 309 310 $qdata->hints = array( 311 1 => new question_hint_with_parts(1, 'Try again.', FORMAT_MOODLE, true, false), 312 2 => new question_hint_with_parts(2, 313 'These are the first three letters of the Greek alphabet.', 314 FORMAT_MOODLE, true, true), 315 ); 316 317 $exporter = new \qformat_xml(); 318 $xml = $exporter->writequestion($qdata); 319 320 $expectedxml = '<!-- question: 123 --> 321 <question type="ddwtos"> 322 <name> 323 <text>A drag-and-drop question</text> 324 </name> 325 <questiontext format="moodle_auto_format"> 326 <text>Put these in order: [[1]], [[2]], [[3]].</text> 327 </questiontext> 328 <generalfeedback format="moodle_auto_format"> 329 <text>The answer is Alpha, Beta, Gamma.</text> 330 </generalfeedback> 331 <defaultgrade>3</defaultgrade> 332 <penalty>0.3333333</penalty> 333 <hidden>0</hidden> 334 <idnumber></idnumber> 335 <shuffleanswers>1</shuffleanswers> 336 <correctfeedback format="moodle_auto_format"> 337 <text><![CDATA[<p>Your answer is correct.</p>]]></text> 338 </correctfeedback> 339 <partiallycorrectfeedback format="moodle_auto_format"> 340 <text><![CDATA[<p>Your answer is partially correct.</p>]]></text> 341 </partiallycorrectfeedback> 342 <incorrectfeedback format="moodle_auto_format"> 343 <text><![CDATA[<p>Your answer is incorrect.</p>]]></text> 344 </incorrectfeedback> 345 <shownumcorrect/> 346 <dragbox> 347 <text>Alpha</text> 348 <group>1</group> 349 </dragbox> 350 <dragbox> 351 <text>Beta</text> 352 <group>1</group> 353 </dragbox> 354 <dragbox> 355 <text>Gamma</text> 356 <group>1</group> 357 <infinite/> 358 </dragbox> 359 <hint format="moodle_auto_format"> 360 <text>Try again.</text> 361 <shownumcorrect/> 362 </hint> 363 <hint format="moodle_auto_format"> 364 <text>These are the first three letters of the Greek alphabet.</text> 365 <shownumcorrect/> 366 <clearwrong/> 367 </hint> 368 </question> 369 '; 370 371 $this->assert_same_xml($expectedxml, $xml); 372 } 373 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body