Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.

Differences Between: [Versions 310 and 311] [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403] [Versions 39 and 311]

   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 qtype_multichoice_multi_question;
  20  use question_answer;
  21  use question_attempt_step;
  22  use question_bank;
  23  use question_classified_response;
  24  use question_state;
  25  
  26  defined('MOODLE_INTERNAL') || die();
  27  
  28  global $CFG;
  29  require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
  30  
  31  /**
  32   * Unit tests for the multiple choice, single response question definition class.
  33   *
  34   * @package   qtype_multichoice
  35   * @copyright 2009 The Open University
  36   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  37   */
  38  class question_single_test extends \advanced_testcase {
  39  
  40      public function test_get_expected_data() {
  41          $question = \test_question_maker::make_a_multichoice_single_question();
  42          $this->assertEquals(array('answer' => PARAM_INT), $question->get_expected_data());
  43      }
  44  
  45      public function test_is_complete_response() {
  46          $question = \test_question_maker::make_a_multichoice_single_question();
  47  
  48          $this->assertFalse($question->is_complete_response(array()));
  49          $this->assertTrue($question->is_complete_response(array('answer' => '0')));
  50          $this->assertTrue($question->is_complete_response(array('answer' => '2')));
  51          $this->assertFalse($question->is_complete_response(array('answer' => '-1')));
  52          $this->assertFalse($question->is_complete_response(array('answer' => -1)));
  53      }
  54  
  55      public function test_is_gradable_response() {
  56          $question = \test_question_maker::make_a_multichoice_single_question();
  57  
  58          $this->assertFalse($question->is_gradable_response(array()));
  59          $this->assertTrue($question->is_gradable_response(array('answer' => '0')));
  60          $this->assertTrue($question->is_gradable_response(array('answer' => '2')));
  61          $this->assertFalse($question->is_gradable_response(array('answer' => '-1')));
  62      }
  63  
  64      public function test_is_same_response() {
  65          $question = \test_question_maker::make_a_multichoice_single_question();
  66          $question->start_attempt(new question_attempt_step(), 1);
  67  
  68          $this->assertTrue($question->is_same_response(
  69                  array(),
  70                  array()));
  71  
  72          $this->assertFalse($question->is_same_response(
  73                  array(),
  74                  array('answer' => '0')));
  75  
  76          $this->assertTrue($question->is_same_response(
  77                  array('answer' => '0'),
  78                  array('answer' => '0')));
  79  
  80          $this->assertFalse($question->is_same_response(
  81                  array('answer' => '0'),
  82                  array('answer' => '1')));
  83  
  84          $this->assertTrue($question->is_same_response(
  85                  array('answer' => '2'),
  86                  array('answer' => '2')));
  87  
  88          $this->assertFalse($question->is_same_response(
  89                  array('answer' => '0'),
  90                  array('answer' => '-1')));
  91  
  92          $this->assertFalse($question->is_same_response(
  93                  array('answer' => '-1'),
  94                  array('answer' => '0')));
  95  
  96          $this->assertTrue($question->is_same_response(
  97                  array('answer' => '-1'),
  98                  array('answer' => '-1')));
  99  
 100          $this->assertTrue($question->is_same_response(
 101                  array(),
 102                  array('answer' => '-1')));
 103      }
 104  
 105      public function test_grading() {
 106          $question = \test_question_maker::make_a_multichoice_single_question();
 107          $question->start_attempt(new question_attempt_step(), 1);
 108  
 109          $this->assertEquals(array(1, question_state::$gradedright),
 110                  $question->grade_response($question->prepare_simulated_post_data(array('answer' => 'A'))));
 111          $this->assertEquals(array(-0.3333333, question_state::$gradedwrong),
 112                  $question->grade_response($question->prepare_simulated_post_data(array('answer' => 'B'))));
 113          $this->assertEquals(array(-0.3333333, question_state::$gradedwrong),
 114                  $question->grade_response($question->prepare_simulated_post_data(array('answer' => 'C'))));
 115      }
 116  
 117      public function test_grading_rounding_three_right() {
 118          question_bank::load_question_definition_classes('multichoice');
 119          $mc = new qtype_multichoice_multi_question();
 120          \test_question_maker::initialise_a_question($mc);
 121          $mc->name = 'Odd numbers';
 122          $mc->questiontext = 'Which are the odd numbers?';
 123          $mc->generalfeedback = '1, 3 and 5 are the odd numbers.';
 124          $mc->qtype = question_bank::get_qtype('multichoice');
 125  
 126          $mc->answernumbering = 'abc';
 127          $mc->showstandardinstruction = 0;
 128  
 129          \test_question_maker::set_standard_combined_feedback_fields($mc);
 130  
 131          $mc->answers = array(
 132              11 => new question_answer(11, '1', 0.3333333, '', FORMAT_HTML),
 133              12 => new question_answer(12, '2', -1, '', FORMAT_HTML),
 134              13 => new question_answer(13, '3', 0.3333333, '', FORMAT_HTML),
 135              14 => new question_answer(14, '4', -1, '', FORMAT_HTML),
 136              15 => new question_answer(15, '5', 0.3333333, '', FORMAT_HTML),
 137              16 => new question_answer(16, '6', -1, '', FORMAT_HTML),
 138          );
 139  
 140          $mc->start_attempt(new question_attempt_step(), 1);
 141  
 142          list($grade, $state) = $mc->grade_response($mc->prepare_simulated_post_data(array('1' => '1', '3' => '1', '5' => '1')));
 143          $this->assertEqualsWithDelta(1, $grade, 0.000001);
 144          $this->assertEquals(question_state::$gradedright, $state);
 145      }
 146  
 147      public function test_get_correct_response() {
 148          $question = \test_question_maker::make_a_multichoice_single_question();
 149          $question->start_attempt(new question_attempt_step(), 1);
 150  
 151          $this->assertEquals($question->prepare_simulated_post_data(array('answer' => 'A')), $question->get_correct_response());
 152      }
 153  
 154      public function test_summarise_response() {
 155          $mc = \test_question_maker::make_a_multichoice_single_question();
 156          $mc->start_attempt(new question_attempt_step(), 1);
 157  
 158          $summary = $mc->summarise_response($mc->prepare_simulated_post_data(array('answer' => 'A')),
 159                                              \test_question_maker::get_a_qa($mc));
 160  
 161          $this->assertEquals('A', $summary);
 162  
 163          $this->assertNull($mc->summarise_response(array(), \test_question_maker::get_a_qa($mc)));
 164          $this->assertNull($mc->summarise_response(array('answer' => '-1'), \test_question_maker::get_a_qa($mc)));
 165      }
 166  
 167      public function test_classify_response() {
 168          $mc = \test_question_maker::make_a_multichoice_single_question();
 169          $mc->start_attempt(new question_attempt_step(), 1);
 170  
 171          $this->assertEquals(array($mc->id => new question_classified_response(14, 'B', -0.3333333)),
 172                              $mc->classify_response($mc->prepare_simulated_post_data(array('answer' => 'B'))));
 173  
 174          $this->assertEquals(array(
 175                  $mc->id => question_classified_response::no_response(),
 176          ), $mc->classify_response(array()));
 177  
 178          $this->assertEquals(array(
 179                  $mc->id => question_classified_response::no_response(),
 180          ), $mc->classify_response(array('answer' => '-1')));
 181      }
 182  
 183      public function test_make_html_inline() {
 184          $mc = \test_question_maker::make_a_multichoice_single_question();
 185          $this->assertEquals('Frog', $mc->make_html_inline('<p>Frog</p>'));
 186          $this->assertEquals('Frog<br />Toad', $mc->make_html_inline("<p>Frog</p>\n<p>Toad</p>"));
 187          $this->assertEquals('<img src="http://example.com/pic.png" alt="Graph" />',
 188                  $mc->make_html_inline(
 189                      '<p><img src="http://example.com/pic.png" alt="Graph" /></p>'));
 190          $this->assertEquals("Frog<br />XXX <img src='http://example.com/pic.png' alt='Graph' />",
 191                  $mc->make_html_inline(" <p> Frog </p> \n\r
 192                      <p> XXX <img src='http://example.com/pic.png' alt='Graph' /> </p> "));
 193          $this->assertEquals('Frog', $mc->make_html_inline('<p>Frog</p><p></p>'));
 194          $this->assertEquals('Frog<br />†', $mc->make_html_inline('<p>Frog</p><p>†</p>'));
 195      }
 196  
 197      public function test_simulated_post_data() {
 198          $mc = \test_question_maker::make_a_multichoice_single_question();
 199          $mc->shuffleanswers = false;
 200          $mc->answers[13]->answer = '<p>A</p>';
 201          $mc->answers[14]->answer = '<p>B</p>';
 202          $mc->answers[15]->answer = '<p>C</p>';
 203          $mc->start_attempt(new question_attempt_step(), 1);
 204  
 205          $originalresponse = array('answer' => 1);
 206  
 207          $simulated = $mc->get_student_response_values_for_simulation($originalresponse);
 208          $this->assertEquals(array('answer' => 'B'), $simulated);
 209  
 210          $reconstucted = $mc->prepare_simulated_post_data($simulated);
 211          $this->assertEquals($originalresponse, $reconstucted);
 212      }
 213  }