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 cbm
  19   * behaviour.
  20   *
  21   * @package    qbehaviour
  22   * @subpackage immediatecbm
  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 cbm 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_immediatecbm_walkthrough_test extends qbehaviour_walkthrough_test_base {
  42      public function test_immediatecbm_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, 'immediatecbm');
  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          $this->assertEquals('A [' . question_cbm::get_short_string(question_cbm::HIGH) . ']',
  62                  $this->quba->get_right_answer_summary($this->slot));
  63          $this->assertRegExp('/' . preg_quote($mc->questiontext, '/') . '/',
  64                  $this->quba->get_question_summary($this->slot));
  65          $this->assertNull($this->quba->get_response_summary($this->slot));
  66  
  67          // Save the wrong answer.
  68          $this->process_submission(array('answer' => $wrongindex, '-certainty' => 1));
  69  
  70          // Verify.
  71          $this->check_current_state(question_state::$todo);
  72          $this->check_current_mark(null);
  73          $this->check_current_output(
  74                  $this->get_contains_mc_radio_expectation($wrongindex, true, true),
  75                  $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, true, false),
  76                  $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, true, false),
  77                  $this->get_contains_submit_button_expectation(true),
  78                  $this->get_does_not_contain_correctness_expectation(),
  79                  $this->get_does_not_contain_feedback_expectation());
  80  
  81          // Submit the right answer.
  82          $this->process_submission(
  83                  array('answer' => $rightindex, '-certainty' => 2, '-submit' => 1));
  84  
  85          // Verify.
  86          $this->check_current_state(question_state::$gradedright);
  87          $this->check_current_mark(2);
  88          $this->check_current_output(
  89                  $this->get_contains_mc_radio_expectation($rightindex, false, true),
  90                  $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false),
  91                  $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false),
  92                  $this->get_contains_correct_expectation());
  93          $this->assertEquals('A [' . question_cbm::get_short_string(2) . ']',
  94                  $this->quba->get_response_summary($this->slot));
  95  
  96          $numsteps = $this->get_step_count();
  97  
  98          // Finish the attempt - should not need to add a new state.
  99          $this->quba->finish_all_questions();
 100  
 101          // Verify.
 102          $this->assertEquals($numsteps, $this->get_step_count());
 103          $this->check_current_state(question_state::$gradedright);
 104          $this->check_current_mark(2);
 105          $this->check_current_output(
 106                  $this->get_contains_mc_radio_expectation($rightindex, false, true),
 107                  $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false),
 108                  $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false),
 109                  $this->get_contains_correct_expectation());
 110  
 111          // Process a manual comment.
 112          $this->manual_grade('Not good enough!', 0.5, FORMAT_HTML);
 113  
 114          // Verify.
 115          $this->check_current_state(question_state::$mangrpartial);
 116          $this->check_current_mark(0.5);
 117          $this->check_current_output(
 118                  $this->get_contains_partcorrect_expectation(),
 119                  new question_pattern_expectation('/' . preg_quote('Not good enough!', '/') . '/'));
 120  
 121          // Now change the correct answer to the question, and regrade.
 122          $mc->answers[13]->fraction = -0.33333333;
 123          $mc->answers[15]->fraction = 1;
 124          $this->quba->regrade_all_questions();
 125  
 126          // Verify.
 127          $this->check_current_state(question_state::$mangrpartial);
 128          $this->check_current_mark(0.5);
 129          $this->check_current_output(
 130                  $this->get_contains_partcorrect_expectation());
 131  
 132          $autogradedstep = $this->get_step($this->get_step_count() - 2);
 133          $this->assertEqualsWithDelta($autogradedstep->get_fraction(), -2, 0.0000001);
 134      }
 135  
 136      public function test_immediatecbm_feedback_multichoice_try_to_submit_blank() {
 137  
 138          // Create a true-false question with correct answer true.
 139          $mc = test_question_maker::make_a_multichoice_single_question();
 140          $this->start_attempt_at_question($mc, 'immediatecbm');
 141  
 142          // Check the initial state.
 143          $this->check_current_state(question_state::$todo);
 144          $this->check_current_mark(null);
 145          $this->check_current_output(
 146                  $this->get_contains_question_text_expectation($mc),
 147                  $this->get_contains_mc_radio_expectation(0, true, false),
 148                  $this->get_contains_mc_radio_expectation(1, true, false),
 149                  $this->get_contains_mc_radio_expectation(2, true, false),
 150                  $this->get_contains_submit_button_expectation(true),
 151                  $this->get_does_not_contain_feedback_expectation());
 152  
 153          // Submit nothing.
 154          $this->process_submission(array('-submit' => 1));
 155  
 156          // Verify.
 157          $this->check_current_state(question_state::$invalid);
 158          $this->check_current_mark(null);
 159          $this->check_current_output(
 160                  $this->get_contains_mc_radio_expectation(0, true, false),
 161                  $this->get_contains_mc_radio_expectation(1, true, false),
 162                  $this->get_contains_mc_radio_expectation(2, true, false),
 163                  $this->get_contains_submit_button_expectation(true),
 164                  $this->get_does_not_contain_correctness_expectation(),
 165                  $this->get_contains_validation_error_expectation());
 166  
 167          // Finish the attempt.
 168          $this->quba->finish_all_questions();
 169  
 170          // Verify.
 171          $this->check_current_state(question_state::$gaveup);
 172          $this->check_current_mark(null);
 173          $this->check_current_output(
 174                  $this->get_contains_mc_radio_expectation(0, false, false),
 175                  $this->get_contains_mc_radio_expectation(1, false, false),
 176                  $this->get_contains_mc_radio_expectation(2, false, false));
 177  
 178          // Process a manual comment.
 179          $this->manual_grade('Not good enough!', 0.5, FORMAT_HTML);
 180  
 181          // Verify.
 182          $this->check_current_state(question_state::$mangrpartial);
 183          $this->check_current_mark(0.5);
 184          $this->check_current_output(
 185                  $this->get_contains_partcorrect_expectation(),
 186                  new question_pattern_expectation('/' . preg_quote('Not good enough!', '/') . '/'));
 187      }
 188  
 189      public function test_immediatecbm_feedback_shortanswer_try_to_submit_no_certainty() {
 190  
 191          // Create a short answer question with correct answer true.
 192          $sa = test_question_maker::make_question('shortanswer');
 193          $this->start_attempt_at_question($sa, 'immediatecbm');
 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_submit_button_expectation(true),
 200                  $this->get_does_not_contain_feedback_expectation());
 201  
 202          // Submit with certainty missing.
 203          $this->process_submission(array('-submit' => 1, 'answer' => 'frog'));
 204  
 205          // Verify.
 206          $this->check_current_state(question_state::$invalid);
 207          $this->check_current_mark(null);
 208          $this->check_current_output(
 209                  $this->get_contains_submit_button_expectation(true),
 210                  $this->get_does_not_contain_correctness_expectation(),
 211                  $this->get_contains_validation_error_expectation());
 212  
 213          // Now get it right.
 214          $this->process_submission(array('-submit' => 1, 'answer' => 'frog', '-certainty' => 3));
 215  
 216          // Verify.
 217          $this->check_current_state(question_state::$gradedright);
 218          $this->check_current_mark(3);
 219          $this->check_current_output(
 220                  $this->get_does_not_contain_validation_error_expectation());
 221      }
 222  
 223      public function test_immediatecbm_feedback_multichoice_wrong_on_finish() {
 224  
 225          // Create a true-false question with correct answer true.
 226          $mc = test_question_maker::make_a_multichoice_single_question();
 227          $this->start_attempt_at_question($mc, 'immediatecbm');
 228  
 229          // Check the initial state.
 230          $this->check_current_state(question_state::$todo);
 231          $this->check_current_mark(null);
 232          $this->check_current_output(
 233                  $this->get_contains_question_text_expectation($mc),
 234                  $this->get_contains_mc_radio_expectation(0, true, false),
 235                  $this->get_contains_mc_radio_expectation(1, true, false),
 236                  $this->get_contains_mc_radio_expectation(2, true, false),
 237                  $this->get_contains_submit_button_expectation(true),
 238                  $this->get_does_not_contain_feedback_expectation());
 239  
 240          $rightindex = $this->get_mc_right_answer_index($mc);
 241          $wrongindex = ($rightindex + 1) % 3;
 242  
 243          // Save the wrong answer.
 244          $this->process_submission(array('answer' => $wrongindex, '-certainty' => 3));
 245  
 246          // Verify.
 247          $this->check_current_state(question_state::$todo);
 248          $this->check_current_mark(null);
 249          $this->check_current_output(
 250                  $this->get_contains_mc_radio_expectation($wrongindex, true, true),
 251                  $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, true, false),
 252                  $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, true, false),
 253                  $this->get_contains_submit_button_expectation(true),
 254                  $this->get_does_not_contain_correctness_expectation());
 255  
 256          // Finish the attempt.
 257          $this->quba->finish_all_questions();
 258  
 259          // Verify.
 260          $this->check_current_state(question_state::$gradedwrong);
 261          $this->check_current_mark(-6);
 262          $this->check_current_output(
 263                  $this->get_contains_mc_radio_expectation($wrongindex, false, true),
 264                  $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, false, false),
 265                  $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, false, false),
 266                  $this->get_contains_incorrect_expectation());
 267      }
 268  
 269      public function test_immediatecbm_cbm_truefalse_no_certainty_feedback_when_not_answered() {
 270  
 271          // Create a true-false question with correct answer true.
 272          $tf = test_question_maker::make_question('truefalse', 'true');
 273          $this->start_attempt_at_question($tf, 'immediatecbm', 2);
 274  
 275          // Verify.
 276          $this->check_current_state(question_state::$todo);
 277          $this->check_current_mark(null);
 278          $this->check_current_output(
 279                  $this->get_does_not_contain_correctness_expectation(),
 280                  $this->get_contains_cbm_radio_expectation(1, true, false),
 281                  $this->get_does_not_contain_feedback_expectation());
 282  
 283          // Finish without answering.
 284          $this->quba->finish_all_questions();
 285  
 286          // Verify.
 287          $this->check_current_state(question_state::$gaveup);
 288          $this->check_current_mark(null);
 289          $this->check_current_output(
 290                  new question_no_pattern_expectation('/class=\"im-feedback/'));
 291      }
 292  }