|
| 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 unit conversion in the Formulas question plugin. |
| 19 | + * |
| 20 | + * @package qtype_formulas |
| 21 | + * @copyright 2023 Philipp E. Imhof |
| 22 | + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
| 23 | + */ |
| 24 | + |
| 25 | +namespace qtype_formulas; |
| 26 | +use qtype_formulas\variables; |
| 27 | +use Exception; |
| 28 | + |
| 29 | +defined('MOODLE_INTERNAL') || die(); |
| 30 | + |
| 31 | +global $CFG; |
| 32 | +require_once($CFG->dirroot . '/question/engine/tests/helpers.php'); |
| 33 | +require_once($CFG->dirroot . '/question/type/formulas/variables.php'); |
| 34 | +require_once($CFG->dirroot . '/question/type/formulas/conversion_rules.php'); |
| 35 | +require_once($CFG->dirroot . '/question/type/formulas/answer_unit.php'); |
| 36 | + |
| 37 | + |
| 38 | +class unit_conversion_test extends \advanced_testcase { |
| 39 | + |
| 40 | + /** |
| 41 | + * @dataProvider provide_numbers_and_units |
| 42 | + */ |
| 43 | + public function test_common_si_units($expected, $inputs): void { |
| 44 | + $qv = new variables; |
| 45 | + $rules = new unit_conversion_rules(); |
| 46 | + $converter = new answer_unit_conversion(); |
| 47 | + // The ruleset "common SI units" is number 1. |
| 48 | + $entry = $rules->entry(1); |
| 49 | + $converter->assign_default_rules(1, $entry[1]); |
| 50 | + |
| 51 | + list($modelnumber, $modelunit) = $qv->split_formula_unit($expected); |
| 52 | + foreach ($inputs as $input) { |
| 53 | + list($answernumber, $answerunit) = $qv->split_formula_unit($input); |
| 54 | + |
| 55 | + // Check if the unit is compatible. |
| 56 | + $checked = $converter->check_convertibility($answerunit, $modelunit); |
| 57 | + $this->assertEquals(true, $checked->convertible); |
| 58 | + // Convert the number and check if the result is OK. |
| 59 | + $factor = $checked->cfactor; |
| 60 | + $this->assertEqualsWithDelta(floatval($modelnumber), floatval($answernumber) * $factor, 1e-8); |
| 61 | + } |
| 62 | + } |
| 63 | + |
| 64 | + public function provide_numbers_and_units(): array { |
| 65 | + return [ |
| 66 | + 'length 1' => ['100 m', ['0.1 km', '10000 cm', '1000 dm', '100000 mm']], |
| 67 | + 'length 2' => ['1 mm', ['1000 um', '1000000 nm', '0.001 m', '0.1 cm']], |
| 68 | + 'length 3' => ['1 nm', ['1000 pm', '1000000 fm']], |
| 69 | + 'area' => ['1 m^2', ['1e-6 km^2', '100 dm^2', '10000 cm^2']], |
| 70 | + 'volume' => ['1 dm^3', ['0.001 m^3', '1000 cm^3']], |
| 71 | + 'time 1' => ['1 ms', ['1000 us', '0.001 s']], |
| 72 | + 'time 2' => ['1 ns', ['1000 ps', '0.001 us', '1000000 fs']], |
| 73 | + 'time squared' => ['1 s^2', ['1000000 ms^2']], |
| 74 | + 'weigth 1' => ['1 g', ['1000 mg', '0.001 kg', '1000000 ug']], |
| 75 | + 'weigth 2' => ['1 ug', ['0.001 mg', '0.000001 g', '1000 ng', '1000000 pg', '1000000000 fg']], |
| 76 | + 'amount of substance 1' => ['1000 mmol', ['1 mol', '1000000 umol']], |
| 77 | + 'amount of substance 2' => ['1 mol', ['1000 mmol', '1000000 umol']], |
| 78 | + 'amount of substance 3' => ['1 mmol', ['0.001 mol', '1000 umol', '1000000 nmol', '1000000000 pmol']], |
| 79 | + 'force 1' => ['1 N', ['0.001 kN', '1000 mN', '1000000 uN']], |
| 80 | + 'force 2' => ['1 uN', ['0.001 mN', '0.000001 N', '1000 nN', '1000000 pN', '1000000000 fN']], |
| 81 | + 'current 1' => ['1 A', ['1000 mA', '1000000 uA', '1000000000 nA']], |
| 82 | + 'current 2' => ['1 uA', ['0.001 mA', '0.000001 A', '1000 nA', '1000000 pA']], |
| 83 | + 'energy 1' => ['1 kJ', ['1000 J', '0.001 MJ', '0.000001 GJ']], |
| 84 | + 'energy 2' => ['1 GJ', ['1000 MJ', '0.001 TJ', '1000000 kJ', '1000000000 J']], |
| 85 | + 'energy 3' => ['1 J', ['1000 mJ', '1000000 uJ', '1000000000 nJ']], |
| 86 | + 'energy J/eV' => ['1 J', ['6241509.47e12 eV', '6241509.47e6 MeV', '6241509470 GeV']], |
| 87 | + 'power 1' => ['1 kW', ['1000 W', '0.001 MW', '0.000001 GW']], |
| 88 | + 'power 2' => ['1 GW', ['1000 MW', '0.001 TW', '1000000 kW', '1000000000 W']], |
| 89 | + 'power 3' => ['1 W', ['1000 mW', '1000000 uW', '1000000000 nW']], |
| 90 | + 'pressure' => ['1 MPa', ['1000 kPa', '1000000 Pa', '0.001 GPa', '0.000001 TPa']], |
| 91 | + 'frequency' => ['1 GHz', ['1000 MHz', '1000000 kHz', '0.001 THz', '0.000001 PHz']], |
| 92 | + 'charge' => ['1 C', ['1000 mC', '1000000 uC', '1e9 nC', '0.001 kC']], |
| 93 | + 'voltage' => ['1000 V', ['1 kV', '1000000 mV', '1e9 uV', '0.001 MV']], |
| 94 | + 'resistance 1' => ['1000 ohm', ['1 kohm', '1000000 mohm', '0.001 Mohm']], |
| 95 | + 'resistance 2' => ['1e9 ohm', ['1 Gohm', '0.001 Tohm']], |
| 96 | + 'capacitance' => ['1 uF', ['0.001 mF', '0.000001 F', '1000 nF']], |
| 97 | + 'flux density' => ['1 uT', ['0.001 mT', '0.000001 T', '1000 nT']], |
| 98 | + 'inductance' => ['1 uH', ['0.001 mH', '0.000001 H', '1000 nH']], |
| 99 | + 'speed' => ['1 m/ms', ['1 km/s']], |
| 100 | + 'combination 1' => ['1 m g/us', ['1000 mm kg ms^-1']], |
| 101 | + 'combination 2' => ['1 kPa s^-2', ['1e-3 Pa ms^-2']], |
| 102 | + 'combination 3' => ['1 m kg s^-2', ['1 m kg / s^2', '1 km g / s^2', '1 km g s^-2']], |
| 103 | + ]; |
| 104 | + } |
| 105 | + |
| 106 | + |
| 107 | + |
| 108 | +} |
0 commit comments