Differences Between: [Versions 310 and 311] [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403] [Versions 39 and 310]
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 /** 19 * This file contains tests that walks a question through the adaptive 20 * behaviour. 21 * 22 * @package qbehaviour 23 * @subpackage adaptive 24 * @copyright 2009 The Open University 25 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 26 */ 27 28 29 defined('MOODLE_INTERNAL') || die(); 30 31 global $CFG; 32 require_once (__DIR__ . '/../../../engine/lib.php'); 33 require_once (__DIR__ . '/../../../engine/tests/helpers.php'); 34 35 36 /** 37 * Unit tests for the adaptive behaviour. 38 * 39 * @copyright 2009 The Open University 40 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 41 */ 42 class qbehaviour_adaptive_walkthrough_test extends qbehaviour_walkthrough_test_base { 43 protected function get_contains_penalty_info_expectation($penalty) { 44 $penaltyinfo = get_string('gradingdetailspenalty', 'qbehaviour_adaptive', 45 format_float($penalty, $this->displayoptions->markdp)); 46 return new question_pattern_expectation('/'.preg_quote($penaltyinfo, '/').'/'); 47 } 48 49 protected function get_does_not_contain_penalty_info_expectation() { 50 $penaltyinfo = get_string('gradingdetailspenalty', 'qbehaviour_adaptive', 'XXXXX'); 51 $penaltypattern = '/'.str_replace('XXXXX', '\\w*', preg_quote($penaltyinfo, '/')).'/'; 52 return new question_no_pattern_expectation($penaltypattern); 53 } 54 55 protected function get_contains_total_penalty_expectation($penalty) { 56 $penaltyinfo = get_string('gradingdetailspenaltytotal', 'qbehaviour_adaptive', 57 format_float($penalty, $this->displayoptions->markdp)); 58 return new question_pattern_expectation('/'.preg_quote($penaltyinfo, '/').'/'); 59 } 60 61 protected function get_does_not_contain_total_penalty_expectation() { 62 $penaltyinfo = get_string('gradingdetailspenaltytotal', 'qbehaviour_adaptive', 'XXXXX'); 63 $penaltypattern = '/'.str_replace('XXXXX', '\\w*', preg_quote($penaltyinfo, '/')).'/'; 64 return new question_no_pattern_expectation($penaltypattern); 65 } 66 67 protected function get_contains_disregarded_info_expectation() { 68 $penaltyinfo = get_string('disregardedwithoutpenalty', 'qbehaviour_adaptive'); 69 return new question_pattern_expectation('/'.preg_quote($penaltyinfo, '/').'/'); 70 } 71 72 protected function get_does_not_contain_disregarded_info_expectation() { 73 $penaltyinfo = get_string('disregardedwithoutpenalty', 'qbehaviour_adaptive'); 74 return new question_no_pattern_expectation('/'.preg_quote($penaltyinfo, '/').'/'); 75 } 76 77 public function test_adaptive_multichoice() { 78 79 // Create a multiple choice, single response question. 80 $mc = test_question_maker::make_a_multichoice_single_question(); 81 $mc->penalty = 0.3333333; 82 $this->start_attempt_at_question($mc, 'adaptive', 3); 83 84 $rightindex = $this->get_mc_right_answer_index($mc); 85 $wrongindex = ($rightindex + 1) % 3; 86 87 // Check the initial state. 88 $this->check_current_state(question_state::$todo); 89 $this->check_current_mark(null); 90 $this->check_current_output( 91 $this->get_contains_marked_out_of_summary(), 92 $this->get_contains_question_text_expectation($mc), 93 $this->get_contains_mc_radio_expectation(0, true, false), 94 $this->get_contains_mc_radio_expectation(1, true, false), 95 $this->get_contains_mc_radio_expectation(2, true, false), 96 $this->get_contains_submit_button_expectation(true), 97 $this->get_does_not_contain_feedback_expectation()); 98 99 // Process a submit. 100 $this->process_submission(array('answer' => $wrongindex, '-submit' => 1)); 101 102 // Verify. 103 $this->check_current_state(question_state::$todo); 104 $this->check_current_mark(0); 105 $this->check_current_output( 106 $this->get_contains_mark_summary(0), 107 $this->get_contains_mc_radio_expectation($wrongindex, true, true), 108 $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, true, false), 109 $this->get_contains_mc_radio_expectation(($wrongindex + 2) % 3, true, false), 110 $this->get_contains_incorrect_expectation(), 111 $this->get_contains_penalty_info_expectation(1.00), 112 $this->get_does_not_contain_total_penalty_expectation()); 113 $this->assertRegExp('/B|C/', 114 $this->quba->get_response_summary($this->slot)); 115 116 // Process a change of answer to the right one, but not sumbitted. 117 $this->process_submission(array('answer' => $rightindex)); 118 119 // Verify. 120 $this->check_current_state(question_state::$todo); 121 $this->check_current_mark(0); 122 $this->check_current_output( 123 $this->get_contains_mark_summary(0), 124 $this->get_contains_mc_radio_expectation($rightindex, true, true), 125 $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, true, false), 126 $this->get_contains_mc_radio_expectation(($rightindex + 2) % 3, true, false)); 127 $this->assertRegExp('/B|C/', 128 $this->quba->get_response_summary($this->slot)); 129 130 // Now submit the right answer. 131 $this->process_submission(array('answer' => $rightindex, '-submit' => 1)); 132 133 // Verify. 134 $this->check_current_state(question_state::$complete); 135 $this->check_current_mark(3 * (1 - $mc->penalty)); 136 $this->check_current_output( 137 $this->get_contains_mark_summary(3 * (1 - $mc->penalty)), 138 $this->get_contains_mc_radio_expectation($rightindex, true, true), 139 $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, true, false), 140 $this->get_contains_mc_radio_expectation(($rightindex + 2) % 3, true, false), 141 $this->get_contains_correct_expectation(), 142 $this->get_does_not_contain_penalty_info_expectation(), 143 $this->get_does_not_contain_total_penalty_expectation()); 144 $this->assertEquals('A', 145 $this->quba->get_response_summary($this->slot)); 146 147 // Finish the attempt. 148 $this->quba->finish_all_questions(); 149 150 // Verify. 151 $this->check_current_state(question_state::$gradedright); 152 $this->check_current_mark(3 * (1 - $mc->penalty)); 153 $this->check_current_output( 154 $this->get_contains_mark_summary(3 * (1 - $mc->penalty)), 155 $this->get_contains_mc_radio_expectation($rightindex, false, true), 156 $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false), 157 $this->get_contains_mc_radio_expectation(($rightindex + 2) % 3, false, false), 158 $this->get_contains_correct_expectation()); 159 160 // Process a manual comment. 161 $this->manual_grade('Not good enough!', 1, FORMAT_HTML); 162 163 // Verify. 164 $this->check_current_state(question_state::$mangrpartial); 165 $this->check_current_mark(1); 166 $this->check_current_output( 167 $this->get_contains_mark_summary(1), 168 new question_pattern_expectation('/' . preg_quote('Not good enough!', '/') . '/')); 169 170 // Now change the correct answer to the question, and regrade. 171 $mc->answers[13]->fraction = -0.33333333; 172 $mc->answers[14]->fraction = 1; // We don't know which "wrong" index we chose above! 173 $mc->answers[15]->fraction = 1; // Therefore, treat answers B and C with the same score. 174 $this->quba->regrade_all_questions(); 175 176 // Verify. 177 $this->check_current_state(question_state::$mangrpartial); 178 $this->check_current_mark(1); 179 $this->check_current_output( 180 $this->get_contains_mark_summary(1), 181 $this->get_contains_partcorrect_expectation()); 182 183 $autogradedstep = $this->get_step($this->get_step_count() - 2); 184 $this->assertEqualsWithDelta($autogradedstep->get_fraction(), 1, 0.0000001); 185 } 186 187 public function test_adaptive_multichoice2() { 188 189 // Create a multiple choice, multiple response question. 190 $mc = test_question_maker::make_a_multichoice_multi_question(); 191 $mc->penalty = 0.3333333; 192 $mc->shuffleanswers = 0; 193 $this->start_attempt_at_question($mc, 'adaptive', 2); 194 195 // Check the initial state. 196 $this->check_current_state(question_state::$todo); 197 $this->check_current_mark(null); 198 $this->check_current_output( 199 $this->get_contains_marked_out_of_summary(), 200 $this->get_contains_question_text_expectation($mc), 201 $this->get_contains_submit_button_expectation(true), 202 $this->get_does_not_contain_feedback_expectation()); 203 204 // Process a submit. 205 $this->process_submission(array('choice0' => 1, 'choice2' => 1, '-submit' => 1)); 206 207 // Verify. 208 $this->check_current_state(question_state::$complete); 209 $this->check_current_mark(2); 210 $this->check_current_output( 211 $this->get_contains_mark_summary(2), 212 $this->get_contains_submit_button_expectation(true), 213 $this->get_contains_correct_expectation(), 214 $this->get_does_not_contain_penalty_info_expectation(), 215 $this->get_does_not_contain_total_penalty_expectation()); 216 217 // Save the same correct answer again. Should not do anything. 218 $numsteps = $this->get_step_count(); 219 $this->process_submission(array('choice0' => 1, 'choice2' => 1)); 220 221 // Verify. 222 $this->check_step_count($numsteps); 223 $this->check_current_mark(2); 224 $this->check_current_state(question_state::$complete); 225 226 // Finish the attempt. 227 $this->quba->finish_all_questions(); 228 229 // Verify. 230 $this->check_step_count($numsteps + 1); 231 $this->check_current_state(question_state::$gradedright); 232 $this->check_current_mark(2); 233 $this->check_current_output( 234 $this->get_contains_mark_summary(2), 235 $this->get_does_not_contain_submit_button_expectation(), 236 $this->get_contains_correct_expectation()); 237 } 238 239 public function test_adaptive_shortanswer_partially_right() { 240 241 // Create a short answer question. 242 $sa = test_question_maker::make_question('shortanswer'); 243 $this->start_attempt_at_question($sa, 'adaptive'); 244 245 // Check the initial state. 246 $this->check_current_state(question_state::$todo); 247 $this->check_current_mark(null); 248 $this->render(); 249 $this->check_output_does_not_contain_text_input_with_class('answer', 'correct'); 250 $this->check_output_does_not_contain_text_input_with_class('answer', 'partiallycorrect'); 251 $this->check_output_does_not_contain_text_input_with_class('answer', 'incorrect'); 252 $this->check_current_output( 253 $this->get_contains_marked_out_of_summary(), 254 $this->get_contains_submit_button_expectation(true), 255 $this->get_does_not_contain_feedback_expectation()); 256 257 // Submit a partially correct answer. 258 $this->process_submission(array('-submit' => 1, 'answer' => 'toad')); 259 260 // Verify. 261 $this->check_current_state(question_state::$todo); 262 $this->check_current_mark(0.8); 263 $this->render(); 264 $this->check_output_contains_text_input_with_class('answer', 'partiallycorrect'); 265 $this->check_current_output( 266 $this->get_contains_mark_summary(0.8), 267 $this->get_contains_submit_button_expectation(true), 268 $this->get_contains_partcorrect_expectation(), 269 $this->get_contains_penalty_info_expectation(0.33), 270 $this->get_does_not_contain_total_penalty_expectation(), 271 $this->get_does_not_contain_validation_error_expectation()); 272 273 // Submit an incorrect answer. 274 $this->process_submission(array('-submit' => 1, 'answer' => 'bumblebee')); 275 276 // Verify. 277 $this->check_current_state(question_state::$todo); 278 $this->check_current_mark(0.8); 279 $this->render(); 280 $this->check_output_contains_text_input_with_class('answer', 'incorrect'); 281 $this->check_current_output( 282 $this->get_contains_mark_summary(0.8), 283 $this->get_contains_submit_button_expectation(true), 284 $this->get_contains_incorrect_expectation(), 285 $this->get_contains_penalty_info_expectation(0.33), 286 $this->get_contains_total_penalty_expectation(0.67), 287 $this->get_does_not_contain_validation_error_expectation()); 288 289 // Submit a correct answer. 290 $this->process_submission(array('-submit' => 1, 'answer' => 'frog')); 291 292 // Verify. 293 $this->check_current_state(question_state::$complete); 294 $this->check_current_mark(0.8); 295 $this->render(); 296 $this->check_output_contains_text_input_with_class('answer', 'correct'); 297 $this->check_current_output( 298 $this->get_contains_mark_summary(0.8), 299 $this->get_contains_submit_button_expectation(true), 300 $this->get_contains_correct_expectation(), 301 $this->get_does_not_contain_penalty_info_expectation(), 302 $this->get_does_not_contain_total_penalty_expectation(), 303 $this->get_does_not_contain_validation_error_expectation()); 304 305 // Finish the attempt. 306 $this->quba->finish_all_questions(); 307 308 // Verify. 309 $this->check_current_state(question_state::$gradedright); 310 $this->check_current_mark(0.8); 311 $this->check_current_output( 312 $this->get_contains_mark_summary(0.8), 313 $this->get_does_not_contain_submit_button_expectation(), 314 $this->get_contains_correct_expectation(), 315 $this->get_does_not_contain_validation_error_expectation()); 316 } 317 318 public function test_adaptive_shortanswer_wrong_right_wrong() { 319 320 // Create a short answer question. 321 $sa = test_question_maker::make_question('shortanswer'); 322 $this->start_attempt_at_question($sa, 'adaptive', 6); 323 324 // Check the initial state. 325 $this->check_current_state(question_state::$todo); 326 $this->check_current_mark(null); 327 $this->check_current_output( 328 $this->get_contains_marked_out_of_summary(), 329 $this->get_contains_submit_button_expectation(true), 330 $this->get_does_not_contain_feedback_expectation()); 331 332 // Submit a wrong answer. 333 $this->process_submission(array('-submit' => 1, 'answer' => 'hippopotamus')); 334 335 // Verify. 336 $this->check_current_state(question_state::$todo); 337 $this->check_current_mark(0); 338 $this->check_current_output( 339 $this->get_contains_mark_summary(0), 340 $this->get_contains_submit_button_expectation(true), 341 $this->get_contains_incorrect_expectation(), 342 $this->get_contains_penalty_info_expectation(2.00), 343 $this->get_does_not_contain_total_penalty_expectation(), 344 $this->get_does_not_contain_validation_error_expectation()); 345 346 // Submit the same wrong answer again. Nothing should change. 347 $this->process_submission(array('-submit' => 1, 'answer' => 'hippopotamus')); 348 349 // Verify. 350 $this->check_current_state(question_state::$todo); 351 $this->check_current_mark(0); 352 $this->check_current_output( 353 $this->get_contains_mark_summary(0), 354 $this->get_contains_submit_button_expectation(true), 355 $this->get_contains_incorrect_expectation(), 356 $this->get_contains_penalty_info_expectation(2.00), 357 $this->get_does_not_contain_total_penalty_expectation(), 358 $this->get_does_not_contain_validation_error_expectation()); 359 360 // Submit a correct answer. 361 $this->process_submission(array('-submit' => 1, 'answer' => 'frog')); 362 363 // Verify. 364 $this->check_current_state(question_state::$complete); 365 $this->check_current_mark(4.00); 366 $this->check_current_output( 367 $this->get_contains_mark_summary(4.00), 368 $this->get_contains_submit_button_expectation(true), 369 $this->get_contains_correct_expectation(), 370 $this->get_does_not_contain_penalty_info_expectation(), 371 $this->get_does_not_contain_total_penalty_expectation(), 372 $this->get_does_not_contain_validation_error_expectation()); 373 374 // Submit another incorrect answer. 375 $this->process_submission(array('-submit' => 1, 'answer' => 'bumblebee')); 376 377 // Verify. 378 $this->check_current_state(question_state::$complete); 379 $this->check_current_mark(4.00); 380 $this->check_current_output( 381 $this->get_contains_mark_summary(4.00), 382 $this->get_contains_submit_button_expectation(true), 383 $this->get_contains_incorrect_expectation(), 384 $this->get_does_not_contain_penalty_info_expectation(), 385 $this->get_does_not_contain_total_penalty_expectation(), 386 $this->get_does_not_contain_validation_error_expectation()); 387 388 // Finish the attempt. 389 $this->quba->finish_all_questions(); 390 391 // Verify. 392 $this->check_current_state(question_state::$gradedwrong); 393 $this->check_current_mark(4.00); 394 $this->check_current_output( 395 $this->get_contains_mark_summary(4.00), 396 $this->get_does_not_contain_submit_button_expectation(), 397 $this->get_contains_incorrect_expectation(), 398 $this->get_does_not_contain_validation_error_expectation()); 399 } 400 401 public function test_adaptive_shortanswer_invalid_after_complete() { 402 403 // Create a short answer question. 404 $sa = test_question_maker::make_question('shortanswer'); 405 $this->start_attempt_at_question($sa, 'adaptive'); 406 407 // Check the initial state. 408 $this->check_current_state(question_state::$todo); 409 $this->check_current_mark(null); 410 $this->check_current_output( 411 $this->get_contains_marked_out_of_summary(), 412 $this->get_contains_submit_button_expectation(true), 413 $this->get_does_not_contain_feedback_expectation()); 414 415 // Submit a wrong answer. 416 $this->process_submission(array('-submit' => 1, 'answer' => 'hippopotamus')); 417 418 // Verify. 419 $this->check_current_state(question_state::$todo); 420 $this->check_current_mark(0); 421 $this->check_current_output( 422 $this->get_contains_mark_summary(0), 423 $this->get_contains_submit_button_expectation(true), 424 $this->get_contains_incorrect_expectation(), 425 $this->get_contains_penalty_info_expectation(0.33), 426 $this->get_does_not_contain_total_penalty_expectation(), 427 $this->get_does_not_contain_validation_error_expectation()); 428 429 // Submit a correct answer. 430 $this->process_submission(array('-submit' => 1, 'answer' => 'frog')); 431 432 // Verify. 433 $this->check_current_state(question_state::$complete); 434 $this->check_current_mark(0.66666667); 435 $this->check_current_output( 436 $this->get_contains_mark_summary(0.67), 437 $this->get_contains_submit_button_expectation(true), 438 $this->get_contains_correct_expectation(), 439 $this->get_does_not_contain_penalty_info_expectation(), 440 $this->get_does_not_contain_total_penalty_expectation(), 441 $this->get_does_not_contain_validation_error_expectation()); 442 443 // Submit an empty answer. 444 $this->process_submission(array('-submit' => 1, 'answer' => '')); 445 446 // Verify. 447 $this->check_current_state(question_state::$invalid); 448 $this->check_current_mark(0.66666667); 449 $this->check_current_output( 450 $this->get_contains_mark_summary(0.67), 451 $this->get_contains_submit_button_expectation(true), 452 $this->get_does_not_contain_penalty_info_expectation(), 453 $this->get_does_not_contain_total_penalty_expectation(), 454 $this->get_contains_validation_error_expectation()); 455 456 // Submit another wrong answer. 457 $this->process_submission(array('-submit' => 1, 'answer' => 'bumblebee')); 458 459 // Verify. 460 $this->check_current_state(question_state::$complete); 461 $this->check_current_mark(0.66666667); 462 $this->check_current_output( 463 $this->get_contains_mark_summary(0.67), 464 $this->get_contains_submit_button_expectation(true), 465 $this->get_contains_incorrect_expectation(), 466 $this->get_does_not_contain_penalty_info_expectation(), 467 $this->get_does_not_contain_total_penalty_expectation(), 468 $this->get_does_not_contain_validation_error_expectation()); 469 470 // Finish the attempt. 471 $this->quba->finish_all_questions(); 472 473 // Verify. 474 $this->check_current_state(question_state::$gradedwrong); 475 $this->check_current_mark(0.66666667); 476 $this->check_current_output( 477 $this->get_contains_mark_summary(0.67), 478 $this->get_does_not_contain_submit_button_expectation(), 479 $this->get_contains_incorrect_expectation(), 480 $this->get_does_not_contain_validation_error_expectation()); 481 } 482 483 public function test_adaptive_shortanswer_zero_penalty() { 484 485 // Create a short answer question. 486 $sa = test_question_maker::make_question('shortanswer'); 487 // Disable penalties for this question. 488 $sa->penalty = 0; 489 $this->start_attempt_at_question($sa, 'adaptive'); 490 491 // Check the initial state. 492 $this->check_current_state(question_state::$todo); 493 $this->check_current_mark(null); 494 $this->check_current_output( 495 $this->get_contains_marked_out_of_summary(), 496 $this->get_contains_submit_button_expectation(true), 497 $this->get_does_not_contain_feedback_expectation()); 498 499 // Submit a wrong answer. 500 $this->process_submission(array('-submit' => 1, 'answer' => 'hippopotamus')); 501 502 // Verify. 503 $this->check_current_state(question_state::$todo); 504 $this->check_current_mark(0); 505 $this->check_current_output( 506 $this->get_contains_mark_summary(0), 507 $this->get_contains_submit_button_expectation(true), 508 $this->get_contains_incorrect_expectation(), 509 $this->get_does_not_contain_penalty_info_expectation(), 510 $this->get_does_not_contain_total_penalty_expectation(), 511 $this->get_does_not_contain_validation_error_expectation()); 512 513 // Submit a correct answer. 514 $this->process_submission(array('-submit' => 1, 'answer' => 'frog')); 515 516 // Verify. 517 $this->check_current_state(question_state::$complete); 518 $this->check_current_mark(1.0); 519 $this->check_current_output( 520 $this->get_contains_mark_summary(1.0), 521 $this->get_contains_submit_button_expectation(true), 522 $this->get_contains_correct_expectation(), 523 $this->get_does_not_contain_penalty_info_expectation(), 524 $this->get_does_not_contain_total_penalty_expectation(), 525 $this->get_does_not_contain_validation_error_expectation()); 526 527 // Finish the attempt. 528 $this->quba->finish_all_questions(); 529 530 // Verify. 531 $this->check_current_state(question_state::$gradedright); 532 $this->check_current_mark(1.0); 533 $this->check_current_output( 534 $this->get_contains_mark_summary(1.0), 535 $this->get_does_not_contain_submit_button_expectation(), 536 $this->get_contains_correct_expectation(), 537 $this->get_does_not_contain_validation_error_expectation()); 538 } 539 540 public function test_adaptive_shortanswer_try_to_submit_blank() { 541 542 // Create a short answer question with correct answer true. 543 $sa = test_question_maker::make_question('shortanswer'); 544 $this->start_attempt_at_question($sa, 'adaptive'); 545 546 // Check the initial state. 547 $this->check_current_state(question_state::$todo); 548 $this->check_current_mark(null); 549 $this->check_current_output( 550 $this->get_contains_marked_out_of_summary(), 551 $this->get_contains_submit_button_expectation(true), 552 $this->get_does_not_contain_feedback_expectation()); 553 554 // Submit with blank answer. 555 $this->process_submission(array('-submit' => 1, 'answer' => '')); 556 557 // Verify. 558 $this->check_current_state(question_state::$invalid); 559 $this->check_current_mark(null); 560 $this->check_current_output( 561 $this->get_contains_marked_out_of_summary(), 562 $this->get_contains_submit_button_expectation(true), 563 $this->get_does_not_contain_correctness_expectation(), 564 $this->get_does_not_contain_penalty_info_expectation(), 565 $this->get_does_not_contain_total_penalty_expectation(), 566 $this->get_contains_validation_error_expectation(), 567 $this->get_contains_disregarded_info_expectation()); 568 $this->assertNull($this->quba->get_response_summary($this->slot)); 569 570 // Now get it wrong. 571 $this->process_submission(array('-submit' => 1, 'answer' => 'toad')); 572 573 // Verify. 574 $this->check_current_state(question_state::$todo); 575 $this->check_current_mark(0.8); 576 $this->check_current_output( 577 $this->get_contains_mark_summary(0.8), 578 $this->get_contains_submit_button_expectation(true), 579 $this->get_contains_partcorrect_expectation(), 580 $this->get_contains_penalty_info_expectation(0.33), 581 $this->get_does_not_contain_total_penalty_expectation(), 582 $this->get_does_not_contain_validation_error_expectation()); 583 584 // Now submit blank again. 585 $this->process_submission(array('-submit' => 1, 'answer' => '')); 586 587 // Verify. 588 $this->check_current_state(question_state::$invalid); 589 $this->check_current_mark(0.8); 590 $this->check_current_output( 591 $this->get_contains_mark_summary(0.8), 592 $this->get_contains_submit_button_expectation(true), 593 $this->get_does_not_contain_correctness_expectation(), 594 $this->get_does_not_contain_penalty_info_expectation(), 595 $this->get_does_not_contain_total_penalty_expectation(), 596 $this->get_contains_validation_error_expectation()); 597 } 598 599 public function test_adaptive_numerical() { 600 601 // Create a numerical question. 602 $sa = test_question_maker::make_question('numerical', 'pi'); 603 $this->start_attempt_at_question($sa, 'adaptive'); 604 605 // Check the initial state. 606 $this->check_current_state(question_state::$todo); 607 $this->check_current_mark(null); 608 $this->check_current_output( 609 $this->get_contains_marked_out_of_summary(), 610 $this->get_contains_submit_button_expectation(true), 611 $this->get_does_not_contain_feedback_expectation()); 612 613 // Submit the correct answer. 614 $this->process_submission(array('-submit' => 1, 'answer' => '3.14')); 615 616 // Verify. 617 $this->check_current_state(question_state::$complete); 618 $this->check_current_mark(1); 619 $this->check_current_output( 620 $this->get_contains_mark_summary(1), 621 $this->get_contains_submit_button_expectation(true), 622 $this->get_contains_correct_expectation(), 623 $this->get_does_not_contain_penalty_info_expectation(), 624 $this->get_does_not_contain_total_penalty_expectation(), 625 $this->get_does_not_contain_validation_error_expectation()); 626 627 // Submit an incorrect answer. 628 $this->process_submission(array('-submit' => 1, 'answer' => '-5')); 629 630 // Verify. 631 $this->check_current_state(question_state::$complete); 632 $this->check_current_mark(1); 633 $this->check_current_output( 634 $this->get_contains_mark_summary(1), 635 $this->get_contains_submit_button_expectation(true), 636 $this->get_contains_incorrect_expectation(), 637 $this->get_does_not_contain_penalty_info_expectation(), 638 $this->get_does_not_contain_total_penalty_expectation(), 639 $this->get_does_not_contain_validation_error_expectation()); 640 641 // Finish the attempt. 642 $this->quba->finish_all_questions(); 643 644 // Verify. 645 $this->check_current_state(question_state::$gradedwrong); 646 $this->check_current_mark(1); 647 $this->check_current_output( 648 $this->get_contains_mark_summary(1), 649 $this->get_does_not_contain_submit_button_expectation(), 650 $this->get_contains_incorrect_expectation(), 651 $this->get_does_not_contain_validation_error_expectation()); 652 } 653 654 public function test_adaptive_numerical_invalid() { 655 656 // Create a numerical question. 657 $numq = test_question_maker::make_question('numerical', 'pi'); 658 $numq->penalty = 0.1; 659 $this->start_attempt_at_question($numq, 'adaptive'); 660 661 // Check the initial state. 662 $this->check_current_state(question_state::$todo); 663 $this->check_current_mark(null); 664 $this->check_current_output( 665 $this->get_contains_marked_out_of_summary(), 666 $this->get_contains_submit_button_expectation(true), 667 $this->get_does_not_contain_feedback_expectation()); 668 669 // Submit a non-numerical answer. 670 $this->process_submission(array('-submit' => 1, 'answer' => 'Pi')); 671 672 // Verify. 673 $this->check_current_state(question_state::$invalid); 674 $this->check_current_mark(null); 675 $this->check_current_output( 676 $this->get_contains_marked_out_of_summary(1), 677 $this->get_contains_submit_button_expectation(true), 678 $this->get_does_not_contain_correctness_expectation(), 679 $this->get_does_not_contain_penalty_info_expectation(), 680 $this->get_does_not_contain_total_penalty_expectation(), 681 $this->get_contains_validation_error_expectation(), 682 $this->get_contains_disregarded_info_expectation()); 683 684 // Submit an incorrect answer. 685 $this->process_submission(array('-submit' => 1, 'answer' => '-5')); 686 687 // Verify. 688 $this->check_current_state(question_state::$todo); 689 $this->check_current_mark(0); 690 $this->check_current_output( 691 $this->get_contains_mark_summary(0), 692 $this->get_contains_submit_button_expectation(true), 693 $this->get_contains_incorrect_expectation(), 694 $this->get_contains_penalty_info_expectation(0.1), 695 $this->get_does_not_contain_total_penalty_expectation(), 696 $this->get_does_not_contain_validation_error_expectation(), 697 $this->get_does_not_contain_disregarded_info_expectation()); 698 699 // Submit another non-numerical answer. 700 $this->process_submission(array('-submit' => 1, 'answer' => 'Pi*2')); 701 702 // Verify. 703 $this->check_current_state(question_state::$invalid); 704 $this->check_current_mark(0); 705 $this->check_current_output( 706 $this->get_contains_mark_summary(0), 707 $this->get_contains_submit_button_expectation(true), 708 $this->get_does_not_contain_correctness_expectation(), 709 $this->get_does_not_contain_penalty_info_expectation(), 710 $this->get_does_not_contain_total_penalty_expectation(), 711 $this->get_contains_validation_error_expectation(), 712 $this->get_contains_disregarded_info_expectation()); 713 714 // Submit the correct answer. 715 $this->process_submission(array('-submit' => 1, 'answer' => '3.14')); 716 717 // Verify. 718 $this->check_current_state(question_state::$complete); 719 $this->check_current_mark(0.9); 720 $this->check_current_output( 721 $this->get_contains_mark_summary(0.9), 722 $this->get_contains_submit_button_expectation(true), 723 $this->get_contains_correct_expectation(), 724 $this->get_does_not_contain_penalty_info_expectation(), 725 $this->get_does_not_contain_total_penalty_expectation(), 726 $this->get_does_not_contain_validation_error_expectation(), 727 $this->get_does_not_contain_disregarded_info_expectation()); 728 729 // Submit another non-numerical answer. 730 $this->process_submission(array('-submit' => 1, 'answer' => 'Pi/3')); 731 732 // Verify. 733 $this->check_current_state(question_state::$invalid); 734 $this->check_current_mark(0.9); 735 $this->check_current_output( 736 $this->get_contains_mark_summary(0.9), 737 $this->get_contains_submit_button_expectation(true), 738 $this->get_does_not_contain_correctness_expectation(), 739 $this->get_does_not_contain_penalty_info_expectation(), 740 $this->get_does_not_contain_total_penalty_expectation(), 741 $this->get_contains_validation_error_expectation(), 742 $this->get_contains_disregarded_info_expectation()); 743 744 // Finish the attempt. 745 $this->quba->finish_all_questions(); 746 747 // Verify. 748 $this->check_current_state(question_state::$gradedwrong); 749 $this->check_current_mark(0.9); 750 $this->check_current_output( 751 $this->get_contains_mark_summary(0.9), 752 $this->get_does_not_contain_submit_button_expectation(), 753 $this->get_contains_incorrect_expectation(), 754 $this->get_does_not_contain_validation_error_expectation(), 755 $this->get_does_not_contain_disregarded_info_expectation()); 756 } 757 758 public function test_adaptive_multianswer() { 759 760 // Create a multianswer question. 761 $q = test_question_maker::make_question('multianswer', 'twosubq'); 762 // To simplify testing, multichoice subquestion's answers are not shuffled. 763 $q->subquestions[2]->shuffleanswers = 0; 764 $choices = array('0' => 'Bow-wow', '1' => 'Wiggly worm', '2' => 'Pussy-cat'); 765 766 $this->start_attempt_at_question($q, 'adaptive', 12); 767 768 // Check the initial state. 769 $this->check_current_state(question_state::$todo); 770 $this->check_current_mark(null); 771 $this->assertEquals('adaptive', 772 $this->quba->get_question_attempt($this->slot)->get_behaviour_name()); 773 $this->render(); 774 $this->check_output_contains_text_input('sub1_answer', '', true); 775 $this->check_output_does_not_contain_text_input_with_class('sub1_answer', 'correct'); 776 $this->check_output_does_not_contain_text_input_with_class('sub1_answer', 'partiallycorrect'); 777 $this->check_output_does_not_contain_text_input_with_class('sub1_answer', 'incorrect'); 778 $this->check_current_output( 779 $this->get_contains_marked_out_of_summary(), 780 $this->get_contains_submit_button_expectation(true), 781 $this->get_does_not_contain_validation_error_expectation(), 782 $this->get_does_not_contain_feedback_expectation()); 783 $this->check_output_contains_selectoptions( 784 $this->get_contains_select_expectation('sub2_answer', $choices, null, true)); 785 786 // Submit an invalid response. 787 $this->process_submission(array('sub1_answer' => '', 'sub2_answer' => 1, '-submit' => 1)); 788 789 // Verify. 790 $this->check_current_state(question_state::$invalid); 791 $this->check_current_mark(null); 792 $this->check_output_contains_text_input('sub1_answer', '', true); 793 $this->check_current_output( 794 $this->get_contains_submit_button_expectation(true), 795 $this->get_does_not_contain_penalty_info_expectation(), 796 $this->get_does_not_contain_total_penalty_expectation(), 797 $this->get_contains_disregarded_info_expectation()); 798 $this->check_output_contains_selectoptions( 799 $this->get_contains_select_expectation('sub2_answer', $choices, 1, true)); 800 801 // Check that extract responses will return the reset data. 802 $prefix = $this->quba->get_field_prefix($this->slot); 803 $this->assertEquals(array('sub2_answer' => 1), 804 $this->quba->extract_responses($this->slot, array($prefix . 'sub2_answer' => 1))); 805 806 // Submit an incorrect response. 807 $this->process_submission(array('sub1_answer' => 'Dog', 808 'sub2_answer' => 1, '-submit' => 1)); 809 810 // Verify. 811 $this->check_current_state(question_state::$todo); 812 $this->check_current_mark(0); 813 $this->render(); 814 $this->check_output_contains_text_input('sub1_answer', 'Dog', true); 815 $this->check_output_contains_text_input_with_class('sub1_answer', 'incorrect'); 816 $this->check_current_output( 817 $this->get_contains_mark_summary(0), 818 $this->get_contains_submit_button_expectation(true), 819 $this->get_contains_incorrect_expectation(), 820 $this->get_contains_penalty_info_expectation(4.00), 821 $this->get_does_not_contain_validation_error_expectation()); 822 $this->check_output_contains_selectoptions( 823 $this->get_contains_select_expectation('sub2_answer', $choices, 1, true)); 824 825 // Submit the right answer. 826 $this->process_submission(array('sub1_answer' => 'Owl', 'sub2_answer' => 2, '-submit' => 1)); 827 828 // Verify. 829 $this->check_current_state(question_state::$complete); 830 $this->check_current_mark(8.00); 831 $this->render(); 832 $this->check_output_contains_text_input('sub1_answer', 'Owl', true); 833 $this->check_output_contains_text_input_with_class('sub1_answer', 'correct'); 834 $this->check_current_output( 835 $this->get_contains_mark_summary(8.00), 836 $this->get_contains_submit_button_expectation(true), 837 $this->get_contains_correct_expectation(), 838 $this->get_does_not_contain_penalty_info_expectation(), 839 $this->get_does_not_contain_total_penalty_expectation(), 840 $this->get_does_not_contain_validation_error_expectation()); 841 $this->check_output_contains_selectoptions( 842 $this->get_contains_select_expectation('sub2_answer', $choices, '2', true)); 843 844 // Finish the attempt. 845 $this->quba->finish_all_questions(); 846 847 // Verify. 848 $this->check_current_state(question_state::$gradedright); 849 $this->check_current_mark(8.00); 850 $this->render(); 851 $this->check_output_contains_text_input('sub1_answer', 'Owl', false); 852 $this->check_output_contains_text_input_with_class('sub1_answer', 'correct'); 853 $this->check_current_output( 854 $this->get_contains_mark_summary(8.00), 855 $this->get_does_not_contain_submit_button_expectation(), 856 $this->get_contains_correct_expectation(), 857 $this->get_does_not_contain_validation_error_expectation()); 858 } 859 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body