Proyectos de Subversion Moodle

Rev

Rev 11 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
namespace qtype_multichoice;
18
 
19
use question_state;
20
 
21
defined('MOODLE_INTERNAL') || die();
22
 
23
global $CFG;
24
require_once($CFG->dirroot . '/question/engine/lib.php');
25
require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
26
 
27
 
28
/**
29
 * Unit tests for the mutiple choice question type.
30
 *
31
 * Note, there are already lots of tests of the multichoice type in the behaviour
32
 * tests. (Search for \test_question_maker::make_a_multichoice.) This file only
33
 * contains a few additional tests for problems that were found during testing.
34
 *
35
 * @package    qtype_multichoice
36
 * @copyright  2010 The Open University
37
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38
 * @covers     \qtype_multichoice_single_question
39
 * @covers     \qtype_multichoice_single_base
40
 */
1441 ariadna 41
final class walkthrough_test extends \qbehaviour_walkthrough_test_base {
11 efrain 42
    public function test_deferredfeedback_feedback_multichoice_single(): void {
1 efrain 43
 
44
        // Create a multichoice, single question.
45
        $mc = \test_question_maker::make_a_multichoice_single_question();
46
        $mc->shuffleanswers = false;
47
        $mc->answers[14]->fraction = 0.1; // Make one of the choices partially right.
48
        $rightindex = 0;
49
 
50
        $this->start_attempt_at_question($mc, 'deferredfeedback', 3);
51
        $this->process_submission(array('answer' => $rightindex));
52
 
53
        // Verify.
54
        $this->check_current_state(question_state::$complete);
55
        $this->check_current_mark(null);
56
        $this->check_current_output(
57
                $this->get_contains_mc_radio_expectation($rightindex, true, true),
58
                $this->get_contains_mc_radio_expectation($rightindex + 1, true, false),
59
                $this->get_contains_mc_radio_expectation($rightindex + 2, true, false),
60
                $this->get_does_not_contain_correctness_expectation(),
61
                $this->get_does_not_contain_feedback_expectation());
62
 
63
        // Finish the attempt.
64
        $this->quba->finish_all_questions();
65
 
66
        // Verify.
67
        $this->check_current_state(question_state::$gradedright);
68
        $this->check_current_mark(3);
69
        $this->check_current_output(
70
                $this->get_contains_mc_radio_expectation($rightindex, false, true),
71
                $this->get_contains_correct_expectation(),
72
                new \question_pattern_expectation('/class="r0 correct"/'),
73
                new \question_pattern_expectation('/class="r1"/'));
74
 
75
        // Regrade with a new version of the question.
76
        $oldmc = \test_question_maker::make_a_multichoice_single_question();
77
        $oldmc->answers = [
78
            23 => $oldmc->answers[13],
79
            24 => $oldmc->answers[14],
80
            25 => $oldmc->answers[15],
81
        ];
82
        $oldmc->answers[23]->fraction = 0.5;
83
        $oldmc->answers[23]->feedback = 'A is now only partially right';
84
        $oldmc->answers[24]->fraction = 1;
85
        $oldmc->answers[24]->answer = 'B is the new right answer';
86
        $this->quba->regrade_question($this->slot, true, null, $oldmc);
87
 
88
        // Verify.
89
        $this->check_current_mark(1.5);
90
        $this->render();
91
        $this->assertStringContainsString('A is now only partially right', $this->currentoutput);
92
        $this->assertStringContainsString('B is the new right answer', $this->currentoutput);
93
        $this->assertStringNotContainsString(
94
                get_string('deletedchoice', 'qtype_multichoice'), $this->currentoutput);
95
    }
96
 
11 efrain 97
    public function test_deferredfeedback_feedback_multichoice_single_showstandardunstruction_yes(): void {
1 efrain 98
 
99
        // Create a multichoice, single question.
100
        $mc = \test_question_maker::make_a_multichoice_single_question();
101
        $mc->showstandardinstruction = true;
102
 
103
        $this->start_attempt_at_question($mc, 'deferredfeedback', 3);
104
        $this->render();
105
 
106
        // Check for 'Show standard instruction'.
107
        $standardinstruction = get_string('selectone', 'qtype_multichoice');
108
        $this->assertStringContainsString($standardinstruction, $this->currentoutput);
109
    }
110
 
11 efrain 111
    public function test_deferredfeedback_feedback_multichoice_single_showstandardunstruction_no(): void {
1 efrain 112
 
113
        // Create a multichoice, single question.
114
        $mc = \test_question_maker::make_a_multichoice_single_question();
115
        $mc->showstandardinstruction = false;
116
 
117
        $this->start_attempt_at_question($mc, 'deferredfeedback', 3);
118
        $this->render();
119
 
120
        // Check for 'Show standard instruction'.
121
        $standardinstruction = get_string('selectmulti', 'qtype_multichoice');
122
        $this->assertStringNotContainsString($standardinstruction, $this->currentoutput);
123
    }
124
 
11 efrain 125
    public function test_deferredfeedback_feedback_multichoice_multi(): void {
1 efrain 126
        // Create a multichoice, multi question.
127
        $mc = \test_question_maker::make_a_multichoice_multi_question();
128
        $mc->shuffleanswers = false;
129
 
130
        $this->start_attempt_at_question($mc, 'deferredfeedback', 2);
131
        $this->process_submission($mc->get_correct_response());
132
        $this->quba->finish_all_questions();
133
 
134
        // Verify.
135
        $this->check_current_state(question_state::$gradedright);
136
        $this->check_current_mark(2);
137
        $this->check_current_output(
138
                $this->get_contains_mc_checkbox_expectation('choice0', false, true),
139
                $this->get_contains_mc_checkbox_expectation('choice1', false, false),
140
                $this->get_contains_mc_checkbox_expectation('choice2', false, true),
141
                $this->get_contains_mc_checkbox_expectation('choice3', false, false),
142
                $this->get_contains_correct_expectation(),
143
                new \question_pattern_expectation('/class="r0 correct"/'),
144
                new \question_pattern_expectation('/class="r1"/'));
145
    }
146
 
147
    /**
148
     * Test for clear choice option.
149
     */
11 efrain 150
    public function test_deferredfeedback_feedback_multichoice_clearchoice(): void {
1 efrain 151
 
152
        // Create a multichoice, single question.
153
        $mc = \test_question_maker::make_a_multichoice_single_question();
154
        $mc->shuffleanswers = false;
155
 
156
        $clearchoice = -1;
157
        $rightchoice = 0;
158
        $wrongchoice = 2;
159
 
160
        $this->start_attempt_at_question($mc, 'deferredfeedback', 3);
161
 
162
        // Let's first submit the wrong choice (2).
163
        $this->process_submission(array('answer' => $wrongchoice));  // Wrong choice (2).
164
 
165
        $this->check_current_mark(null);
166
        // Clear choice radio should not be checked.
167
        $this->check_current_output(
168
            $this->get_contains_mc_radio_expectation($rightchoice, true, false), // Not checked.
169
            $this->get_contains_mc_radio_expectation($rightchoice + 1, true, false), // Not checked.
170
            $this->get_contains_mc_radio_expectation($rightchoice + 2, true, true), // Wrong choice (2) checked.
171
            $this->get_contains_mc_radio_expectation($clearchoice, true, false), // Not checked.
172
            $this->get_does_not_contain_correctness_expectation(),
173
            $this->get_does_not_contain_feedback_expectation()
174
        );
175
 
176
        // Now, let's clear our previous choice.
177
        $this->process_submission(array('answer' => $clearchoice)); // Clear choice (-1).
178
        $this->check_current_mark(null);
179
 
180
        // This time, the clear choice radio should be the only one checked.
181
        $this->check_current_output(
182
            $this->get_contains_mc_radio_expectation($rightchoice, true, false), // Not checked.
183
            $this->get_contains_mc_radio_expectation($rightchoice + 1, true, false), // Not checked.
184
            $this->get_contains_mc_radio_expectation($rightchoice + 2, true, false), // Not checked.
185
            $this->get_contains_mc_radio_expectation($clearchoice, true, true), // Clear choice radio checked.
186
            $this->get_does_not_contain_correctness_expectation(),
187
            $this->get_does_not_contain_feedback_expectation()
188
        );
189
 
190
        // Finally, let's submit the right choice.
191
        $this->process_submission(array('answer' => $rightchoice)); // Right choice (0).
192
        $this->check_current_state(question_state::$complete);
193
        $this->check_current_mark(null);
194
        $this->check_current_output(
195
            $this->get_contains_mc_radio_expectation($rightchoice, true, true),
196
            $this->get_contains_mc_radio_expectation($rightchoice + 1, true, false),
197
            $this->get_contains_mc_radio_expectation($rightchoice + 2, true, false),
198
            $this->get_contains_mc_radio_expectation($clearchoice, true, false),
199
            $this->get_does_not_contain_correctness_expectation(),
200
            $this->get_does_not_contain_feedback_expectation()
201
        );
202
 
203
        // Finish the attempt.
204
        $this->finish();
205
 
206
        // Verify.
207
        $this->check_current_state(question_state::$gradedright);
208
        $this->check_current_mark(3);
209
        $this->check_current_output(
210
            $this->get_contains_mc_radio_expectation($rightchoice, false, true),
211
            $this->get_contains_correct_expectation(),
212
            new \question_pattern_expectation('/class="r0 correct"/'),
213
            new \question_pattern_expectation('/class="r1"/'));
214
    }
215
 
11 efrain 216
    public function test_each_attempt_builds_on_last_and_regrade(): void {
1 efrain 217
 
218
        // Create a multichoice, single question.
219
        $mc = \test_question_maker::make_a_multichoice_single_question();
220
        $mc->shuffleanswers = false;
221
 
222
        $rightchoice = 0;
223
 
224
        $this->start_attempt_at_question(clone($mc), 'deferredfeedback', 3);
225
 
226
        // Submit the answer false (correct).
227
        $this->process_submission(['answer' => $rightchoice]);
228
 
229
        // Finish the attempt.
230
        $this->quba->finish_all_questions();
231
 
232
        // Check the state.
233
        $this->check_current_state(question_state::$gradedright);
234
        $this->check_current_mark(3);
235
        $this->check_current_output(
236
            $this->get_contains_mc_radio_expectation($rightchoice, false, true),
237
            $this->get_contains_mc_radio_expectation($rightchoice + 1, false, false),
238
            $this->get_contains_mc_radio_expectation($rightchoice + 2, false, false));
239
 
240
        // Start a new attempt based on the first one.
241
        $firstattemptqa = $this->quba->get_question_attempt($this->slot);
242
        $this->quba = \question_engine::make_questions_usage_by_activity('unit_test',
243
                \context_system::instance());
244
        $this->quba->set_preferred_behaviour('deferredfeedback');
245
        $this->slot = $this->quba->add_question(clone($mc), 3);
246
        $this->quba->start_question_based_on($this->slot, $firstattemptqa);
247
 
248
        // Verify.
249
        $this->check_current_state(question_state::$complete);
250
        $this->check_current_mark(null);
251
        $this->check_current_output(
252
            $this->get_contains_mc_radio_expectation($rightchoice, true, true),
253
            $this->get_contains_mc_radio_expectation($rightchoice + 1, true, false),
254
            $this->get_contains_mc_radio_expectation($rightchoice + 2, true, false));
255
 
256
        // Finish the attempt without changing the answer.
257
        $this->quba->finish_all_questions();
258
 
259
        // Check the state.
260
        $this->check_current_state(question_state::$gradedright);
261
        $this->check_current_mark(3);
262
        $this->check_current_output(
263
            $this->get_contains_mc_radio_expectation($rightchoice, false, true),
264
            $this->get_contains_mc_radio_expectation($rightchoice + 1, false, false),
265
            $this->get_contains_mc_radio_expectation($rightchoice + 2, false, false));
266
 
267
        // Regrade the attempt - code based on question_usage_by_activity::regrade_question.
268
        $oldqa = $this->quba->get_question_attempt($this->slot);
269
        $newqa = new \question_attempt(clone($mc),
270
                $oldqa->get_usage_id(), $this->quba->get_observer());
271
        $newqa->set_database_id($oldqa->get_database_id());
272
        $newqa->set_slot($oldqa->get_slot());
273
        $newqa->set_max_mark(3);
274
        $newqa->regrade($oldqa, true);
275
 
276
        // Check the state.
277
        $this->assertEquals(question_state::$gradedright, $newqa->get_state());
278
        $this->assertEquals(3, $newqa->get_mark());
279
    }
280
 
11 efrain 281
    public function test_deferredfeedback_feedback_multichoice_multi_showstandardunstruction_yes(): void {
1 efrain 282
 
283
        // Create a multichoice, multi question.
284
        $mc = \test_question_maker::make_a_multichoice_multi_question();
285
        $mc->showstandardinstruction = true;
286
 
287
        $this->start_attempt_at_question($mc, 'deferredfeedback', 3);
288
        $this->render();
289
 
290
        // Check for 'Show standard instruction'.
291
        $standardinstruction = get_string('selectmulti', 'qtype_multichoice');
292
        $this->assertStringContainsString($standardinstruction, $this->currentoutput);
293
    }
294
 
11 efrain 295
    public function test_deferredfeedback_feedback_multichoice_multi_showstandardunstruction_no(): void {
1 efrain 296
 
297
        // Create a multichoice, multi question.
298
        $mc = \test_question_maker::make_a_multichoice_multi_question();
299
        $mc->showstandardinstruction = false;
300
 
301
        $this->start_attempt_at_question($mc, 'deferredfeedback', 3);
302
        $this->render();
303
 
304
        // Check for 'Show standard instruction'.
305
        $standardinstruction = \html_writer::tag('legend', get_string('answer'), [
1441 ariadna 306
            'class' => 'prompt h6 fw-normal visually-hidden',
1 efrain 307
        ]);
308
        $this->assertStringContainsString($standardinstruction, $this->currentoutput);
309
    }
310
 
311
}