MDL-61410 question: fix unit tests failures
[moodle.git] / question / type / gapselect / tests / questiontype_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  * Unit tests for the select missing words question question definition class.
19  *
20  * @package   qtype_gapselect
21  * @copyright 2012 The Open University
22  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
26 defined('MOODLE_INTERNAL') || die();
27 global $CFG;
29 require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
30 require_once($CFG->dirroot . '/question/type/gapselect/tests/helper.php');
33 /**
34  * Unit tests for the select missing words question definition class.
35  *
36  * @copyright 2012 The Open University
37  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38  */
39 class qtype_gapselect_test extends question_testcase {
40     /** @var qtype_gapselect instance of the question type class to test. */
41     protected $qtype;
43     protected function setUp() {
44         $this->qtype = question_bank::get_qtype('gapselect');;
45     }
47     protected function tearDown() {
48         $this->qtype = null;
49     }
51     /**
52      * Asserts that two strings containing XML are the same ignoring the line-endings.
53      * @param unknown $expectedxml
54      * @param unknown $xml
55      */
56     public function assert_same_xml($expectedxml, $xml) {
57         $this->assertEquals(str_replace("\r\n", "\n", $expectedxml),
58                 str_replace("\r\n", "\n", $xml));
59     }
61     /**
62      * Get some test question data.
63      * @return object the data to construct a question like
64      * {@link qtype_gapselect_test_helper::make_a_gapselect_question()}.
65      */
66     protected function get_test_question_data() {
67         global $USER;
69         $gapselect = new stdClass();
70         $gapselect->id = 0;
71         $gapselect->category = 0;
72         $gapselect->contextid = 0;
73         $gapselect->parent = 0;
74         $gapselect->questiontextformat = FORMAT_HTML;
75         $gapselect->generalfeedbackformat = FORMAT_HTML;
76         $gapselect->defaultmark = 1;
77         $gapselect->penalty = 0.3333333;
78         $gapselect->length = 1;
79         $gapselect->stamp = make_unique_id_code();
80         $gapselect->version = make_unique_id_code();
81         $gapselect->hidden = 0;
82         $gapselect->timecreated = time();
83         $gapselect->timemodified = time();
84         $gapselect->createdby = $USER->id;
85         $gapselect->modifiedby = $USER->id;
87         $gapselect->name = 'Selection from drop down list question';
88         $gapselect->questiontext = 'The [[1]] brown [[2]] jumped over the [[3]] dog.';
89         $gapselect->generalfeedback = 'This sentence uses each letter of the alphabet.';
90         $gapselect->qtype = 'gapselect';
92         $gapselect->options = new stdClass();
93         $gapselect->options->shuffleanswers = true;
95         test_question_maker::set_standard_combined_feedback_fields($gapselect->options);
97         $gapselect->options->answers = array(
98             (object) array('answer' => 'quick', 'feedback' => '1'),
99             (object) array('answer' => 'fox', 'feedback' => '2'),
100             (object) array('answer' => 'lazy', 'feedback' => '3'),
101             (object) array('answer' => 'assiduous', 'feedback' => '3'),
102             (object) array('answer' => 'dog', 'feedback' => '2'),
103             (object) array('answer' => 'slow', 'feedback' => '1'),
104         );
106         return $gapselect;
107     }
109     public function test_name() {
110         $this->assertEquals($this->qtype->name(), 'gapselect');
111     }
113     public function test_can_analyse_responses() {
114         $this->assertTrue($this->qtype->can_analyse_responses());
115     }
117     public function test_initialise_question_instance() {
118         $qdata = $this->get_test_question_data();
120         $expected = qtype_gapselect_test_helper::make_a_gapselect_question();
121         $expected->stamp = $qdata->stamp;
122         $expected->version = $qdata->version;
124         $q = $this->qtype->make_question($qdata);
126         $this->assertEquals($expected, $q);
127     }
129     public function test_get_random_guess_score() {
130         $q = $this->get_test_question_data();
131         $this->assertEquals(0.5, $this->qtype->get_random_guess_score($q), '', 0.0000001);
132     }
134     public function test_get_possible_responses() {
135         $q = $this->get_test_question_data();
137         $this->assertEquals(array(
138             1 => array(
139                 1 => new question_possible_response('quick', 1 / 3),
140                 2 => new question_possible_response('slow', 0),
141                 null => question_possible_response::no_response()),
142             2 => array(
143                 1 => new question_possible_response('fox', 1 / 3),
144                 2 => new question_possible_response('dog', 0),
145                 null => question_possible_response::no_response()),
146             3 => array(
147                 1 => new question_possible_response('lazy', 1 / 3),
148                 2 => new question_possible_response('assiduous', 0),
149                 null => question_possible_response::no_response()),
150         ), $this->qtype->get_possible_responses($q));
151     }
153     public function test_xml_import() {
154         $xml = '  <question type="gapselect">
155     <name>
156       <text>A select missing words question</text>
157     </name>
158     <questiontext format="moodle_auto_format">
159       <text>Put these in order: [[1]], [[2]], [[3]].</text>
160     </questiontext>
161     <generalfeedback>
162       <text>The answer is Alpha, Beta, Gamma.</text>
163     </generalfeedback>
164     <defaultgrade>3</defaultgrade>
165     <penalty>0.3333333</penalty>
166     <hidden>0</hidden>
167     <shuffleanswers>1</shuffleanswers>
168     <correctfeedback>
169       <text><![CDATA[<p>Your answer is correct.</p>]]></text>
170     </correctfeedback>
171     <partiallycorrectfeedback>
172       <text><![CDATA[<p>Your answer is partially correct.</p>]]></text>
173     </partiallycorrectfeedback>
174     <incorrectfeedback>
175       <text><![CDATA[<p>Your answer is incorrect.</p>]]></text>
176     </incorrectfeedback>
177     <shownumcorrect/>
178     <selectoption>
179       <text>Alpha</text>
180       <group>1</group>
181     </selectoption>
182     <selectoption>
183       <text>Beta</text>
184       <group>1</group>
185     </selectoption>
186     <selectoption>
187       <text>Gamma</text>
188       <group>1</group>
189     </selectoption>
190     <hint format="moodle_auto_format">
191       <text>Try again.</text>
192       <shownumcorrect />
193     </hint>
194     <hint format="moodle_auto_format">
195       <text>These are the first three letters of the Greek alphabet.</text>
196       <shownumcorrect />
197       <clearwrong />
198     </hint>
199   </question>';
200         $xmldata = xmlize($xml);
202         $importer = new qformat_xml();
203         $q = $importer->try_importing_using_qtypes(
204                 $xmldata['question'], null, null, 'gapselect');
206         $expectedq = new stdClass();
207         $expectedq->qtype = 'gapselect';
208         $expectedq->name = 'A select missing words question';
209         $expectedq->questiontext = 'Put these in order: [[1]], [[2]], [[3]].';
210         $expectedq->questiontextformat = FORMAT_MOODLE;
211         $expectedq->generalfeedback = 'The answer is Alpha, Beta, Gamma.';
212         $expectedq->defaultmark = 3;
213         $expectedq->length = 1;
214         $expectedq->penalty = 0.3333333;
216         $expectedq->shuffleanswers = 1;
217         $expectedq->correctfeedback = array('text' => '<p>Your answer is correct.</p>',
218                 'format' => FORMAT_MOODLE);
219         $expectedq->partiallycorrectfeedback = array(
220                 'text' => '<p>Your answer is partially correct.</p>',
221                 'format' => FORMAT_MOODLE);
222         $expectedq->shownumcorrect = true;
223         $expectedq->incorrectfeedback = array('text' => '<p>Your answer is incorrect.</p>',
224                 'format' => FORMAT_MOODLE);
226         $expectedq->choices = array(
227             array('answer' => 'Alpha', 'choicegroup' => 1),
228             array('answer' => 'Beta', 'choicegroup' => 1),
229             array('answer' => 'Gamma', 'choicegroup' => 1),
230         );
232         $expectedq->hint = array(
233                 array('text' => 'Try again.', 'format' => FORMAT_MOODLE),
234                 array('text' => 'These are the first three letters of the Greek alphabet.',
235                         'format' => FORMAT_MOODLE));
236         $expectedq->hintshownumcorrect = array(true, true);
237         $expectedq->hintclearwrong = array(false, true);
238         $this->assert(new question_check_specified_fields_expectation($expectedq), $q);
239         $this->assertEquals($expectedq->hint, $q->hint);
240     }
242     public function test_xml_export() {
243         $qdata = new stdClass();
244         $qdata->id = 123;
245         $qdata->contextid = \context_system::instance()->id;
246         $qdata->qtype = 'gapselect';
247         $qdata->name = 'A select missing words question';
248         $qdata->questiontext = 'Put these in order: [[1]], [[2]], [[3]].';
249         $qdata->questiontextformat = FORMAT_MOODLE;
250         $qdata->generalfeedback = 'The answer is Alpha, Beta, Gamma.';
251         $qdata->generalfeedbackformat = FORMAT_MOODLE;
252         $qdata->defaultmark = 3;
253         $qdata->length = 1;
254         $qdata->penalty = 0.3333333;
255         $qdata->hidden = 0;
257         $qdata->options = new stdClass();
258         $qdata->options->shuffleanswers = 1;
259         $qdata->options->correctfeedback = '<p>Your answer is correct.</p>';
260         $qdata->options->correctfeedbackformat = FORMAT_MOODLE;
261         $qdata->options->partiallycorrectfeedback = '<p>Your answer is partially correct.</p>';
262                 $qdata->options->partiallycorrectfeedbackformat = FORMAT_MOODLE;
263         $qdata->options->shownumcorrect = true;
264         $qdata->options->incorrectfeedback = '<p>Your answer is incorrect.</p>';
265         $qdata->options->incorrectfeedbackformat = FORMAT_MOODLE;
267         $qdata->options->answers = array(
268             13 => new question_answer(13, 'Alpha', 0, '1', FORMAT_MOODLE),
269             14 => new question_answer(14, 'Beta', 0, '1', FORMAT_MOODLE),
270             15 => new question_answer(15, 'Gamma', 0, '1', FORMAT_MOODLE),
271         );
273         $qdata->hints = array(
274             1 => new question_hint_with_parts(1, 'Try again.', FORMAT_MOODLE, true, false),
275             2 => new question_hint_with_parts(2,
276                     'These are the first three letters of the Greek alphabet.',
277                     FORMAT_MOODLE, true, true),
278         );
280         $exporter = new qformat_xml();
281         $xml = $exporter->writequestion($qdata);
283         $expectedxml = '<!-- question: 123  -->
284   <question type="gapselect">
285     <name>
286       <text>A select missing words question</text>
287     </name>
288     <questiontext format="moodle_auto_format">
289       <text>Put these in order: [[1]], [[2]], [[3]].</text>
290     </questiontext>
291     <generalfeedback format="moodle_auto_format">
292       <text>The answer is Alpha, Beta, Gamma.</text>
293     </generalfeedback>
294     <defaultgrade>3</defaultgrade>
295     <penalty>0.3333333</penalty>
296     <hidden>0</hidden>
297     <shuffleanswers>1</shuffleanswers>
298     <correctfeedback format="moodle_auto_format">
299       <text><![CDATA[<p>Your answer is correct.</p>]]></text>
300     </correctfeedback>
301     <partiallycorrectfeedback format="moodle_auto_format">
302       <text><![CDATA[<p>Your answer is partially correct.</p>]]></text>
303     </partiallycorrectfeedback>
304     <incorrectfeedback format="moodle_auto_format">
305       <text><![CDATA[<p>Your answer is incorrect.</p>]]></text>
306     </incorrectfeedback>
307     <shownumcorrect/>
308     <selectoption>
309       <text>Alpha</text>
310       <group>1</group>
311     </selectoption>
312     <selectoption>
313       <text>Beta</text>
314       <group>1</group>
315     </selectoption>
316     <selectoption>
317       <text>Gamma</text>
318       <group>1</group>
319     </selectoption>
320     <hint format="moodle_auto_format">
321       <text>Try again.</text>
322       <shownumcorrect/>
323     </hint>
324     <hint format="moodle_auto_format">
325       <text>These are the first three letters of the Greek alphabet.</text>
326       <shownumcorrect/>
327       <clearwrong/>
328     </hint>
329   </question>
330 ';
332         $this->assert_same_xml($expectedxml, $xml);
333     }