Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.0.x will end 8 May 2023 (12 months).
  • Bug fixes for security issues in 4.0.x will end 13 November 2023 (18 months).
  • PHP version: minimum PHP 7.3.0 Note: the minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is also supported.

Differences Between: [Versions 310 and 400] [Versions 39 and 400]

   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 qformat_multianswer;
  18  
  19  use qformat_multianswer;
  20  use question_check_specified_fields_expectation;
  21  
  22  defined('MOODLE_INTERNAL') || die();
  23  
  24  global $CFG;
  25  require_once($CFG->libdir . '/questionlib.php');
  26  require_once($CFG->dirroot . '/question/format.php');
  27  require_once($CFG->dirroot . '/question/format/multianswer/format.php');
  28  require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
  29  
  30  /**
  31   * Unit tests for the Embedded answer (Cloze) question importer.
  32   *
  33   * @package   qformat_multianswer
  34   * @copyright 2012 The Open University
  35   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  36   */
  37  class multianswerformat_test extends \question_testcase {
  38  
  39      public function test_import() {
  40          $lines = file(__DIR__ . '/fixtures/questions.multianswer.txt');
  41  
  42          $importer = new qformat_multianswer();
  43          $qs = $importer->readquestions($lines);
  44  
  45          $expectedq = (object) array(
  46              'name' => 'Match the following cities with the correct state:
  47  * San Francisco: {#1}
  48  * ...',
  49              'questiontext' => 'Match the following cities with the correct state:
  50  * San Francisco: {#1}
  51  * Tucson: {#2}
  52  * Los Angeles: {#3}
  53  * Phoenix: {#4}
  54  The capital of France is {#5}.
  55  ',
  56              'questiontextformat' => FORMAT_MOODLE,
  57              'generalfeedback' => '',
  58              'generalfeedbackformat' => FORMAT_MOODLE,
  59              'qtype' => 'multianswer',
  60              'defaultmark' => 5,
  61              'penalty' => 0.3333333,
  62              'length' => 1,
  63          );
  64  
  65          $this->assertEquals(1, count($qs));
  66          $this->assert(new question_check_specified_fields_expectation($expectedq), $qs[0]);
  67  
  68          $this->assertEquals('multichoice', $qs[0]->options->questions[1]->qtype);
  69          $this->assertEquals('multichoice', $qs[0]->options->questions[2]->qtype);
  70          $this->assertEquals('multichoice', $qs[0]->options->questions[3]->qtype);
  71          $this->assertEquals('multichoice', $qs[0]->options->questions[4]->qtype);
  72          $this->assertEquals('shortanswer', $qs[0]->options->questions[5]->qtype);
  73      }
  74  
  75      public function test_read_brokencloze_1() {
  76          $lines = file(__DIR__ . '/fixtures/broken_multianswer_1.txt');
  77          $importer = new qformat_multianswer();
  78  
  79          // The importer echoes some errors, so we need to capture and check that.
  80          ob_start();
  81          $questions = $importer->readquestions($lines);
  82          $output = ob_get_contents();
  83          ob_end_clean();
  84  
  85          // Check that there were some expected errors.
  86          $this->assertStringContainsString('Error importing question', $output);
  87          $this->assertStringContainsString('Invalid embedded answers (Cloze) question', $output);
  88          $this->assertStringContainsString('This type of question requires at least 2 choices', $output);
  89  
  90          // No question  have been imported.
  91          $this->assertCount(0, $questions);
  92      }
  93  
  94      public function test_read_brokencloze_2() {
  95          $lines = file(__DIR__ . '/fixtures/broken_multianswer_2.txt');
  96          $importer = new qformat_multianswer();
  97  
  98          // The importer echoes some errors, so we need to capture and check that.
  99          ob_start();
 100          $questions = $importer->readquestions($lines);
 101          $output = ob_get_contents();
 102          ob_end_clean();
 103  
 104          // Check that there were some expected errors.
 105          $this->assertStringContainsString('Error importing question', $output);
 106          $this->assertStringContainsString('Invalid embedded answers (Cloze) question', $output);
 107          $this->assertStringContainsString('One of the answers should have a score of 100% so it is possible to get full marks for this question.',
 108                  $output);
 109  
 110          // No question  have been imported.
 111          $this->assertCount(0, $questions);
 112      }
 113  
 114      public function test_read_brokencloze_3() {
 115          $lines = file(__DIR__ . '/fixtures/broken_multianswer_3.txt');
 116          $importer = new qformat_multianswer();
 117  
 118          // The importer echoes some errors, so we need to capture and check that.
 119          ob_start();
 120          $questions = $importer->readquestions($lines);
 121          $output = ob_get_contents();
 122          ob_end_clean();
 123  
 124          // Check that there were some expected errors.
 125          $this->assertStringContainsString('Error importing question', $output);
 126          $this->assertStringContainsString('Invalid embedded answers (Cloze) question', $output);
 127          $this->assertStringContainsString('The answer must be a number, for example -1.234 or 3e8, or \'*\'.', $output);
 128  
 129          // No question  have been imported.
 130          $this->assertCount(0, $questions);
 131      }
 132  
 133      public function test_read_brokencloze_4() {
 134          $lines = file(__DIR__ . '/fixtures/broken_multianswer_4.txt');
 135          $importer = new qformat_multianswer();
 136  
 137          // The importer echoes some errors, so we need to capture and check that.
 138          ob_start();
 139          $questions = $importer->readquestions($lines);
 140          $output = ob_get_contents();
 141          ob_end_clean();
 142  
 143          // Check that there were some expected errors.
 144          $this->assertStringContainsString('Error importing question', $output);
 145          $this->assertStringContainsString('Invalid embedded answers (Cloze) question', $output);
 146          $this->assertStringContainsString('The question text must include at least one embedded answer.', $output);
 147  
 148          // No question  have been imported.
 149          $this->assertCount(0, $questions);
 150      }
 151  }