Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.

Differences Between: [Versions 310 and 311] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403] [Versions 39 and 311]

   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   * Unit tests for the numerical questions answers processor.
  19   *
  20   * @package    qtype_numerical
  21   * @category   test
  22   * @copyright  2008 The Open University
  23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  namespace qtype_numerical;
  27  
  28  use qtype_numerical_answer_processor;
  29  
  30  defined('MOODLE_INTERNAL') || die();
  31  
  32  global $CFG;
  33  require_once($CFG->dirroot . '/question/type/numerical/questiontype.php');
  34  
  35  class testable_qtype_numerical_answer_processor extends qtype_numerical_answer_processor {
  36      public function parse_response($response) {
  37          return parent::parse_response($response);
  38      }
  39  }
  40  
  41  /**
  42   * Unit test for the numerical questions answers processor.
  43   *
  44   * @package    qtype_numerical
  45   * @category   test
  46   * @copyright  2008 The Open University
  47   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  48   */
  49  class answerprocessor_test extends \advanced_testcase {
  50      public function test_parse_response() {
  51          $ap = new testable_qtype_numerical_answer_processor(
  52                  array('m' => 1, 'cm' => 100), false, '.', ',');
  53  
  54          $this->assertEquals(array('3', '142', '', ''), $ap->parse_response('3.142'));
  55          $this->assertEquals(array('', '2', '', ''), $ap->parse_response('.2'));
  56          $this->assertEquals(array('1', '', '', ''), $ap->parse_response('1.'));
  57          $this->assertEquals(array('1', '0', '', ''), $ap->parse_response('1.0'));
  58          $this->assertEquals(array('-1', '', '', ''), $ap->parse_response('-1.'));
  59          $this->assertEquals(array('+1', '0', '', ''), $ap->parse_response('+1.0'));
  60  
  61          $this->assertEquals(array('1', '', '4', ''), $ap->parse_response('1e4'));
  62          $this->assertEquals(array('3', '142', '-4', ''), $ap->parse_response('3.142E-4'));
  63          $this->assertEquals(array('', '2', '+2', ''), $ap->parse_response('.2e+2'));
  64          $this->assertEquals(array('1', '', '-1', ''), $ap->parse_response('1.e-1'));
  65          $this->assertEquals(array('1', '0', '0', ''), $ap->parse_response('1.0e0'));
  66  
  67          $this->assertEquals(array('3', '', '8', ''), $ap->parse_response('3x10^8'));
  68          $this->assertEquals(array('3', '', '8', ''), $ap->parse_response('3×10^8'));
  69          $this->assertEquals(array('3', '0', '8', ''), $ap->parse_response('3.0*10^8'));
  70          $this->assertEquals(array('3', '00', '-8', ''), $ap->parse_response('3.00x10**-8'));
  71          $this->assertEquals(array('0', '001', '7', ''), $ap->parse_response('0.001×10**7'));
  72  
  73          $this->assertEquals(array('1', '', '', 'm'), $ap->parse_response('1m'));
  74          $this->assertEquals(array('3', '142', '', 'm'), $ap->parse_response('3.142 m'));
  75          $this->assertEquals(array('', '2', '', 'm'), $ap->parse_response('.2m'));
  76          $this->assertEquals(array('1', '', '', 'cm'), $ap->parse_response('1.cm'));
  77          $this->assertEquals(array('1', '0', '', 'cm'), $ap->parse_response('1.0   cm'));
  78          $this->assertEquals(array('-1', '', '', 'm'), $ap->parse_response('-1.m'));
  79          $this->assertEquals(array('+1', '0', '', 'cm'), $ap->parse_response('+1.0cm'));
  80  
  81          $this->assertEquals(array('1', '', '4', 'm'), $ap->parse_response('1e4 m'));
  82          $this->assertEquals(array('3', '142', '-4', 'cm'), $ap->parse_response('3.142E-4  cm'));
  83          $this->assertEquals(array('', '2', '+2', 'm'), $ap->parse_response('.2e+2m'));
  84          $this->assertEquals(array('1', '', '-1', 'm'), $ap->parse_response('1.e-1 m'));
  85          $this->assertEquals(array('1', '0', '0', 'cm'), $ap->parse_response('1.0e0cm'));
  86  
  87          $this->assertEquals(array('1000000', '', '', ''),
  88                  $ap->parse_response('1,000,000'));
  89          $this->assertEquals(array('1000', '00', '', 'm'),
  90                  $ap->parse_response('1,000.00 m'));
  91  
  92          $this->assertEquals(array(null, null, null, null), $ap->parse_response('frog'));
  93          $this->assertEquals(array('3', '', '', 'frogs'), $ap->parse_response('3 frogs'));
  94          $this->assertEquals(array(null, null, null, null), $ap->parse_response('. m'));
  95          $this->assertEquals(array(null, null, null, null), $ap->parse_response('.e8 m'));
  96          $this->assertEquals(array(null, null, null, null), $ap->parse_response(','));
  97      }
  98  
  99      protected function verify_value_and_unit($exectedval, $expectedunit, $expectedmultiplier,
 100              qtype_numerical_answer_processor $ap, $input, $separateunit = null) {
 101          list($val, $unit, $multiplier) = $ap->apply_units($input, $separateunit);
 102          if (is_null($exectedval)) {
 103              $this->assertNull($val);
 104          } else {
 105              $this->assertEqualsWithDelta($exectedval, $val, 0.0001);
 106          }
 107          $this->assertEquals($expectedunit, $unit);
 108          if (is_null($expectedmultiplier)) {
 109              $this->assertNull($multiplier);
 110          } else {
 111              $this->assertEqualsWithDelta($expectedmultiplier, $multiplier, 0.0001);
 112          }
 113      }
 114  
 115      public function test_apply_units() {
 116          $ap = new qtype_numerical_answer_processor(
 117                  array('m/s' => 1, 'c' => 3.3356409519815E-9,
 118                          'mph' => 2.2369362920544), false, '.', ',');
 119  
 120          $this->verify_value_and_unit(3e8, 'm/s', 1, $ap, '3x10^8 m/s');
 121          $this->verify_value_and_unit(3e8, '', null, $ap, '3x10^8');
 122          $this->verify_value_and_unit(1, 'c', 299792458, $ap, '1c');
 123          $this->verify_value_and_unit(1, 'mph', 0.44704, $ap, '0001.000 mph');
 124  
 125          $this->verify_value_and_unit(1, 'frogs', null, $ap, '1 frogs');
 126          $this->verify_value_and_unit(null, null, null, $ap, '. m/s');
 127      }
 128  
 129      public function test_apply_units_separate_unit() {
 130          $ap = new qtype_numerical_answer_processor(
 131                  array('m/s' => 1, 'c' => 3.3356409519815E-9,
 132                          'mph' => 2.2369362920544), false, '.', ',');
 133  
 134          $this->verify_value_and_unit(3e8, 'm/s', 1, $ap, '3x10^8', 'm/s');
 135          $this->verify_value_and_unit(3e8, '', null, $ap, '3x10^8', '');
 136          $this->verify_value_and_unit(1, 'c', 299792458, $ap, '1', 'c');
 137          $this->verify_value_and_unit(1, 'mph', 0.44704, $ap, '0001.000', 'mph');
 138  
 139          $this->verify_value_and_unit(1, 'frogs', null, $ap, '1', 'frogs');
 140          $this->verify_value_and_unit(null, null, null, $ap, '.', 'm/s');
 141      }
 142  
 143      public function test_euro_style() {
 144          $ap = new qtype_numerical_answer_processor(array(), false, ',', ' ');
 145  
 146          $this->assertEquals(array(-1000, '', null), $ap->apply_units('-1 000'));
 147          $this->assertEquals(array(3.14159, '', null), $ap->apply_units('3,14159'));
 148      }
 149  
 150      public function test_percent() {
 151          $ap = new qtype_numerical_answer_processor(array('%' => 100), false, '.', ',');
 152  
 153          $this->assertEquals(array('3', '%', 0.01), $ap->apply_units('3%'));
 154          $this->assertEquals(array('1e-6', '%', 0.01), $ap->apply_units('1e-6 %'));
 155          $this->assertEquals(array('100', '', null), $ap->apply_units('100'));
 156      }
 157  
 158      public function test_currency() {
 159          $ap = new qtype_numerical_answer_processor(array('$' => 1, '£' => 1), true, '.', ',');
 160  
 161          $this->assertEquals(array('1234.56', '£', 1), $ap->apply_units('£1,234.56'));
 162          $this->assertEquals(array('100', '$', 1), $ap->apply_units('$100'));
 163          $this->assertEquals(array('100', '$', 1), $ap->apply_units('$100.'));
 164          $this->assertEquals(array('100.00', '$', 1), $ap->apply_units('$100.00'));
 165          $this->assertEquals(array('100', '', null), $ap->apply_units('100'));
 166          $this->assertEquals(array('100', 'frog', null), $ap->apply_units('frog 100'));
 167      }
 168  }