Differences Between: [Versions 310 and 311] [Versions 39 and 311]
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 qbehaviour_adaptivenopenalty; 18 19 use question_state; 20 21 defined('MOODLE_INTERNAL') || die(); 22 23 global $CFG; 24 require_once (__DIR__ . '/../../../engine/lib.php'); 25 require_once (__DIR__ . '/../../../engine/tests/helpers.php'); 26 27 28 /** 29 * Unit tests for the adaptive (no penalties) behaviour. 30 * 31 * @package qbehaviour_adaptivenopenalty 32 * @copyright 2009 The Open University 33 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 34 */ 35 class walkthrough_test extends \qbehaviour_walkthrough_test_base { 36 37 protected function get_does_not_contain_gradingdetails_expectation() { 38 return new \question_no_pattern_expectation('/class="gradingdetails"/'); 39 } 40 41 protected function get_does_not_contain_penalty_info_expectation() { 42 $penaltyinfo = get_string('gradingdetailspenalty', 'qbehaviour_adaptive', 'XXXXX'); 43 $penaltypattern = '/'.str_replace('XXXXX', '\\w*', preg_quote($penaltyinfo, '/')).'/'; 44 return new \question_no_pattern_expectation($penaltypattern); 45 } 46 47 protected function get_does_not_contain_total_penalty_expectation() { 48 $penaltyinfo = get_string('gradingdetailspenaltytotal', 'qbehaviour_adaptive', 'XXXXX'); 49 $penaltypattern = '/'.str_replace('XXXXX', '\\w*', preg_quote($penaltyinfo, '/')).'/'; 50 return new \question_no_pattern_expectation($penaltypattern); 51 } 52 53 public function test_multichoice() { 54 55 // Create a multiple choice, single response question. 56 $mc = \test_question_maker::make_a_multichoice_single_question(); 57 $mc->penalty = 0.3333333; 58 $this->start_attempt_at_question($mc, 'adaptivenopenalty', 3); 59 60 $rightindex = $this->get_mc_right_answer_index($mc); 61 $wrongindex = ($rightindex + 1) % 3; 62 63 // Check the initial state. 64 $this->check_current_state(question_state::$todo); 65 $this->check_current_mark(null); 66 $this->check_current_output( 67 $this->get_contains_marked_out_of_summary(), 68 $this->get_contains_question_text_expectation($mc), 69 $this->get_contains_mc_radio_expectation(0, true, false), 70 $this->get_contains_mc_radio_expectation(1, true, false), 71 $this->get_contains_mc_radio_expectation(2, true, false), 72 $this->get_contains_submit_button_expectation(true), 73 $this->get_does_not_contain_feedback_expectation()); 74 75 // Process a submit. 76 $this->process_submission(array('answer' => $wrongindex, '-submit' => 1)); 77 78 // Verify. 79 $this->check_current_state(question_state::$todo); 80 $this->check_current_mark(0); 81 $this->check_current_output( 82 $this->get_contains_mark_summary(0), 83 $this->get_contains_mc_radio_expectation($wrongindex, true, true), 84 $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, true, false), 85 $this->get_contains_mc_radio_expectation(($wrongindex + 2) % 3, true, false), 86 $this->get_contains_incorrect_expectation(), 87 $this->get_does_not_contain_penalty_info_expectation(), 88 $this->get_does_not_contain_total_penalty_expectation()); 89 $this->assertMatchesRegularExpression('/B|C/', 90 $this->quba->get_response_summary($this->slot)); 91 92 // Process a change of answer to the right one, but not sumbitted. 93 $this->process_submission(array('answer' => $rightindex)); 94 95 // Verify. 96 $this->check_current_state(question_state::$todo); 97 $this->check_current_mark(0); 98 $this->check_current_output( 99 $this->get_contains_mark_summary(0), 100 $this->get_contains_mc_radio_expectation($rightindex, true, true), 101 $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, true, false), 102 $this->get_contains_mc_radio_expectation(($rightindex + 2) % 3, true, false)); 103 $this->assertMatchesRegularExpression('/B|C/', 104 $this->quba->get_response_summary($this->slot)); 105 106 // Now submit the right answer. 107 $this->process_submission(array('answer' => $rightindex, '-submit' => 1)); 108 109 // Verify. 110 $this->check_current_state(question_state::$complete); 111 $this->check_current_mark(3); 112 $this->check_current_output( 113 $this->get_contains_mark_summary(3), 114 $this->get_contains_mc_radio_expectation($rightindex, true, true), 115 $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, true, false), 116 $this->get_contains_mc_radio_expectation(($rightindex + 2) % 3, true, false), 117 $this->get_contains_correct_expectation(), 118 $this->get_does_not_contain_penalty_info_expectation(), 119 $this->get_does_not_contain_total_penalty_expectation()); 120 $this->assertEquals('A', 121 $this->quba->get_response_summary($this->slot)); 122 123 // Finish the attempt. 124 $this->quba->finish_all_questions(); 125 126 // Verify. 127 $this->check_current_state(question_state::$gradedright); 128 $this->check_current_mark(3); 129 $this->check_current_output( 130 $this->get_contains_mark_summary(3), 131 $this->get_contains_mc_radio_expectation($rightindex, false, true), 132 $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false), 133 $this->get_contains_mc_radio_expectation(($rightindex + 2) % 3, false, false), 134 $this->get_contains_correct_expectation()); 135 136 // Process a manual comment. 137 $this->manual_grade('Not good enough!', 1, FORMAT_HTML); 138 139 // Verify. 140 $this->check_current_state(question_state::$mangrpartial); 141 $this->check_current_mark(1); 142 $this->check_current_output( 143 $this->get_contains_mark_summary(1), 144 new \question_pattern_expectation('/' . preg_quote('Not good enough!', '/') . '/')); 145 146 // Now change the correct answer to the question, and regrade. 147 $mc->answers[13]->fraction = -0.33333333; 148 $mc->answers[14]->fraction = 1; // We don't know which "wrong" index we chose above! 149 $mc->answers[15]->fraction = 1; // Therefore, treat answers B and C with the same score. 150 $this->quba->regrade_all_questions(); 151 152 // Verify. 153 $this->check_current_state(question_state::$mangrpartial); 154 $this->check_current_mark(1); 155 $this->check_current_output( 156 $this->get_contains_mark_summary(1), 157 $this->get_contains_partcorrect_expectation()); 158 159 $autogradedstep = $this->get_step($this->get_step_count() - 3); 160 $this->assertEqualsWithDelta($autogradedstep->get_fraction(), 1, 0.0000001); 161 } 162 163 public function test_multichoice2() { 164 165 // Create a multiple choice, multiple response question. 166 $mc = \test_question_maker::make_a_multichoice_multi_question(); 167 $mc->penalty = 0.3333333; 168 $mc->shuffleanswers = 0; 169 $this->start_attempt_at_question($mc, 'adaptivenopenalty', 2); 170 171 // Check the initial state. 172 $this->check_current_state(question_state::$todo); 173 $this->check_current_mark(null); 174 $this->check_current_output( 175 $this->get_contains_marked_out_of_summary(), 176 $this->get_contains_question_text_expectation($mc), 177 $this->get_contains_submit_button_expectation(true), 178 $this->get_does_not_contain_feedback_expectation()); 179 180 // Process a submit. 181 $this->process_submission(array('choice0' => 1, 'choice2' => 1, '-submit' => 1)); 182 183 // Verify. 184 $this->check_current_state(question_state::$complete); 185 $this->check_current_mark(2); 186 $this->check_current_output( 187 $this->get_contains_mark_summary(2), 188 $this->get_contains_submit_button_expectation(true), 189 $this->get_contains_correct_expectation(), 190 $this->get_does_not_contain_penalty_info_expectation(), 191 $this->get_does_not_contain_total_penalty_expectation()); 192 193 // Save the same correct answer again. Should no do anything. 194 $numsteps = $this->get_step_count(); 195 $this->process_submission(array('choice0' => 1, 'choice2' => 1)); 196 197 // Verify. 198 $this->check_step_count($numsteps); 199 $this->check_current_state(question_state::$complete); 200 201 // Finish the attempt. 202 $this->quba->finish_all_questions(); 203 204 // Verify. 205 $this->check_step_count($numsteps + 1); 206 $this->check_current_state(question_state::$gradedright); 207 $this->check_current_mark(2); 208 $this->check_current_output( 209 $this->get_contains_mark_summary(2), 210 $this->get_does_not_contain_submit_button_expectation(), 211 $this->get_contains_correct_expectation()); 212 } 213 214 public function test_numerical_invalid() { 215 216 // Create a numerical question 217 $numq = \test_question_maker::make_question('numerical', 'pi'); 218 $numq->penalty = 0.1; 219 $this->start_attempt_at_question($numq, 'adaptivenopenalty'); 220 221 // Check the initial state. 222 $this->check_current_state(question_state::$todo); 223 $this->check_current_mark(null); 224 $this->check_current_output( 225 $this->get_contains_marked_out_of_summary(), 226 $this->get_contains_submit_button_expectation(true), 227 $this->get_does_not_contain_feedback_expectation()); 228 229 // Submit a non-numerical answer. 230 $this->process_submission(array('-submit' => 1, 'answer' => 'Pi')); 231 232 // Verify. 233 $this->check_current_state(question_state::$invalid); 234 $this->check_current_mark(null); 235 $this->check_current_output( 236 $this->get_contains_marked_out_of_summary(1), 237 $this->get_contains_submit_button_expectation(true), 238 $this->get_does_not_contain_correctness_expectation(), 239 $this->get_contains_validation_error_expectation(), 240 $this->get_does_not_contain_feedback_expectation()); 241 242 // Submit an incorrect answer. 243 $this->process_submission(array('-submit' => 1, 'answer' => '-5')); 244 245 // Verify. 246 $this->check_current_state(question_state::$todo); 247 $this->check_current_mark(0); 248 $this->check_current_output( 249 $this->get_contains_mark_summary(0), 250 $this->get_contains_submit_button_expectation(true), 251 $this->get_contains_incorrect_expectation(), 252 $this->get_does_not_contain_penalty_info_expectation(), 253 $this->get_does_not_contain_total_penalty_expectation(), 254 $this->get_does_not_contain_validation_error_expectation()); 255 256 // Submit another non-numerical answer. 257 $this->process_submission(array('-submit' => 1, 'answer' => 'Pi*2')); 258 259 // Verify. 260 $this->check_current_state(question_state::$invalid); 261 $this->check_current_mark(0); 262 $this->check_current_output( 263 $this->get_contains_mark_summary(0), 264 $this->get_contains_submit_button_expectation(true), 265 $this->get_does_not_contain_correctness_expectation(), 266 $this->get_contains_validation_error_expectation(), 267 $this->get_does_not_contain_gradingdetails_expectation()); 268 269 // Submit the correct answer. 270 $this->process_submission(array('-submit' => 1, 'answer' => '3.14')); 271 272 // Verify. 273 $this->check_current_state(question_state::$complete); 274 $this->check_current_mark(1.0); 275 $this->check_current_output( 276 $this->get_contains_mark_summary(1.0), 277 $this->get_contains_submit_button_expectation(true), 278 $this->get_contains_correct_expectation(), 279 $this->get_does_not_contain_validation_error_expectation()); 280 281 // Submit another non-numerical answer. 282 $this->process_submission(array('-submit' => 1, 'answer' => 'Pi/3')); 283 284 // Verify. 285 $this->check_current_state(question_state::$invalid); 286 $this->check_current_mark(1.0); 287 $this->check_current_output( 288 $this->get_contains_mark_summary(1.0), 289 $this->get_contains_submit_button_expectation(true), 290 $this->get_does_not_contain_correctness_expectation(), 291 $this->get_contains_validation_error_expectation(), 292 $this->get_does_not_contain_gradingdetails_expectation()); 293 294 // Finish the attempt. 295 $this->quba->finish_all_questions(); 296 297 // Verify. 298 $this->check_current_state(question_state::$gradedwrong); 299 $this->check_current_mark(1.0); 300 $this->check_current_output( 301 $this->get_contains_mark_summary(1.0), 302 $this->get_does_not_contain_submit_button_expectation(), 303 $this->get_contains_incorrect_expectation(), 304 $this->get_does_not_contain_validation_error_expectation()); 305 } 306 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body