See Release Notes
Long Term Support Release
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 core_question; 18 19 use question_attempt; 20 use question_attempt_step; 21 use question_state; 22 use testable_question_attempt; 23 24 defined('MOODLE_INTERNAL') || die(); 25 26 global $CFG; 27 require_once (__DIR__ . '/../lib.php'); 28 require_once (__DIR__ . '/helpers.php'); 29 30 /** 31 * These tests use a standard fixture of a {@link question_attempt} with three steps. 32 * 33 * Action methods like start, process_action and finish are assumed to be 34 * tested by walkthrough tests in the various behaviours. 35 * 36 * @package core_question 37 * @category test 38 * @copyright 2009 The Open University 39 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 40 */ 41 class questionattempt_with_steps_test extends \advanced_testcase { 42 private $question; 43 private $qa; 44 45 protected function setUp(): void { 46 $this->question = \test_question_maker::make_question('description'); 47 $this->qa = new testable_question_attempt($this->question, 0, null, 2); 48 for ($i = 0; $i < 3; $i++) { 49 $step = new question_attempt_step(array('i' => $i)); 50 $this->qa->add_step($step); 51 } 52 } 53 54 protected function tearDown(): void { 55 $this->qa = null; 56 } 57 58 public function test_get_step_before_start() { 59 $this->expectException(\moodle_exception::class); 60 $step = $this->qa->get_step(-1); 61 } 62 63 public function test_get_step_at_start() { 64 $step = $this->qa->get_step(0); 65 $this->assertEquals(0, $step->get_qt_var('i')); 66 } 67 68 public function test_get_step_at_end() { 69 $step = $this->qa->get_step(2); 70 $this->assertEquals(2, $step->get_qt_var('i')); 71 } 72 73 public function test_get_step_past_end() { 74 $this->expectException(\moodle_exception::class); 75 $step = $this->qa->get_step(3); 76 } 77 78 public function test_get_num_steps() { 79 $this->assertEquals(3, $this->qa->get_num_steps()); 80 } 81 82 public function test_get_last_step() { 83 $step = $this->qa->get_last_step(); 84 $this->assertEquals(2, $step->get_qt_var('i')); 85 } 86 87 public function test_get_last_qt_var_there1() { 88 $this->assertEquals(2, $this->qa->get_last_qt_var('i')); 89 } 90 91 public function test_get_last_qt_var_there2() { 92 $this->qa->get_step(0)->set_qt_var('_x', 'a value'); 93 $this->assertEquals('a value', $this->qa->get_last_qt_var('_x')); 94 } 95 96 public function test_get_last_qt_var_missing() { 97 $this->assertNull($this->qa->get_last_qt_var('notthere')); 98 } 99 100 public function test_get_last_qt_var_missing_default() { 101 $this->assertEquals('default', $this->qa->get_last_qt_var('notthere', 'default')); 102 } 103 104 public function test_get_last_behaviour_var_missing() { 105 $this->assertNull($this->qa->get_last_qt_var('notthere')); 106 } 107 108 public function test_get_last_behaviour_var_there() { 109 $this->qa->get_step(1)->set_behaviour_var('_x', 'a value'); 110 $this->assertEquals('a value', '' . $this->qa->get_last_behaviour_var('_x')); 111 } 112 113 public function test_get_state_gets_state_of_last() { 114 $this->qa->get_step(2)->set_state(question_state::$gradedright); 115 $this->qa->get_step(1)->set_state(question_state::$gradedwrong); 116 $this->assertEquals(question_state::$gradedright, $this->qa->get_state()); 117 } 118 119 public function test_get_mark_gets_mark_of_last() { 120 $this->assertEquals(2, $this->qa->get_max_mark()); 121 $this->qa->get_step(2)->set_fraction(0.5); 122 $this->qa->get_step(1)->set_fraction(0.1); 123 $this->assertEquals(1, $this->qa->get_mark()); 124 } 125 126 public function test_get_fraction_gets_fraction_of_last() { 127 $this->qa->get_step(2)->set_fraction(0.5); 128 $this->qa->get_step(1)->set_fraction(0.1); 129 $this->assertEquals(0.5, $this->qa->get_fraction()); 130 } 131 132 public function test_get_fraction_returns_null_if_none() { 133 $this->assertNull($this->qa->get_fraction()); 134 } 135 136 public function test_format_mark() { 137 $this->qa->get_step(2)->set_fraction(0.5); 138 $this->assertEquals('1.00', $this->qa->format_mark(2)); 139 } 140 141 public function test_format_max_mark() { 142 $this->assertEquals('2.0000000', $this->qa->format_max_mark(7)); 143 } 144 145 public function test_get_min_fraction() { 146 $this->qa->set_min_fraction(-1); 147 $this->assertEquals(-1, $this->qa->get_min_fraction()); 148 } 149 150 public function test_cannot_get_min_fraction_before_start() { 151 $qa = new question_attempt($this->question, 0); 152 $this->expectException('moodle_exception'); 153 $qa->get_min_fraction(); 154 } 155 156 public function test_get_max_fraction() { 157 $this->qa->set_max_fraction(2); 158 $this->assertEquals(2, $this->qa->get_max_fraction()); 159 } 160 161 public function test_cannot_get_max_fraction_before_start() { 162 $qa = new question_attempt($this->question, 0); 163 $this->expectException('moodle_exception'); 164 $qa->get_max_fraction(); 165 } 166 167 /** 168 * Test cases for {@see test_validate_manual_mark()}. 169 * 170 * @return array test cases 171 */ 172 public function validate_manual_mark_cases(): array { 173 // Recall, the DB schema stores question grade information to 7 decimal places. 174 return [ 175 [0, 1, 2, null, ''], 176 [0, 1, 2, '', ''], 177 [0, 1, 2, '0', ''], 178 [0, 1, 2, '0.0', ''], 179 [0, 1, 2, '2,0', ''], 180 [0, 1, 2, 'frog', get_string('manualgradeinvalidformat', 'question')], 181 [0, 1, 2, '2.1', get_string('manualgradeoutofrange', 'question')], 182 [0, 1, 2, '-0,01', get_string('manualgradeoutofrange', 'question')], 183 [-0.3333333, 1, 0.75, '0.75', ''], 184 [-0.3333333, 1, 0.75, '0.7500001', get_string('manualgradeoutofrange', 'question')], 185 [-0.3333333, 1, 0.75, '-0.25', ''], 186 [-0.3333333, 1, 0.75, '-0.2500001', get_string('manualgradeoutofrange', 'question')], 187 ]; 188 } 189 190 /** 191 * Test validate_manual_mark. 192 * 193 * @dataProvider validate_manual_mark_cases 194 * 195 * @param float $minfraction minimum fraction for the question being attempted. 196 * @param float $maxfraction maximum fraction for the question being attempted. 197 * @param float $maxmark marks for the question attempt. 198 * @param string|null $currentmark submitted mark. 199 * @param string $expectederror expected error, if any. 200 */ 201 public function test_validate_manual_mark(float $minfraction, float $maxfraction, 202 float $maxmark, ?string $currentmark, string $expectederror) { 203 $this->qa->set_min_fraction($minfraction); 204 $this->qa->set_max_fraction($maxfraction); 205 $this->qa->set_max_mark($maxmark); 206 $this->assertSame($expectederror, $this->qa->validate_manual_mark($currentmark)); 207 } 208 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body