on-demand release 3.10beta+
[moodle.git] / question / behaviour / immediatefeedback / tests / walkthrough_test.php
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/>.
17 /**
18  * This file contains tests that walks a question through the immediate feedback
19  * behaviour.
20  *
21  * @package    qbehaviour
22  * @subpackage immediatefeedback
23  * @copyright  2009 The Open University
24  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25  */
28 defined('MOODLE_INTERNAL') || die();
30 global $CFG;
31 require_once(__DIR__ . '/../../../engine/lib.php');
32 require_once(__DIR__ . '/../../../engine/tests/helpers.php');
35 /**
36  * Unit tests for the immediate feedback behaviour.
37  *
38  * @copyright  2009 The Open University
39  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
40  */
41 class qbehaviour_immediatefeedback_walkthrough_test extends qbehaviour_walkthrough_test_base {
42     public function test_immediatefeedback_feedback_multichoice_right() {
44         // Create a true-false question with correct answer true.
45         $mc = test_question_maker::make_a_multichoice_single_question();
46         $this->start_attempt_at_question($mc, 'immediatefeedback');
48         $rightindex = $this->get_mc_right_answer_index($mc);
49         $wrongindex = ($rightindex + 1) % 3;
51         // Check the initial state.
52         $this->check_current_state(question_state::$todo);
53         $this->check_current_mark(null);
54         $this->check_current_output(
55                 $this->get_contains_question_text_expectation($mc),
56                 $this->get_contains_mc_radio_expectation(0, true, false),
57                 $this->get_contains_mc_radio_expectation(1, true, false),
58                 $this->get_contains_mc_radio_expectation(2, true, false),
59                 $this->get_contains_submit_button_expectation(true),
60                 $this->get_does_not_contain_feedback_expectation());
62         // Save the wrong answer.
63         $this->process_submission(array('answer' => $wrongindex));
65         // Verify.
66         $this->check_current_state(question_state::$todo);
67         $this->check_current_mark(null);
68         $this->check_current_output(
69                 $this->get_contains_mc_radio_expectation($wrongindex, true, true),
70                 $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, true, false),
71                 $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, true, false),
72                 $this->get_contains_submit_button_expectation(true),
73                 $this->get_does_not_contain_correctness_expectation(),
74                 $this->get_does_not_contain_feedback_expectation());
76         // Submit the right answer.
77         $this->process_submission(array('answer' => $rightindex, '-submit' => 1));
79         // Verify.
80         $this->check_current_state(question_state::$gradedright);
81         $this->check_current_mark(1);
82         $this->check_current_output(
83                 $this->get_contains_mc_radio_expectation($rightindex, false, true),
84                 $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false),
85                 $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false),
86                 $this->get_contains_correct_expectation());
87         $this->assertEquals('A',
88                 $this->quba->get_response_summary($this->slot));
90         $numsteps = $this->get_step_count();
92         // Now try to save again - as if the user clicked next in the quiz.
93         $this->process_submission(array('answer' => $rightindex));
95         // Verify.
96         $this->assertEquals($numsteps, $this->get_step_count());
97         $this->check_current_state(question_state::$gradedright);
98         $this->check_current_mark(1);
99         $this->check_current_output(
100                 $this->get_contains_mc_radio_expectation($rightindex, false, true),
101                 $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false),
102                 $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false),
103                 $this->get_contains_correct_expectation());
105         // Finish the attempt - should not need to add a new state.
106         $this->quba->finish_all_questions();
108         // Verify.
109         $this->assertEquals($numsteps, $this->get_step_count());
110         $this->check_current_state(question_state::$gradedright);
111         $this->check_current_mark(1);
112         $this->check_current_output(
113                 $this->get_contains_mc_radio_expectation($rightindex, false, true),
114                 $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false),
115                 $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false),
116                 $this->get_contains_correct_expectation());
118         // Process a manual comment.
119         $this->manual_grade('Not good enough!', 0.5, FORMAT_HTML);
121         // Verify.
122         $this->check_current_state(question_state::$mangrpartial);
123         $this->check_current_mark(0.5);
124         $this->check_current_output(
125                 $this->get_contains_partcorrect_expectation(),
126                 new question_pattern_expectation('/' . preg_quote('Not good enough!', '/') . '/'));
128         // Now change the correct answer to the question, and regrade.
129         $mc->answers[13]->fraction = -0.33333333;
130         $mc->answers[15]->fraction = 1;
131         $this->quba->regrade_all_questions();
133         // Verify.
134         $this->check_current_state(question_state::$mangrpartial);
135         $this->check_current_mark(0.5);
136         $this->check_current_output(
137                 $this->get_contains_partcorrect_expectation());
139         $autogradedstep = $this->get_step($this->get_step_count() - 2);
140         $this->assertEqualsWithDelta($autogradedstep->get_fraction(), -0.3333333, 0.0000001);
141     }
143     public function test_immediatefeedback_feedback_multichoice_try_to_submit_blank() {
145         // Create a true-false question with correct answer true.
146         $mc = test_question_maker::make_a_multichoice_single_question();
147         $this->start_attempt_at_question($mc, 'immediatefeedback');
149         // Check the initial state.
150         $this->check_current_state(question_state::$todo);
151         $this->check_current_mark(null);
152         $this->check_current_output(
153                 $this->get_contains_question_text_expectation($mc),
154                 $this->get_contains_mc_radio_expectation(0, true, false),
155                 $this->get_contains_mc_radio_expectation(1, true, false),
156                 $this->get_contains_mc_radio_expectation(2, true, false),
157                 $this->get_contains_submit_button_expectation(true),
158                 $this->get_does_not_contain_feedback_expectation());
160         // Submit nothing.
161         $this->process_submission(array('-submit' => 1));
163         // Verify.
164         $this->check_current_state(question_state::$invalid);
165         $this->check_current_mark(null);
166         $this->check_current_output(
167                 $this->get_contains_mc_radio_expectation(0, true, false),
168                 $this->get_contains_mc_radio_expectation(1, true, false),
169                 $this->get_contains_mc_radio_expectation(2, true, false),
170                 $this->get_contains_submit_button_expectation(true),
171                 $this->get_does_not_contain_correctness_expectation(),
172                 $this->get_does_not_contain_feedback_expectation(),
173                 $this->get_contains_validation_error_expectation());
174         $this->assertNull($this->quba->get_response_summary($this->slot));
176         // Finish the attempt.
177         $this->quba->finish_all_questions();
179         // Verify.
180         $this->check_current_state(question_state::$gaveup);
181         $this->check_current_mark(null);
182         $this->check_current_output(
183                 $this->get_contains_mc_radio_expectation(0, false, false),
184                 $this->get_contains_mc_radio_expectation(1, false, false),
185                 $this->get_contains_mc_radio_expectation(2, false, false));
187         // Process a manual comment.
188         $this->manual_grade('Not good enough!', 0.5, FORMAT_HTML);
190         // Verify.
191         $this->check_current_state(question_state::$mangrpartial);
192         $this->check_current_mark(0.5);
193         $this->check_current_output(
194                 $this->get_contains_partcorrect_expectation(),
195                 new question_pattern_expectation('/' . preg_quote('Not good enough!', '/') . '/'));
196     }
198     public function test_immediatefeedback_feedback_multichoice_wrong_on_finish() {
200         // Create a true-false question with correct answer true.
201         $mc = test_question_maker::make_a_multichoice_single_question();
202         $this->start_attempt_at_question($mc, 'immediatefeedback');
204         // Check the initial state.
205         $this->check_current_state(question_state::$todo);
206         $this->check_current_mark(null);
207         $this->check_current_output(
208                 $this->get_contains_question_text_expectation($mc),
209                 $this->get_contains_mc_radio_expectation(0, true, false),
210                 $this->get_contains_mc_radio_expectation(1, true, false),
211                 $this->get_contains_mc_radio_expectation(2, true, false),
212                 $this->get_contains_submit_button_expectation(true),
213                 $this->get_does_not_contain_feedback_expectation());
215         $rightindex = $this->get_mc_right_answer_index($mc);
216         $wrongindex = ($rightindex + 1) % 3;
218         // Save the wrong answer.
219         $this->process_submission(array('answer' => $wrongindex));
221         // Verify.
222         $this->check_current_state(question_state::$todo);
223         $this->check_current_mark(null);
224         $this->check_current_output(
225                 $this->get_contains_mc_radio_expectation($wrongindex, true, true),
226                 $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, true, false),
227                 $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, true, false),
228                 $this->get_contains_submit_button_expectation(true),
229                 $this->get_does_not_contain_correctness_expectation(),
230                 $this->get_does_not_contain_feedback_expectation());
232         // Finish the attempt.
233         $this->quba->finish_all_questions();
235         // Verify.
236         $this->check_current_state(question_state::$gradedwrong);
237         $this->check_current_mark(-0.3333333);
238         $this->check_current_output(
239                 $this->get_contains_mc_radio_expectation($wrongindex, false, true),
240                 $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, false, false),
241                 $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, false, false),
242                 $this->get_contains_incorrect_expectation());
243         $this->assertRegExp('/B|C/',
244                 $this->quba->get_response_summary($this->slot));
245     }