Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 310 and 401] [Versions 39 and 401]

   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 qtype_calculated;
  18  
  19  use question_attempt_step;
  20  use question_classified_response;
  21  use question_display_options;
  22  use question_state;
  23  use qtype_numerical;
  24  
  25  defined('MOODLE_INTERNAL') || die();
  26  
  27  global $CFG;
  28  require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
  29  
  30  
  31  /**
  32   * Unit tests for qtype_calculated_definition.
  33   *
  34   * @package    qtype_calculated
  35   * @copyright  2011 The Open University
  36   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  37   */
  38  class question_test extends \advanced_testcase {
  39      public function test_is_complete_response() {
  40          $question = \test_question_maker::make_question('calculated');
  41  
  42          $this->assertFalse($question->is_complete_response(array()));
  43          $this->assertTrue($question->is_complete_response(array('answer' => '0')));
  44          $this->assertTrue($question->is_complete_response(array('answer' => 0)));
  45          $this->assertFalse($question->is_complete_response(array('answer' => 'test')));
  46      }
  47  
  48      public function test_is_gradable_response() {
  49          $question = \test_question_maker::make_question('calculated');
  50  
  51          $this->assertFalse($question->is_gradable_response(array()));
  52          $this->assertTrue($question->is_gradable_response(array('answer' => '0')));
  53          $this->assertTrue($question->is_gradable_response(array('answer' => 0)));
  54          $this->assertTrue($question->is_gradable_response(array('answer' => 'test')));
  55      }
  56  
  57      public function test_grading() {
  58          $question = \test_question_maker::make_question('calculated');
  59          $question->start_attempt(new question_attempt_step(), 1);
  60          $values = $question->vs->get_values();
  61  
  62          $this->assertEquals(array(0, question_state::$gradedwrong),
  63                  $question->grade_response(array('answer' => $values['a'] - $values['b'])));
  64          $this->assertEquals(array(1, question_state::$gradedright),
  65                  $question->grade_response(array('answer' => $values['a'] + $values['b'])));
  66      }
  67  
  68      public function test_get_correct_response() {
  69          // Testing with 3.0 + 0.1416.
  70          $question = \test_question_maker::make_question('calculated');
  71          $question->start_attempt(new question_attempt_step(), 3);
  72          $values = $question->vs->get_values();
  73          $this->assertSame(array('answer' => '3.01' ), $question->get_correct_response());
  74          foreach ($question->answers as $answer) {
  75              $answer->correctanswerlength = 2;
  76              $answer->correctanswerformat = 2;
  77          }
  78          $this->assertSame(array('answer' => '3.0' ), $question->get_correct_response());
  79  
  80          // Testing with 1.0 + 5.0.
  81          $question = \test_question_maker::make_question('calculated');
  82          $question->start_attempt(new question_attempt_step(), 1);
  83          $values = $question->vs->get_values();
  84          $this->assertSame(array('answer' => '6.00' ), $question->get_correct_response());
  85  
  86          foreach ($question->answers as $answer) {
  87              $answer->correctanswerlength = 2;
  88              $answer->correctanswerformat = 2;
  89          }
  90          $this->assertSame(array('answer' => '6.0' ),
  91                  $question->get_correct_response());
  92          // Testing with 31.0 + 0.01416 .
  93          $question = \test_question_maker::make_question('calculated');
  94          $question->start_attempt(new question_attempt_step(), 4);
  95          $values = $question->vs->get_values();
  96          $this->assertSame(array('answer' => '31.01' ), $question->get_correct_response());
  97  
  98          foreach ($question->answers as $answer) {
  99              $answer->correctanswerlength = 3;
 100              $answer->correctanswerformat = 2;
 101          }
 102          $this->assertSame(array('answer' => '31.0' ), $question->get_correct_response());
 103  
 104      }
 105  
 106      public function test_get_question_summary() {
 107          $question = \test_question_maker::make_question('calculated');
 108          $question->start_attempt(new question_attempt_step(), 1);
 109          $values = $question->vs->get_values();
 110  
 111          $qsummary = $question->get_question_summary();
 112          $this->assertEquals('What is ' . $values['a'] . ' + ' . $values['b'] . '?', $qsummary);
 113      }
 114  
 115      public function test_summarise_response() {
 116          $question = \test_question_maker::make_question('calculated');
 117          $question->start_attempt(new question_attempt_step(), 1);
 118          $values = $question->vs->get_values();
 119  
 120          $this->assertEquals('3.1', $question->summarise_response(array('answer' => '3.1')));
 121      }
 122  
 123      public function test_classify_response() {
 124          $question = \test_question_maker::make_question('calculated');
 125          $question->start_attempt(new question_attempt_step(), 1);
 126          $values = $question->vs->get_values();
 127  
 128          $this->assertEquals(array(
 129                  new question_classified_response(13, $values['a'] + $values['b'], 1.0)),
 130                  $question->classify_response(array('answer' => $values['a'] + $values['b'])));
 131          $this->assertEquals(array(
 132                  new question_classified_response(14, $values['a'] - $values['b'], 0.0)),
 133                  $question->classify_response(array('answer' => $values['a'] - $values['b'])));
 134          $this->assertEquals(array(
 135                  new question_classified_response(17, 7 * $values['a'], 0.0)),
 136                  $question->classify_response(array('answer' => 7 * $values['a'])));
 137          $this->assertEquals(array(
 138                  question_classified_response::no_response()),
 139                  $question->classify_response(array('answer' => '')));
 140      }
 141  
 142      public function test_classify_response_no_star() {
 143          $question = \test_question_maker::make_question('calculated');
 144          unset($question->answers[17]);
 145          $question->start_attempt(new question_attempt_step(), 1);
 146          $values = $question->vs->get_values();
 147  
 148          $this->assertEquals(array(
 149                  new question_classified_response(13, $values['a'] + $values['b'], 1.0)),
 150                  $question->classify_response(array('answer' => $values['a'] + $values['b'])));
 151          $this->assertEquals(array(
 152                  new question_classified_response(14, $values['a'] - $values['b'], 0.0)),
 153                  $question->classify_response(array('answer' => $values['a'] - $values['b'])));
 154          $this->assertEquals(array(
 155                  new question_classified_response(0, 7 * $values['a'], 0.0)),
 156                  $question->classify_response(array('answer' => 7 * $values['a'])));
 157          $this->assertEquals(array(
 158                  question_classified_response::no_response()),
 159                  $question->classify_response(array('answer' => '')));
 160      }
 161  
 162      public function test_get_variants_selection_seed_q_not_synchronised() {
 163          $question = \test_question_maker::make_question('calculated');
 164          $this->assertEquals($question->stamp, $question->get_variants_selection_seed());
 165      }
 166  
 167      public function test_get_variants_selection_seed_q_synchronised_datasets_not() {
 168          $question = \test_question_maker::make_question('calculated');
 169          $question->synchronised = true;
 170          $this->assertEquals($question->stamp, $question->get_variants_selection_seed());
 171      }
 172  
 173      public function test_get_variants_selection_seed_q_synchronised() {
 174          $question = \test_question_maker::make_question('calculated');
 175          $question->synchronised = true;
 176          $question->datasetloader->set_are_synchronised($question->category, true);
 177          $this->assertEquals('category' . $question->category,
 178                  $question->get_variants_selection_seed());
 179      }
 180  
 181      /**
 182       * test_get_question_definition_for_external_rendering
 183       */
 184      public function test_get_question_definition_for_external_rendering() {
 185          $this->resetAfterTest();
 186  
 187          $question = \test_question_maker::make_question('calculated');
 188          $question->start_attempt(new question_attempt_step(), 1);
 189          $qa = \test_question_maker::get_a_qa($question);
 190          $displayoptions = new question_display_options();
 191  
 192          $options = $question->get_question_definition_for_external_rendering($qa, $displayoptions);
 193          $this->assertNotEmpty($options);
 194          $this->assertEquals(0, $options['unitgradingtype']);
 195          $this->assertEquals(0, $options['unitpenalty']);
 196          $this->assertEquals(qtype_numerical::UNITNONE, $options['unitdisplay']);
 197          $this->assertEmpty($options['unitsleft']);
 198      }
 199  }