[ Index ] |
PHP Cross Reference of moodle-2.8 |
[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 tests that walks a question through the interactive 19 * behaviour. 20 * 21 * @package qbehaviour 22 * @subpackage interactive 23 * @copyright 2009 The Open University 24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 25 */ 26 27 28 defined('MOODLE_INTERNAL') || die(); 29 30 global $CFG; 31 require_once(dirname(__FILE__) . '/../../../engine/lib.php'); 32 require_once(dirname(__FILE__) . '/../../../engine/tests/helpers.php'); 33 34 35 /** 36 * Unit tests for the interactive behaviour. 37 * 38 * @copyright 2009 The Open University 39 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 40 */ 41 class qbehaviour_interactive_walkthrough_test extends qbehaviour_walkthrough_test_base { 42 43 public function test_interactive_feedback_multichoice_right() { 44 45 // Create a multichoice single question. 46 $mc = test_question_maker::make_a_multichoice_single_question(); 47 $mc->hints = array( 48 new question_hint_with_parts(0, 'This is the first hint.', FORMAT_HTML, false, false), 49 new question_hint_with_parts(0, 'This is the second hint.', FORMAT_HTML, true, true), 50 ); 51 $this->start_attempt_at_question($mc, 'interactive'); 52 53 $rightindex = $this->get_mc_right_answer_index($mc); 54 $wrongindex = ($rightindex + 1) % 3; 55 56 // Check the initial state. 57 $this->check_current_state(question_state::$todo); 58 $this->check_current_mark(null); 59 $this->check_current_output( 60 $this->get_contains_marked_out_of_summary(), 61 $this->get_contains_question_text_expectation($mc), 62 $this->get_contains_mc_radio_expectation(0, true, false), 63 $this->get_contains_mc_radio_expectation(1, true, false), 64 $this->get_contains_mc_radio_expectation(2, true, false), 65 $this->get_contains_submit_button_expectation(true), 66 $this->get_does_not_contain_feedback_expectation(), 67 $this->get_tries_remaining_expectation(3), 68 $this->get_no_hint_visible_expectation()); 69 70 // Save the wrong answer. 71 $this->process_submission(array('answer' => $wrongindex)); 72 73 // Verify. 74 $this->check_current_state(question_state::$todo); 75 $this->check_current_mark(null); 76 $this->check_current_output( 77 $this->get_contains_marked_out_of_summary(), 78 $this->get_contains_mc_radio_expectation($wrongindex, true, true), 79 $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, true, false), 80 $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, true, false), 81 $this->get_contains_submit_button_expectation(true), 82 $this->get_does_not_contain_correctness_expectation(), 83 $this->get_does_not_contain_feedback_expectation(), 84 $this->get_tries_remaining_expectation(3), 85 $this->get_no_hint_visible_expectation()); 86 87 // Submit the wrong answer. 88 $this->process_submission(array('answer' => $wrongindex, '-submit' => 1)); 89 90 // Verify. 91 $this->check_current_state(question_state::$todo); 92 $this->check_current_mark(null); 93 $this->check_current_output( 94 $this->get_contains_marked_out_of_summary(), 95 $this->get_contains_mc_radio_expectation($wrongindex, false, true), 96 $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, false, false), 97 $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, false, false), 98 $this->get_contains_submit_button_expectation(false), 99 $this->get_contains_try_again_button_expectation(true), 100 $this->get_does_not_contain_correctness_expectation(), 101 new question_pattern_expectation('/' . 102 preg_quote(get_string('notcomplete', 'qbehaviour_interactive'), '/') . '/'), 103 $this->get_contains_hint_expectation('This is the first hint')); 104 105 // Check that, if we review in this state, the try again button is disabled. 106 $displayoptions = new question_display_options(); 107 $displayoptions->readonly = true; 108 $html = $this->quba->render_question($this->slot, $displayoptions); 109 $this->assert($this->get_contains_try_again_button_expectation(false), $html); 110 111 // Do try again. 112 $this->process_submission(array('-tryagain' => 1)); 113 114 // Verify. 115 $this->check_current_state(question_state::$todo); 116 $this->check_current_mark(null); 117 $this->check_current_output( 118 $this->get_contains_marked_out_of_summary(), 119 $this->get_contains_mc_radio_expectation($wrongindex, true, true), 120 $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, true, false), 121 $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, true, false), 122 $this->get_contains_submit_button_expectation(true), 123 $this->get_does_not_contain_correctness_expectation(), 124 $this->get_does_not_contain_feedback_expectation(), 125 $this->get_tries_remaining_expectation(2), 126 $this->get_no_hint_visible_expectation()); 127 128 // Submit the right answer. 129 $this->process_submission(array('answer' => $rightindex, '-submit' => 1)); 130 131 // Verify. 132 $this->check_current_state(question_state::$gradedright); 133 $this->check_current_mark(0.6666667); 134 $this->check_current_output( 135 $this->get_contains_mark_summary(0.6666667), 136 $this->get_contains_mc_radio_expectation($rightindex, false, true), 137 $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false), 138 $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false), 139 $this->get_contains_submit_button_expectation(false), 140 $this->get_contains_correct_expectation(), 141 $this->get_no_hint_visible_expectation()); 142 143 // Finish the attempt - should not need to add a new state. 144 $numsteps = $this->get_step_count(); 145 $this->quba->finish_all_questions(); 146 147 // Verify. 148 $this->assertEquals($numsteps, $this->get_step_count()); 149 $this->check_current_state(question_state::$gradedright); 150 $this->check_current_mark(0.6666667); 151 $this->check_current_output( 152 $this->get_contains_mark_summary(0.6666667), 153 $this->get_contains_mc_radio_expectation($rightindex, false, true), 154 $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false), 155 $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false), 156 $this->get_contains_correct_expectation(), 157 $this->get_no_hint_visible_expectation()); 158 159 // Process a manual comment. 160 $this->manual_grade('Not good enough!', 0.5, FORMAT_HTML); 161 162 // Verify. 163 $this->check_current_state(question_state::$mangrpartial); 164 $this->check_current_mark(0.5); 165 $this->check_current_output( 166 $this->get_contains_mark_summary(0.5), 167 $this->get_contains_partcorrect_expectation(), 168 new question_pattern_expectation('/' . preg_quote('Not good enough!', '/') . '/')); 169 170 // Check regrading does not mess anything up. 171 $this->quba->regrade_all_questions(); 172 173 // Verify. 174 $this->check_current_state(question_state::$mangrpartial); 175 $this->check_current_mark(0.5); 176 $this->check_current_output( 177 $this->get_contains_mark_summary(0.5), 178 $this->get_contains_partcorrect_expectation()); 179 180 $autogradedstep = $this->get_step($this->get_step_count() - 2); 181 $this->assertEquals($autogradedstep->get_fraction(), 0.6666667, '', 0.0000001); 182 } 183 184 public function test_interactive_finish_when_try_again_showing() { 185 186 // Create a multichoice single question. 187 $mc = test_question_maker::make_a_multichoice_single_question(); 188 $mc->hints = array( 189 new question_hint_with_parts(0, 'This is the first hint.', FORMAT_HTML, false, false), 190 ); 191 $this->start_attempt_at_question($mc, 'interactive'); 192 193 $rightindex = $this->get_mc_right_answer_index($mc); 194 $wrongindex = ($rightindex + 1) % 3; 195 196 // Check the initial state. 197 $this->check_current_state(question_state::$todo); 198 $this->check_current_mark(null); 199 $this->check_current_output( 200 $this->get_contains_marked_out_of_summary(), 201 $this->get_contains_question_text_expectation($mc), 202 $this->get_contains_mc_radio_expectation(0, true, false), 203 $this->get_contains_mc_radio_expectation(1, true, false), 204 $this->get_contains_mc_radio_expectation(2, true, false), 205 $this->get_contains_submit_button_expectation(true), 206 $this->get_does_not_contain_feedback_expectation(), 207 $this->get_tries_remaining_expectation(2), 208 $this->get_no_hint_visible_expectation(), 209 new question_pattern_expectation('/' . 210 preg_quote(get_string('selectone', 'qtype_multichoice'), '/') . '/')); 211 212 // Submit the wrong answer. 213 $this->process_submission(array('answer' => $wrongindex, '-submit' => 1)); 214 215 // Verify. 216 $this->check_current_state(question_state::$todo); 217 $this->check_current_mark(null); 218 $this->check_current_output( 219 $this->get_contains_marked_out_of_summary(), 220 $this->get_contains_mc_radio_expectation($wrongindex, false, true), 221 $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, false, false), 222 $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, false, false), 223 $this->get_contains_submit_button_expectation(false), 224 $this->get_contains_try_again_button_expectation(true), 225 $this->get_does_not_contain_correctness_expectation(), 226 new question_pattern_expectation('/' . 227 preg_quote(get_string('notcomplete', 'qbehaviour_interactive'), '/') . '/'), 228 $this->get_contains_hint_expectation('This is the first hint')); 229 230 // Finish the attempt. 231 $this->quba->finish_all_questions(); 232 233 // Verify. 234 $this->check_current_state(question_state::$gradedwrong); 235 $this->check_current_mark(0); 236 $this->check_current_output( 237 $this->get_contains_mark_summary(0), 238 $this->get_contains_mc_radio_expectation($wrongindex, false, true), 239 $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, false, false), 240 $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, false, false), 241 $this->get_contains_incorrect_expectation(), 242 $this->get_no_hint_visible_expectation()); 243 } 244 245 public function test_interactive_shortanswer_try_to_submit_blank() { 246 247 // Create a short answer question. 248 $sa = test_question_maker::make_question('shortanswer'); 249 $sa->hints = array( 250 new question_hint(0, 'This is the first hint.', FORMAT_HTML), 251 new question_hint(0, 'This is the second hint.', FORMAT_HTML), 252 ); 253 $this->start_attempt_at_question($sa, 'interactive'); 254 255 // Check the initial state. 256 $this->check_current_state(question_state::$todo); 257 $this->check_current_mark(null); 258 $this->check_current_output( 259 $this->get_contains_marked_out_of_summary(), 260 $this->get_contains_submit_button_expectation(true), 261 $this->get_does_not_contain_feedback_expectation(), 262 $this->get_does_not_contain_validation_error_expectation(), 263 $this->get_does_not_contain_try_again_button_expectation(), 264 $this->get_no_hint_visible_expectation()); 265 266 // Submit blank. 267 $this->process_submission(array('-submit' => 1, 'answer' => '')); 268 269 // Verify. 270 $this->check_current_state(question_state::$invalid); 271 $this->check_current_mark(null); 272 $this->check_current_output( 273 $this->get_contains_marked_out_of_summary(), 274 $this->get_contains_submit_button_expectation(true), 275 $this->get_does_not_contain_feedback_expectation(), 276 $this->get_contains_validation_error_expectation(), 277 $this->get_does_not_contain_try_again_button_expectation(), 278 $this->get_no_hint_visible_expectation()); 279 280 // Now get it wrong. 281 $this->process_submission(array('-submit' => 1, 'answer' => 'newt')); 282 283 // Verify. 284 $this->check_current_state(question_state::$todo); 285 $this->check_current_mark(null); 286 $this->check_current_output( 287 $this->get_contains_marked_out_of_summary(), 288 $this->get_contains_submit_button_expectation(false), 289 $this->get_does_not_contain_validation_error_expectation(), 290 $this->get_contains_try_again_button_expectation(true), 291 new question_pattern_expectation('/' . 292 preg_quote(get_string('notcomplete', 'qbehaviour_interactive'), '/') . '/'), 293 $this->get_contains_hint_expectation('This is the first hint')); 294 $this->assertEquals('newt', 295 $this->quba->get_response_summary($this->slot)); 296 297 // Try again. 298 $this->process_submission(array('-tryagain' => 1)); 299 300 // Verify. 301 $this->check_current_state(question_state::$todo); 302 $this->check_current_mark(null); 303 $this->check_current_output( 304 $this->get_contains_marked_out_of_summary(), 305 $this->get_contains_submit_button_expectation(true), 306 $this->get_does_not_contain_feedback_expectation(), 307 $this->get_does_not_contain_validation_error_expectation(), 308 $this->get_does_not_contain_try_again_button_expectation(), 309 $this->get_no_hint_visible_expectation()); 310 311 // Now submit blank again. 312 $this->process_submission(array('-submit' => 1, 'answer' => '')); 313 314 // Verify. 315 $this->check_current_state(question_state::$invalid); 316 $this->check_current_mark(null); 317 $this->check_current_output( 318 $this->get_contains_marked_out_of_summary(), 319 $this->get_contains_submit_button_expectation(true), 320 $this->get_does_not_contain_feedback_expectation(), 321 $this->get_contains_validation_error_expectation(), 322 $this->get_does_not_contain_try_again_button_expectation(), 323 $this->get_no_hint_visible_expectation()); 324 325 // Now get it right. 326 $this->process_submission(array('-submit' => 1, 'answer' => 'frog')); 327 328 // Verify. 329 $this->check_current_state(question_state::$gradedright); 330 $this->check_current_mark(0.6666667); 331 $this->check_current_output( 332 $this->get_contains_mark_summary(0.6666667), 333 $this->get_contains_submit_button_expectation(false), 334 $this->get_contains_correct_expectation(), 335 $this->get_does_not_contain_validation_error_expectation(), 336 $this->get_no_hint_visible_expectation()); 337 $this->assertEquals('frog', 338 $this->quba->get_response_summary($this->slot)); 339 } 340 341 public function test_interactive_feedback_multichoice_multiple_reset() { 342 343 // Create a multichoice multiple question. 344 $mc = test_question_maker::make_a_multichoice_multi_question(); 345 $mc->hints = array( 346 new question_hint_with_parts(0, 'This is the first hint.', FORMAT_HTML, true, true), 347 new question_hint_with_parts(0, 'This is the second hint.', FORMAT_HTML, true, true), 348 ); 349 $this->start_attempt_at_question($mc, 'interactive', 2); 350 351 $right = array_keys($mc->get_correct_response()); 352 $wrong = array_diff(array('choice0', 'choice1', 'choice2', 'choice3'), $right); 353 $wrong = array_values(array_diff( 354 array('choice0', 'choice1', 'choice2', 'choice3'), $right)); 355 356 // Check the initial state. 357 $this->check_current_state(question_state::$todo); 358 $this->check_current_mark(null); 359 $this->check_current_output( 360 $this->get_contains_marked_out_of_summary(), 361 $this->get_contains_question_text_expectation($mc), 362 $this->get_contains_mc_checkbox_expectation('choice0', true, false), 363 $this->get_contains_mc_checkbox_expectation('choice1', true, false), 364 $this->get_contains_mc_checkbox_expectation('choice2', true, false), 365 $this->get_contains_mc_checkbox_expectation('choice3', true, false), 366 $this->get_contains_submit_button_expectation(true), 367 $this->get_does_not_contain_feedback_expectation(), 368 $this->get_does_not_contain_num_parts_correct(), 369 $this->get_tries_remaining_expectation(3), 370 $this->get_no_hint_visible_expectation(), 371 new question_pattern_expectation('/' . 372 preg_quote(get_string('selectmulti', 'qtype_multichoice'), '/') . '/')); 373 374 // Submit an answer with one right, and one wrong. 375 $this->process_submission(array($right[0] => 1, $wrong[0] => 1, '-submit' => 1)); 376 377 // Verify. 378 $this->check_current_state(question_state::$todo); 379 $this->check_current_mark(null); 380 $this->check_current_output( 381 $this->get_contains_marked_out_of_summary(), 382 $this->get_contains_mc_checkbox_expectation($right[0], false, true), 383 $this->get_contains_mc_checkbox_expectation($right[1], false, false), 384 $this->get_contains_mc_checkbox_expectation($wrong[0], false, true), 385 $this->get_contains_mc_checkbox_expectation($wrong[1], false, false), 386 $this->get_contains_submit_button_expectation(false), 387 $this->get_contains_try_again_button_expectation(true), 388 $this->get_does_not_contain_correctness_expectation(), 389 new question_pattern_expectation('/' . 390 preg_quote(get_string('notcomplete', 'qbehaviour_interactive'), '/') . '/'), 391 $this->get_contains_hint_expectation('This is the first hint'), 392 $this->get_contains_num_parts_correct(1), 393 $this->get_contains_standard_incorrect_combined_feedback_expectation(), 394 $this->get_contains_hidden_expectation( 395 $this->quba->get_field_prefix($this->slot) . $right[0], '1'), 396 $this->get_does_not_contain_hidden_expectation( 397 $this->quba->get_field_prefix($this->slot) . $right[1]), 398 $this->get_contains_hidden_expectation( 399 $this->quba->get_field_prefix($this->slot) . $wrong[0], '0'), 400 $this->get_does_not_contain_hidden_expectation( 401 $this->quba->get_field_prefix($this->slot) . $wrong[1])); 402 403 // Do try again. 404 $this->process_submission(array($right[0] => 1, '-tryagain' => 1)); 405 406 // Verify. 407 $this->check_current_state(question_state::$todo); 408 $this->check_current_mark(null); 409 $this->check_current_output( 410 $this->get_contains_marked_out_of_summary(), 411 $this->get_contains_mc_checkbox_expectation($right[0], true, true), 412 $this->get_contains_mc_checkbox_expectation($right[1], true, false), 413 $this->get_contains_mc_checkbox_expectation($wrong[0], true, false), 414 $this->get_contains_mc_checkbox_expectation($wrong[1], true, false), 415 $this->get_contains_submit_button_expectation(true), 416 $this->get_does_not_contain_correctness_expectation(), 417 $this->get_does_not_contain_feedback_expectation(), 418 $this->get_tries_remaining_expectation(2), 419 $this->get_no_hint_visible_expectation()); 420 } 421 422 public function test_interactive_regrade_changing_num_tries_leaving_open() { 423 // Create a multichoice multiple question. 424 $q = test_question_maker::make_question('shortanswer'); 425 $q->hints = array( 426 new question_hint_with_parts(0, 'This is the first hint.', FORMAT_HTML, true, true), 427 new question_hint_with_parts(0, 'This is the second hint.', FORMAT_HTML, true, true), 428 ); 429 $this->start_attempt_at_question($q, 'interactive', 3); 430 431 // Check the initial state. 432 $this->check_current_state(question_state::$todo); 433 $this->check_current_mark(null); 434 $this->check_current_output( 435 $this->get_tries_remaining_expectation(3)); 436 437 // Submit the right answer. 438 $this->process_submission(array('answer' => 'frog', '-submit' => 1)); 439 440 // Verify. 441 $this->check_current_state(question_state::$gradedright); 442 $this->check_current_mark(3); 443 444 // Now change the quiestion so that answer is only partially right, and regrade. 445 $q->answers[13]->fraction = 0.6666667; 446 $q->answers[14]->fraction = 1; 447 448 $this->quba->regrade_all_questions(false); 449 450 // Verify. 451 $this->check_current_state(question_state::$todo); 452 $this->check_current_mark(null); 453 } 454 455 public function test_interactive_regrade_changing_num_tries_finished() { 456 // Create a multichoice multiple question. 457 $q = test_question_maker::make_question('shortanswer'); 458 $q->hints = array( 459 new question_hint_with_parts(0, 'This is the first hint.', FORMAT_HTML, true, true), 460 new question_hint_with_parts(0, 'This is the second hint.', FORMAT_HTML, true, true), 461 ); 462 $this->start_attempt_at_question($q, 'interactive', 3); 463 464 // Check the initial state. 465 $this->check_current_state(question_state::$todo); 466 $this->check_current_mark(null); 467 $this->check_current_output( 468 $this->get_tries_remaining_expectation(3)); 469 470 // Submit the right answer. 471 $this->process_submission(array('answer' => 'frog', '-submit' => 1)); 472 473 // Verify. 474 $this->check_current_state(question_state::$gradedright); 475 $this->check_current_mark(3); 476 477 // Now change the quiestion so that answer is only partially right, and regrade. 478 $q->answers[13]->fraction = 0.6666667; 479 $q->answers[14]->fraction = 1; 480 481 $this->quba->regrade_all_questions(true); 482 483 // Verify. 484 $this->check_current_state(question_state::$gradedpartial); 485 // TODO I don't think 1 is the right fraction here. However, it is what 486 // you get attempting a question like this without regrading being involved, 487 // and I am currently interested in testing regrading here. 488 $this->check_current_mark(1); 489 } 490 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:29:05 2014 | Cross-referenced by PHPXref 0.7.1 |