See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 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 /** 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 /** 31 * Unit test for the numerical questions answers processor. 32 * 33 * @package qtype_numerical 34 * @category test 35 * @copyright 2008 The Open University 36 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 37 * @covers \qtype_numerical_answer_processor 38 */ 39 class answerprocessor_test extends \advanced_testcase { 40 /** 41 * Test setup. 42 */ 43 public function setUp(): void { 44 global $CFG; 45 46 require_once("{$CFG->dirroot}/question/type/numerical/questiontype.php"); 47 } 48 49 /** 50 * Test the parse_response function. 51 * 52 * @covers ::parse_response 53 * @dataProvider parse_response_provider 54 * @param array $expected 55 * @param mixed $args 56 */ 57 public function test_parse_response(array $expected, $args): void { 58 $ap = new qtype_numerical_answer_processor([ 59 'm' => 1, 60 'cm' => 100, 61 ], false, '.', ','); 62 63 $rc = new \ReflectionClass($ap); 64 $rcm = $rc->getMethod('parse_response'); 65 $rcm->setAccessible(true); 66 67 $this->assertEquals($expected, $rcm->invoke($ap, $args)); 68 } 69 70 /** 71 * Data provider for the parse_response function. 72 * 73 * @return array 74 */ 75 public function parse_response_provider(): array { 76 return [ 77 [['3', '142', '', ''], '3.142'], 78 [['', '2', '', ''], '.2'], 79 [['1', '', '', ''], '1.'], 80 [['1', '0', '', ''], '1.0'], 81 [['-1', '', '', ''], '-1.'], 82 [['+1', '0', '', ''], '+1.0'], 83 84 [['1', '', '4', ''], '1e4'], 85 [['3', '142', '-4', ''], '3.142E-4'], 86 [['', '2', '+2', ''], '.2e+2'], 87 [['1', '', '-1', ''], '1.e-1'], 88 [['1', '0', '0', ''], '1.0e0'], 89 90 [['3', '', '8', ''], '3x10^8'], 91 [['3', '', '8', ''], '3×10^8'], 92 [['3', '0', '8', ''], '3.0*10^8'], 93 [['3', '00', '-8', ''], '3.00x10**-8'], 94 [['0', '001', '7', ''], '0.001×10**7'], 95 96 [['1', '', '', 'm'], '1m'], 97 [['3', '142', '', 'm'], '3.142 m'], 98 [['', '2', '', 'm'], '.2m'], 99 [['1', '', '', 'cm'], '1.cm'], 100 [['1', '0', '', 'cm'], '1.0 cm'], 101 [['-1', '', '', 'm'], '-1.m'], 102 [['+1', '0', '', 'cm'], '+1.0cm'], 103 104 [['1', '', '4', 'm'], '1e4 m'], 105 [['3', '142', '-4', 'cm'], '3.142E-4 cm'], 106 [['', '2', '+2', 'm'], '.2e+2m'], 107 [['1', '', '-1', 'm'], '1.e-1 m'], 108 [['1', '0', '0', 'cm'], '1.0e0cm'], 109 110 [['1000000', '', '', ''], '1,000,000'], 111 [['1000', '00', '', 'm'], '1,000.00 m'], 112 113 [[null, null, null, null], 'frog'], 114 [['3', '', '', 'frogs'], '3 frogs'], 115 [[null, null, null, null], '. m'], 116 [[null, null, null, null], '.e8 m'], 117 [[null, null, null, null], ','], 118 ]; 119 } 120 121 /** 122 * Call apply_units and verify the value and units returned. 123 * 124 * @param int|float $exectedval 125 * @param null|string $expectedunit 126 * @param int|float $expectedmultiplier 127 * @param qtype_numerical_answer_processor $ap 128 * @param null|int|float $input 129 * @param null|string $separateunit 130 */ 131 protected function verify_value_and_unit( 132 $exectedval, 133 $expectedunit, 134 $expectedmultiplier, 135 qtype_numerical_answer_processor $ap, 136 $input, 137 $separateunit = null 138 ): void { 139 [$val, $unit, $multiplier] = $ap->apply_units($input, $separateunit); 140 if (is_null($exectedval)) { 141 $this->assertNull($val); 142 } else { 143 $this->assertEqualsWithDelta($exectedval, $val, 0.0001); 144 } 145 $this->assertEquals($expectedunit, $unit); 146 if (is_null($expectedmultiplier)) { 147 $this->assertNull($multiplier); 148 } else { 149 $this->assertEqualsWithDelta($expectedmultiplier, $multiplier, 0.0001); 150 } 151 } 152 153 /** 154 * Test the apply_units function with various parameters. 155 * 156 * @covers \qtype_numerical_answer_processor::apply_units 157 * @dataProvider apply_units_provider 158 * @param mixed $expectedvalue 159 * @param string|null $expectedunit 160 * @param float|int|null $expectedmultiplier 161 * @param string|null $input 162 */ 163 public function test_apply_units( 164 $expectedvalue, 165 $expectedunit, 166 $expectedmultiplier, 167 $input 168 ): void { 169 $ap = new qtype_numerical_answer_processor( 170 [ 171 'm/s' => 1, 172 'c' => 3.3356409519815E-9, 173 'mph' => 2.2369362920544 174 ], 175 false, 176 '.', 177 ',' 178 ); 179 180 $this->verify_value_and_unit( 181 $expectedvalue, 182 $expectedunit, 183 $expectedmultiplier, 184 $ap, 185 $input 186 ); 187 } 188 189 /** 190 * Data provider for apply_units tests. 191 * 192 * @return array 193 */ 194 public function apply_units_provider(): array { 195 return [ 196 [3e8, 'm/s', 1, '3x10^8 m/s'], 197 [3e8, '', null, '3x10^8'], 198 [1, 'c', 299792458, '1c'], 199 [1, 'mph', 0.44704, '0001.000 mph'], 200 201 [1, 'frogs', null, '1 frogs'], 202 [null, null, null, '. m/s'], 203 [null, null, null, null], 204 [null, null, null, ''], 205 [null, null, null, ' '], 206 ]; 207 } 208 209 /** 210 * Test the apply_units function with various parameters and different units. 211 * 212 * @covers \qtype_numerical_answer_processor::apply_units 213 * @dataProvider apply_units_provider_with_units 214 * @param mixed $expectedvalue 215 * @param string|null $expectedunit 216 * @param float|int|null $expectedmultiplier 217 * @param string|null $input 218 * @param string $units 219 */ 220 public function test_apply_units_with_unit( 221 $expectedvalue, 222 $expectedunit, 223 $expectedmultiplier, 224 $input, 225 $units 226 ): void { 227 $ap = new qtype_numerical_answer_processor( 228 [ 229 'm/s' => 1, 230 'c' => 3.3356409519815E-9, 231 'mph' => 2.2369362920544 232 ], 233 false, 234 '.', 235 ',' 236 ); 237 238 $this->verify_value_and_unit( 239 $expectedvalue, 240 $expectedunit, 241 $expectedmultiplier, 242 $ap, 243 $input, 244 $units 245 ); 246 } 247 248 /** 249 * Data provider for apply_units with different units. 250 * 251 * @return array 252 */ 253 public function apply_units_provider_with_units(): array { 254 return [ 255 [3e8, 'm/s', 1, '3x10^8', 'm/s'], 256 [3e8, '', null, '3x10^8', ''], 257 [1, 'c', 299792458, '1', 'c'], 258 [1, 'mph', 0.44704, '0001.000', 'mph'], 259 260 [1, 'frogs', null, '1', 'frogs'], 261 [null, null, null, '.', 'm/s'], 262 ]; 263 } 264 265 /** 266 * Test apply_units with a comma float unit. 267 * 268 * @covers \qtype_numerical_answer_processor::apply_units 269 * @dataProvider euro_provider 270 * @param array $expected 271 * @param string $params 272 */ 273 public function test_euro_style(array $expected, string $params): void { 274 $ap = new qtype_numerical_answer_processor([], false, ',', ' '); 275 $this->assertEquals($expected, $ap->apply_units($params)); 276 } 277 278 /** 279 * Data provider for apply_units with euro float separators. 280 * 281 * return array 282 */ 283 public function euro_provider(): array { 284 return [ 285 [[-1000, '', null], '-1 000'], 286 [[3.14159, '', null], '3,14159'], 287 ]; 288 } 289 290 /** 291 * Test apply_units with percentage values. 292 * 293 * @covers \qtype_numerical_answer_processor::apply_units 294 * @dataProvider percent_provider 295 * @param array $expected 296 * @param string $params 297 */ 298 public function test_percent(array $expected, string $params): void { 299 $ap = new qtype_numerical_answer_processor(['%' => 100], false, '.', ','); 300 $this->assertEquals($expected, $ap->apply_units($params)); 301 } 302 303 /** 304 * Data provider for apply_units with percentages. 305 * 306 * @return array 307 */ 308 public function percent_provider(): array { 309 return [ 310 [['3', '%', 0.01], '3%'], 311 [['1e-6', '%', 0.01], '1e-6 %'], 312 [['100', '', null], '100'], 313 ]; 314 } 315 316 /** 317 * Test apply_units with currency values. 318 * 319 * @covers \qtype_numerical_answer_processor::apply_units 320 * @dataProvider currency_provider 321 * @param array $expected 322 * @param string $params 323 */ 324 public function test_currency(array $expected, string $params): void { 325 $ap = new qtype_numerical_answer_processor([ 326 '$' => 1, 327 '£' => 1, 328 ], true, '.', ','); 329 $this->assertEquals($expected, $ap->apply_units($params)); 330 } 331 332 /** 333 * Data provider for apply_units with currency values. 334 * 335 * @return array 336 */ 337 public function currency_provider(): array { 338 return [ 339 [['1234.56', '£', 1], '£1,234.56'], 340 [['100', '$', 1], '$100'], 341 [['100', '$', 1], '$100.'], 342 [['100.00', '$', 1], '$100.00'], 343 [['100', '', null], '100'], 344 [['100', 'frog', null], 'frog 100'], 345 ]; 346 } 347 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body