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