Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

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   * This file contains tests that walks a question through the immediate feedback
  19   * behaviour.
  20   *
  21   * @package    qbehaviour
  22   * @subpackage immediatefeedback
  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 (__DIR__ . '/../../../engine/lib.php');
  32  require_once (__DIR__ . '/../../../engine/tests/helpers.php');
  33  
  34  
  35  /**
  36   * Unit tests for the immediate feedback 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_immediatefeedback_walkthrough_test extends qbehaviour_walkthrough_test_base {
  42      public function test_immediatefeedback_feedback_multichoice_right() {
  43  
  44          // Create a true-false question with correct answer true.
  45          $mc = test_question_maker::make_a_multichoice_single_question();
  46          $this->start_attempt_at_question($mc, 'immediatefeedback');
  47  
  48          $rightindex = $this->get_mc_right_answer_index($mc);
  49          $wrongindex = ($rightindex + 1) % 3;
  50  
  51          // Check the initial state.
  52          $this->check_current_state(question_state::$todo);
  53          $this->check_current_mark(null);
  54          $this->check_current_output(
  55                  $this->get_contains_question_text_expectation($mc),
  56                  $this->get_contains_mc_radio_expectation(0, true, false),
  57                  $this->get_contains_mc_radio_expectation(1, true, false),
  58                  $this->get_contains_mc_radio_expectation(2, true, false),
  59                  $this->get_contains_submit_button_expectation(true),
  60                  $this->get_does_not_contain_feedback_expectation());
  61  
  62          // Save the wrong answer.
  63          $this->process_submission(array('answer' => $wrongindex));
  64  
  65          // Verify.
  66          $this->check_current_state(question_state::$todo);
  67          $this->check_current_mark(null);
  68          $this->check_current_output(
  69                  $this->get_contains_mc_radio_expectation($wrongindex, true, true),
  70                  $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, true, false),
  71                  $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, true, false),
  72                  $this->get_contains_submit_button_expectation(true),
  73                  $this->get_does_not_contain_correctness_expectation(),
  74                  $this->get_does_not_contain_feedback_expectation());
  75  
  76          // Submit the right answer.
  77          $this->process_submission(array('answer' => $rightindex, '-submit' => 1));
  78  
  79          // Verify.
  80          $this->check_current_state(question_state::$gradedright);
  81          $this->check_current_mark(1);
  82          $this->check_current_output(
  83                  $this->get_contains_mc_radio_expectation($rightindex, false, true),
  84                  $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false),
  85                  $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false),
  86                  $this->get_contains_correct_expectation());
  87          $this->assertEquals('A',
  88                  $this->quba->get_response_summary($this->slot));
  89  
  90          $numsteps = $this->get_step_count();
  91  
  92          // Now try to save again - as if the user clicked next in the quiz.
  93          $this->process_submission(array('answer' => $rightindex));
  94  
  95          // Verify.
  96          $this->assertEquals($numsteps, $this->get_step_count());
  97          $this->check_current_state(question_state::$gradedright);
  98          $this->check_current_mark(1);
  99          $this->check_current_output(
 100                  $this->get_contains_mc_radio_expectation($rightindex, false, true),
 101                  $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false),
 102                  $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false),
 103                  $this->get_contains_correct_expectation());
 104  
 105          // Finish the attempt - should not need to add a new state.
 106          $this->quba->finish_all_questions();
 107  
 108          // Verify.
 109          $this->assertEquals($numsteps, $this->get_step_count());
 110          $this->check_current_state(question_state::$gradedright);
 111          $this->check_current_mark(1);
 112          $this->check_current_output(
 113                  $this->get_contains_mc_radio_expectation($rightindex, false, true),
 114                  $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false),
 115                  $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false),
 116                  $this->get_contains_correct_expectation());
 117  
 118          // Process a manual comment.
 119          $this->manual_grade('Not good enough!', 0.5, FORMAT_HTML);
 120  
 121          // Verify.
 122          $this->check_current_state(question_state::$mangrpartial);
 123          $this->check_current_mark(0.5);
 124          $this->check_current_output(
 125                  $this->get_contains_partcorrect_expectation(),
 126                  new question_pattern_expectation('/' . preg_quote('Not good enough!', '/') . '/'));
 127  
 128          // Now change the correct answer to the question, and regrade.
 129          $mc->answers[13]->fraction = -0.33333333;
 130          $mc->answers[15]->fraction = 1;
 131          $this->quba->regrade_all_questions();
 132  
 133          // Verify.
 134          $this->check_current_state(question_state::$mangrpartial);
 135          $this->check_current_mark(0.5);
 136          $this->check_current_output(
 137                  $this->get_contains_partcorrect_expectation());
 138  
 139          $autogradedstep = $this->get_step($this->get_step_count() - 2);
 140          $this->assertEqualsWithDelta($autogradedstep->get_fraction(), -0.3333333, 0.0000001);
 141      }
 142  
 143      public function test_immediatefeedback_feedback_multichoice_try_to_submit_blank() {
 144  
 145          // Create a true-false question with correct answer true.
 146          $mc = test_question_maker::make_a_multichoice_single_question();
 147          $this->start_attempt_at_question($mc, 'immediatefeedback');
 148  
 149          // Check the initial state.
 150          $this->check_current_state(question_state::$todo);
 151          $this->check_current_mark(null);
 152          $this->check_current_output(
 153                  $this->get_contains_question_text_expectation($mc),
 154                  $this->get_contains_mc_radio_expectation(0, true, false),
 155                  $this->get_contains_mc_radio_expectation(1, true, false),
 156                  $this->get_contains_mc_radio_expectation(2, true, false),
 157                  $this->get_contains_submit_button_expectation(true),
 158                  $this->get_does_not_contain_feedback_expectation());
 159  
 160          // Submit nothing.
 161          $this->process_submission(array('-submit' => 1));
 162  
 163          // Verify.
 164          $this->check_current_state(question_state::$invalid);
 165          $this->check_current_mark(null);
 166          $this->check_current_output(
 167                  $this->get_contains_mc_radio_expectation(0, true, false),
 168                  $this->get_contains_mc_radio_expectation(1, true, false),
 169                  $this->get_contains_mc_radio_expectation(2, true, false),
 170                  $this->get_contains_submit_button_expectation(true),
 171                  $this->get_does_not_contain_correctness_expectation(),
 172                  $this->get_does_not_contain_feedback_expectation(),
 173                  $this->get_contains_validation_error_expectation());
 174          $this->assertNull($this->quba->get_response_summary($this->slot));
 175  
 176          // Finish the attempt.
 177          $this->quba->finish_all_questions();
 178  
 179          // Verify.
 180          $this->check_current_state(question_state::$gaveup);
 181          $this->check_current_mark(null);
 182          $this->check_current_output(
 183                  $this->get_contains_mc_radio_expectation(0, false, false),
 184                  $this->get_contains_mc_radio_expectation(1, false, false),
 185                  $this->get_contains_mc_radio_expectation(2, false, false));
 186  
 187          // Process a manual comment.
 188          $this->manual_grade('Not good enough!', 0.5, FORMAT_HTML);
 189  
 190          // Verify.
 191          $this->check_current_state(question_state::$mangrpartial);
 192          $this->check_current_mark(0.5);
 193          $this->check_current_output(
 194                  $this->get_contains_partcorrect_expectation(),
 195                  new question_pattern_expectation('/' . preg_quote('Not good enough!', '/') . '/'));
 196      }
 197  
 198      public function test_immediatefeedback_feedback_multichoice_wrong_on_finish() {
 199  
 200          // Create a true-false question with correct answer true.
 201          $mc = test_question_maker::make_a_multichoice_single_question();
 202          $this->start_attempt_at_question($mc, 'immediatefeedback');
 203  
 204          // Check the initial state.
 205          $this->check_current_state(question_state::$todo);
 206          $this->check_current_mark(null);
 207          $this->check_current_output(
 208                  $this->get_contains_question_text_expectation($mc),
 209                  $this->get_contains_mc_radio_expectation(0, true, false),
 210                  $this->get_contains_mc_radio_expectation(1, true, false),
 211                  $this->get_contains_mc_radio_expectation(2, true, false),
 212                  $this->get_contains_submit_button_expectation(true),
 213                  $this->get_does_not_contain_feedback_expectation());
 214  
 215          $rightindex = $this->get_mc_right_answer_index($mc);
 216          $wrongindex = ($rightindex + 1) % 3;
 217  
 218          // Save the wrong answer.
 219          $this->process_submission(array('answer' => $wrongindex));
 220  
 221          // Verify.
 222          $this->check_current_state(question_state::$todo);
 223          $this->check_current_mark(null);
 224          $this->check_current_output(
 225                  $this->get_contains_mc_radio_expectation($wrongindex, true, true),
 226                  $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, true, false),
 227                  $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, true, false),
 228                  $this->get_contains_submit_button_expectation(true),
 229                  $this->get_does_not_contain_correctness_expectation(),
 230                  $this->get_does_not_contain_feedback_expectation());
 231  
 232          // Finish the attempt.
 233          $this->quba->finish_all_questions();
 234  
 235          // Verify.
 236          $this->check_current_state(question_state::$gradedwrong);
 237          $this->check_current_mark(-0.3333333);
 238          $this->check_current_output(
 239                  $this->get_contains_mc_radio_expectation($wrongindex, false, true),
 240                  $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, false, false),
 241                  $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, false, false),
 242                  $this->get_contains_incorrect_expectation());
 243          $this->assertRegExp('/B|C/',
 244                  $this->quba->get_response_summary($this->slot));
 245      }
 246  }