[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
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 * This file contains overall tests of multianswer questions. 19 * 20 * @package qtype 21 * @subpackage multianswer 22 * @copyright 2011 The Open University 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 global $CFG; 30 require_once($CFG->dirroot . '/question/engine/tests/helpers.php'); 31 32 33 /** 34 * Unit tests for the multianswer question type. 35 * 36 * @copyright 2011 The Open University 37 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 38 */ 39 class qtype_multianswer_walkthrough_test extends qbehaviour_walkthrough_test_base { 40 41 protected function get_contains_subq_status(question_state $state) { 42 return new question_pattern_expectation('~' . 43 preg_quote($state->default_string(true), '~') . '<br />~'); 44 } 45 46 public function test_deferred_feedback() { 47 48 // Create a multianswer question. 49 $q = test_question_maker::make_question('multianswer', 'fourmc'); 50 $this->start_attempt_at_question($q, 'deferredfeedback', 4); 51 52 // Check the initial state. 53 $this->check_current_state(question_state::$todo); 54 $this->check_current_mark(null); 55 $this->check_current_output( 56 $this->get_contains_marked_out_of_summary(), 57 $this->get_does_not_contain_feedback_expectation(), 58 $this->get_does_not_contain_validation_error_expectation()); 59 60 // Save in incomplete answer. 61 $this->process_submission(array('sub1_answer' => '1', 'sub2_answer' => '', 62 'sub3_answer' => '', 'sub4_answer' => '')); 63 64 // Verify. 65 $this->check_current_state(question_state::$invalid); 66 $this->check_current_mark(null); 67 $this->check_current_output( 68 $this->get_contains_marked_out_of_summary(), 69 $this->get_does_not_contain_feedback_expectation(), 70 $this->get_contains_validation_error_expectation()); 71 72 // Save a partially correct answer. 73 $this->process_submission(array('sub1_answer' => '1', 'sub2_answer' => '1', 74 'sub3_answer' => '1', 'sub4_answer' => '1')); 75 76 // Verify. 77 $this->check_current_state(question_state::$complete); 78 $this->check_current_mark(null); 79 $this->check_current_output( 80 $this->get_contains_marked_out_of_summary(), 81 $this->get_does_not_contain_feedback_expectation(), 82 $this->get_does_not_contain_validation_error_expectation()); 83 84 // Now submit all and finish. 85 $this->finish(); 86 87 // Verify. 88 $this->check_current_state(question_state::$gradedpartial); 89 $this->check_current_mark(2); 90 $this->check_current_output( 91 $this->get_contains_mark_summary(2), 92 $this->get_contains_partcorrect_expectation(), 93 $this->get_does_not_contain_validation_error_expectation()); 94 } 95 96 public function test_deferred_feedback_numericalzero_not_answered() { 97 // Tests the situation found in MDL-35370. 98 99 // Create a multianswer question with one numerical subquestion, right answer zero. 100 $q = test_question_maker::make_question('multianswer', 'numericalzero'); 101 $this->start_attempt_at_question($q, 'deferredfeedback', 1); 102 103 // Check the initial state. 104 $this->check_current_state(question_state::$todo); 105 $this->check_current_mark(null); 106 $this->check_current_output( 107 $this->get_contains_marked_out_of_summary(), 108 $this->get_does_not_contain_feedback_expectation(), 109 $this->get_does_not_contain_validation_error_expectation()); 110 111 // Now submit all and finish. 112 $this->finish(); 113 114 // Verify. 115 $this->check_current_state(question_state::$gaveup); 116 $this->check_current_mark(null); 117 $this->check_current_output( 118 $this->get_contains_marked_out_of_summary(), 119 new question_pattern_expectation('~<input[^>]* class="incorrect" [^>]*/>~'), 120 $this->get_contains_subq_status(question_state::$gaveup), 121 $this->get_does_not_contain_validation_error_expectation()); 122 } 123 124 public function test_deferred_feedback_numericalzero_0_answer() { 125 // Tests the situation found in MDL-35370. 126 127 // Create a multianswer question with one numerical subquestion, right answer zero. 128 $q = test_question_maker::make_question('multianswer', 'numericalzero'); 129 $this->start_attempt_at_question($q, 'deferredfeedback', 1); 130 131 // Check the initial state. 132 $this->check_current_state(question_state::$todo); 133 $this->check_current_mark(null); 134 $this->check_current_output( 135 $this->get_contains_marked_out_of_summary(), 136 $this->get_does_not_contain_feedback_expectation(), 137 $this->get_does_not_contain_validation_error_expectation()); 138 139 // Save a the correct answer. 140 $this->process_submission(array('sub1_answer' => '0')); 141 142 // Verify. 143 $this->check_current_state(question_state::$complete); 144 $this->check_current_mark(null); 145 $this->check_current_output( 146 $this->get_contains_marked_out_of_summary(), 147 $this->get_does_not_contain_feedback_expectation(), 148 $this->get_does_not_contain_validation_error_expectation()); 149 150 // Now submit all and finish. 151 $this->finish(); 152 153 // Verify. 154 $this->check_current_state(question_state::$gradedright); 155 $this->check_current_mark(1); 156 $this->check_current_output( 157 $this->get_contains_mark_summary(1), 158 $this->get_contains_correct_expectation(), 159 $this->get_contains_subq_status(question_state::$gradedright), 160 $this->get_does_not_contain_validation_error_expectation()); 161 } 162 163 public function test_deferred_feedback_numericalzero_0_wrong() { 164 // Tests the situation found in MDL-35370. 165 166 // Create a multianswer question with one numerical subquestion, right answer zero. 167 $q = test_question_maker::make_question('multianswer', 'numericalzero'); 168 $this->start_attempt_at_question($q, 'deferredfeedback', 1); 169 170 // Check the initial state. 171 $this->check_current_state(question_state::$todo); 172 $this->check_current_mark(null); 173 $this->check_current_output( 174 $this->get_contains_marked_out_of_summary(), 175 $this->get_does_not_contain_feedback_expectation(), 176 $this->get_does_not_contain_validation_error_expectation()); 177 178 // Save a the correct answer. 179 $this->process_submission(array('sub1_answer' => '42')); 180 181 // Verify. 182 $this->check_current_state(question_state::$complete); 183 $this->check_current_mark(null); 184 $this->check_current_output( 185 $this->get_contains_marked_out_of_summary(), 186 $this->get_does_not_contain_feedback_expectation(), 187 $this->get_does_not_contain_validation_error_expectation()); 188 189 // Now submit all and finish. 190 $this->finish(); 191 192 // Verify. 193 $this->check_current_state(question_state::$gradedwrong); 194 $this->check_current_mark(0); 195 $this->check_current_output( 196 $this->get_contains_mark_summary(0), 197 $this->get_contains_incorrect_expectation(), 198 $this->get_contains_subq_status(question_state::$gradedwrong), 199 $this->get_does_not_contain_validation_error_expectation()); 200 } 201 202 public function test_interactive_feedback() { 203 204 // Create a multianswer question. 205 $q = test_question_maker::make_question('multianswer', 'fourmc'); 206 $q->hints = array( 207 new question_hint_with_parts(11, 'This is the first hint.', FORMAT_HTML, false, true), 208 new question_hint_with_parts(12, 'This is the second hint.', FORMAT_HTML, true, true), 209 ); 210 $choices = array('' => '', '0' => 'California', '1' => 'Arizona'); 211 212 $this->start_attempt_at_question($q, 'interactive', 4); 213 214 // Check the initial state. 215 $this->check_current_state(question_state::$todo); 216 $this->check_current_mark(null); 217 $this->assertEquals('interactivecountback', 218 $this->quba->get_question_attempt($this->slot)->get_behaviour_name()); 219 $this->check_current_output( 220 $this->get_contains_marked_out_of_summary(), 221 $this->get_contains_select_expectation('sub1_answer', $choices, null, true), 222 $this->get_contains_select_expectation('sub2_answer', $choices, null, true), 223 $this->get_contains_select_expectation('sub3_answer', $choices, null, true), 224 $this->get_contains_select_expectation('sub4_answer', $choices, null, true), 225 $this->get_contains_submit_button_expectation(true), 226 $this->get_does_not_contain_validation_error_expectation(), 227 $this->get_does_not_contain_feedback_expectation(), 228 $this->get_tries_remaining_expectation(3), 229 $this->get_does_not_contain_num_parts_correct(), 230 $this->get_no_hint_visible_expectation()); 231 232 // Submit a completely wrong response. 233 $this->process_submission(array('sub1_answer' => '1', 'sub2_answer' => '0', 234 'sub3_answer' => '1', 'sub4_answer' => '0', '-submit' => 1)); 235 236 // Verify. 237 $this->check_current_state(question_state::$todo); 238 $this->check_current_mark(null); 239 $this->check_current_output( 240 $this->get_contains_select_expectation('sub1_answer', $choices, 1, false), 241 $this->get_contains_select_expectation('sub2_answer', $choices, 0, false), 242 $this->get_contains_select_expectation('sub3_answer', $choices, 1, false), 243 $this->get_contains_select_expectation('sub4_answer', $choices, 0, false), 244 $this->get_does_not_contain_num_parts_correct(), 245 $this->get_contains_hidden_expectation( 246 $this->quba->get_field_prefix($this->slot) . 'sub1_answer', ''), 247 $this->get_contains_hidden_expectation( 248 $this->quba->get_field_prefix($this->slot) . 'sub2_answer', ''), 249 $this->get_contains_hidden_expectation( 250 $this->quba->get_field_prefix($this->slot) . 'sub3_answer', ''), 251 $this->get_contains_hidden_expectation( 252 $this->quba->get_field_prefix($this->slot) . 'sub4_answer', ''), 253 $this->get_does_not_contain_submit_button_expectation(), 254 $this->get_contains_try_again_button_expectation(true), 255 $this->get_does_not_contain_correctness_expectation(), 256 $this->get_contains_hint_expectation('This is the first hint.')); 257 258 // Check that, if we review in this state, the try again button is disabled. 259 $displayoptions = new question_display_options(); 260 $displayoptions->readonly = true; 261 $html = $this->quba->render_question($this->slot, $displayoptions); 262 $this->assert($this->get_contains_try_again_button_expectation(false), $html); 263 264 // Try again. 265 $this->process_submission(array('sub1_answer' => '', 266 'sub2_answer' => '', 'sub3_answer' => '', 267 'sub4_answer' => '', '-tryagain' => 1)); 268 269 // Verify. 270 $this->check_current_state(question_state::$todo); 271 $this->check_current_mark(null); 272 $this->check_current_output( 273 $this->get_contains_select_expectation('sub1_answer', $choices, null, true), 274 $this->get_contains_select_expectation('sub2_answer', $choices, null, true), 275 $this->get_contains_select_expectation('sub3_answer', $choices, null, true), 276 $this->get_contains_select_expectation('sub4_answer', $choices, null, true), 277 $this->get_contains_submit_button_expectation(true), 278 $this->get_does_not_contain_feedback_expectation(), 279 $this->get_tries_remaining_expectation(2), 280 $this->get_no_hint_visible_expectation()); 281 282 // Submit a partially wrong response. 283 $this->process_submission(array('sub1_answer' => '1', 'sub2_answer' => '1', 284 'sub3_answer' => '1', 'sub4_answer' => '1', '-submit' => 1)); 285 286 // Verify. 287 $this->check_current_state(question_state::$todo); 288 $this->check_current_mark(null); 289 $this->check_current_output( 290 $this->get_contains_select_expectation('sub1_answer', $choices, 1, false), 291 $this->get_contains_select_expectation('sub2_answer', $choices, 1, false), 292 $this->get_contains_select_expectation('sub3_answer', $choices, 1, false), 293 $this->get_contains_select_expectation('sub4_answer', $choices, 1, false), 294 $this->get_contains_num_parts_correct(2), 295 $this->get_contains_hidden_expectation( 296 $this->quba->get_field_prefix($this->slot) . 'sub1_answer', ''), 297 $this->get_contains_hidden_expectation( 298 $this->quba->get_field_prefix($this->slot) . 'sub2_answer', '1'), 299 $this->get_contains_hidden_expectation( 300 $this->quba->get_field_prefix($this->slot) . 'sub3_answer', ''), 301 $this->get_contains_hidden_expectation( 302 $this->quba->get_field_prefix($this->slot) . 'sub4_answer', '1'), 303 $this->get_does_not_contain_submit_button_expectation(), 304 $this->get_contains_hint_expectation('This is the second hint.')); 305 306 // Try again. 307 $this->process_submission(array('sub1_answer' => '', 308 'sub2_answer' => '1', 'sub3_answer' => '', 309 'sub4_answer' => '1', '-tryagain' => 1)); 310 311 // Verify. 312 $this->check_current_state(question_state::$todo); 313 $this->check_current_mark(null); 314 $this->check_current_output( 315 $this->get_contains_select_expectation('sub1_answer', $choices, '', true), 316 $this->get_contains_select_expectation('sub2_answer', $choices, '1', true), 317 $this->get_contains_select_expectation('sub3_answer', $choices, '', true), 318 $this->get_contains_select_expectation('sub4_answer', $choices, '1', true), 319 $this->get_contains_submit_button_expectation(true), 320 $this->get_does_not_contain_feedback_expectation(), 321 $this->get_tries_remaining_expectation(1), 322 $this->get_no_hint_visible_expectation()); 323 } 324 325 public function test_interactive_partial_response_does_not_reveal_answer() { 326 327 // Create a multianswer question. 328 $q = test_question_maker::make_question('multianswer', 'fourmc'); 329 $q->hints = array( 330 new question_hint_with_parts(11, 'This is the first hint.', FORMAT_HTML, false, true), 331 new question_hint_with_parts(12, 'This is the second hint.', FORMAT_HTML, true, true), 332 ); 333 $choices = array('' => '', '0' => 'California', '1' => 'Arizona'); 334 335 $this->start_attempt_at_question($q, 'interactive', 4); 336 337 // Check the initial state. 338 $this->check_current_state(question_state::$todo); 339 $this->check_current_mark(null); 340 $this->assertEquals('interactivecountback', 341 $this->quba->get_question_attempt($this->slot)->get_behaviour_name()); 342 $this->check_current_output( 343 $this->get_contains_marked_out_of_summary(), 344 $this->get_contains_select_expectation('sub1_answer', $choices, null, true), 345 $this->get_contains_select_expectation('sub2_answer', $choices, null, true), 346 $this->get_contains_select_expectation('sub3_answer', $choices, null, true), 347 $this->get_contains_select_expectation('sub4_answer', $choices, null, true), 348 $this->get_contains_submit_button_expectation(true), 349 $this->get_does_not_contain_validation_error_expectation(), 350 $this->get_does_not_contain_feedback_expectation(), 351 $this->get_tries_remaining_expectation(3), 352 $this->get_does_not_contain_num_parts_correct(), 353 $this->get_no_hint_visible_expectation()); 354 355 // Submit an incomplete response response. 356 $this->process_submission(array('sub1_answer' => '1', 'sub2_answer' => '1', '-submit' => 1)); 357 358 // Verify. 359 $this->check_current_state(question_state::$invalid); 360 $this->check_current_mark(null); 361 $this->check_current_output( 362 $this->get_contains_select_expectation('sub1_answer', $choices, 1, true), 363 $this->get_contains_select_expectation('sub2_answer', $choices, 1, true), 364 $this->get_contains_select_expectation('sub3_answer', $choices, null, true), 365 $this->get_contains_select_expectation('sub4_answer', $choices, null, true), 366 $this->get_does_not_contain_num_parts_correct(), 367 $this->get_contains_validation_error_expectation(), 368 $this->get_contains_submit_button_expectation(true), 369 $this->get_does_not_contain_try_again_button_expectation(), 370 $this->get_does_not_contain_correctness_expectation(), 371 $this->get_no_hint_visible_expectation()); 372 $this->render(); 373 $a = array('mark' => '0.00', 'max' => '1.00'); 374 $this->assertNotRegExp('~' . preg_quote(get_string('markoutofmax', 'question', $a), '~') . '~', 375 $this->currentoutput); 376 $a['mark'] = '1.00'; 377 $this->assertNotRegExp('~' . preg_quote(get_string('markoutofmax', 'question', $a), '~') . '~', 378 $this->currentoutput); 379 } 380 381 public function test_interactivecountback_feedback() { 382 383 // Create a multianswer question. 384 $q = test_question_maker::make_question('multianswer', 'fourmc'); 385 $q->hints = array( 386 new question_hint_with_parts(11, 'This is the first hint.', FORMAT_HTML, true, true), 387 new question_hint_with_parts(12, 'This is the second hint.', FORMAT_HTML, true, true), 388 ); 389 $choices = array('' => '', '0' => 'California', '1' => 'Arizona'); 390 391 $this->start_attempt_at_question($q, 'interactive', 12); 392 393 // Check the initial state. 394 $this->check_current_state(question_state::$todo); 395 $this->check_current_mark(null); 396 $this->assertEquals('interactivecountback', 397 $this->quba->get_question_attempt($this->slot)->get_behaviour_name()); 398 $this->check_current_output( 399 $this->get_contains_marked_out_of_summary(), 400 $this->get_contains_select_expectation('sub1_answer', $choices, null, true), 401 $this->get_contains_select_expectation('sub2_answer', $choices, null, true), 402 $this->get_contains_select_expectation('sub3_answer', $choices, null, true), 403 $this->get_contains_select_expectation('sub4_answer', $choices, null, true), 404 $this->get_contains_submit_button_expectation(true), 405 $this->get_does_not_contain_validation_error_expectation(), 406 $this->get_does_not_contain_feedback_expectation(), 407 $this->get_tries_remaining_expectation(3), 408 $this->get_no_hint_visible_expectation()); 409 410 // Submit an answer with two right, and two wrong. 411 $this->process_submission(array('sub1_answer' => '1', 'sub2_answer' => '1', 412 'sub3_answer' => '1', 'sub4_answer' => '1', '-submit' => 1)); 413 414 // Verify. 415 $this->check_current_state(question_state::$todo); 416 $this->check_current_mark(null); 417 $this->check_current_output( 418 $this->get_contains_select_expectation('sub1_answer', $choices, 1, false), 419 $this->get_contains_select_expectation('sub2_answer', $choices, 1, false), 420 $this->get_contains_select_expectation('sub3_answer', $choices, 1, false), 421 $this->get_contains_select_expectation('sub4_answer', $choices, 1, false), 422 $this->get_does_not_contain_submit_button_expectation(), 423 $this->get_contains_try_again_button_expectation(true), 424 $this->get_does_not_contain_correctness_expectation(), 425 new question_pattern_expectation('/Tries remaining: 2/'), 426 $this->get_contains_hint_expectation('This is the first hint.')); 427 428 // Check that extract responses will return the reset data. 429 $prefix = $this->quba->get_field_prefix($this->slot); 430 $this->assertEquals(array('sub1_answer' => 1), 431 $this->quba->extract_responses($this->slot, array($prefix . 'sub1_answer' => 1))); 432 433 // Do try again. 434 $this->process_submission(array('sub1_answer' => '', 435 'sub2_answer' => '1', 'sub3_answer' => '', 436 'sub4_answer' => '1', '-tryagain' => 1)); 437 438 // Verify. 439 $this->check_current_state(question_state::$todo); 440 $this->check_current_mark(null); 441 $this->check_current_output( 442 $this->get_contains_select_expectation('sub1_answer', $choices, '', true), 443 $this->get_contains_select_expectation('sub2_answer', $choices, '1', true), 444 $this->get_contains_select_expectation('sub3_answer', $choices, '', true), 445 $this->get_contains_select_expectation('sub4_answer', $choices, '1', true), 446 $this->get_contains_submit_button_expectation(true), 447 $this->get_does_not_contain_feedback_expectation(), 448 $this->get_tries_remaining_expectation(2), 449 $this->get_no_hint_visible_expectation()); 450 451 // Submit the right answer. 452 $this->process_submission(array('sub1_answer' => '0', 'sub2_answer' => '1', 453 'sub3_answer' => '0', 'sub4_answer' => '1', '-submit' => 1)); 454 455 // Verify. 456 $this->check_current_state(question_state::$gradedright); 457 $this->check_current_mark(10); 458 $this->check_current_output( 459 $this->get_contains_select_expectation('sub1_answer', $choices, '0', false), 460 $this->get_contains_select_expectation('sub2_answer', $choices, '1', false), 461 $this->get_contains_select_expectation('sub3_answer', $choices, '0', false), 462 $this->get_contains_select_expectation('sub4_answer', $choices, '1', false), 463 $this->get_does_not_contain_submit_button_expectation(), 464 $this->get_does_not_contain_try_again_button_expectation(), 465 $this->get_contains_correct_expectation(), 466 new question_no_pattern_expectation('/class="control\b[^"]*\bpartiallycorrect"/')); 467 } 468 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |