Differences Between: [Versions 310 and 402] [Versions 311 and 402] [Versions 39 and 402] [Versions 400 and 402] [Versions 401 and 402]
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 /** 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 */ 24 25 26 defined('MOODLE_INTERNAL') || die(); 27 28 global $CFG; 29 require_once($CFG->dirroot . '/question/type/multianswer/question.php'); 30 31 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', 'multiple', 'zeroweight'); 41 } 42 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'); 57 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'); 64 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->defaultmark = 1; 82 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; 93 94 $mc->shuffleanswers = 0; 95 $mc->answernumbering = 'none'; 96 $mc->layout = qtype_multichoice_base::LAYOUT_DROPDOWN; 97 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->defaultmark = 1; 108 109 $q->subquestions = array( 110 1 => $sa, 111 2 => $mc, 112 ); 113 114 return $q; 115 } 116 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); 125 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'; 131 132 $qdata->defaultmark = 2.0; 133 $qdata->qtype = 'multianswer'; 134 $qdata->status = \core_question\local\bank\question_version_status::QUESTION_STATUS_READY; 135 136 $sa = new stdClass(); 137 test_question_maker::initialise_question_data($sa); 138 139 $sa->name = 'Simple multianswer'; 140 $sa->questiontext = '{1:SHORTANSWER:Dog#Wrong, silly!~=Owl#Well done!~*#Wrong answer}'; 141 $sa->generalfeedback = ''; 142 $sa->penalty = 0.0; 143 $sa->qtype = 'shortanswer'; 144 $sa->status = \core_question\local\bank\question_version_status::QUESTION_STATUS_READY; 145 146 $sa->options = new stdClass(); 147 $sa->options->usecase = 0; 148 149 $sa->options->answers = array( 150 13 => new question_answer(13, 'Dog', 0, 'Wrong, silly!', FORMAT_HTML), 151 14 => new question_answer(14, 'Owl', 1, 'Well done!', FORMAT_HTML), 152 15 => new question_answer(15, '*', 0, 'Wrong answer', FORMAT_HTML), 153 ); 154 155 $mc = new stdClass(); 156 test_question_maker::initialise_question_data($mc); 157 158 $mc->name = 'Simple multianswer'; 159 $mc->questiontext = '{1:MULTICHOICE:Bow-wow#You seem to have a dog obsessions!~' . 160 'Wiggly worm#Now you are just being ridiculous!~=Pussy-cat#Well done!}'; 161 $mc->generalfeedback = ''; 162 $mc->penalty = 0.0; 163 $mc->qtype = 'multichoice'; 164 $mc->status = \core_question\local\bank\question_version_status::QUESTION_STATUS_READY; 165 166 $mc->options = new stdClass(); 167 $mc->options->layout = 0; 168 $mc->options->single = 1; 169 $mc->options->shuffleanswers = 0; 170 $mc->options->correctfeedback = ''; 171 $mc->options->correctfeedbackformat = 1; 172 $mc->options->partiallycorrectfeedback = ''; 173 $mc->options->partiallycorrectfeedbackformat = 1; 174 $mc->options->incorrectfeedback = ''; 175 $mc->options->incorrectfeedbackformat = 1; 176 $mc->options->answernumbering = 0; 177 $mc->options->shownumcorrect = 0; 178 179 $mc->options->answers = array( 180 23 => new question_answer(23, 'Bow-wow', 0, 181 'You seem to have a dog obsessions!', FORMAT_HTML), 182 24 => new question_answer(24, 'Wiggly worm', 0, 183 'Now you are just being ridiculous!', FORMAT_HTML), 184 25 => new question_answer(25, 'Pussy-cat', 1, 185 'Well done!', FORMAT_HTML), 186 ); 187 188 $qdata->options = new stdClass(); 189 $qdata->options->questions = array( 190 1 => $sa, 191 2 => $mc, 192 ); 193 194 $qdata->hints = array( 195 new question_hint_with_parts(0, 'Hint 1', FORMAT_HTML, 0, 0), 196 new question_hint_with_parts(0, 'Hint 2', FORMAT_HTML, 0, 0), 197 ); 198 199 return $qdata; 200 } 201 202 /** 203 * Makes a multianswer question onetaining one blank in some text. 204 * This question has no hints. 205 * 206 * @return object the question definition data, as it might be returned from 207 * get_question_options. 208 */ 209 public function get_multianswer_question_data_dollarsigns() { 210 $qdata = new stdClass(); 211 test_question_maker::initialise_question_data($qdata); 212 213 $qdata->name = 'Multianswer with $s'; 214 $qdata->questiontext = 215 'Which is the right order? {#1}'; 216 $qdata->generalfeedback = ''; 217 218 $qdata->defaultmark = 1.0; 219 $qdata->qtype = 'multianswer'; 220 $qdata->status = \core_question\local\bank\question_version_status::QUESTION_STATUS_READY; 221 222 $mc = new stdClass(); 223 test_question_maker::initialise_question_data($mc); 224 225 $mc->name = 'Multianswer with $s'; 226 $mc->questiontext = '{1:MULTICHOICE:=y,y,$3~$3,y,y}'; 227 $mc->generalfeedback = ''; 228 $mc->penalty = 0.0; 229 $mc->qtype = 'multichoice'; 230 $mc->status = \core_question\local\bank\question_version_status::QUESTION_STATUS_READY; 231 232 $mc->options = new stdClass(); 233 $mc->options->layout = 0; 234 $mc->options->single = 1; 235 $mc->options->shuffleanswers = 0; 236 $mc->options->correctfeedback = ''; 237 $mc->options->correctfeedbackformat = 1; 238 $mc->options->partiallycorrectfeedback = ''; 239 $mc->options->partiallycorrectfeedbackformat = 1; 240 $mc->options->incorrectfeedback = ''; 241 $mc->options->incorrectfeedbackformat = 1; 242 $mc->options->answernumbering = 0; 243 $mc->options->shownumcorrect = 0; 244 245 $mc->options->answers = array( 246 23 => new question_answer(23, 'y,y,$3', 0, '', FORMAT_HTML), 247 24 => new question_answer(24, '$3,y,y', 0, '', FORMAT_HTML), 248 ); 249 250 $qdata->options = new stdClass(); 251 $qdata->options->questions = array( 252 1 => $mc, 253 ); 254 255 $qdata->hints = array( 256 ); 257 258 return $qdata; 259 } 260 261 /** 262 * Makes a multianswer question about completing two blanks in some text. 263 * @return object the question definition data, as it might be returned from 264 * the question editing form. 265 */ 266 public function get_multianswer_question_form_data_twosubq() { 267 $formdata = new stdClass(); 268 $formdata->name = 'Simple multianswer'; 269 $formdata->questiontext = array('text' => 'Complete this opening line of verse: "The ' . 270 '{1:SHORTANSWER:Dog#Wrong, silly!~=Owl#Well done!~*#Wrong answer} ' . 271 'and the {1:MULTICHOICE:Bow-wow#You seem to have a dog obsessions!' . 272 '~Wiggly worm#Now you are just being ridiculous!~=Pussy-cat#Well done!}' . 273 ' went to sea".', 'format' => FORMAT_HTML); 274 $formdata->generalfeedback = array('text' => 'General feedback: It\'s from "The Owl and the Pussy-cat" ' . 275 'by Lear: "The owl and the pussycat went to sea', 'format' => FORMAT_HTML); 276 277 $formdata->hint = array( 278 0 => array('text' => 'Hint 1', 'format' => FORMAT_HTML, 'itemid' => 0), 279 1 => array('text' => 'Hint 2', 'format' => FORMAT_HTML, 'itemid' => 0), 280 ); 281 282 $formdata->status = \core_question\local\bank\question_version_status::QUESTION_STATUS_READY; 283 284 return $formdata; 285 } 286 287 /** 288 * Makes a multianswer question about completing two blanks in some text. 289 * @return qtype_multianswer_question 290 */ 291 public function make_multianswer_question_fourmc() { 292 question_bank::load_question_definition_classes('multianswer'); 293 $q = new qtype_multianswer_question(); 294 test_question_maker::initialise_a_question($q); 295 $q->name = 'Multianswer four multi-choice'; 296 $q->questiontext = '<p>Match the following cities with the correct state:</p> 297 <ul> 298 <li>San Francisco: {#1}</li> 299 <li>Tucson: {#2}</li> 300 <li>Los Angeles: {#3}</li> 301 <li>Phoenix: {#4}</li> 302 </ul>'; 303 $q->questiontextformat = FORMAT_HTML; 304 $q->generalfeedback = ''; 305 $q->qtype = question_bank::get_qtype('multianswer'); 306 307 $q->textfragments = array('<p>Match the following cities with the correct state:</p> 308 <ul> 309 <li>San Francisco: ', '</li> 310 <li>Tucson: ', '</li> 311 <li>Los Angeles: ', '</li> 312 <li>Phoenix: ', '</li> 313 </ul>'); 314 $q->places = array('1' => '1', '2' => '2', '3' => '3', '4' => '4'); 315 316 $subqdata = array( 317 1 => array('qt' => '{1:MULTICHOICE:=California#OK~Arizona#Wrong}', 'California' => 'OK', 'Arizona' => 'Wrong'), 318 2 => array('qt' => '{1:MULTICHOICE:%0%California#Wrong~=Arizona#OK}', 'California' => 'Wrong', 'Arizona' => 'OK'), 319 3 => array('qt' => '{1:MULTICHOICE:=California#OK~Arizona#Wrong}', 'California' => 'OK', 'Arizona' => 'Wrong'), 320 4 => array('qt' => '{1:MULTICHOICE:%0%California#Wrong~=Arizona#OK}', 'California' => 'Wrong', 'Arizona' => 'OK'), 321 ); 322 foreach ($subqdata as $i => $data) { 323 // Multiple-choice subquestion. 324 question_bank::load_question_definition_classes('multichoice'); 325 $mc = new qtype_multichoice_single_question(); 326 test_question_maker::initialise_a_question($mc); 327 $mc->name = 'Multianswer four multi-choice'; 328 $mc->questiontext = $data['qt']; 329 $mc->questiontextformat = FORMAT_HTML; 330 $mc->generalfeedback = ''; 331 $mc->generalfeedbackformat = FORMAT_HTML; 332 333 $mc->shuffleanswers = 0; // TODO this is a cheat to make the unit tests easier to write. 334 // In reality, multianswer questions always shuffle. 335 $mc->answernumbering = 'none'; 336 $mc->layout = qtype_multichoice_base::LAYOUT_DROPDOWN; 337 338 $mc->answers = array( 339 10 * $i => new question_answer(13, 'California', (float) ($data['California'] == 'OK'), 340 $data['California'], FORMAT_HTML), 341 10 * $i + 1 => new question_answer(14, 'Arizona', (float) ($data['Arizona'] == 'OK'), 342 $data['Arizona'], FORMAT_HTML), 343 ); 344 $mc->qtype = question_bank::get_qtype('multichoice'); 345 $mc->defaultmark = 1; 346 347 $q->subquestions[$i] = $mc; 348 } 349 350 return $q; 351 } 352 353 /** 354 * Makes a multianswer question with one numerical subquestion, right answer 0. 355 * This is used for testing the MDL-35370 bug. 356 * @return qtype_multianswer_question 357 */ 358 public function make_multianswer_question_numericalzero() { 359 question_bank::load_question_definition_classes('multianswer'); 360 $q = new qtype_multianswer_question(); 361 test_question_maker::initialise_a_question($q); 362 $q->name = 'Numerical zero'; 363 $q->questiontext = 364 'Enter zero: {#1}.'; 365 $q->generalfeedback = ''; 366 $q->qtype = question_bank::get_qtype('multianswer'); 367 368 $q->textfragments = array( 369 'Enter zero: ', 370 '.', 371 ); 372 $q->places = array('1' => '1'); 373 374 // Numerical subquestion. 375 question_bank::load_question_definition_classes('numerical'); 376 $sub = new qtype_numerical_question(); 377 test_question_maker::initialise_a_question($sub); 378 $sub->name = 'Numerical zero'; 379 $sub->questiontext = '{1:NUMERICAL:=0:0}'; 380 $sub->questiontextformat = FORMAT_HTML; 381 $sub->generalfeedback = ''; 382 $sub->generalfeedbackformat = FORMAT_HTML; 383 $sub->answers = array( 384 13 => new qtype_numerical_answer(13, '0', 1.0, '', FORMAT_HTML, 0), 385 ); 386 $sub->qtype = question_bank::get_qtype('numerical'); 387 $sub->ap = new qtype_numerical_answer_processor(array()); 388 $sub->defaultmark = 1; 389 390 $q->subquestions = array( 391 1 => $sub, 392 ); 393 394 return $q; 395 } 396 397 /** 398 * Makes a multianswer question with multichoice_multiple questions in it. 399 * @return qtype_multianswer_question 400 */ 401 public function make_multianswer_question_multiple() { 402 question_bank::load_question_definition_classes('multianswer'); 403 $q = new qtype_multianswer_question(); 404 test_question_maker::initialise_a_question($q); 405 $q->name = 'Multichoice multiple'; 406 $q->questiontext = 'Please select the fruits {#1} and vegetables {#2}'; 407 $q->generalfeedback = 'You should know which foods are fruits or vegetables.'; 408 $q->qtype = question_bank::get_qtype('multianswer'); 409 410 $q->textfragments = array( 411 'Please select the fruits ', 412 ' and vegetables ', 413 '' 414 ); 415 $q->places = array('1' => '1', '2' => '2'); 416 417 // Multiple-choice subquestion. 418 question_bank::load_question_definition_classes('multichoice'); 419 $mc = new qtype_multichoice_multi_question(); 420 test_question_maker::initialise_a_question($mc); 421 $mc->name = 'Multianswer 1'; 422 $mc->questiontext = '{1:MULTIRESPONSE:=Apple#Good~%-50%Burger~%-50%Hot dog#Not a fruit~%-50%Pizza' . 423 '~=Orange#Correct~=Banana}'; 424 $mc->questiontextformat = FORMAT_HTML; 425 $mc->generalfeedback = ''; 426 $mc->generalfeedbackformat = FORMAT_HTML; 427 428 $mc->shuffleanswers = 0; 429 $mc->answernumbering = 'none'; 430 $mc->layout = qtype_multichoice_base::LAYOUT_VERTICAL; 431 432 $mc->answers = array( 433 16 => new question_answer(16, 'Apple', 0.3333333, 434 'Good', FORMAT_HTML), 435 17 => new question_answer(17, 'Burger', -0.5, 436 '', FORMAT_HTML), 437 18 => new question_answer(18, 'Hot dog', -0.5, 438 'Not a fruit', FORMAT_HTML), 439 19 => new question_answer(19, 'Pizza', -0.5, 440 '', FORMAT_HTML), 441 20 => new question_answer(20, 'Orange', 0.3333333, 442 'Correct', FORMAT_HTML), 443 21 => new question_answer(21, 'Banana', 0.3333333, 444 '', FORMAT_HTML), 445 ); 446 $mc->qtype = question_bank::get_qtype('multichoice'); 447 $mc->defaultmark = 1; 448 449 // Multiple-choice subquestion. 450 question_bank::load_question_definition_classes('multichoice'); 451 $mc2 = new qtype_multichoice_multi_question(); 452 test_question_maker::initialise_a_question($mc2); 453 $mc2->name = 'Multichoice 2'; 454 $mc2->questiontext = '{1:MULTIRESPONSE:=Raddish#Good~%-50%Chocolate~%-50%Biscuit#Not a vegetable~%-50%Cheese' . 455 '~=Carrot#Correct}'; 456 $mc2->questiontextformat = FORMAT_HTML; 457 $mc2->generalfeedback = ''; 458 $mc2->generalfeedbackformat = FORMAT_HTML; 459 460 $mc2->shuffleanswers = 0; 461 $mc2->answernumbering = 'none'; 462 $mc2->layout = qtype_multichoice_base::LAYOUT_VERTICAL; 463 464 $mc2->answers = array( 465 22 => new question_answer(22, 'Raddish', 0.5, 466 'Good', FORMAT_HTML), 467 23 => new question_answer(23, 'Chocolate', -0.5, 468 '', FORMAT_HTML), 469 24 => new question_answer(24, 'Biscuit', -0.5, 470 'Not a vegetable', FORMAT_HTML), 471 25 => new question_answer(25, 'Cheese', -0.5, 472 '', FORMAT_HTML), 473 26 => new question_answer(26, 'Carrot', 0.5, 474 'Correct', FORMAT_HTML), 475 ); 476 $mc2->qtype = question_bank::get_qtype('multichoice'); 477 $mc2->defaultmark = 1; 478 479 $q->subquestions = array( 480 1 => $mc, 481 2 => $mc2, 482 ); 483 484 return $q; 485 } 486 487 /** 488 * Makes a multianswer question with zero weight. 489 * This is used for testing the MDL-77378 bug. 490 * @return qtype_multianswer_question 491 */ 492 public function make_multianswer_question_zeroweight() { 493 question_bank::load_question_definition_classes('multianswer'); 494 $q = new qtype_multianswer_question(); 495 test_question_maker::initialise_a_question($q); 496 $q->name = 'Zero weight'; 497 $q->questiontext = 498 'Optional question: {#1}.'; 499 $q->generalfeedback = ''; 500 $q->qtype = question_bank::get_qtype('multianswer'); 501 $q->textfragments = array( 502 'Optional question: ', 503 '.', 504 ); 505 $q->places = array('1' => '1'); 506 507 // Shortanswer subquestion. 508 question_bank::load_question_definition_classes('shortanswer'); 509 $sa = new qtype_shortanswer_question(); 510 test_question_maker::initialise_a_question($sa); 511 $sa->name = 'Zero weight'; 512 $sa->questiontext = '{0:SHORTANSWER:~%0%Input box~%100%*}'; 513 $sa->questiontextformat = FORMAT_HTML; 514 $sa->generalfeedback = ''; 515 $sa->generalfeedbackformat = FORMAT_HTML; 516 $sa->usecase = true; 517 $sa->answers = array( 518 13 => new question_answer(13, 'Input box', 0.0, '', FORMAT_HTML), 519 14 => new question_answer(14, '*', 1.0, '', FORMAT_HTML), 520 ); 521 $sa->qtype = question_bank::get_qtype('shortanswer'); 522 $sa->defaultmark = 0; 523 524 $q->subquestions = array( 525 1 => $sa, 526 ); 527 528 return $q; 529 } 530 531 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body