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