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 namespace qtype_ddmarker; 18 19 use question_display_options; 20 use question_hint_ddmarker; 21 use question_pattern_expectation; 22 use question_state; 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/ddmarker/tests/helper.php'); 29 30 31 /** 32 * Unit tests for the drag-and-drop markers question type. 33 * 34 * @package qtype_ddmarker 35 * @copyright 2012 The Open University 36 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 37 * @covers \qtype_ddmarker_question 38 * @covers \qtype_ddmarker_renderer 39 * @covers \question_hint_ddmarker 40 */ 41 class walkthrough_test extends \qbehaviour_walkthrough_test_base { 42 43 /** 44 * Get an expectation that the output contains a marker. 45 * 46 * @param int $choice which choice. 47 * @param bool $infinite whether there are infinitely many of that choice. 48 * @return \question_contains_tag_with_attributes the expectation. 49 */ 50 protected function get_contains_draggable_marker_home_expectation($choice, $infinite) { 51 $class = 'marker choice'.$choice; 52 if ($infinite) { 53 $class .= ' infinite'; 54 } 55 56 $expectedattrs = array(); 57 $expectedattrs['class'] = $class; 58 59 return new \question_contains_tag_with_attributes('span', $expectedattrs); 60 } 61 62 /** 63 * Get an expectation that the output contains a hidden input with certain name and optionally value. 64 * 65 * Like the parent method, but make it more specific to this question type. 66 * 67 * @param string $choiceno hidden field name. 68 * @param string|null $value if passed, this value will also be asserted. 69 * @return \question_contains_tag_with_attributes the expectation. 70 */ 71 protected function get_contains_hidden_expectation($choiceno, $value = null) { 72 $name = $this->quba->get_field_prefix($this->slot) .'c'. $choiceno; 73 $expectedattributes = array('type' => 'hidden', 'name' => s($name)); 74 $expectedattributes['class'] = "choices choice{$choiceno}"; 75 if (!is_null($value)) { 76 $expectedattributes['value'] = s($value); 77 } 78 return new \question_contains_tag_with_attributes('input', $expectedattributes); 79 } 80 81 public function test_interactive_behaviour() { 82 83 // Create a drag-and-drop question. 84 $dd = \test_question_maker::make_question('ddmarker'); 85 $dd->hints = array( 86 new question_hint_ddmarker(13, 'This is the first hint.', 87 FORMAT_HTML, false, false, false), 88 new question_hint_ddmarker(14, 'This is the second hint.', 89 FORMAT_HTML, true, true, false), 90 ); 91 $dd->shufflechoices = false; 92 $this->start_attempt_at_question($dd, 'interactive', 12); 93 94 // Check the initial state. 95 $this->check_current_state(question_state::$todo); 96 $this->check_current_mark(null); 97 98 $this->check_current_output( 99 $this->get_contains_draggable_marker_home_expectation(1, false), 100 $this->get_contains_draggable_marker_home_expectation(2, false), 101 $this->get_contains_draggable_marker_home_expectation(3, false), 102 $this->get_contains_hidden_expectation(1), 103 $this->get_contains_hidden_expectation(2), 104 $this->get_contains_hidden_expectation(3), 105 $this->get_contains_submit_button_expectation(true), 106 $this->get_does_not_contain_feedback_expectation(), 107 $this->get_tries_remaining_expectation(3), 108 $this->get_no_hint_visible_expectation()); 109 110 $completelywrong = array('c1' => '0,250', 'c2' => '100,250', 'c3' => '150,250'); 111 // Save the wrong answer. 112 $this->process_submission($completelywrong); 113 // Verify. 114 $this->check_current_state(question_state::$todo); 115 $this->check_current_mark(null); 116 117 $this->check_current_output( 118 $this->get_contains_draggable_marker_home_expectation(1, false), 119 $this->get_contains_draggable_marker_home_expectation(2, false), 120 $this->get_contains_draggable_marker_home_expectation(3, false), 121 $this->get_contains_hidden_expectation(1, '0,250'), 122 $this->get_contains_hidden_expectation(2, '100,250'), 123 $this->get_contains_hidden_expectation(3, '150,250'), 124 $this->get_contains_submit_button_expectation(true), 125 $this->get_does_not_contain_feedback_expectation(), 126 $this->get_tries_remaining_expectation(3), 127 $this->get_no_hint_visible_expectation()); 128 // Submit the wrong answer. 129 $this->process_submission($completelywrong + array('-submit' => 1)); 130 131 // Verify. 132 $this->check_current_state(question_state::$todo); 133 $this->check_current_mark(null); 134 $this->check_current_output( 135 $this->get_contains_draggable_marker_home_expectation(1, false), 136 $this->get_contains_draggable_marker_home_expectation(2, false), 137 $this->get_contains_draggable_marker_home_expectation(3, false), 138 $this->get_contains_hidden_expectation(1, '0,250'), 139 $this->get_contains_hidden_expectation(2, '100,250'), 140 $this->get_contains_hidden_expectation(3, '150,250'), 141 $this->get_contains_try_again_button_expectation(true), 142 $this->get_contains_hint_expectation('This is the first hint')); 143 144 // Do try again. 145 $this->process_submission(array('-tryagain' => 1)); 146 147 // Verify. 148 $this->check_current_state(question_state::$todo); 149 $this->check_current_mark(null); 150 151 $this->check_current_output( 152 $this->get_contains_draggable_marker_home_expectation(1, false), 153 $this->get_contains_draggable_marker_home_expectation(2, false), 154 $this->get_contains_draggable_marker_home_expectation(3, false), 155 $this->get_contains_hidden_expectation(1, '0,250'), 156 $this->get_contains_hidden_expectation(2, '100,250'), 157 $this->get_contains_hidden_expectation(3, '150,250'), 158 $this->get_contains_submit_button_expectation(true), 159 $this->get_does_not_contain_correctness_expectation(), 160 $this->get_does_not_contain_feedback_expectation(), 161 $this->get_tries_remaining_expectation(2), 162 $this->get_no_hint_visible_expectation()); 163 164 // Submit the right answer. 165 $this->process_submission( 166 array('c1' => '50,50', 'c2' => '150,50', 'c3' => '100,150', '-submit' => 1)); 167 168 // Verify. 169 $this->check_current_state(question_state::$gradedright); 170 $this->check_current_mark(8); 171 $this->check_current_output( 172 $this->get_contains_draggable_marker_home_expectation(1, false), 173 $this->get_contains_draggable_marker_home_expectation(2, false), 174 $this->get_contains_draggable_marker_home_expectation(3, false), 175 $this->get_contains_hidden_expectation(1, '50,50'), 176 $this->get_contains_hidden_expectation(2, '150,50'), 177 $this->get_contains_hidden_expectation(3, '100,150'), 178 $this->get_does_not_contain_submit_button_expectation(), 179 $this->get_contains_correct_expectation(), 180 $this->get_no_hint_visible_expectation()); 181 182 // Check regrading does not mess anything up. 183 $this->quba->regrade_all_questions(); 184 185 // Verify. 186 $this->check_current_state(question_state::$gradedright); 187 $this->check_current_mark(8); 188 } 189 190 public function test_deferred_feedback() { 191 192 // Create a drag-and-drop question. 193 $dd = \test_question_maker::make_question('ddmarker'); 194 $dd->shufflechoices = false; 195 $this->start_attempt_at_question($dd, 'deferredfeedback', 12); 196 197 // Check the initial state. 198 $this->check_current_state(question_state::$todo); 199 $this->check_current_mark(null); 200 201 $this->check_current_output( 202 $this->get_contains_draggable_marker_home_expectation(1, false), 203 $this->get_contains_draggable_marker_home_expectation(2, false), 204 $this->get_contains_draggable_marker_home_expectation(3, false), 205 $this->get_contains_hidden_expectation(1), 206 $this->get_contains_hidden_expectation(2), 207 $this->get_contains_hidden_expectation(3), 208 $this->get_does_not_contain_feedback_expectation()); 209 210 // Save a partial answer. 211 $this->process_submission(array('c1' => '150,50', 'c2' => '50,50')); 212 // Verify. 213 $this->check_current_state(question_state::$complete); 214 $this->check_current_mark(null); 215 216 $this->check_current_output( 217 $this->get_contains_draggable_marker_home_expectation(1, false), 218 $this->get_contains_draggable_marker_home_expectation(2, false), 219 $this->get_contains_draggable_marker_home_expectation(3, false), 220 $this->get_contains_hidden_expectation(1, '150,50'), 221 $this->get_contains_hidden_expectation(2, '50,50'), 222 $this->get_contains_hidden_expectation(3, ''), 223 $this->get_does_not_contain_correctness_expectation(), 224 $this->get_does_not_contain_feedback_expectation()); 225 // Save the right answer. 226 $this->process_submission( 227 array('c1' => '50,50', 'c2' => '150,50', 'c3' => '100,150')); 228 229 // Verify. 230 $this->check_current_state(question_state::$complete); 231 $this->check_current_mark(null); 232 $this->check_current_output( 233 $this->get_contains_draggable_marker_home_expectation(1, false), 234 $this->get_contains_draggable_marker_home_expectation(2, false), 235 $this->get_contains_draggable_marker_home_expectation(3, false), 236 $this->get_contains_hidden_expectation(1, '50,50'), 237 $this->get_contains_hidden_expectation(2, '150,50'), 238 $this->get_contains_hidden_expectation(3, '100,150'), 239 $this->get_does_not_contain_correctness_expectation(), 240 $this->get_does_not_contain_feedback_expectation()); 241 242 // Finish the attempt. 243 $this->quba->finish_all_questions(); 244 245 // Verify. 246 $this->check_current_state(question_state::$gradedright); 247 $this->check_current_mark(12); 248 249 $this->check_current_output( 250 $this->get_contains_draggable_marker_home_expectation(1, false), 251 $this->get_contains_draggable_marker_home_expectation(2, false), 252 $this->get_contains_draggable_marker_home_expectation(3, false), 253 $this->get_contains_hidden_expectation(1, '50,50'), 254 $this->get_contains_hidden_expectation(2, '150,50'), 255 $this->get_contains_hidden_expectation(3, '100,150'), 256 $this->get_contains_correct_expectation()); 257 258 // Change the right answer a bit. 259 $dd->rightchoices[2] = 1; 260 261 // Check regrading does not mess anything up. 262 $this->quba->regrade_all_questions(); 263 264 // Verify. 265 $this->check_current_state(question_state::$gradedpartial); 266 $this->check_current_mark(8); 267 } 268 269 public function test_deferred_feedback_unanswered() { 270 271 // Create a drag-and-drop question. 272 $dd = \test_question_maker::make_question('ddmarker'); 273 $dd->shufflechoices = false; 274 $this->start_attempt_at_question($dd, 'deferredfeedback', 12); 275 276 // Check the initial state. 277 $this->check_current_state(question_state::$todo); 278 $this->check_current_mark(null); 279 $this->check_current_output( 280 $this->get_contains_draggable_marker_home_expectation(1, false), 281 $this->get_contains_draggable_marker_home_expectation(2, false), 282 $this->get_contains_draggable_marker_home_expectation(3, false), 283 $this->get_contains_hidden_expectation(1), 284 $this->get_contains_hidden_expectation(2), 285 $this->get_contains_hidden_expectation(3), 286 $this->get_does_not_contain_correctness_expectation(), 287 $this->get_does_not_contain_feedback_expectation()); 288 $this->check_step_count(1); 289 290 // Save a blank response. 291 $this->process_submission(array('c1' => '', 'c2' => '', 'c3' => '')); 292 293 // Verify. 294 $this->check_current_state(question_state::$todo); 295 $this->check_current_mark(null); 296 $this->check_current_output( 297 $this->get_contains_draggable_marker_home_expectation(1, false), 298 $this->get_contains_draggable_marker_home_expectation(2, false), 299 $this->get_contains_draggable_marker_home_expectation(3, false), 300 $this->get_contains_hidden_expectation(1, ''), 301 $this->get_contains_hidden_expectation(2, ''), 302 $this->get_contains_hidden_expectation(3, ''), 303 $this->get_does_not_contain_correctness_expectation(), 304 $this->get_does_not_contain_feedback_expectation()); 305 $this->check_step_count(1); 306 307 // Finish the attempt. 308 $this->quba->finish_all_questions(); 309 310 // Verify. 311 $this->check_current_state(question_state::$gaveup); 312 $this->check_current_mark(null); 313 $this->check_current_output( 314 $this->get_contains_draggable_marker_home_expectation(1, false), 315 $this->get_contains_draggable_marker_home_expectation(2, false), 316 $this->get_contains_draggable_marker_home_expectation(3, false)); 317 } 318 319 public function test_deferred_feedback_partial_answer() { 320 321 // Create a drag-and-drop question. 322 $dd = \test_question_maker::make_question('ddmarker'); 323 $dd->shufflechoices = false; 324 $this->start_attempt_at_question($dd, 'deferredfeedback', 3); 325 326 // Check the initial state. 327 $this->check_current_state(question_state::$todo); 328 $this->check_current_mark(null); 329 $this->check_current_output( 330 $this->get_contains_draggable_marker_home_expectation(1, false), 331 $this->get_contains_draggable_marker_home_expectation(2, false), 332 $this->get_contains_draggable_marker_home_expectation(3, false), 333 $this->get_contains_hidden_expectation(1), 334 $this->get_contains_hidden_expectation(2), 335 $this->get_contains_hidden_expectation(3), 336 $this->get_does_not_contain_correctness_expectation(), 337 $this->get_does_not_contain_feedback_expectation()); 338 339 $this->process_submission(array('c1' => '50,50', 'c2' => '150,50', 'c3' => '')); 340 341 // Verify. 342 $this->check_current_state(question_state::$complete); 343 $this->check_current_mark(null); 344 $this->check_current_output( 345 $this->get_contains_draggable_marker_home_expectation(1, false), 346 $this->get_contains_draggable_marker_home_expectation(2, false), 347 $this->get_contains_draggable_marker_home_expectation(3, false), 348 $this->get_contains_hidden_expectation(1, '50,50'), 349 $this->get_contains_hidden_expectation(2, '150,50'), 350 $this->get_contains_hidden_expectation(3, ''), 351 $this->get_does_not_contain_correctness_expectation(), 352 $this->get_does_not_contain_feedback_expectation()); 353 354 // Finish the attempt. 355 $this->quba->finish_all_questions(); 356 357 // Verify. 358 $this->check_current_state(question_state::$gradedpartial); 359 $this->check_current_mark(2); 360 $this->check_current_output( 361 $this->get_contains_draggable_marker_home_expectation(1, false), 362 $this->get_contains_draggable_marker_home_expectation(2, false), 363 $this->get_contains_draggable_marker_home_expectation(3, false), 364 $this->get_contains_partcorrect_expectation()); 365 } 366 367 public function test_interactive_grading() { 368 369 // Create a drag-and-drop question. 370 $dd = \test_question_maker::make_question('ddmarker'); 371 $dd->hints = array( 372 new question_hint_ddmarker(1, 'This is the first hint.', 373 FORMAT_MOODLE, true, true, false), 374 new question_hint_ddmarker(2, 'This is the second hint.', 375 FORMAT_MOODLE, true, true, false), 376 ); 377 $dd->shufflechoices = false; 378 $this->start_attempt_at_question($dd, 'interactive', 12); 379 380 // Check the initial state. 381 $this->check_current_state(question_state::$todo); 382 $this->check_current_mark(null); 383 $this->assertEquals('interactivecountback', 384 $this->quba->get_question_attempt($this->slot)->get_behaviour_name()); 385 $this->check_current_output( 386 $this->get_contains_draggable_marker_home_expectation(1, false), 387 $this->get_contains_draggable_marker_home_expectation(2, false), 388 $this->get_contains_draggable_marker_home_expectation(3, false), 389 $this->get_contains_hidden_expectation(1), 390 $this->get_contains_hidden_expectation(2), 391 $this->get_contains_hidden_expectation(3), 392 $this->get_contains_submit_button_expectation(true), 393 $this->get_does_not_contain_feedback_expectation(), 394 $this->get_tries_remaining_expectation(3), 395 $this->get_does_not_contain_num_parts_correct(), 396 $this->get_no_hint_visible_expectation()); 397 398 // Submit an response with the first two parts right. 399 $this->process_submission( 400 array('c1' => '50,50', 'c2' => '150,50', 'c3' => '150,50', '-submit' => 1)); 401 402 // Verify. 403 $this->check_current_state(question_state::$todo); 404 $this->check_current_mark(null); 405 $this->check_current_output( 406 $this->get_contains_draggable_marker_home_expectation(1, false), 407 $this->get_contains_draggable_marker_home_expectation(2, false), 408 $this->get_contains_draggable_marker_home_expectation(3, false), 409 $this->get_does_not_contain_submit_button_expectation(), 410 $this->get_contains_try_again_button_expectation(true), 411 $this->get_does_not_contain_correctness_expectation(), 412 $this->get_contains_hint_expectation('This is the first hint'), 413 $this->get_contains_num_parts_correct(2), 414 $this->get_contains_standard_partiallycorrect_combined_feedback_expectation(), 415 $this->get_contains_hidden_expectation(1, '50,50'), 416 $this->get_contains_hidden_expectation(2, '150,50'), 417 $this->get_contains_hidden_expectation(3, '150,50')); 418 419 // Check that extract responses will return the reset data. 420 $prefix = $this->quba->get_field_prefix($this->slot); 421 $this->assertEquals(array('c1' => '50,50', 'c2' => '150,50'), 422 $this->quba->extract_responses($this->slot, 423 array($prefix . 'c1' => '50,50', $prefix . 'c2' => '150,50', '-tryagain' => 1))); 424 425 // Do try again. 426 // keys c3 is an extra hidden fields to clear data. 427 $this->process_submission( 428 array('c1' => '50,50', 'c2' => '150,50', 'c3' => '', '-tryagain' => 1)); 429 430 // Verify. 431 $this->check_current_state(question_state::$todo); 432 $this->check_current_mark(null); 433 $this->check_current_output( 434 $this->get_contains_draggable_marker_home_expectation(1, false), 435 $this->get_contains_draggable_marker_home_expectation(2, false), 436 $this->get_contains_draggable_marker_home_expectation(3, false), 437 $this->get_contains_hidden_expectation(1, '50,50'), 438 $this->get_contains_hidden_expectation(2, '150,50'), 439 $this->get_contains_hidden_expectation(3, ''), 440 $this->get_contains_submit_button_expectation(true), 441 $this->get_does_not_contain_try_again_button_expectation(), 442 $this->get_does_not_contain_correctness_expectation(), 443 $this->get_does_not_contain_feedback_expectation(), 444 $this->get_tries_remaining_expectation(2), 445 $this->get_no_hint_visible_expectation()); 446 447 // Submit an response with the first and last parts right. 448 $this->process_submission( 449 array('c1' => '50,50', 'c2' => '150,150', 'c3' => '100,150', '-submit' => 1)); 450 451 // Verify. 452 $this->check_current_state(question_state::$todo); 453 $this->check_current_mark(null); 454 $this->check_current_output( 455 $this->get_contains_draggable_marker_home_expectation(1, false), 456 $this->get_contains_draggable_marker_home_expectation(2, false), 457 $this->get_contains_draggable_marker_home_expectation(3, false), 458 $this->get_does_not_contain_submit_button_expectation(), 459 $this->get_contains_try_again_button_expectation(true), 460 $this->get_does_not_contain_correctness_expectation(), 461 $this->get_contains_hint_expectation('This is the second hint'), 462 $this->get_contains_num_parts_correct(2), 463 $this->get_contains_standard_partiallycorrect_combined_feedback_expectation(), 464 $this->get_contains_hidden_expectation(1, '50,50'), 465 $this->get_contains_hidden_expectation(2, '150,150'), 466 $this->get_contains_hidden_expectation(3, '100,150')); 467 468 // Do try again. 469 $this->process_submission( 470 array('c1' => '50,50', 'c2' => '', 'c3' => '', '-tryagain' => 1)); 471 472 // Verify. 473 $this->check_current_state(question_state::$todo); 474 $this->check_current_mark(null); 475 $this->check_current_output( 476 $this->get_contains_draggable_marker_home_expectation(1, false), 477 $this->get_contains_draggable_marker_home_expectation(2, false), 478 $this->get_contains_draggable_marker_home_expectation(3, false), 479 $this->get_contains_hidden_expectation(1, '50,50'), 480 $this->get_contains_hidden_expectation(2, ''), 481 $this->get_contains_hidden_expectation(3, ''), 482 $this->get_contains_submit_button_expectation(true), 483 $this->get_does_not_contain_try_again_button_expectation(), 484 $this->get_does_not_contain_correctness_expectation(), 485 $this->get_does_not_contain_feedback_expectation(), 486 $this->get_tries_remaining_expectation(1), 487 $this->get_no_hint_visible_expectation()); 488 489 // Submit the right answer. 490 $this->process_submission( 491 array('c1' => '50,50', 'c2' => '150,50', 'c3' => '100,150', '-submit' => 1)); 492 493 // Verify. 494 $this->check_current_state(question_state::$gradedright); 495 $this->check_current_mark(8); 496 $this->check_current_output( 497 $this->get_contains_draggable_marker_home_expectation(1, false), 498 $this->get_contains_draggable_marker_home_expectation(2, false), 499 $this->get_contains_draggable_marker_home_expectation(3, false), 500 $this->get_contains_hidden_expectation(1, '50,50'), 501 $this->get_contains_hidden_expectation(2, '150,50'), 502 $this->get_contains_hidden_expectation(3, '100,150'), 503 $this->get_does_not_contain_submit_button_expectation(), 504 $this->get_does_not_contain_try_again_button_expectation(), 505 $this->get_contains_correct_expectation(), 506 $this->get_no_hint_visible_expectation(), 507 $this->get_does_not_contain_num_parts_correct(), 508 $this->get_contains_standard_correct_combined_feedback_expectation()); 509 } 510 511 public function test_interactive_correct_no_submit() { 512 513 // Create a drag-and-drop question. 514 $dd = \test_question_maker::make_question('ddmarker'); 515 $dd->hints = array( 516 new question_hint_ddmarker(23, 'This is the first hint.', 517 FORMAT_MOODLE, false, false, false), 518 new question_hint_ddmarker(24, 'This is the second hint.', 519 FORMAT_MOODLE, true, true, false), 520 ); 521 $dd->shufflechoices = false; 522 $this->start_attempt_at_question($dd, 'interactive', 3); 523 524 // Check the initial state. 525 $this->check_current_state(question_state::$todo); 526 $this->check_current_mark(null); 527 $this->check_current_output( 528 $this->get_contains_draggable_marker_home_expectation(1, false), 529 $this->get_contains_draggable_marker_home_expectation(2, false), 530 $this->get_contains_draggable_marker_home_expectation(3, false), 531 $this->get_contains_hidden_expectation(1), 532 $this->get_contains_hidden_expectation(2), 533 $this->get_contains_hidden_expectation(3), 534 $this->get_contains_submit_button_expectation(true), 535 $this->get_does_not_contain_feedback_expectation(), 536 $this->get_tries_remaining_expectation(3), 537 $this->get_no_hint_visible_expectation()); 538 539 // Save the right answer. 540 $this->process_submission(array('c1' => '50,50', 'c2' => '150,50', 'c3' => '100,150')); 541 542 // Finish the attempt without clicking check. 543 $this->quba->finish_all_questions(); 544 545 // Verify. 546 $this->check_current_state(question_state::$gradedright); 547 $this->check_current_mark(3); 548 $this->check_current_output( 549 $this->get_contains_draggable_marker_home_expectation(1, false), 550 $this->get_contains_draggable_marker_home_expectation(2, false), 551 $this->get_contains_draggable_marker_home_expectation(3, false), 552 $this->get_does_not_contain_submit_button_expectation(), 553 $this->get_contains_correct_expectation(), 554 $this->get_no_hint_visible_expectation()); 555 556 // Check regrading does not mess anything up. 557 $this->quba->regrade_all_questions(); 558 559 // Verify. 560 $this->check_current_state(question_state::$gradedright); 561 $this->check_current_mark(3); 562 } 563 564 public function test_interactive_partial_no_submit() { 565 566 // Create a drag-and-drop question. 567 $dd = \test_question_maker::make_question('ddmarker'); 568 $dd->hints = array( 569 new question_hint_ddmarker(23, 'This is the first hint.', 570 FORMAT_MOODLE, false, false, false), 571 new question_hint_ddmarker(24, 'This is the second hint.', 572 FORMAT_MOODLE, true, true, false), 573 ); 574 $dd->shufflechoices = false; 575 $this->start_attempt_at_question($dd, 'interactive', 3); 576 577 // Check the initial state. 578 $this->check_current_state(question_state::$todo); 579 $this->check_current_mark(null); 580 581 $this->check_current_output( 582 $this->get_contains_draggable_marker_home_expectation(1, false), 583 $this->get_contains_draggable_marker_home_expectation(2, false), 584 $this->get_contains_draggable_marker_home_expectation(3, false), 585 $this->get_contains_hidden_expectation(1), 586 $this->get_contains_hidden_expectation(2), 587 $this->get_contains_hidden_expectation(3), 588 $this->get_contains_submit_button_expectation(true), 589 $this->get_does_not_contain_feedback_expectation(), 590 $this->get_tries_remaining_expectation(3), 591 $this->get_no_hint_visible_expectation()); 592 593 // Save the a partially right answer. 594 $this->process_submission(array('c1' => '50,50', 'c2' => '50,50', 'c3' => '100,150')); 595 596 // Finish the attempt without clicking check. 597 $this->quba->finish_all_questions(); 598 599 // Verify. 600 $this->check_current_state(question_state::$gradedpartial); 601 $this->check_current_mark(2); 602 603 $this->check_current_output( 604 $this->get_contains_draggable_marker_home_expectation(1, false), 605 $this->get_contains_draggable_marker_home_expectation(2, false), 606 $this->get_contains_draggable_marker_home_expectation(3, false), 607 $this->get_does_not_contain_submit_button_expectation(), 608 $this->get_contains_partcorrect_expectation(), 609 $this->get_no_hint_visible_expectation()); 610 611 // Check regrading does not mess anything up. 612 $this->quba->regrade_all_questions(); 613 614 // Verify. 615 $this->check_current_state(question_state::$gradedpartial); 616 $this->check_current_mark(2); 617 } 618 619 public function test_interactive_no_right_clears() { 620 621 // Create a drag-and-drop question. 622 $dd = \test_question_maker::make_question('ddmarker'); 623 $dd->hints = array( 624 new question_hint_ddmarker(23, 'This is the first hint.', 625 FORMAT_MOODLE, false, true, false), 626 new question_hint_ddmarker(24, 'This is the second hint.', 627 FORMAT_MOODLE, true, true, false), 628 ); 629 $dd->shufflechoices = false; 630 $this->start_attempt_at_question($dd, 'interactive', 3); 631 632 // Check the initial state. 633 $this->check_current_state(question_state::$todo); 634 $this->check_current_mark(null); 635 636 $this->check_current_output( 637 $this->get_contains_marked_out_of_summary(), 638 $this->get_contains_draggable_marker_home_expectation(1, false), 639 $this->get_contains_draggable_marker_home_expectation(2, false), 640 $this->get_contains_draggable_marker_home_expectation(3, false), 641 $this->get_contains_hidden_expectation(1), 642 $this->get_contains_hidden_expectation(2), 643 $this->get_contains_hidden_expectation(3), 644 $this->get_contains_submit_button_expectation(true), 645 $this->get_does_not_contain_feedback_expectation(), 646 $this->get_tries_remaining_expectation(3), 647 $this->get_no_hint_visible_expectation()); 648 649 // Save the a completely wrong answer. 650 $this->process_submission( 651 array('c1' => '100,150', 'c2' => '100,150', 'c3' => '50,50', '-submit' => 1)); 652 653 // Verify. 654 $this->check_current_state(question_state::$todo); 655 $this->check_current_mark(null); 656 $this->check_current_output( 657 $this->get_contains_marked_out_of_summary(), 658 $this->get_contains_draggable_marker_home_expectation(1, false), 659 $this->get_contains_draggable_marker_home_expectation(2, false), 660 $this->get_contains_draggable_marker_home_expectation(3, false), 661 $this->get_does_not_contain_submit_button_expectation(), 662 $this->get_contains_hint_expectation('This is the first hint')); 663 664 // Do try again. 665 $this->process_submission( 666 array('c1' => '', 'c2' => '', 'c3' => '', '-tryagain' => 1)); 667 668 // Check that all the wrong answers have been cleared. 669 $this->check_current_state(question_state::$todo); 670 $this->check_current_mark(null); 671 $this->check_current_output( 672 $this->get_contains_marked_out_of_summary(), 673 $this->get_contains_draggable_marker_home_expectation(1, false), 674 $this->get_contains_draggable_marker_home_expectation(2, false), 675 $this->get_contains_draggable_marker_home_expectation(3, false), 676 $this->get_contains_hidden_expectation(1, ''), 677 $this->get_contains_hidden_expectation(2, ''), 678 $this->get_contains_hidden_expectation(3, ''), 679 $this->get_contains_submit_button_expectation(true), 680 $this->get_does_not_contain_feedback_expectation(), 681 $this->get_tries_remaining_expectation(2), 682 $this->get_no_hint_visible_expectation()); 683 } 684 685 public function test_display_of_right_answer_when_shuffled() { 686 687 // Create a drag-and-drop question. 688 $dd = \test_question_maker::make_question('ddmarker'); 689 $this->start_attempt_at_question($dd, 'deferredfeedback', 3); 690 691 // Check the initial state. 692 $this->check_current_state(question_state::$todo); 693 $this->check_current_mark(null); 694 695 $this->check_current_output( 696 $this->get_contains_hidden_expectation(1), 697 $this->get_contains_hidden_expectation(2), 698 $this->get_contains_hidden_expectation(3), 699 $this->get_does_not_contain_feedback_expectation()); 700 701 // Save a partial answer. 702 $this->process_submission($dd->get_correct_response()); 703 704 // Verify. 705 $this->check_current_state(question_state::$complete); 706 $this->check_current_mark(null); 707 $rightanswer = array($dd->get_right_choice_for(1) => '50,50', 708 $dd->get_right_choice_for(2) => '150,50', 709 $dd->get_right_choice_for(3) => '100,150'); 710 $this->check_current_output( 711 $this->get_contains_hidden_expectation(1, $rightanswer[1]), 712 $this->get_contains_hidden_expectation(2, $rightanswer[2]), 713 $this->get_contains_hidden_expectation(3, $rightanswer[3]), 714 $this->get_does_not_contain_correctness_expectation(), 715 $this->get_does_not_contain_feedback_expectation()); 716 717 // Finish the attempt. 718 $this->quba->finish_all_questions(); 719 720 // Verify. 721 $this->displayoptions->rightanswer = question_display_options::VISIBLE; 722 $this->assertEquals('{Drop zone 1 -> quick}, '. 723 '{Drop zone 2 -> fox}, '. 724 '{Drop zone 3 -> lazy}', 725 $dd->get_right_answer_summary()); 726 $this->check_current_state(question_state::$gradedright); 727 $this->check_current_mark(3); 728 } 729 730 public function test_interactive_state_which_incorrect() { 731 732 // Create a drag-and-drop question. 733 $dd = \test_question_maker::make_question('ddmarker'); 734 $dd->hints = [ 735 new question_hint_ddmarker(23, 'This is the first hint.', 736 FORMAT_MOODLE, false, true, true), 737 ]; 738 $dd->shufflechoices = false; 739 $this->start_attempt_at_question($dd, 'interactive', 2); 740 741 // Check the initial state. 742 $this->check_current_state(question_state::$todo); 743 $this->check_current_mark(null); 744 745 $this->check_current_output( 746 $this->get_contains_marked_out_of_summary(), 747 $this->get_contains_draggable_marker_home_expectation(1, false), 748 $this->get_contains_draggable_marker_home_expectation(2, false), 749 $this->get_contains_draggable_marker_home_expectation(3, false), 750 $this->get_contains_hidden_expectation(1), 751 $this->get_contains_hidden_expectation(2), 752 $this->get_contains_hidden_expectation(3), 753 $this->get_contains_submit_button_expectation(true), 754 $this->get_does_not_contain_feedback_expectation(), 755 $this->get_tries_remaining_expectation(2), 756 $this->get_no_hint_visible_expectation()); 757 758 // Save the a completely wrong answer. 759 $this->process_submission( 760 ['c1' => '100,150', 'c2' => '100,150', 'c3' => '50,50', '-submit' => 1]); 761 762 // Verify. 763 $this->check_current_state(question_state::$todo); 764 $this->check_current_mark(null); 765 $this->check_current_output( 766 $this->get_contains_marked_out_of_summary(), 767 $this->get_contains_draggable_marker_home_expectation(1, false), 768 $this->get_contains_draggable_marker_home_expectation(2, false), 769 $this->get_contains_draggable_marker_home_expectation(3, false), 770 $this->get_does_not_contain_submit_button_expectation(), 771 new question_pattern_expectation('~' . preg_quote( 772 '<div class="wrongparts">Markers placed in the wrong area: ' . 773 '<span class="wrongpart">quick</span>, <span class="wrongpart">fox</span>, ' . 774 '<span class="wrongpart">lazy</span>', 775 '~') . '~'), 776 $this->get_contains_hint_expectation('This is the first hint')); 777 } 778 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body