36cc73c965b54e3306434efdef23e27176ba19f5
[moodle.git] / question / behaviour / deferredcbm / 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 deferred feedback
19  * with certainty base marking behaviour.
20  *
21  * @package    qbehaviour
22  * @subpackage deferredcbm
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(dirname(__FILE__) . '/../../../engine/lib.php');
32 require_once(dirname(__FILE__) . '/../../../engine/tests/helpers.php');
35 /**
36  * Unit tests for the deferred feedback with certainty base marking 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_deferredcbm_walkthrough_test extends qbehaviour_walkthrough_test_base {
42     public function test_deferred_cbm_truefalse_high_certainty() {
44         // Create a true-false question with correct answer true.
45         $tf = test_question_maker::make_question('truefalse', 'true');
46         $this->start_attempt_at_question($tf, 'deferredcbm', 2);
48         // Verify.
49         $this->check_current_state(question_state::$todo);
50         $this->check_current_mark(null);
51         $this->check_current_output(
52                 $this->get_contains_question_text_expectation($tf),
53                 $this->get_contains_tf_true_radio_expectation(true, false),
54                 $this->get_contains_tf_false_radio_expectation(true, false),
55                 $this->get_contains_cbm_radio_expectation(1, true, false),
56                 $this->get_contains_cbm_radio_expectation(2, true, false),
57                 $this->get_contains_cbm_radio_expectation(3, true, false),
58                 $this->get_does_not_contain_feedback_expectation());
60         // Process the data extracted for this question.
61         $this->process_submission(array('answer' => 1, '-certainty' => 3));
63         // Verify.
64         $this->check_current_state(question_state::$complete);
65         $this->check_current_mark(null);
66         $this->check_current_output(
67                 $this->get_contains_tf_true_radio_expectation(true, true),
68                 $this->get_contains_cbm_radio_expectation(3, true, true),
69                 $this->get_does_not_contain_correctness_expectation(),
70                 $this->get_does_not_contain_feedback_expectation());
72         // Process the same data again, check it does not create a new step.
73         $numsteps = $this->get_step_count();
74         $this->process_submission(array('answer' => 1, '-certainty' => 3));
75         $this->check_step_count($numsteps);
77         // Process different data, check it creates a new step.
78         $this->process_submission(array('answer' => 1, '-certainty' => 1));
79         $this->check_step_count($numsteps + 1);
80         $this->check_current_state(question_state::$complete);
82         // Change back, check it creates a new step.
83         $this->process_submission(array('answer' => 1, '-certainty' => 3));
84         $this->check_step_count($numsteps + 2);
86         // Finish the attempt.
87         $this->quba->finish_all_questions();
89         // Verify.
90         $this->check_current_state(question_state::$gradedright);
91         $this->check_current_mark(2);
92         $this->check_current_output(
93                 $this->get_contains_tf_true_radio_expectation(false, true),
94                 $this->get_contains_cbm_radio_expectation(3, false, true),
95                 $this->get_contains_correct_expectation());
97         // Process a manual comment.
98         $this->manual_grade('Not good enough!', 1, FORMAT_HTML);
100         // Verify.
101         $this->check_current_state(question_state::$mangrpartial);
102         $this->check_current_mark(1);
103         $this->check_current_output(new question_pattern_expectation('/' .
104                 preg_quote('Not good enough!', '/') . '/'));
106         // Now change the correct answer to the question, and regrade.
107         $tf->rightanswer = false;
108         $this->quba->regrade_all_questions();
110         // Verify.
111         $this->check_current_state(question_state::$mangrpartial);
112         $this->check_current_mark(1);
113         $autogradedstep = $this->get_step($this->get_step_count() - 2);
114         $this->assertEquals($autogradedstep->get_fraction(), -2, '', 0.0000001);
115     }
117     public function test_deferred_cbm_truefalse_low_certainty() {
119         // Create a true-false question with correct answer true.
120         $tf = test_question_maker::make_question('truefalse', 'true');
121         $this->start_attempt_at_question($tf, 'deferredcbm', 2);
123         // Verify.
124         $this->check_current_state(question_state::$todo);
125         $this->check_current_mark(null);
126         $this->check_current_output(
127                 $this->get_does_not_contain_correctness_expectation(),
128                 $this->get_contains_cbm_radio_expectation(1, true, false),
129                 $this->get_does_not_contain_feedback_expectation());
131         // Submit ansewer with low certainty.
132         $this->process_submission(array('answer' => 1, '-certainty' => 1));
134         // Verify.
135         $this->check_current_state(question_state::$complete);
136         $this->check_current_mark(null);
137         $this->check_current_output($this->get_does_not_contain_correctness_expectation(),
138                 $this->get_contains_cbm_radio_expectation(1, true, true),
139                 $this->get_does_not_contain_feedback_expectation());
141         // Finish the attempt.
142         $this->quba->finish_all_questions();
144         // Verify.
145         $this->check_current_state(question_state::$gradedright);
146         $this->check_current_mark(0.6666667);
147         $this->check_current_output($this->get_contains_correct_expectation(),
148                 $this->get_contains_cbm_radio_expectation(1, false, true));
149         $this->assertEquals(get_string('true', 'qtype_truefalse') . ' [' .
150                 question_cbm::get_string(1) . ']',
151                 $this->quba->get_response_summary($this->slot));
152     }
154     public function test_deferred_cbm_truefalse_default_certainty() {
156         // Create a true-false question with correct answer true.
157         $tf = test_question_maker::make_question('truefalse', 'true');
158         $this->start_attempt_at_question($tf, 'deferredcbm', 2);
160         // Verify.
161         $this->check_current_state(question_state::$todo);
162         $this->check_current_mark(null);
163         $this->check_current_output(
164                 $this->get_does_not_contain_correctness_expectation(),
165                 $this->get_contains_cbm_radio_expectation(1, true, false),
166                 $this->get_does_not_contain_feedback_expectation());
168         // Submit ansewer with low certainty and finish the attempt.
169         $this->process_submission(array('answer' => 1));
170         $this->quba->finish_all_questions();
172         // Verify.
173         $qa = $this->quba->get_question_attempt($this->slot);
174         $this->check_current_state(question_state::$gradedright);
175         $this->check_current_mark(0.6666667);
176         $this->check_current_output($this->get_contains_correct_expectation(),
177                 $this->get_contains_cbm_radio_expectation(1, false, false),
178                 new question_pattern_expectation('/' . preg_quote(
179                         get_string('assumingcertainty', 'qbehaviour_deferredcbm',
180                         question_cbm::get_string(
181                             $qa->get_last_behaviour_var('_assumedcertainty'))), '/') . '/'));
182         $this->assertEquals(get_string('true', 'qtype_truefalse'),
183                 $this->quba->get_response_summary($this->slot));
184     }
186     public function test_deferredcbm_resume_multichoice_single() {
188         // Create a multiple-choice question.
189         $mc = test_question_maker::make_a_multichoice_single_question();
191         // Attempt it getting it wrong.
192         $this->start_attempt_at_question($mc, 'deferredcbm', 3);
193         $rightindex = $this->get_mc_right_answer_index($mc);
194         $wrongindex = ($rightindex + 1) % 3;
195         $this->process_submission(array('answer' => $wrongindex, '-certainty' => 2));
196         $this->quba->finish_all_questions();
198         // Verify.
199         $this->check_current_state(question_state::$gradedwrong);
200         $this->check_current_mark(-3.3333333);
201         $this->check_current_output(
202                 $this->get_contains_mc_radio_expectation($wrongindex, false, true),
203                 $this->get_contains_cbm_radio_expectation(2, false, true),
204                 $this->get_contains_incorrect_expectation());
205         $this->assertEquals('A [' . question_cbm::get_string(question_cbm::HIGH) . ']',
206                 $this->quba->get_right_answer_summary($this->slot));
207         $this->assertRegExp('/' . preg_quote($mc->questiontext, '/') . '/',
208                 $this->quba->get_question_summary($this->slot));
209         $this->assertRegExp('/(B|C) \[' . preg_quote(question_cbm::get_string(2), '/') . '\]/',
210                 $this->quba->get_response_summary($this->slot));
212         // Save the old attempt.
213         $oldqa = $this->quba->get_question_attempt($this->slot);
215         // Reinitialise.
216         $this->setUp();
217         $this->quba->set_preferred_behaviour('deferredcbm');
218         $this->slot = $this->quba->add_question($mc, 3);
219         $this->quba->start_question_based_on($this->slot, $oldqa);
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_cbm_radio_expectation(2, true, true),
227                 $this->get_does_not_contain_feedback_expectation(),
228                 $this->get_does_not_contain_correctness_expectation());
229         $this->assertEquals('A [' . question_cbm::get_string(question_cbm::HIGH) . ']',
230                 $this->quba->get_right_answer_summary($this->slot));
231         $this->assertRegExp('/' . preg_quote($mc->questiontext, '/') . '/',
232                 $this->quba->get_question_summary($this->slot));
233         $this->assertNull($this->quba->get_response_summary($this->slot));
235         // Now get it right.
236         $this->process_submission(array('answer' => $rightindex, '-certainty' => 3));
237         $this->quba->finish_all_questions();
239         // Verify.
240         $this->check_current_state(question_state::$gradedright);
241         $this->check_current_mark(3);
242         $this->check_current_output(
243                 $this->get_contains_mc_radio_expectation($rightindex, false, true),
244                 $this->get_contains_cbm_radio_expectation(3, false, true),
245                 $this->get_contains_correct_expectation());
246         $this->assertRegExp('/(A) \[' . preg_quote(question_cbm::get_string(3), '/') . '\]/',
247                 $this->quba->get_response_summary($this->slot));
248     }
250     public function test_deferred_cbm_truefalse_no_certainty_feedback_when_not_answered() {
252         // Create a true-false question with correct answer true.
253         $tf = test_question_maker::make_question('truefalse', 'true');
254         $this->start_attempt_at_question($tf, 'deferredcbm', 2);
256         // Verify.
257         $this->check_current_state(question_state::$todo);
258         $this->check_current_mark(null);
259         $this->check_current_output(
260                 $this->get_does_not_contain_correctness_expectation(),
261                 $this->get_contains_cbm_radio_expectation(1, true, false),
262                 $this->get_does_not_contain_feedback_expectation());
264         // Finish without answering.
265         $this->quba->finish_all_questions();
267         // Verify.
268         $this->check_current_state(question_state::$gaveup);
269         $this->check_current_mark(null);
270         $this->check_current_output(
271                 new question_no_pattern_expectation('/class=\"im-feedback/'));
272     }