|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 // This file is part of Moodle - http://moodle.org/ 00003 // 00004 // Moodle is free software: you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation, either version 3 of the License, or 00007 // (at your option) any later version. 00008 // 00009 // Moodle is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00016 00028 defined('MOODLE_INTERNAL') || die(); 00029 00030 require_once($CFG->dirroot . '/question/engine/simpletest/helpers.php'); 00031 00032 00039 class qtype_match_walkthrough_test extends qbehaviour_walkthrough_test_base { 00040 00041 public function test_deferred_feedback_unanswered() { 00042 00043 // Create a matching question. 00044 $m = test_question_maker::make_a_matching_question(); 00045 $m->shufflestems = false; 00046 $this->start_attempt_at_question($m, 'deferredfeedback', 4); 00047 00048 $choiceorder = $m->get_choice_order(); 00049 $orderforchoice = array_combine(array_values($choiceorder), array_keys($choiceorder)); 00050 $choices = array(0 => get_string('choose') . '...'); 00051 foreach ($choiceorder as $key => $choice) { 00052 $choices[$key] = $m->choices[$choice]; 00053 } 00054 00055 // Check the initial state. 00056 $this->check_current_state(question_state::$todo); 00057 $this->check_current_mark(null); 00058 $this->check_current_output( 00059 $this->get_contains_select_expectation('sub0', $choices, null, true), 00060 $this->get_contains_select_expectation('sub1', $choices, null, true), 00061 $this->get_contains_select_expectation('sub2', $choices, null, true), 00062 $this->get_contains_select_expectation('sub3', $choices, null, true), 00063 $this->get_contains_question_text_expectation($m), 00064 $this->get_does_not_contain_feedback_expectation()); 00065 $this->check_step_count(1); 00066 00067 // Save a blank response. 00068 $this->process_submission(array('sub0' => '0', 'sub1' => '0', 00069 'sub2' => '0', 'sub3' => '0')); 00070 00071 // Verify. 00072 $this->check_current_state(question_state::$todo); 00073 $this->check_current_mark(null); 00074 $this->check_current_output( 00075 $this->get_contains_select_expectation('sub0', $choices, null, true), 00076 $this->get_contains_select_expectation('sub1', $choices, null, true), 00077 $this->get_contains_select_expectation('sub2', $choices, null, true), 00078 $this->get_contains_select_expectation('sub3', $choices, null, true), 00079 $this->get_contains_question_text_expectation($m), 00080 $this->get_does_not_contain_feedback_expectation()); 00081 $this->check_step_count(1); 00082 00083 // Finish the attempt. 00084 $this->quba->finish_all_questions(); 00085 00086 // Verify. 00087 $this->check_current_state(question_state::$gaveup); 00088 $this->check_current_mark(null); 00089 $this->check_current_output( 00090 $this->get_contains_select_expectation('sub0', $choices, null, false), 00091 $this->get_contains_select_expectation('sub1', $choices, null, false), 00092 $this->get_contains_select_expectation('sub2', $choices, null, false), 00093 $this->get_contains_select_expectation('sub3', $choices, null, false)); 00094 } 00095 00096 public function test_deferred_feedback_partial_answer() { 00097 00098 // Create a matching question. 00099 $m = test_question_maker::make_a_matching_question(); 00100 $m->shufflestems = false; 00101 $this->start_attempt_at_question($m, 'deferredfeedback', 4); 00102 00103 $choiceorder = $m->get_choice_order(); 00104 $orderforchoice = array_combine(array_values($choiceorder), array_keys($choiceorder)); 00105 $choices = array(0 => get_string('choose') . '...'); 00106 foreach ($choiceorder as $key => $choice) { 00107 $choices[$key] = $m->choices[$choice]; 00108 } 00109 00110 // Check the initial state. 00111 $this->check_current_state(question_state::$todo); 00112 $this->check_current_mark(null); 00113 $this->check_current_output( 00114 $this->get_contains_select_expectation('sub0', $choices, null, true), 00115 $this->get_contains_select_expectation('sub1', $choices, null, true), 00116 $this->get_contains_select_expectation('sub2', $choices, null, true), 00117 $this->get_contains_select_expectation('sub3', $choices, null, true), 00118 $this->get_contains_question_text_expectation($m), 00119 $this->get_does_not_contain_feedback_expectation()); 00120 00121 // Save a partial response. 00122 $this->process_submission(array('sub0' => $orderforchoice[1], 00123 'sub1' => $orderforchoice[2], 'sub2' => '0', 'sub3' => '0')); 00124 00125 // Verify. 00126 $this->check_current_state(question_state::$invalid); 00127 $this->check_current_mark(null); 00128 $this->check_current_output( 00129 $this->get_contains_select_expectation('sub0', $choices, 1, true), 00130 $this->get_contains_select_expectation('sub1', $choices, 2, true), 00131 $this->get_contains_select_expectation('sub2', $choices, null, true), 00132 $this->get_contains_select_expectation('sub3', $choices, null, true), 00133 $this->get_contains_question_text_expectation($m), 00134 $this->get_does_not_contain_feedback_expectation()); 00135 00136 // Finish the attempt. 00137 $this->quba->finish_all_questions(); 00138 00139 // Verify. 00140 $this->check_current_state(question_state::$gradedpartial); 00141 $this->check_current_mark(2); 00142 $this->check_current_output( 00143 $this->get_contains_select_expectation('sub0', $choices, 1, false), 00144 $this->get_contains_select_expectation('sub1', $choices, 2, false), 00145 $this->get_contains_select_expectation('sub2', $choices, null, false), 00146 $this->get_contains_select_expectation('sub3', $choices, null, false), 00147 $this->get_contains_partcorrect_expectation()); 00148 } 00149 00150 public function test_interactive_correct_no_submit() { 00151 00152 // Create a matching question. 00153 $m = test_question_maker::make_a_matching_question(); 00154 $m->hints = array( 00155 new question_hint_with_parts(11, 'This is the first hint.', FORMAT_HTML, false, false), 00156 new question_hint_with_parts(12, 'This is the second hint.', FORMAT_HTML, true, true), 00157 ); 00158 $m->shufflestems = false; 00159 $this->start_attempt_at_question($m, 'interactive', 4); 00160 00161 $choiceorder = $m->get_choice_order(); 00162 $orderforchoice = array_combine(array_values($choiceorder), array_keys($choiceorder)); 00163 $choices = array(0 => get_string('choose') . '...'); 00164 foreach ($choiceorder as $key => $choice) { 00165 $choices[$key] = $m->choices[$choice]; 00166 } 00167 00168 // Check the initial state. 00169 $this->check_current_state(question_state::$todo); 00170 $this->check_current_mark(null); 00171 $this->check_current_output( 00172 $this->get_contains_select_expectation('sub0', $choices, null, true), 00173 $this->get_contains_select_expectation('sub1', $choices, null, true), 00174 $this->get_contains_select_expectation('sub2', $choices, null, true), 00175 $this->get_contains_select_expectation('sub3', $choices, null, true), 00176 $this->get_contains_submit_button_expectation(true), 00177 $this->get_does_not_contain_feedback_expectation(), 00178 $this->get_tries_remaining_expectation(3), 00179 $this->get_no_hint_visible_expectation()); 00180 00181 // Save the right answer. 00182 $this->process_submission(array('sub0' => $orderforchoice[1], 00183 'sub1' => $orderforchoice[2], 'sub2' => $orderforchoice[2], 00184 'sub3' => $orderforchoice[1])); 00185 00186 // Finish the attempt without clicking check. 00187 $this->quba->finish_all_questions(); 00188 00189 // Verify. 00190 $this->check_current_state(question_state::$gradedright); 00191 $this->check_current_mark(4); 00192 $this->check_current_output( 00193 $this->get_contains_select_expectation('sub0', $choices, 1, false), 00194 $this->get_contains_select_expectation('sub1', $choices, 2, false), 00195 $this->get_contains_select_expectation('sub2', $choices, 2, false), 00196 $this->get_contains_select_expectation('sub3', $choices, 1, false), 00197 $this->get_contains_submit_button_expectation(false), 00198 $this->get_contains_correct_expectation(), 00199 $this->get_no_hint_visible_expectation()); 00200 } 00201 00202 public function test_interactive_partial_no_submit() { 00203 00204 // Create a matching question. 00205 $m = test_question_maker::make_a_matching_question(); 00206 $m->hints = array( 00207 new question_hint_with_parts(11, 'This is the first hint.', FORMAT_HTML, false, false), 00208 new question_hint_with_parts(12, 'This is the second hint.', FORMAT_HTML, true, true), 00209 ); 00210 $m->shufflestems = false; 00211 $this->start_attempt_at_question($m, 'interactive', 4); 00212 00213 $choiceorder = $m->get_choice_order(); 00214 $orderforchoice = array_combine(array_values($choiceorder), array_keys($choiceorder)); 00215 $choices = array(0 => get_string('choose') . '...'); 00216 foreach ($choiceorder as $key => $choice) { 00217 $choices[$key] = $m->choices[$choice]; 00218 } 00219 00220 // Check the initial state. 00221 $this->check_current_state(question_state::$todo); 00222 $this->check_current_mark(null); 00223 $this->check_current_output( 00224 $this->get_contains_select_expectation('sub0', $choices, null, true), 00225 $this->get_contains_select_expectation('sub1', $choices, null, true), 00226 $this->get_contains_select_expectation('sub2', $choices, null, true), 00227 $this->get_contains_select_expectation('sub3', $choices, null, true), 00228 $this->get_contains_submit_button_expectation(true), 00229 $this->get_does_not_contain_feedback_expectation(), 00230 $this->get_tries_remaining_expectation(3), 00231 $this->get_no_hint_visible_expectation()); 00232 00233 // Save the right answer. 00234 $this->process_submission(array('sub0' => $orderforchoice[1], 00235 'sub1' => $orderforchoice[2], 'sub2' => $orderforchoice[1], 00236 'sub3' => '0')); 00237 00238 // Finish the attempt without clicking check. 00239 $this->quba->finish_all_questions(); 00240 00241 // Verify. 00242 $this->check_current_state(question_state::$gradedpartial); 00243 $this->check_current_mark(2); 00244 $this->check_current_output( 00245 $this->get_contains_select_expectation('sub0', $choices, 1, false), 00246 $this->get_contains_select_expectation('sub1', $choices, 2, false), 00247 $this->get_contains_select_expectation('sub2', $choices, 1, false), 00248 $this->get_contains_select_expectation('sub3', $choices, null, false), 00249 $this->get_contains_submit_button_expectation(false), 00250 $this->get_contains_partcorrect_expectation(), 00251 $this->get_no_hint_visible_expectation()); 00252 } 00253 00254 public function test_interactive_with_invalid() { 00255 00256 // Create a matching question. 00257 $m = test_question_maker::make_a_matching_question(); 00258 $m->hints = array( 00259 new question_hint_with_parts(11, 'This is the first hint.', FORMAT_HTML, false, false), 00260 new question_hint_with_parts(12, 'This is the second hint.', FORMAT_HTML, true, true), 00261 ); 00262 $m->shufflestems = false; 00263 $this->start_attempt_at_question($m, 'interactive', 4); 00264 00265 $choiceorder = $m->get_choice_order(); 00266 $orderforchoice = array_combine(array_values($choiceorder), array_keys($choiceorder)); 00267 $choices = array(0 => get_string('choose') . '...'); 00268 foreach ($choiceorder as $key => $choice) { 00269 $choices[$key] = $m->choices[$choice]; 00270 } 00271 00272 // Check the initial state. 00273 $this->check_current_state(question_state::$todo); 00274 $this->check_current_mark(null); 00275 $this->check_current_output( 00276 $this->get_contains_select_expectation('sub0', $choices, null, true), 00277 $this->get_contains_select_expectation('sub1', $choices, null, true), 00278 $this->get_contains_select_expectation('sub2', $choices, null, true), 00279 $this->get_contains_select_expectation('sub3', $choices, null, true), 00280 $this->get_contains_submit_button_expectation(true), 00281 $this->get_does_not_contain_feedback_expectation(), 00282 $this->get_tries_remaining_expectation(3), 00283 $this->get_no_hint_visible_expectation()); 00284 00285 // Try to submit an invalid answer. 00286 $this->process_submission(array('sub0' => '0', 00287 'sub1' => '0', 'sub2' => '0', 00288 'sub3' => '0', '-submit' => '1')); 00289 00290 // Verify. 00291 $this->check_current_state(question_state::$invalid); 00292 $this->check_current_mark(null); 00293 $this->check_current_output( 00294 $this->get_contains_select_expectation('sub0', $choices, null, true), 00295 $this->get_contains_select_expectation('sub1', $choices, null, true), 00296 $this->get_contains_select_expectation('sub2', $choices, null, true), 00297 $this->get_contains_select_expectation('sub3', $choices, null, true), 00298 $this->get_contains_submit_button_expectation(true), 00299 $this->get_does_not_contain_feedback_expectation(), 00300 $this->get_invalid_answer_expectation(), 00301 $this->get_no_hint_visible_expectation()); 00302 00303 // Now submit the right answer. 00304 $this->process_submission(array('sub0' => $orderforchoice[1], 00305 'sub1' => $orderforchoice[2], 'sub2' => $orderforchoice[2], 00306 'sub3' => $orderforchoice[1], '-submit' => '1')); 00307 00308 // Verify. 00309 $this->check_current_state(question_state::$gradedright); 00310 $this->check_current_mark(4); 00311 $this->check_current_output( 00312 $this->get_contains_select_expectation('sub0', $choices, 1, false), 00313 $this->get_contains_select_expectation('sub1', $choices, 2, false), 00314 $this->get_contains_select_expectation('sub2', $choices, 2, false), 00315 $this->get_contains_select_expectation('sub3', $choices, 1, false), 00316 $this->get_contains_submit_button_expectation(false), 00317 $this->get_contains_correct_expectation(), 00318 $this->get_no_hint_visible_expectation()); 00319 } 00320 00321 public function test_match_with_tricky_html_choices() { 00322 00323 // Create a matching question. 00324 $m = test_question_maker::make_a_matching_question(); 00325 $m->stems = array( 00326 1 => '(1, 2]', 00327 2 => '[1, 2]', 00328 3 => '[1, 2)', 00329 ); 00330 $m->choices = array( 00331 1 => '1 < x ≤ 2', 00332 2 => '1 ≤ x ≤ 2', 00333 3 => '1 ≤ x < 2', 00334 ); 00335 $m->right = array(1 => 1, 2 => 2, 3 => 3); 00336 $m->shufflestems = false; 00337 $this->start_attempt_at_question($m, 'deferredfeedback', 3); 00338 00339 $choiceorder = $m->get_choice_order(); 00340 $orderforchoice = array_combine(array_values($choiceorder), array_keys($choiceorder)); 00341 $choices = array(0 => get_string('choose') . '...'); 00342 foreach ($choiceorder as $key => $choice) { 00343 $choices[$key] = $m->choices[$choice]; 00344 } 00345 00346 // Check the initial state. 00347 $this->check_current_state(question_state::$todo); 00348 $this->check_current_mark(null); 00349 $this->check_current_output( 00350 $this->get_contains_select_expectation('sub0', $choices, null, true), 00351 $this->get_contains_select_expectation('sub1', $choices, null, true), 00352 $this->get_contains_select_expectation('sub2', $choices, null, true), 00353 $this->get_contains_question_text_expectation($m), 00354 $this->get_does_not_contain_feedback_expectation()); 00355 $this->check_step_count(1); 00356 00357 $rightresponse = array('sub0' => $orderforchoice[1], 00358 'sub1' => $orderforchoice[2], 'sub2' => $orderforchoice[3]); 00359 $rightresponsesummary = 00360 '(1, 2] -> 1 < x ≤ 2; [1, 2] -> 1 ≤ x ≤ 2; [1, 2) -> 1 ≤ x < 2'; 00361 00362 $this->process_submission($rightresponse); 00363 $this->process_submission(array('-finish' => 1)); 00364 00365 $this->assertEqual($rightresponsesummary, $m->summarise_response($rightresponse)); 00366 00367 $this->displayoptions->history = 1; 00368 $this->check_current_output( 00369 new PatternExpectation('/' . 00370 preg_quote(htmlspecialchars($rightresponsesummary), '/') . '/')); 00371 } 00372 00373 public function test_match_clear_wrong() { 00374 00375 // Create a matching question. 00376 $m = test_question_maker::make_a_matching_question(); 00377 $m->hints = array( 00378 new question_hint_with_parts(11, 'This is the first hint.', FORMAT_HTML, false, true), 00379 new question_hint_with_parts(12, 'This is the second hint.', FORMAT_HTML, true, true), 00380 ); 00381 $m->shufflestems = false; 00382 $this->start_attempt_at_question($m, 'interactive', 4); 00383 00384 $choiceorder = $m->get_choice_order(); 00385 $orderforchoice = array_combine(array_values($choiceorder), array_keys($choiceorder)); 00386 $choices = array(0 => get_string('choose') . '...'); 00387 foreach ($choiceorder as $key => $choice) { 00388 $choices[$key] = $m->choices[$choice]; 00389 } 00390 00391 // Check the initial state. 00392 $this->check_current_state(question_state::$todo); 00393 $this->check_current_mark(null); 00394 $this->check_current_output( 00395 $this->get_contains_select_expectation('sub0', $choices, null, true), 00396 $this->get_contains_select_expectation('sub1', $choices, null, true), 00397 $this->get_contains_select_expectation('sub2', $choices, null, true), 00398 $this->get_contains_select_expectation('sub3', $choices, null, true), 00399 $this->get_contains_submit_button_expectation(true), 00400 $this->get_does_not_contain_feedback_expectation(), 00401 $this->get_tries_remaining_expectation(3), 00402 $this->get_no_hint_visible_expectation()); 00403 00404 // Submit a completely wrong response. 00405 $this->process_submission(array('sub0' => $orderforchoice[3], 00406 'sub1' => $orderforchoice[3], 'sub2' => $orderforchoice[3], 00407 'sub3' => $orderforchoice[3], '-submit' => 1)); 00408 00409 // Verify. 00410 $this->check_current_state(question_state::$todo); 00411 $this->check_current_mark(null); 00412 $this->check_current_output( 00413 $this->get_contains_select_expectation('sub0', $choices, 3, false), 00414 $this->get_contains_select_expectation('sub1', $choices, 3, false), 00415 $this->get_contains_select_expectation('sub2', $choices, 3, false), 00416 $this->get_contains_select_expectation('sub3', $choices, 3, false), 00417 $this->get_contains_hidden_expectation( 00418 $this->quba->get_field_prefix($this->slot) . 'sub0', '0'), 00419 $this->get_contains_hidden_expectation( 00420 $this->quba->get_field_prefix($this->slot) . 'sub1', '0'), 00421 $this->get_contains_hidden_expectation( 00422 $this->quba->get_field_prefix($this->slot) . 'sub2', '0'), 00423 $this->get_contains_hidden_expectation( 00424 $this->quba->get_field_prefix($this->slot) . 'sub3', '0'), 00425 $this->get_contains_submit_button_expectation(false), 00426 $this->get_contains_hint_expectation('This is the first hint.')); 00427 00428 // Try again. 00429 $this->process_submission(array('sub0' => 0, 00430 'sub1' => 0, 'sub2' => 0, 00431 'sub3' => 0, '-tryagain' => 1)); 00432 00433 // Verify. 00434 $this->check_current_state(question_state::$todo); 00435 $this->check_current_mark(null); 00436 $this->check_current_output( 00437 $this->get_contains_select_expectation('sub0', $choices, null, true), 00438 $this->get_contains_select_expectation('sub1', $choices, null, true), 00439 $this->get_contains_select_expectation('sub2', $choices, null, true), 00440 $this->get_contains_select_expectation('sub3', $choices, null, true), 00441 $this->get_contains_submit_button_expectation(true), 00442 $this->get_does_not_contain_feedback_expectation(), 00443 $this->get_tries_remaining_expectation(2), 00444 $this->get_no_hint_visible_expectation()); 00445 00446 // Submit a partially wrong response. 00447 $this->process_submission(array('sub0' => $orderforchoice[3], 00448 'sub1' => $orderforchoice[3], 'sub2' => $orderforchoice[2], 00449 'sub3' => $orderforchoice[1], '-submit' => 1)); 00450 00451 // Verify. 00452 $this->check_current_state(question_state::$todo); 00453 $this->check_current_mark(null); 00454 $this->check_current_output( 00455 $this->get_contains_select_expectation('sub0', $choices, 3, false), 00456 $this->get_contains_select_expectation('sub1', $choices, 3, false), 00457 $this->get_contains_select_expectation('sub2', $choices, 2, false), 00458 $this->get_contains_select_expectation('sub3', $choices, 1, false), 00459 $this->get_contains_hidden_expectation( 00460 $this->quba->get_field_prefix($this->slot) . 'sub0', '0'), 00461 $this->get_contains_hidden_expectation( 00462 $this->quba->get_field_prefix($this->slot) . 'sub1', '0'), 00463 $this->get_contains_hidden_expectation( 00464 $this->quba->get_field_prefix($this->slot) . 'sub2', $orderforchoice[2]), 00465 $this->get_contains_hidden_expectation( 00466 $this->quba->get_field_prefix($this->slot) . 'sub3', $orderforchoice[1]), 00467 $this->get_contains_submit_button_expectation(false), 00468 $this->get_contains_hint_expectation('This is the second hint.')); 00469 00470 // Try again. 00471 $this->process_submission(array('sub0' => 0, 00472 'sub1' => 0, 'sub2' => $orderforchoice[2], 00473 'sub3' => $orderforchoice[1], '-tryagain' => 1)); 00474 00475 // Verify. 00476 $this->check_current_state(question_state::$todo); 00477 $this->check_current_mark(null); 00478 $this->check_current_output( 00479 $this->get_contains_select_expectation('sub0', $choices, null, true), 00480 $this->get_contains_select_expectation('sub1', $choices, null, true), 00481 $this->get_contains_select_expectation('sub2', $choices, 2, true), 00482 $this->get_contains_select_expectation('sub3', $choices, 1, true), 00483 $this->get_contains_submit_button_expectation(true), 00484 $this->get_does_not_contain_feedback_expectation(), 00485 $this->get_tries_remaining_expectation(1), 00486 $this->get_no_hint_visible_expectation()); 00487 } 00488 }