MDL-37506 question code: incorrect preg_quote uses.
[moodle.git] / question / behaviour / adaptive / 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/>.
18 /**
19  * This file contains tests that walks a question through the adaptive
20  * behaviour.
21  *
22  * @package    qbehaviour
23  * @subpackage adaptive
24  * @copyright  2009 The Open University
25  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26  */
29 defined('MOODLE_INTERNAL') || die();
31 global $CFG;
32 require_once(dirname(__FILE__) . '/../../../engine/lib.php');
33 require_once(dirname(__FILE__) . '/../../../engine/tests/helpers.php');
36 /**
37  * Unit tests for the adaptive behaviour.
38  *
39  * @copyright  2009 The Open University
40  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
41  */
42 class qbehaviour_adaptive_walkthrough_test extends qbehaviour_walkthrough_test_base {
43     protected function get_contains_penalty_info_expectation($penalty) {
44         $penaltyinfo = get_string('gradingdetailspenalty', 'qbehaviour_adaptive',
45                                   format_float($penalty, $this->displayoptions->markdp));
46         return new question_pattern_expectation('/'.preg_quote($penaltyinfo, '/').'/');
47     }
49     protected function get_does_not_contain_penalty_info_expectation() {
50         $penaltyinfo = get_string('gradingdetailspenalty', 'qbehaviour_adaptive', 'XXXXX');
51         $penaltypattern = '/'.str_replace('XXXXX', '\\w*', preg_quote($penaltyinfo, '/')).'/';
52         return new question_no_pattern_expectation($penaltypattern);
53     }
55     protected function get_contains_total_penalty_expectation($penalty) {
56         $penaltyinfo = get_string('gradingdetailspenaltytotal', 'qbehaviour_adaptive',
57                                   format_float($penalty, $this->displayoptions->markdp));
58         return new question_pattern_expectation('/'.preg_quote($penaltyinfo, '/').'/');
59     }
61     protected function get_does_not_contain_total_penalty_expectation() {
62         $penaltyinfo = get_string('gradingdetailspenaltytotal', 'qbehaviour_adaptive', 'XXXXX');
63         $penaltypattern = '/'.str_replace('XXXXX', '\\w*', preg_quote($penaltyinfo, '/')).'/';
64         return new question_no_pattern_expectation($penaltypattern);
65     }
67     protected function get_contains_disregarded_info_expectation() {
68         $penaltyinfo = get_string('disregardedwithoutpenalty', 'qbehaviour_adaptive');
69         return new question_pattern_expectation('/'.preg_quote($penaltyinfo, '/').'/');
70     }
72     protected function get_does_not_contain_disregarded_info_expectation() {
73         $penaltyinfo = get_string('disregardedwithoutpenalty', 'qbehaviour_adaptive');
74         return new question_no_pattern_expectation('/'.preg_quote($penaltyinfo, '/').'/');
75     }
77     public function test_adaptive_multichoice() {
79         // Create a multiple choice, single response question.
80         $mc = test_question_maker::make_a_multichoice_single_question();
81         $mc->penalty = 0.3333333;
82         $this->start_attempt_at_question($mc, 'adaptive', 3);
84         $rightindex = $this->get_mc_right_answer_index($mc);
85         $wrongindex = ($rightindex + 1) % 3;
87         // Check the initial state.
88         $this->check_current_state(question_state::$todo);
89         $this->check_current_mark(null);
90         $this->check_current_output(
91                 $this->get_contains_marked_out_of_summary(),
92                 $this->get_contains_question_text_expectation($mc),
93                 $this->get_contains_mc_radio_expectation(0, true, false),
94                 $this->get_contains_mc_radio_expectation(1, true, false),
95                 $this->get_contains_mc_radio_expectation(2, true, false),
96                 $this->get_contains_submit_button_expectation(true),
97                 $this->get_does_not_contain_feedback_expectation());
99         // Process a submit.
100         $this->process_submission(array('answer' => $wrongindex, '-submit' => 1));
102         // Verify.
103         $this->check_current_state(question_state::$todo);
104         $this->check_current_mark(0);
105         $this->check_current_output(
106                 $this->get_contains_mark_summary(0),
107                 $this->get_contains_mc_radio_expectation($wrongindex, true, true),
108                 $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, true, false),
109                 $this->get_contains_mc_radio_expectation(($wrongindex + 2) % 3, true, false),
110                 $this->get_contains_incorrect_expectation(),
111                 $this->get_contains_penalty_info_expectation(1.00),
112                 $this->get_does_not_contain_total_penalty_expectation());
113         $this->assertRegExp('/B|C/',
114                 $this->quba->get_response_summary($this->slot));
116         // Process a change of answer to the right one, but not sumbitted.
117         $this->process_submission(array('answer' => $rightindex));
119         // Verify.
120         $this->check_current_state(question_state::$todo);
121         $this->check_current_mark(0);
122         $this->check_current_output(
123                 $this->get_contains_mark_summary(0),
124                 $this->get_contains_mc_radio_expectation($rightindex, true, true),
125                 $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, true, false),
126                 $this->get_contains_mc_radio_expectation(($rightindex + 2) % 3, true, false));
127         $this->assertRegExp('/B|C/',
128                 $this->quba->get_response_summary($this->slot));
130         // Now submit the right answer.
131         $this->process_submission(array('answer' => $rightindex, '-submit' => 1));
133         // Verify.
134         $this->check_current_state(question_state::$complete);
135         $this->check_current_mark(3 * (1 - $mc->penalty));
136         $this->check_current_output(
137                 $this->get_contains_mark_summary(3 * (1 - $mc->penalty)),
138                 $this->get_contains_mc_radio_expectation($rightindex, true, true),
139                 $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, true, false),
140                 $this->get_contains_mc_radio_expectation(($rightindex + 2) % 3, true, false),
141                 $this->get_contains_correct_expectation(),
142                 $this->get_does_not_contain_penalty_info_expectation(),
143                 $this->get_does_not_contain_total_penalty_expectation());
144         $this->assertEquals('A',
145                 $this->quba->get_response_summary($this->slot));
147         // Finish the attempt.
148         $this->quba->finish_all_questions();
150         // Verify.
151         $this->check_current_state(question_state::$gradedright);
152         $this->check_current_mark(3 * (1 - $mc->penalty));
153         $this->check_current_output(
154                 $this->get_contains_mark_summary(3 * (1 - $mc->penalty)),
155                 $this->get_contains_mc_radio_expectation($rightindex, false, true),
156                 $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false),
157                 $this->get_contains_mc_radio_expectation(($rightindex + 2) % 3, false, false),
158                 $this->get_contains_correct_expectation());
160         // Process a manual comment.
161         $this->manual_grade('Not good enough!', 1);
163         // Verify.
164         $this->check_current_state(question_state::$mangrpartial);
165         $this->check_current_mark(1);
166         $this->check_current_output(
167                 $this->get_contains_mark_summary(1),
168                 new question_pattern_expectation('/' . preg_quote('Not good enough!', '/') . '/'));
170         // Now change the correct answer to the question, and regrade.
171         $mc->answers[13]->fraction = -0.33333333;
172         $mc->answers[14]->fraction = 1; // We don't know which "wrong" index we chose above!
173         $mc->answers[15]->fraction = 1; // Therefore, treat answers B and C with the same score.
174         $this->quba->regrade_all_questions();
176         // Verify.
177         $this->check_current_state(question_state::$mangrpartial);
178         $this->check_current_mark(1);
179         $this->check_current_output(
180                 $this->get_contains_mark_summary(1),
181                 $this->get_contains_partcorrect_expectation());
183         $autogradedstep = $this->get_step($this->get_step_count() - 2);
184         $this->assertEquals($autogradedstep->get_fraction(), 1, '', 0.0000001);
185     }
187     public function test_adaptive_multichoice2() {
189         // Create a multiple choice, multiple response question.
190         $mc = test_question_maker::make_a_multichoice_multi_question();
191         $mc->penalty = 0.3333333;
192         $mc->shuffleanswers = 0;
193         $this->start_attempt_at_question($mc, 'adaptive', 2);
195         // Check the initial state.
196         $this->check_current_state(question_state::$todo);
197         $this->check_current_mark(null);
198         $this->check_current_output(
199                 $this->get_contains_marked_out_of_summary(),
200                 $this->get_contains_question_text_expectation($mc),
201                 $this->get_contains_submit_button_expectation(true),
202                 $this->get_does_not_contain_feedback_expectation());
204         // Process a submit.
205         $this->process_submission(array('choice0' => 1, 'choice2' => 1, '-submit' => 1));
207         // Verify.
208         $this->check_current_state(question_state::$complete);
209         $this->check_current_mark(2);
210         $this->check_current_output(
211                 $this->get_contains_mark_summary(2),
212                 $this->get_contains_submit_button_expectation(true),
213                 $this->get_contains_correct_expectation(),
214                 $this->get_does_not_contain_penalty_info_expectation(),
215                 $this->get_does_not_contain_total_penalty_expectation());
217         // Save the same correct answer again. Should not do anything.
218         $numsteps = $this->get_step_count();
219         $this->process_submission(array('choice0' => 1, 'choice2' => 1));
221         // Verify.
222         $this->check_step_count($numsteps);
223         $this->check_current_mark(2);
224         $this->check_current_state(question_state::$complete);
226         // Finish the attempt.
227         $this->quba->finish_all_questions();
229         // Verify.
230         $this->check_step_count($numsteps + 1);
231         $this->check_current_state(question_state::$gradedright);
232         $this->check_current_mark(2);
233         $this->check_current_output(
234                 $this->get_contains_mark_summary(2),
235                 $this->get_contains_submit_button_expectation(false),
236                 $this->get_contains_correct_expectation());
237     }
239     public function test_adaptive_shortanswer_partially_right() {
241         // Create a short answer question
242         $sa = test_question_maker::make_question('shortanswer');
243         $this->start_attempt_at_question($sa, 'adaptive');
245         // Check the initial state.
246         $this->check_current_state(question_state::$todo);
247         $this->check_current_mark(null);
248         $this->check_current_output(
249                 $this->get_contains_marked_out_of_summary(),
250                 $this->get_contains_submit_button_expectation(true),
251                 $this->get_does_not_contain_feedback_expectation());
253         // Submit a partially correct answer.
254         $this->process_submission(array('-submit' => 1, 'answer' => 'toad'));
256         // Verify.
257         $this->check_current_state(question_state::$todo);
258         $this->check_current_mark(0.8);
259         $this->check_current_output(
260                 $this->get_contains_mark_summary(0.8),
261                 $this->get_contains_submit_button_expectation(true),
262                 $this->get_contains_partcorrect_expectation(),
263                 $this->get_contains_penalty_info_expectation(0.33),
264                 $this->get_does_not_contain_total_penalty_expectation(),
265                 $this->get_does_not_contain_validation_error_expectation());
267         // Submit an incorrect answer.
268         $this->process_submission(array('-submit' => 1, 'answer' => 'bumblebee'));
270         // Verify.
271         $this->check_current_state(question_state::$todo);
272         $this->check_current_mark(0.8);
273         $this->check_current_output(
274                 $this->get_contains_mark_summary(0.8),
275                 $this->get_contains_submit_button_expectation(true),
276                 $this->get_contains_incorrect_expectation(),
277                 $this->get_contains_penalty_info_expectation(0.33),
278                 $this->get_contains_total_penalty_expectation(0.67),
279                 $this->get_does_not_contain_validation_error_expectation());
281         // Submit a correct answer.
282         $this->process_submission(array('-submit' => 1, 'answer' => 'frog'));
284         // Verify.
285         $this->check_current_state(question_state::$complete);
286         $this->check_current_mark(0.8);
287         $this->check_current_output(
288                 $this->get_contains_mark_summary(0.8),
289                 $this->get_contains_submit_button_expectation(true),
290                 $this->get_contains_correct_expectation(),
291                 $this->get_does_not_contain_penalty_info_expectation(),
292                 $this->get_does_not_contain_total_penalty_expectation(),
293                 $this->get_does_not_contain_validation_error_expectation());
295         // Finish the attempt.
296         $this->quba->finish_all_questions();
298         // Verify.
299         $this->check_current_state(question_state::$gradedright);
300         $this->check_current_mark(0.8);
301         $this->check_current_output(
302                 $this->get_contains_mark_summary(0.8),
303                 $this->get_contains_submit_button_expectation(false),
304                 $this->get_contains_correct_expectation(),
305                 $this->get_does_not_contain_validation_error_expectation());
306     }
308     public function test_adaptive_shortanswer_wrong_right_wrong() {
310         // Create a short answer question
311         $sa = test_question_maker::make_question('shortanswer');
312         $this->start_attempt_at_question($sa, 'adaptive', 6);
314         // Check the initial state.
315         $this->check_current_state(question_state::$todo);
316         $this->check_current_mark(null);
317         $this->check_current_output(
318                 $this->get_contains_marked_out_of_summary(),
319                 $this->get_contains_submit_button_expectation(true),
320                 $this->get_does_not_contain_feedback_expectation());
322         // Submit a wrong answer.
323         $this->process_submission(array('-submit' => 1, 'answer' => 'hippopotamus'));
325         // Verify.
326         $this->check_current_state(question_state::$todo);
327         $this->check_current_mark(0);
328         $this->check_current_output(
329                 $this->get_contains_mark_summary(0),
330                 $this->get_contains_submit_button_expectation(true),
331                 $this->get_contains_incorrect_expectation(),
332                 $this->get_contains_penalty_info_expectation(2.00),
333                 $this->get_does_not_contain_total_penalty_expectation(),
334                 $this->get_does_not_contain_validation_error_expectation());
336         // Submit the same wrong answer again. Nothing should change.
337         $this->process_submission(array('-submit' => 1, 'answer' => 'hippopotamus'));
339         // Verify.
340         $this->check_current_state(question_state::$todo);
341         $this->check_current_mark(0);
342         $this->check_current_output(
343                 $this->get_contains_mark_summary(0),
344                 $this->get_contains_submit_button_expectation(true),
345                 $this->get_contains_incorrect_expectation(),
346                 $this->get_contains_penalty_info_expectation(2.00),
347                 $this->get_does_not_contain_total_penalty_expectation(),
348                 $this->get_does_not_contain_validation_error_expectation());
350         // Submit a correct answer.
351         $this->process_submission(array('-submit' => 1, 'answer' => 'frog'));
353         // Verify.
354         $this->check_current_state(question_state::$complete);
355         $this->check_current_mark(4.00);
356         $this->check_current_output(
357                 $this->get_contains_mark_summary(4.00),
358                 $this->get_contains_submit_button_expectation(true),
359                 $this->get_contains_correct_expectation(),
360                 $this->get_does_not_contain_penalty_info_expectation(),
361                 $this->get_does_not_contain_total_penalty_expectation(),
362                 $this->get_does_not_contain_validation_error_expectation());
364         // Submit another incorrect answer.
365         $this->process_submission(array('-submit' => 1, 'answer' => 'bumblebee'));
367         // Verify.
368         $this->check_current_state(question_state::$complete);
369         $this->check_current_mark(4.00);
370         $this->check_current_output(
371                 $this->get_contains_mark_summary(4.00),
372                 $this->get_contains_submit_button_expectation(true),
373                 $this->get_contains_incorrect_expectation(),
374                 $this->get_does_not_contain_penalty_info_expectation(),
375                 $this->get_does_not_contain_total_penalty_expectation(),
376                 $this->get_does_not_contain_validation_error_expectation());
378         // Finish the attempt.
379         $this->quba->finish_all_questions();
381         // Verify.
382         $this->check_current_state(question_state::$gradedwrong);
383         $this->check_current_mark(4.00);
384         $this->check_current_output(
385                 $this->get_contains_mark_summary(4.00),
386                 $this->get_contains_submit_button_expectation(false),
387                 $this->get_contains_incorrect_expectation(),
388                 $this->get_does_not_contain_validation_error_expectation());
389     }
391     public function test_adaptive_shortanswer_invalid_after_complete() {
393         // Create a short answer question
394         $sa = test_question_maker::make_question('shortanswer');
395         $this->start_attempt_at_question($sa, 'adaptive');
397         // Check the initial state.
398         $this->check_current_state(question_state::$todo);
399         $this->check_current_mark(null);
400         $this->check_current_output(
401                 $this->get_contains_marked_out_of_summary(),
402                 $this->get_contains_submit_button_expectation(true),
403                 $this->get_does_not_contain_feedback_expectation());
405         // Submit a wrong answer.
406         $this->process_submission(array('-submit' => 1, 'answer' => 'hippopotamus'));
408         // Verify.
409         $this->check_current_state(question_state::$todo);
410         $this->check_current_mark(0);
411         $this->check_current_output(
412                 $this->get_contains_mark_summary(0),
413                 $this->get_contains_submit_button_expectation(true),
414                 $this->get_contains_incorrect_expectation(),
415                 $this->get_contains_penalty_info_expectation(0.33),
416                 $this->get_does_not_contain_total_penalty_expectation(),
417                 $this->get_does_not_contain_validation_error_expectation());
419         // Submit a correct answer.
420         $this->process_submission(array('-submit' => 1, 'answer' => 'frog'));
422         // Verify.
423         $this->check_current_state(question_state::$complete);
424         $this->check_current_mark(0.66666667);
425         $this->check_current_output(
426                 $this->get_contains_mark_summary(0.67),
427                 $this->get_contains_submit_button_expectation(true),
428                 $this->get_contains_correct_expectation(),
429                 $this->get_does_not_contain_penalty_info_expectation(),
430                 $this->get_does_not_contain_total_penalty_expectation(),
431                 $this->get_does_not_contain_validation_error_expectation());
433         // Submit an empty answer.
434         $this->process_submission(array('-submit' => 1, 'answer' => ''));
436         // Verify.
437         $this->check_current_state(question_state::$invalid);
438         $this->check_current_mark(0.66666667);
439         $this->check_current_output(
440                 $this->get_contains_mark_summary(0.67),
441                 $this->get_contains_submit_button_expectation(true),
442                 $this->get_does_not_contain_penalty_info_expectation(),
443                 $this->get_does_not_contain_total_penalty_expectation(),
444                 $this->get_contains_validation_error_expectation());
446         // Submit another wrong answer.
447         $this->process_submission(array('-submit' => 1, 'answer' => 'bumblebee'));
449         // Verify.
450         $this->check_current_state(question_state::$complete);
451         $this->check_current_mark(0.66666667);
452         $this->check_current_output(
453                 $this->get_contains_mark_summary(0.67),
454                 $this->get_contains_submit_button_expectation(true),
455                 $this->get_contains_incorrect_expectation(),
456                 $this->get_does_not_contain_penalty_info_expectation(),
457                 $this->get_does_not_contain_total_penalty_expectation(),
458                 $this->get_does_not_contain_validation_error_expectation());
460         // Finish the attempt.
461         $this->quba->finish_all_questions();
463         // Verify.
464         $this->check_current_state(question_state::$gradedwrong);
465         $this->check_current_mark(0.66666667);
466         $this->check_current_output(
467                 $this->get_contains_mark_summary(0.67),
468                 $this->get_contains_submit_button_expectation(false),
469                 $this->get_contains_incorrect_expectation(),
470                 $this->get_does_not_contain_validation_error_expectation());
471     }
473     public function test_adaptive_shortanswer_zero_penalty() {
475         // Create a short answer question
476         $sa = test_question_maker::make_question('shortanswer');
477         // Disable penalties for this question
478         $sa->penalty = 0;
479         $this->start_attempt_at_question($sa, 'adaptive');
481         // Check the initial state.
482         $this->check_current_state(question_state::$todo);
483         $this->check_current_mark(null);
484         $this->check_current_output(
485                 $this->get_contains_marked_out_of_summary(),
486                 $this->get_contains_submit_button_expectation(true),
487                 $this->get_does_not_contain_feedback_expectation());
489         // Submit a wrong answer.
490         $this->process_submission(array('-submit' => 1, 'answer' => 'hippopotamus'));
492         // Verify.
493         $this->check_current_state(question_state::$todo);
494         $this->check_current_mark(0);
495         $this->check_current_output(
496                 $this->get_contains_mark_summary(0),
497                 $this->get_contains_submit_button_expectation(true),
498                 $this->get_contains_incorrect_expectation(),
499                 $this->get_does_not_contain_penalty_info_expectation(),
500                 $this->get_does_not_contain_total_penalty_expectation(),
501                 $this->get_does_not_contain_validation_error_expectation());
503         // Submit a correct answer.
504         $this->process_submission(array('-submit' => 1, 'answer' => 'frog'));
506         // Verify.
507         $this->check_current_state(question_state::$complete);
508         $this->check_current_mark(1.0);
509         $this->check_current_output(
510                 $this->get_contains_mark_summary(1.0),
511                 $this->get_contains_submit_button_expectation(true),
512                 $this->get_contains_correct_expectation(),
513                 $this->get_does_not_contain_penalty_info_expectation(),
514                 $this->get_does_not_contain_total_penalty_expectation(),
515                 $this->get_does_not_contain_validation_error_expectation());
517         // Finish the attempt.
518         $this->quba->finish_all_questions();
520         // Verify.
521         $this->check_current_state(question_state::$gradedright);
522         $this->check_current_mark(1.0);
523         $this->check_current_output(
524                 $this->get_contains_mark_summary(1.0),
525                 $this->get_contains_submit_button_expectation(false),
526                 $this->get_contains_correct_expectation(),
527                 $this->get_does_not_contain_validation_error_expectation());
528     }
530     public function test_adaptive_shortanswer_try_to_submit_blank() {
532         // Create a short answer question with correct answer true.
533         $sa = test_question_maker::make_question('shortanswer');
534         $this->start_attempt_at_question($sa, 'adaptive');
536         // Check the initial state.
537         $this->check_current_state(question_state::$todo);
538         $this->check_current_mark(null);
539         $this->check_current_output(
540                 $this->get_contains_marked_out_of_summary(),
541                 $this->get_contains_submit_button_expectation(true),
542                 $this->get_does_not_contain_feedback_expectation());
544         // Submit with blank answer.
545         $this->process_submission(array('-submit' => 1, 'answer' => ''));
547         // Verify.
548         $this->check_current_state(question_state::$invalid);
549         $this->check_current_mark(null);
550         $this->check_current_output(
551                 $this->get_contains_marked_out_of_summary(),
552                 $this->get_contains_submit_button_expectation(true),
553                 $this->get_does_not_contain_correctness_expectation(),
554                 $this->get_does_not_contain_penalty_info_expectation(),
555                 $this->get_does_not_contain_total_penalty_expectation(),
556                 $this->get_contains_validation_error_expectation(),
557                 $this->get_contains_disregarded_info_expectation());
558         $this->assertNull($this->quba->get_response_summary($this->slot));
560         // Now get it wrong.
561         $this->process_submission(array('-submit' => 1, 'answer' => 'toad'));
563         // Verify.
564         $this->check_current_state(question_state::$todo);
565         $this->check_current_mark(0.8);
566         $this->check_current_output(
567                 $this->get_contains_mark_summary(0.8),
568                 $this->get_contains_submit_button_expectation(true),
569                 $this->get_contains_partcorrect_expectation(),
570                 $this->get_contains_penalty_info_expectation(0.33),
571                 $this->get_does_not_contain_total_penalty_expectation(),
572                 $this->get_does_not_contain_validation_error_expectation());
574         // Now submit blank again.
575         $this->process_submission(array('-submit' => 1, 'answer' => ''));
577         // Verify.
578         $this->check_current_state(question_state::$invalid);
579         $this->check_current_mark(0.8);
580         $this->check_current_output(
581                 $this->get_contains_mark_summary(0.8),
582                 $this->get_contains_submit_button_expectation(true),
583                 $this->get_does_not_contain_correctness_expectation(),
584                 $this->get_does_not_contain_penalty_info_expectation(),
585                 $this->get_does_not_contain_total_penalty_expectation(),
586                 $this->get_contains_validation_error_expectation());
587     }
589     public function test_adaptive_numerical() {
591         // Create a numerical question
592         $sa = test_question_maker::make_question('numerical', 'pi');
593         $this->start_attempt_at_question($sa, 'adaptive');
595         // Check the initial state.
596         $this->check_current_state(question_state::$todo);
597         $this->check_current_mark(null);
598         $this->check_current_output(
599                 $this->get_contains_marked_out_of_summary(),
600                 $this->get_contains_submit_button_expectation(true),
601                 $this->get_does_not_contain_feedback_expectation());
603         // Submit the correct answer.
604         $this->process_submission(array('-submit' => 1, 'answer' => '3.14'));
606         // Verify.
607         $this->check_current_state(question_state::$complete);
608         $this->check_current_mark(1);
609         $this->check_current_output(
610                 $this->get_contains_mark_summary(1),
611                 $this->get_contains_submit_button_expectation(true),
612                 $this->get_contains_correct_expectation(),
613                 $this->get_does_not_contain_penalty_info_expectation(),
614                 $this->get_does_not_contain_total_penalty_expectation(),
615                 $this->get_does_not_contain_validation_error_expectation());
617         // Submit an incorrect answer.
618         $this->process_submission(array('-submit' => 1, 'answer' => '-5'));
620         // Verify.
621         $this->check_current_state(question_state::$complete);
622         $this->check_current_mark(1);
623         $this->check_current_output(
624                 $this->get_contains_mark_summary(1),
625                 $this->get_contains_submit_button_expectation(true),
626                 $this->get_contains_incorrect_expectation(),
627                 $this->get_does_not_contain_penalty_info_expectation(),
628                 $this->get_does_not_contain_total_penalty_expectation(),
629                 $this->get_does_not_contain_validation_error_expectation());
631         // Finish the attempt.
632         $this->quba->finish_all_questions();
634         // Verify.
635         $this->check_current_state(question_state::$gradedwrong);
636         $this->check_current_mark(1);
637         $this->check_current_output(
638                 $this->get_contains_mark_summary(1),
639                 $this->get_contains_submit_button_expectation(false),
640                 $this->get_contains_incorrect_expectation(),
641                 $this->get_does_not_contain_validation_error_expectation());
642     }
644     public function test_adaptive_numerical_invalid() {
646         // Create a numerical question
647         $numq = test_question_maker::make_question('numerical', 'pi');
648         $numq->penalty = 0.1;
649         $this->start_attempt_at_question($numq, 'adaptive');
651         // Check the initial state.
652         $this->check_current_state(question_state::$todo);
653         $this->check_current_mark(null);
654         $this->check_current_output(
655                 $this->get_contains_marked_out_of_summary(),
656                 $this->get_contains_submit_button_expectation(true),
657                 $this->get_does_not_contain_feedback_expectation());
659         // Submit a non-numerical answer.
660         $this->process_submission(array('-submit' => 1, 'answer' => 'Pi'));
662         // Verify.
663         $this->check_current_state(question_state::$invalid);
664         $this->check_current_mark(null);
665         $this->check_current_output(
666                 $this->get_contains_marked_out_of_summary(1),
667                 $this->get_contains_submit_button_expectation(true),
668                 $this->get_does_not_contain_correctness_expectation(),
669                 $this->get_does_not_contain_penalty_info_expectation(),
670                 $this->get_does_not_contain_total_penalty_expectation(),
671                 $this->get_contains_validation_error_expectation(),
672                 $this->get_contains_disregarded_info_expectation());
674         // Submit an incorrect answer.
675         $this->process_submission(array('-submit' => 1, 'answer' => '-5'));
677         // Verify.
678         $this->check_current_state(question_state::$todo);
679         $this->check_current_mark(0);
680         $this->check_current_output(
681                 $this->get_contains_mark_summary(0),
682                 $this->get_contains_submit_button_expectation(true),
683                 $this->get_contains_incorrect_expectation(),
684                 $this->get_contains_penalty_info_expectation(0.1),
685                 $this->get_does_not_contain_total_penalty_expectation(),
686                 $this->get_does_not_contain_validation_error_expectation(),
687                 $this->get_does_not_contain_disregarded_info_expectation());
689         // Submit another non-numerical answer.
690         $this->process_submission(array('-submit' => 1, 'answer' => 'Pi*2'));
692         // Verify.
693         $this->check_current_state(question_state::$invalid);
694         $this->check_current_mark(0);
695         $this->check_current_output(
696                 $this->get_contains_mark_summary(0),
697                 $this->get_contains_submit_button_expectation(true),
698                 $this->get_does_not_contain_correctness_expectation(),
699                 $this->get_does_not_contain_penalty_info_expectation(),
700                 $this->get_does_not_contain_total_penalty_expectation(),
701                 $this->get_contains_validation_error_expectation(),
702                 $this->get_contains_disregarded_info_expectation());
704         // Submit the correct answer.
705         $this->process_submission(array('-submit' => 1, 'answer' => '3.14'));
707         // Verify.
708         $this->check_current_state(question_state::$complete);
709         $this->check_current_mark(0.9);
710         $this->check_current_output(
711                 $this->get_contains_mark_summary(0.9),
712                 $this->get_contains_submit_button_expectation(true),
713                 $this->get_contains_correct_expectation(),
714                 $this->get_does_not_contain_penalty_info_expectation(),
715                 $this->get_does_not_contain_total_penalty_expectation(),
716                 $this->get_does_not_contain_validation_error_expectation(),
717                 $this->get_does_not_contain_disregarded_info_expectation());
719         // Submit another non-numerical answer.
720         $this->process_submission(array('-submit' => 1, 'answer' => 'Pi/3'));
722         // Verify.
723         $this->check_current_state(question_state::$invalid);
724         $this->check_current_mark(0.9);
725         $this->check_current_output(
726                 $this->get_contains_mark_summary(0.9),
727                 $this->get_contains_submit_button_expectation(true),
728                 $this->get_does_not_contain_correctness_expectation(),
729                 $this->get_does_not_contain_penalty_info_expectation(),
730                 $this->get_does_not_contain_total_penalty_expectation(),
731                 $this->get_contains_validation_error_expectation(),
732                 $this->get_contains_disregarded_info_expectation());
734         // Finish the attempt.
735         $this->quba->finish_all_questions();
737         // Verify.
738         $this->check_current_state(question_state::$gradedwrong);
739         $this->check_current_mark(0.9);
740         $this->check_current_output(
741                 $this->get_contains_mark_summary(0.9),
742                 $this->get_contains_submit_button_expectation(false),
743                 $this->get_contains_incorrect_expectation(),
744                 $this->get_does_not_contain_validation_error_expectation(),
745                 $this->get_does_not_contain_disregarded_info_expectation());
746     }