Differences Between: [Versions 39 and 310]
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 /** 18 * Unit tests for the mulitple choice question definition class. 19 * 20 * @package qtype_multichoice 21 * @copyright 2013 The Open University 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 26 defined('MOODLE_INTERNAL') || die(); 27 28 global $CFG; 29 require_once($CFG->dirroot . '/question/engine/tests/helpers.php'); 30 require_once($CFG->dirroot . '/question/type/multichoice/questiontype.php'); 31 require_once($CFG->dirroot . '/question/type/edit_question_form.php'); 32 require_once($CFG->dirroot . '/question/type/multichoice/edit_multichoice_form.php'); 33 34 /** 35 * Unit tests for the multiple choice question definition class. 36 * 37 * @copyright 2009 The Open University 38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 39 */ 40 class qtype_multichoice_test extends advanced_testcase { 41 protected $qtype; 42 43 protected function setUp(): void { 44 $this->qtype = new qtype_multichoice(); 45 } 46 47 protected function tearDown(): void { 48 $this->qtype = null; 49 } 50 51 public function test_name() { 52 $this->assertEquals($this->qtype->name(), 'multichoice'); 53 } 54 55 protected function get_test_question_data() { 56 $q = new stdClass(); 57 $q->id = 1; 58 $q->options = new stdClass(); 59 $q->options->single = true; 60 $q->options->answers[1] = (object) array('answer' => 'frog', 61 'answerformat' => FORMAT_HTML, 'fraction' => 1); 62 $q->options->answers[2] = (object) array('answer' => 'toad', 63 'answerformat' => FORMAT_HTML, 'fraction' => 0); 64 65 return $q; 66 } 67 68 public function test_can_analyse_responses() { 69 $this->assertTrue($this->qtype->can_analyse_responses()); 70 } 71 72 public function test_get_random_guess_score() { 73 $q = $this->get_test_question_data(); 74 $this->assertEquals(0.5, $this->qtype->get_random_guess_score($q)); 75 } 76 77 public function test_get_random_guess_score_multi() { 78 $q = $this->get_test_question_data(); 79 $q->options->single = false; 80 $this->assertNull($this->qtype->get_random_guess_score($q)); 81 } 82 83 public function test_get_possible_responses_single() { 84 $q = $this->get_test_question_data(); 85 $responses = $this->qtype->get_possible_responses($q); 86 87 $this->assertEquals(array( 88 $q->id => array( 89 1 => new question_possible_response('frog', 1), 90 2 => new question_possible_response('toad', 0), 91 null => question_possible_response::no_response(), 92 )), $this->qtype->get_possible_responses($q)); 93 } 94 95 public function test_get_possible_responses_multi() { 96 $q = $this->get_test_question_data(); 97 $q->options->single = false; 98 99 $this->assertEquals(array( 100 1 => array(1 => new question_possible_response('frog', 1)), 101 2 => array(2 => new question_possible_response('toad', 0)), 102 ), $this->qtype->get_possible_responses($q)); 103 } 104 105 public function get_question_saving_which() { 106 return array(array('two_of_four'), array('one_of_four')); 107 } 108 109 /** 110 * @dataProvider get_question_saving_which 111 */ 112 public function test_question_saving_two_of_four($which) { 113 $this->resetAfterTest(true); 114 $this->setAdminUser(); 115 116 $questiondata = test_question_maker::get_question_data('multichoice', $which); 117 $formdata = test_question_maker::get_question_form_data('multichoice', $which); 118 119 $generator = $this->getDataGenerator()->get_plugin_generator('core_question'); 120 $cat = $generator->create_question_category(array()); 121 122 $formdata->category = "{$cat->id},{$cat->contextid}"; 123 qtype_multichoice_edit_form::mock_submit((array)$formdata); 124 125 $form = qtype_multichoice_test_helper::get_question_editing_form($cat, $questiondata); 126 127 $this->assertTrue($form->is_validated()); 128 129 $fromform = $form->get_data(); 130 131 $returnedfromsave = $this->qtype->save_question($questiondata, $fromform); 132 $actualquestionsdata = question_load_questions(array($returnedfromsave->id)); 133 $actualquestiondata = end($actualquestionsdata); 134 135 foreach ($questiondata as $property => $value) { 136 if (!in_array($property, array('id', 'version', 'timemodified', 'timecreated', 'options', 'hints', 'stamp'))) { 137 $this->assertEquals($value, $actualquestiondata->$property); 138 } 139 } 140 141 foreach ($questiondata->options as $optionname => $value) { 142 if ($optionname != 'answers') { 143 $this->assertEquals($value, $actualquestiondata->options->$optionname); 144 } 145 } 146 147 foreach ($questiondata->hints as $hint) { 148 $actualhint = array_shift($actualquestiondata->hints); 149 foreach ($hint as $property => $value) { 150 if (!in_array($property, array('id', 'questionid', 'options'))) { 151 $this->assertEquals($value, $actualhint->$property); 152 } 153 } 154 } 155 156 foreach ($questiondata->options->answers as $answer) { 157 $actualanswer = array_shift($actualquestiondata->options->answers); 158 foreach ($answer as $ansproperty => $ansvalue) { 159 // This question does not use 'answerformat', will ignore it. 160 if (!in_array($ansproperty, array('id', 'question', 'answerformat'))) { 161 $this->assertEquals($ansvalue, $actualanswer->$ansproperty); 162 } 163 } 164 } 165 } 166 167 /** 168 * Test to make sure that loading of question options works, including in an error case. 169 */ 170 public function test_get_question_options() { 171 global $DB; 172 173 $this->resetAfterTest(true); 174 $this->setAdminUser(); 175 176 // Create a complete, in DB question to use. 177 $questiondata = test_question_maker::get_question_data('multichoice', 'two_of_four'); 178 $formdata = test_question_maker::get_question_form_data('multichoice', 'two_of_four'); 179 180 $generator = $this->getDataGenerator()->get_plugin_generator('core_question'); 181 $cat = $generator->create_question_category(array()); 182 183 $formdata->category = "{$cat->id},{$cat->contextid}"; 184 qtype_multichoice_edit_form::mock_submit((array)$formdata); 185 186 $form = qtype_multichoice_test_helper::get_question_editing_form($cat, $questiondata); 187 188 $this->assertTrue($form->is_validated()); 189 190 $fromform = $form->get_data(); 191 192 $returnedfromsave = $this->qtype->save_question($questiondata, $fromform); 193 194 // Now get just the raw DB record. 195 $question = $DB->get_record('question', ['id' => $returnedfromsave->id], '*', MUST_EXIST); 196 197 // Load it. 198 $this->qtype->get_question_options($question); 199 $this->assertDebuggingNotCalled(); 200 $this->assertInstanceOf(stdClass::class, $question->options); 201 202 $options = $question->options; 203 $this->assertEquals($question->id, $options->questionid); 204 $this->assertEquals(0, $options->single); 205 206 $this->assertCount(4, $options->answers); 207 208 // Now we are going to delete the options record. 209 $DB->delete_records('qtype_multichoice_options', ['questionid' => $question->id]); 210 211 // Now see what happens. 212 $question = $DB->get_record('question', ['id' => $returnedfromsave->id], '*', MUST_EXIST); 213 $this->qtype->get_question_options($question); 214 215 $this->assertDebuggingCalled('Question ID '.$question->id.' was missing an options record. Using default.'); 216 $this->assertInstanceOf(stdClass::class, $question->options); 217 $options = $question->options; 218 $this->assertEquals($question->id, $options->questionid); 219 $this->assertCount(4, $options->answers); 220 221 $this->assertEquals(get_string('correctfeedbackdefault', 'question'), $options->correctfeedback); 222 $this->assertEquals(FORMAT_HTML, $options->correctfeedbackformat); 223 224 // We no longer know how many answers, so it just has to guess with the default value. 225 $this->assertEquals(get_config('qtype_multichoice', 'answerhowmany'), $options->single); 226 227 // And finally we try again with no answer either. 228 $DB->delete_records('question_answers', ['question' => $question->id]); 229 230 $question = $DB->get_record('question', ['id' => $returnedfromsave->id], '*', MUST_EXIST); 231 $this->qtype->get_question_options($question); 232 233 $this->assertDebuggingCalled('Question ID '.$question->id.' was missing an options record. Using default.'); 234 $this->assertInstanceOf(stdClass::class, $question->options); 235 $options = $question->options; 236 $this->assertEquals($question->id, $options->questionid); 237 $this->assertCount(0, $options->answers); 238 } 239 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body