MDL-67673 phpunit: Bump to PHPUnit 8.5 and remove DBunit
[moodle.git] / question / engine / tests / questionattempt_with_steps_test.php
CommitLineData
eca230b5
TH
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
30defined('MOODLE_INTERNAL') || die();
31
32global $CFG;
1fcf0ca8
RS
33require_once(__DIR__ . '/../lib.php');
34require_once(__DIR__ . '/helpers.php');
eca230b5
TH
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 */
43class question_attempt_with_steps_test extends advanced_testcase {
44 private $question;
45 private $qa;
46
47 protected function setUp() {
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() {
57 $this->qa = null;
58 }
59
52f3e060
RT
60 /**
61 * @expectedException moodle_exception
62 */
eca230b5 63 public function test_get_step_before_start() {
eca230b5
TH
64 $step = $this->qa->get_step(-1);
65 }
66
67 public function test_get_step_at_start() {
68 $step = $this->qa->get_step(0);
69 $this->assertEquals(0, $step->get_qt_var('i'));
70 }
71
72 public function test_get_step_at_end() {
73 $step = $this->qa->get_step(2);
74 $this->assertEquals(2, $step->get_qt_var('i'));
75 }
76
52f3e060
RT
77 /**
78 * @expectedException moodle_exception
79 */
eca230b5 80 public function test_get_step_past_end() {
eca230b5
TH
81 $step = $this->qa->get_step(3);
82 }
83
84 public function test_get_num_steps() {
85 $this->assertEquals(3, $this->qa->get_num_steps());
86 }
87
88 public function test_get_last_step() {
89 $step = $this->qa->get_last_step();
90 $this->assertEquals(2, $step->get_qt_var('i'));
91 }
92
93 public function test_get_last_qt_var_there1() {
94 $this->assertEquals(2, $this->qa->get_last_qt_var('i'));
95 }
96
97 public function test_get_last_qt_var_there2() {
98 $this->qa->get_step(0)->set_qt_var('_x', 'a value');
99 $this->assertEquals('a value', $this->qa->get_last_qt_var('_x'));
100 }
101
102 public function test_get_last_qt_var_missing() {
103 $this->assertNull($this->qa->get_last_qt_var('notthere'));
104 }
105
106 public function test_get_last_qt_var_missing_default() {
107 $this->assertEquals('default', $this->qa->get_last_qt_var('notthere', 'default'));
108 }
109
110 public function test_get_last_behaviour_var_missing() {
111 $this->assertNull($this->qa->get_last_qt_var('notthere'));
112 }
113
114 public function test_get_last_behaviour_var_there() {
115 $this->qa->get_step(1)->set_behaviour_var('_x', 'a value');
116 $this->assertEquals('a value', '' . $this->qa->get_last_behaviour_var('_x'));
117 }
118
119 public function test_get_state_gets_state_of_last() {
120 $this->qa->get_step(2)->set_state(question_state::$gradedright);
121 $this->qa->get_step(1)->set_state(question_state::$gradedwrong);
122 $this->assertEquals(question_state::$gradedright, $this->qa->get_state());
123 }
124
125 public function test_get_mark_gets_mark_of_last() {
126 $this->assertEquals(2, $this->qa->get_max_mark());
127 $this->qa->get_step(2)->set_fraction(0.5);
128 $this->qa->get_step(1)->set_fraction(0.1);
129 $this->assertEquals(1, $this->qa->get_mark());
130 }
131
132 public function test_get_fraction_gets_fraction_of_last() {
133 $this->qa->get_step(2)->set_fraction(0.5);
134 $this->qa->get_step(1)->set_fraction(0.1);
135 $this->assertEquals(0.5, $this->qa->get_fraction());
136 }
137
138 public function test_get_fraction_returns_null_if_none() {
139 $this->assertNull($this->qa->get_fraction());
140 }
141
142 public function test_format_mark() {
143 $this->qa->get_step(2)->set_fraction(0.5);
144 $this->assertEquals('1.00', $this->qa->format_mark(2));
145 }
146
147 public function test_format_max_mark() {
148 $this->assertEquals('2.0000000', $this->qa->format_max_mark(7));
149 }
150
151 public function test_get_min_fraction() {
152 $this->qa->set_min_fraction(-1);
4e3d8293 153 $this->assertEquals(-1, $this->qa->get_min_fraction());
eca230b5
TH
154 }
155
156 public function test_cannot_get_min_fraction_before_start() {
157 $qa = new question_attempt($this->question, 0);
52f3e060 158 $this->expectException('moodle_exception');
eca230b5
TH
159 $qa->get_min_fraction();
160 }
4e3d8293
TH
161
162 public function test_get_max_fraction() {
163 $this->qa->set_max_fraction(2);
164 $this->assertEquals(2, $this->qa->get_max_fraction());
165 }
166
167 public function test_cannot_get_max_fraction_before_start() {
168 $qa = new question_attempt($this->question, 0);
52f3e060 169 $this->expectException('moodle_exception');
4e3d8293
TH
170 $qa->get_max_fraction();
171 }
b2694c02 172
e3bfcb1c
TH
173 /**
174 * Test cases for {@see test_validate_manual_mark()}.
175 *
176 * @return array test cases
177 */
178 public function validate_manual_mark_cases(): array {
179 // Recall, the DB schema stores question grade information to 7 decimal places.
180 return [
181 [0, 1, 2, null, ''],
182 [0, 1, 2, '', ''],
183 [0, 1, 2, '0', ''],
184 [0, 1, 2, '0.0', ''],
185 [0, 1, 2, '2,0', ''],
186 [0, 1, 2, 'frog', get_string('manualgradeinvalidformat', 'question')],
187 [0, 1, 2, '2.1', get_string('manualgradeoutofrange', 'question')],
188 [0, 1, 2, '-0,01', get_string('manualgradeoutofrange', 'question')],
189 [-0.3333333, 1, 0.75, '0.75', ''],
190 [-0.3333333, 1, 0.75, '0.7500001', get_string('manualgradeoutofrange', 'question')],
191 [-0.3333333, 1, 0.75, '-0.25', ''],
192 [-0.3333333, 1, 0.75, '-0.2500001', get_string('manualgradeoutofrange', 'question')],
193 ];
194 }
195
196 /**
197 * Test validate_manual_mark.
198 *
199 * @dataProvider validate_manual_mark_cases
200 *
201 * @param float $minfraction minimum fraction for the question being attempted.
202 * @param float $maxfraction maximum fraction for the question being attempted.
203 * @param float $maxmark marks for the question attempt.
204 * @param string|null $currentmark submitted mark.
205 * @param string $expectederror expected error, if any.
206 */
207 public function test_validate_manual_mark(float $minfraction, float $maxfraction,
208 float $maxmark, ?string $currentmark, string $expectederror) {
209 $this->qa->set_min_fraction($minfraction);
210 $this->qa->set_max_fraction($maxfraction);
211 $this->qa->set_max_mark($maxmark);
212 $this->assertSame($expectederror, $this->qa->validate_manual_mark($currentmark));
b2694c02 213 }
eca230b5 214}