Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 3.9.x will end* 10 May 2021 (12 months).
  • Bug fixes for security issues in 3.9.x will end* 8 May 2023 (36 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 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 and 403]

   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 overall tests of numerical questions.
  19   *
  20   * @package    qtype
  21   * @subpackage numerical
  22   * @copyright  2011 The Open University
  23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  
  27  defined('MOODLE_INTERNAL') || die();
  28  
  29  global $CFG;
  30  require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
  31  require_once($CFG->dirroot . '/question/type/numerical/tests/helper.php');
  32  
  33  
  34  /**
  35   * Unit tests for the numerical question type.
  36   *
  37   * @copyright  2011 The Open University
  38   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  39   */
  40  class qtype_numerical_walkthrough_test extends qbehaviour_walkthrough_test_base {
  41      public function test_interactive_currency() {
  42  
  43          // Create a gapselect question.
  44          $q = test_question_maker::make_question('numerical', 'currency');
  45          $q->hints = array(
  46              new question_hint(1, 'This is the first hint.', FORMAT_HTML),
  47              new question_hint(2, 'This is the second hint.', FORMAT_HTML),
  48          );
  49          $this->start_attempt_at_question($q, 'interactive', 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_marked_out_of_summary(),
  56                  $this->get_contains_submit_button_expectation(true),
  57                  $this->get_does_not_contain_feedback_expectation(),
  58                  $this->get_does_not_contain_validation_error_expectation(),
  59                  $this->get_does_not_contain_try_again_button_expectation(),
  60                  $this->get_no_hint_visible_expectation());
  61  
  62          // Submit blank.
  63          $this->process_submission(array('-submit' => 1, 'answer' => ''));
  64  
  65          // Verify.
  66          $this->check_current_state(question_state::$invalid);
  67          $this->check_current_mark(null);
  68          $this->check_current_output(
  69                  $this->get_contains_marked_out_of_summary(),
  70                  $this->get_contains_submit_button_expectation(true),
  71                  $this->get_does_not_contain_feedback_expectation(),
  72                  $this->get_contains_validation_error_expectation(),
  73                  $this->get_does_not_contain_try_again_button_expectation(),
  74                  $this->get_no_hint_visible_expectation());
  75  
  76          // Sumit something that does not look liek a number.
  77          $this->process_submission(array('-submit' => 1, 'answer' => 'newt'));
  78  
  79          // Verify.
  80          $this->check_current_state(question_state::$invalid);
  81          $this->check_current_mark(null);
  82          $this->check_current_output(
  83                  $this->get_contains_marked_out_of_summary(),
  84                  $this->get_contains_submit_button_expectation(true),
  85                  $this->get_does_not_contain_feedback_expectation(),
  86                  $this->get_contains_validation_error_expectation(),
  87                  new question_pattern_expectation('/' .
  88                          preg_quote(get_string('invalidnumber', 'qtype_numerical'), '/') . '/'),
  89                  $this->get_does_not_contain_try_again_button_expectation(),
  90                  $this->get_no_hint_visible_expectation());
  91  
  92          // Now get it right.
  93          $this->process_submission(array('-submit' => 1, 'answer' => '$1332'));
  94  
  95          // Verify.
  96          $this->check_current_state(question_state::$gradedright);
  97          $this->check_current_mark(3);
  98          $this->check_current_output(
  99                  $this->get_contains_mark_summary(3),
 100                  $this->get_does_not_contain_submit_button_expectation(),
 101                  $this->get_contains_correct_expectation(),
 102                  $this->get_does_not_contain_validation_error_expectation(),
 103                  $this->get_no_hint_visible_expectation());
 104          $this->assertEquals('$1332',
 105                  $this->quba->get_response_summary($this->slot));
 106      }
 107  
 108      public function test_deferredfeedback_currency() {
 109  
 110          // Create a gapselect question.
 111          $q = test_question_maker::make_question('numerical', 'currency');
 112          $this->start_attempt_at_question($q, 'deferredfeedback', 3);
 113  
 114          // Check the initial state.
 115          $this->check_current_state(question_state::$todo);
 116          $this->check_current_mark(null);
 117          $this->check_current_output(
 118                  $this->get_contains_marked_out_of_summary(),
 119                  $this->get_does_not_contain_feedback_expectation(),
 120                  $this->get_does_not_contain_validation_error_expectation(),
 121                  $this->get_does_not_contain_try_again_button_expectation(),
 122                  $this->get_no_hint_visible_expectation());
 123  
 124          // Submit blank.
 125          $this->process_submission(array('answer' => ''));
 126  
 127          // Verify.
 128          $this->check_current_state(question_state::$todo);
 129          $this->check_current_mark(null);
 130          $this->check_current_output(
 131                  $this->get_contains_marked_out_of_summary(),
 132                  $this->get_does_not_contain_feedback_expectation(),
 133                  $this->get_does_not_contain_validation_error_expectation(),
 134                  $this->get_does_not_contain_try_again_button_expectation(),
 135                  $this->get_no_hint_visible_expectation());
 136  
 137          // Sumit something that does not look like a number.
 138          $this->process_submission(array('answer' => '$newt'));
 139  
 140          // Verify.
 141          $this->check_current_state(question_state::$invalid);
 142          $this->check_current_mark(null);
 143          $this->check_current_output(
 144                  $this->get_contains_marked_out_of_summary(),
 145                  $this->get_does_not_contain_feedback_expectation(),
 146                  $this->get_contains_validation_error_expectation(),
 147                  new question_pattern_expectation('/' .
 148                          preg_quote(get_string('invalidnumber', 'qtype_numerical'), '/') . '/'),
 149                  $this->get_does_not_contain_try_again_button_expectation(),
 150                  $this->get_no_hint_visible_expectation());
 151  
 152          // Now put in the right answer but without a unit.
 153          $this->process_submission(array('answer' => '1332'));
 154  
 155          $this->check_current_state(question_state::$complete);
 156          $this->check_current_mark(null);
 157          $this->check_current_output(
 158                  $this->get_contains_marked_out_of_summary(),
 159                  $this->get_does_not_contain_feedback_expectation(),
 160                  $this->get_does_not_contain_validation_error_expectation(),
 161                  $this->get_does_not_contain_try_again_button_expectation(),
 162                  $this->get_no_hint_visible_expectation());
 163  
 164          // Submit all and finish.
 165          $this->finish();
 166  
 167          // Verify.
 168          $this->check_current_state(question_state::$gradedpartial);
 169          $this->check_current_mark(2.4);
 170          $this->check_current_output(
 171                  $this->get_contains_mark_summary(2.4),
 172                  $this->get_contains_partcorrect_expectation(),
 173                  $this->get_does_not_contain_validation_error_expectation(),
 174                  $this->get_no_hint_visible_expectation());
 175          $this->assertEquals('1332',
 176                  $this->quba->get_response_summary($this->slot));
 177      }
 178  
 179      // Todo. Test validation if you try to type a unit into a question that does
 180      // not expect one.
 181  
 182      public function test_deferredfeedback_unit() {
 183  
 184          // Create a gapselect question.
 185          $q = test_question_maker::make_question('numerical', 'unit');
 186          $this->start_attempt_at_question($q, 'deferredfeedback', 1);
 187  
 188          $unitchoices = array(
 189              'm' => 'm',
 190              'cm' => 'cm',
 191          );
 192  
 193          // Check the initial state.
 194          $this->check_current_state(question_state::$todo);
 195          $this->check_current_mark(null);
 196          $this->check_current_output(
 197                  $this->get_contains_marked_out_of_summary(),
 198                  $this->get_does_not_contain_feedback_expectation(),
 199                  $this->get_does_not_contain_validation_error_expectation(),
 200                  $this->get_does_not_contain_try_again_button_expectation(),
 201                  $this->get_no_hint_visible_expectation());
 202          $this->check_output_contains_selectoptions(
 203                  $this->get_contains_select_expectation('unit', $unitchoices, null, true));
 204  
 205          // Submit blank.
 206          $this->process_submission(array('answer' => ''));
 207  
 208          // Verify.
 209          $this->check_current_state(question_state::$todo);
 210          $this->check_current_mark(null);
 211          $this->check_current_output(
 212                  $this->get_contains_marked_out_of_summary(),
 213                  $this->get_does_not_contain_feedback_expectation(),
 214                  $this->get_does_not_contain_validation_error_expectation(),
 215                  $this->get_does_not_contain_try_again_button_expectation(),
 216                  $this->get_no_hint_visible_expectation());
 217          $this->check_output_contains_selectoptions(
 218                  $this->get_contains_select_expectation('unit', $unitchoices, null, true));
 219  
 220          // Sumit something that does not look like a number, but with a unit.
 221          $this->process_submission(array('answer' => 'newt', 'unit' => 'cm'));
 222  
 223          // Verify.
 224          $this->check_current_state(question_state::$invalid);
 225          $this->check_current_mark(null);
 226          $this->check_current_output(
 227                  $this->get_contains_marked_out_of_summary(),
 228                  $this->get_does_not_contain_feedback_expectation(),
 229                  $this->get_contains_validation_error_expectation(),
 230                  new question_pattern_expectation('/' .
 231                          preg_quote(get_string('invalidnumber', 'qtype_numerical'), '/') . '/'),
 232                  $this->get_does_not_contain_try_again_button_expectation(),
 233                  $this->get_no_hint_visible_expectation());
 234          $this->check_output_contains_selectoptions(
 235                  $this->get_contains_select_expectation('unit', $unitchoices, 'cm', true));
 236  
 237          // Now put in the right answer but without a unit.
 238          $this->process_submission(array('answer' => '1.25', 'unit' => ''));
 239  
 240          $this->check_current_state(question_state::$invalid);
 241          $this->check_current_mark(null);
 242          $this->check_current_output(
 243                  $this->get_contains_marked_out_of_summary(),
 244                  $this->get_does_not_contain_feedback_expectation(),
 245                  $this->get_contains_validation_error_expectation(),
 246                  new question_pattern_expectation('/' .
 247                          preg_quote(get_string('unitnotselected', 'qtype_numerical'), '/') . '/'),
 248                  $this->get_does_not_contain_try_again_button_expectation(),
 249                  $this->get_no_hint_visible_expectation());
 250          $this->check_output_contains_selectoptions(
 251                  $this->get_contains_select_expectation('unit', $unitchoices, '', true));
 252  
 253          // Now put in the right answer with a unit.
 254          $this->process_submission(array('answer' => '1.25', 'unit' => 'm'));
 255  
 256          $this->check_current_state(question_state::$complete);
 257          $this->check_current_mark(null);
 258          $this->check_current_output(
 259                  $this->get_contains_marked_out_of_summary(),
 260                  $this->get_does_not_contain_feedback_expectation(),
 261                  $this->get_does_not_contain_validation_error_expectation(),
 262                  $this->get_does_not_contain_try_again_button_expectation(),
 263                  $this->get_no_hint_visible_expectation());
 264          $this->check_output_contains_selectoptions(
 265                  $this->get_contains_select_expectation('unit', $unitchoices, 'm', true));
 266  
 267          // Submit all and finish.
 268          $this->finish();
 269  
 270          // Verify.
 271          $this->check_current_state(question_state::$gradedright);
 272          $this->check_current_mark(1);
 273          $this->check_current_output(
 274                  $this->get_contains_mark_summary(1),
 275                  $this->get_contains_correct_expectation(),
 276                  $this->get_does_not_contain_validation_error_expectation(),
 277                  $this->get_no_hint_visible_expectation());
 278          $this->check_output_contains_selectoptions(
 279                  $this->get_contains_select_expectation('unit', $unitchoices, 'm', false));
 280          $this->assertEquals('1.25 m',
 281                  $this->quba->get_response_summary($this->slot));
 282      }
 283  }