[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/question/format/xml/tests/ -> xmlformat_test.php (source)

   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 Moodle XML format.
  19   *
  20   * @package    qformat_xml
  21   * @copyright  2010 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->libdir . '/questionlib.php');
  30  require_once($CFG->dirroot . '/question/format/xml/format.php');
  31  require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
  32  
  33  
  34  /**
  35   * Unit tests for the matching 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 qformat_xml_test extends question_testcase {
  41      public function assert_same_xml($expectedxml, $xml) {
  42          $this->assertEquals(str_replace("\r\n", "\n", $expectedxml),
  43                  str_replace("\r\n", "\n", $xml));
  44      }
  45  
  46      public function make_test_question() {
  47          global $USER;
  48          $q = new stdClass();
  49          $q->id = 0;
  50          $q->contextid = 0;
  51          $q->category = 0;
  52          $q->parent = 0;
  53          $q->questiontextformat = FORMAT_HTML;
  54          $q->generalfeedbackformat = FORMAT_HTML;
  55          $q->defaultmark = 1;
  56          $q->penalty = 0.3333333;
  57          $q->length = 1;
  58          $q->stamp = make_unique_id_code();
  59          $q->version = make_unique_id_code();
  60          $q->hidden = 0;
  61          $q->timecreated = time();
  62          $q->timemodified = time();
  63          $q->createdby = $USER->id;
  64          $q->modifiedby = $USER->id;
  65          return $q;
  66      }
  67  
  68      /**
  69       * The data the XML import format sends to save_question is not exactly
  70       * the same as the data returned from the editing form, so this method
  71       * makes necessary changes to the return value of
  72       * test_question_maker::get_question_form_data so that the tests can work.
  73       * @param object $expectedq as returned by get_question_form_data.
  74       * @return object one more likely to match the return value of import_...().
  75       */
  76      public function remove_irrelevant_form_data_fields($expectedq) {
  77          return $this->itemid_to_files($expectedq);
  78      }
  79  
  80      /**
  81       * Becuase XML import uses a files array instead of an itemid integer to
  82       * handle saving files with a question, we need to covert the output of
  83       * test_question_maker::get_question_form_data to match. This method recursively
  84       * replaces all array elements with key itemid with an array entry with
  85       * key files and value an empty array.
  86       *
  87       * @param mixed $var any data structure.
  88       * @return mixed an equivalent structure with the relacements made.
  89       */
  90      protected function itemid_to_files($var) {
  91          if (is_object($var)) {
  92              $newvar = new stdClass();
  93              foreach (get_object_vars($var) as $field => $value) {
  94                  $newvar->$field = $this->itemid_to_files($value);
  95              }
  96  
  97          } else if (is_array($var)) {
  98              $newvar = array();
  99              foreach ($var as $index => $value) {
 100                  if ($index === 'itemid') {
 101                      $newvar['files'] = array();
 102                  } else {
 103                      $newvar[$index] = $this->itemid_to_files($value);
 104                  }
 105              }
 106  
 107          } else {
 108              $newvar = $var;
 109          }
 110  
 111          return $newvar;
 112      }
 113  
 114      public function test_xml_escape_simple_input_not_escaped() {
 115          $exporter = new qformat_xml();
 116          $string = 'Nothing funny here. Even if we go to a café or to 日本.';
 117          $this->assertEquals($string, $exporter->xml_escape($string));
 118      }
 119  
 120      public function test_xml_escape_html_wrapped_in_cdata() {
 121          $exporter = new qformat_xml();
 122          $string = '<p>Nothing <b>funny<b> here. Even if we go to a café or to 日本.</p>';
 123          $this->assertEquals('<![CDATA[' . $string . ']]>', $exporter->xml_escape($string));
 124      }
 125  
 126      public function test_xml_escape_script_tag_handled_ok() {
 127          $exporter = new qformat_xml();
 128          $input = '<script><![CDATA[alert(1<2);]]></script>';
 129          $expected = '<![CDATA[<script><![CDATA[alert(1<2);]]]]><![CDATA[></script>]]>';
 130          $this->assertEquals($expected, $exporter->xml_escape($input));
 131  
 132          // Check that parsing the expected result does give the input again.
 133          $parsed = simplexml_load_string('<div>' . $expected . '</div>');
 134          $this->assertEquals($input, $parsed->xpath('//div')[0]);
 135      }
 136  
 137      public function test_xml_escape_code_that_looks_like_cdata_end_ok() {
 138          $exporter = new qformat_xml();
 139          $input = "if (x[[0]]>a) print('hah');";
 140          $expected = "<![CDATA[if (x[[0]]]]><![CDATA[>a) print('hah');]]>";
 141          $this->assertEquals($expected, $exporter->xml_escape($input));
 142  
 143          // Check that parsing the expected result does give the input again.
 144          $parsed = simplexml_load_string('<div>' . $expected . '</div>');
 145          $this->assertEquals($input, $parsed->xpath('//div')[0]);
 146      }
 147  
 148      public function test_write_hint_basic() {
 149          $q = $this->make_test_question();
 150          $q->name = 'Short answer question';
 151          $q->questiontext = 'Name an amphibian: __________';
 152          $q->generalfeedback = 'Generalfeedback: frog or toad would have been OK.';
 153          if (!isset($q->options)) {
 154              $q->options = new stdClass();
 155          }
 156          $q->options->usecase = false;
 157          $q->options->answers = array(
 158              13 => new question_answer(13, 'frog', 1.0, 'Frog is a very good answer.', FORMAT_HTML),
 159              14 => new question_answer(14, 'toad', 0.8, 'Toad is an OK good answer.', FORMAT_HTML),
 160              15 => new question_answer(15, '*', 0.0, 'That is a bad answer.', FORMAT_HTML),
 161          );
 162          $q->qtype = 'shortanswer';
 163          $q->hints = array(
 164              new question_hint(0, 'This is the first hint.', FORMAT_MOODLE),
 165          );
 166  
 167          $exporter = new qformat_xml();
 168          $xml = $exporter->writequestion($q);
 169  
 170          $this->assertRegExp('|<hint format=\"moodle_auto_format\">\s*<text>\s*' .
 171                  'This is the first hint\.\s*</text>\s*</hint>|', $xml);
 172          $this->assertNotRegExp('|<shownumcorrect/>|', $xml);
 173          $this->assertNotRegExp('|<clearwrong/>|', $xml);
 174          $this->assertNotRegExp('|<options>|', $xml);
 175      }
 176  
 177      public function test_write_hint_with_parts() {
 178          $q = $this->make_test_question();
 179          $q->name = 'Matching question';
 180          $q->questiontext = 'Classify the animals.';
 181          $q->generalfeedback = 'Frogs and toads are amphibians, the others are mammals.';
 182          $q->qtype = 'match';
 183  
 184          if (!isset($q->options)) {
 185              $q->options = new stdClass();
 186          }
 187          $q->options->shuffleanswers = 1;
 188          $q->options->correctfeedback = '';
 189          $q->options->correctfeedbackformat = FORMAT_HTML;
 190          $q->options->partiallycorrectfeedback = '';
 191          $q->options->partiallycorrectfeedbackformat = FORMAT_HTML;
 192          $q->options->incorrectfeedback = '';
 193          $q->options->incorrectfeedbackformat = FORMAT_HTML;
 194  
 195          $q->options->subquestions = array();
 196          $q->hints = array(
 197              new question_hint_with_parts(0, 'This is the first hint.', FORMAT_HTML, false, true),
 198              new question_hint_with_parts(0, 'This is the second hint.', FORMAT_HTML, true, false),
 199          );
 200  
 201          $exporter = new qformat_xml();
 202          $xml = $exporter->writequestion($q);
 203  
 204          $this->assertRegExp(
 205                  '|<hint format=\"html\">\s*<text>\s*This is the first hint\.\s*</text>|', $xml);
 206          $this->assertRegExp(
 207                  '|<hint format=\"html\">\s*<text>\s*This is the second hint\.\s*</text>|', $xml);
 208          list($ignored, $hint1, $hint2) = explode('<hint', $xml);
 209          $this->assertNotRegExp('|<shownumcorrect/>|', $hint1);
 210          $this->assertRegExp('|<clearwrong/>|', $hint1);
 211          $this->assertRegExp('|<shownumcorrect/>|', $hint2);
 212          $this->assertNotRegExp('|<clearwrong/>|', $hint2);
 213          $this->assertNotRegExp('|<options>|', $xml);
 214      }
 215  
 216      public function test_import_hints_no_parts() {
 217          $xml = <<<END
 218  <question>
 219      <hint>
 220          <text>This is the first hint</text>
 221          <clearwrong/>
 222      </hint>
 223      <hint>
 224          <text>This is the second hint</text>
 225          <shownumcorrect/>
 226      </hint>
 227  </question>
 228  END;
 229  
 230          $questionxml = xmlize($xml);
 231          $qo = new stdClass();
 232  
 233          $importer = new qformat_xml();
 234          $importer->import_hints($qo, $questionxml['question'], false, false, 'html');
 235  
 236          $this->assertEquals(array(
 237                  array('text' => 'This is the first hint',
 238                          'format' => FORMAT_HTML),
 239                  array('text' => 'This is the second hint',
 240                          'format' => FORMAT_HTML),
 241                  ), $qo->hint);
 242          $this->assertFalse(isset($qo->hintclearwrong));
 243          $this->assertFalse(isset($qo->hintshownumcorrect));
 244      }
 245  
 246      public function test_import_hints_with_parts() {
 247          $xml = <<<END
 248  <question>
 249      <hint>
 250          <text>This is the first hint</text>
 251          <clearwrong/>
 252      </hint>
 253      <hint>
 254          <text>This is the second hint</text>
 255          <shownumcorrect/>
 256      </hint>
 257  </question>
 258  END;
 259  
 260          $questionxml = xmlize($xml);
 261          $qo = new stdClass();
 262  
 263          $importer = new qformat_xml();
 264          $importer->import_hints($qo, $questionxml['question'], true, true, 'html');
 265  
 266          $this->assertEquals(array(
 267                  array('text' => 'This is the first hint',
 268                          'format' => FORMAT_HTML),
 269                  array('text' => 'This is the second hint',
 270                          'format' => FORMAT_HTML),
 271                  ), $qo->hint);
 272          $this->assertEquals(array(1, 0), $qo->hintclearwrong);
 273          $this->assertEquals(array(0, 1), $qo->hintshownumcorrect);
 274      }
 275  
 276      public function test_import_no_hints_no_error() {
 277          $xml = <<<END
 278  <question>
 279  </question>
 280  END;
 281  
 282          $questionxml = xmlize($xml);
 283          $qo = new stdClass();
 284  
 285          $importer = new qformat_xml();
 286          $importer->import_hints($qo, $questionxml['question'], 'html');
 287  
 288          $this->assertFalse(isset($qo->hint));
 289      }
 290  
 291      public function test_import_description() {
 292          $xml = '  <question type="description">
 293      <name>
 294        <text>A description</text>
 295      </name>
 296      <questiontext format="html">
 297        <text>The question text.</text>
 298      </questiontext>
 299      <generalfeedback>
 300        <text>Here is some general feedback.</text>
 301      </generalfeedback>
 302      <defaultgrade>0</defaultgrade>
 303      <penalty>0</penalty>
 304      <hidden>0</hidden>
 305      <tags>
 306        <tag><text>tagDescription</text></tag>
 307        <tag><text>tagTest</text></tag>
 308      </tags>
 309    </question>';
 310          $xmldata = xmlize($xml);
 311  
 312          $importer = new qformat_xml();
 313          $q = $importer->import_description($xmldata['question']);
 314  
 315          $expectedq = new stdClass();
 316          $expectedq->qtype = 'description';
 317          $expectedq->name = 'A description';
 318          $expectedq->questiontext = 'The question text.';
 319          $expectedq->questiontextformat = FORMAT_HTML;
 320          $expectedq->generalfeedback = 'Here is some general feedback.';
 321          $expectedq->defaultmark = 0;
 322          $expectedq->length = 0;
 323          $expectedq->penalty = 0;
 324          $expectedq->tags = array('tagDescription', 'tagTest');
 325  
 326          $this->assert(new question_check_specified_fields_expectation($expectedq), $q);
 327      }
 328  
 329      public function test_export_description() {
 330          $qdata = new stdClass();
 331          $qdata->id = 123;
 332          $qdata->contextid = 0;
 333          $qdata->qtype = 'description';
 334          $qdata->name = 'A description';
 335          $qdata->questiontext = 'The question text.';
 336          $qdata->questiontextformat = FORMAT_HTML;
 337          $qdata->generalfeedback = 'Here is some general feedback.';
 338          $qdata->generalfeedbackformat = FORMAT_HTML;
 339          $qdata->defaultmark = 0;
 340          $qdata->length = 0;
 341          $qdata->penalty = 0;
 342          $qdata->hidden = 0;
 343  
 344          $exporter = new qformat_xml();
 345          $xml = $exporter->writequestion($qdata);
 346  
 347          $expectedxml = '<!-- question: 123  -->
 348    <question type="description">
 349      <name>
 350        <text>A description</text>
 351      </name>
 352      <questiontext format="html">
 353        <text>The question text.</text>
 354      </questiontext>
 355      <generalfeedback format="html">
 356        <text>Here is some general feedback.</text>
 357      </generalfeedback>
 358      <defaultgrade>0</defaultgrade>
 359      <penalty>0</penalty>
 360      <hidden>0</hidden>
 361    </question>
 362  ';
 363  
 364          $this->assert_same_xml($expectedxml, $xml);
 365      }
 366  
 367      public function test_import_essay_20() {
 368          $xml = '  <question type="essay">
 369      <name>
 370        <text>An essay</text>
 371      </name>
 372      <questiontext format="moodle_auto_format">
 373        <text>Write something.</text>
 374      </questiontext>
 375      <generalfeedback>
 376        <text>I hope you wrote something interesting.</text>
 377      </generalfeedback>
 378      <defaultgrade>1</defaultgrade>
 379      <penalty>0</penalty>
 380      <hidden>0</hidden>
 381      <tags>
 382        <tag><text>tagEssay</text></tag>
 383        <tag><text>tagEssay20</text></tag>
 384        <tag><text>tagTest</text></tag>
 385      </tags>
 386    </question>';
 387          $xmldata = xmlize($xml);
 388  
 389          $importer = new qformat_xml();
 390          $q = $importer->import_essay($xmldata['question']);
 391  
 392          $expectedq = new stdClass();
 393          $expectedq->qtype = 'essay';
 394          $expectedq->name = 'An essay';
 395          $expectedq->questiontext = 'Write something.';
 396          $expectedq->questiontextformat = FORMAT_MOODLE;
 397          $expectedq->generalfeedback = 'I hope you wrote something interesting.';
 398          $expectedq->defaultmark = 1;
 399          $expectedq->length = 1;
 400          $expectedq->penalty = 0;
 401          $expectedq->responseformat = 'editor';
 402          $expectedq->responserequired = 1;
 403          $expectedq->responsefieldlines = 15;
 404          $expectedq->attachments = 0;
 405          $expectedq->attachmentsrequired = 0;
 406          $expectedq->graderinfo['text'] = '';
 407          $expectedq->graderinfo['format'] = FORMAT_MOODLE;
 408          $expectedq->responsetemplate['text'] = '';
 409          $expectedq->responsetemplate['format'] = FORMAT_MOODLE;
 410          $expectedq->tags = array('tagEssay', 'tagEssay20', 'tagTest');
 411  
 412          $this->assert(new question_check_specified_fields_expectation($expectedq), $q);
 413      }
 414  
 415      public function test_import_essay_21() {
 416          $xml = '  <question type="essay">
 417      <name>
 418        <text>An essay</text>
 419      </name>
 420      <questiontext format="moodle_auto_format">
 421        <text>Write something.</text>
 422      </questiontext>
 423      <generalfeedback>
 424        <text>I hope you wrote something interesting.</text>
 425      </generalfeedback>
 426      <defaultgrade>1</defaultgrade>
 427      <penalty>0</penalty>
 428      <hidden>0</hidden>
 429      <responseformat>monospaced</responseformat>
 430      <responserequired>0</responserequired>
 431      <responsefieldlines>42</responsefieldlines>
 432      <attachments>-1</attachments>
 433      <attachmentsrequired>1</attachmentsrequired>
 434      <graderinfo format="html">
 435          <text><![CDATA[<p>Grade <b>generously</b>!</p>]]></text>
 436      </graderinfo>
 437      <responsetemplate format="html">
 438          <text><![CDATA[<p>Here is something <b>really</b> interesting.</p>]]></text>
 439      </responsetemplate>
 440      <tags>
 441        <tag><text>tagEssay</text></tag>
 442        <tag><text>tagEssay21</text></tag>
 443        <tag><text>tagTest</text></tag>
 444      </tags>
 445    </question>';
 446          $xmldata = xmlize($xml);
 447  
 448          $importer = new qformat_xml();
 449          $q = $importer->import_essay($xmldata['question']);
 450  
 451          $expectedq = new stdClass();
 452          $expectedq->qtype = 'essay';
 453          $expectedq->name = 'An essay';
 454          $expectedq->questiontext = 'Write something.';
 455          $expectedq->questiontextformat = FORMAT_MOODLE;
 456          $expectedq->generalfeedback = 'I hope you wrote something interesting.';
 457          $expectedq->defaultmark = 1;
 458          $expectedq->length = 1;
 459          $expectedq->penalty = 0;
 460          $expectedq->responseformat = 'monospaced';
 461          $expectedq->responserequired = 0;
 462          $expectedq->responsefieldlines = 42;
 463          $expectedq->attachments = -1;
 464          $expectedq->attachmentsrequired = 1;
 465          $expectedq->graderinfo['text'] = '<p>Grade <b>generously</b>!</p>';
 466          $expectedq->graderinfo['format'] = FORMAT_HTML;
 467          $expectedq->responsetemplate['text'] = '<p>Here is something <b>really</b> interesting.</p>';
 468          $expectedq->responsetemplate['format'] = FORMAT_HTML;
 469          $expectedq->tags = array('tagEssay', 'tagEssay21', 'tagTest');
 470  
 471          $this->assert(new question_check_specified_fields_expectation($expectedq), $q);
 472      }
 473  
 474      public function test_export_essay() {
 475          $qdata = new stdClass();
 476          $qdata->id = 123;
 477          $qdata->contextid = 0;
 478          $qdata->qtype = 'essay';
 479          $qdata->name = 'An essay';
 480          $qdata->questiontext = 'Write something.';
 481          $qdata->questiontextformat = FORMAT_MOODLE;
 482          $qdata->generalfeedback = 'I hope you wrote something interesting.';
 483          $qdata->generalfeedbackformat = FORMAT_MOODLE;
 484          $qdata->defaultmark = 1;
 485          $qdata->length = 1;
 486          $qdata->penalty = 0;
 487          $qdata->hidden = 0;
 488          $qdata->options = new stdClass();
 489          $qdata->options->id = 456;
 490          $qdata->options->questionid = 123;
 491          $qdata->options->responseformat = 'monospaced';
 492          $qdata->options->responserequired = 0;
 493          $qdata->options->responsefieldlines = 42;
 494          $qdata->options->attachments = -1;
 495          $qdata->options->attachmentsrequired = 1;
 496          $qdata->options->graderinfo = '<p>Grade <b>generously</b>!</p>';
 497          $qdata->options->graderinfoformat = FORMAT_HTML;
 498          $qdata->options->responsetemplate = '<p>Here is something <b>really</b> interesting.</p>';
 499          $qdata->options->responsetemplateformat = FORMAT_HTML;
 500          $exporter = new qformat_xml();
 501          $xml = $exporter->writequestion($qdata);
 502  
 503          $expectedxml = '<!-- question: 123  -->
 504    <question type="essay">
 505      <name>
 506        <text>An essay</text>
 507      </name>
 508      <questiontext format="moodle_auto_format">
 509        <text>Write something.</text>
 510      </questiontext>
 511      <generalfeedback format="moodle_auto_format">
 512        <text>I hope you wrote something interesting.</text>
 513      </generalfeedback>
 514      <defaultgrade>1</defaultgrade>
 515      <penalty>0</penalty>
 516      <hidden>0</hidden>
 517      <responseformat>monospaced</responseformat>
 518      <responserequired>0</responserequired>
 519      <responsefieldlines>42</responsefieldlines>
 520      <attachments>-1</attachments>
 521      <attachmentsrequired>1</attachmentsrequired>
 522      <graderinfo format="html">
 523        <text><![CDATA[<p>Grade <b>generously</b>!</p>]]></text>
 524      </graderinfo>
 525      <responsetemplate format="html">
 526        <text><![CDATA[<p>Here is something <b>really</b> interesting.</p>]]></text>
 527      </responsetemplate>
 528    </question>
 529  ';
 530  
 531          $this->assert_same_xml($expectedxml, $xml);
 532      }
 533  
 534      public function test_import_match_19() {
 535          $xml = '  <question type="matching">
 536      <name>
 537        <text>Matching question</text>
 538      </name>
 539      <questiontext format="html">
 540        <text>Match the upper and lower case letters.</text>
 541      </questiontext>
 542      <generalfeedback>
 543        <text>The answer is A -> a, B -> b and C -> c.</text>
 544      </generalfeedback>
 545      <defaultgrade>1</defaultgrade>
 546      <penalty>0.3333333</penalty>
 547      <hidden>0</hidden>
 548      <shuffleanswers>false</shuffleanswers>
 549      <correctfeedback>
 550        <text>Well done.</text>
 551      </correctfeedback>
 552      <partiallycorrectfeedback>
 553        <text>Not entirely.</text>
 554      </partiallycorrectfeedback>
 555      <incorrectfeedback>
 556        <text>Completely wrong!</text>
 557      </incorrectfeedback>
 558      <subquestion>
 559        <text>A</text>
 560        <answer>
 561          <text>a</text>
 562        </answer>
 563      </subquestion>
 564      <subquestion>
 565        <text>B</text>
 566        <answer>
 567          <text>b</text>
 568        </answer>
 569      </subquestion>
 570      <subquestion>
 571        <text>C</text>
 572        <answer>
 573          <text>c</text>
 574        </answer>
 575      </subquestion>
 576      <subquestion>
 577        <text></text>
 578        <answer>
 579          <text>d</text>
 580        </answer>
 581      </subquestion>
 582      <hint>
 583        <text>Hint 1</text>
 584        <shownumcorrect />
 585      </hint>
 586      <hint>
 587        <text></text>
 588        <shownumcorrect />
 589        <clearwrong />
 590      </hint>
 591      <tags>
 592        <tag><text>tagMatching</text></tag>
 593        <tag><text>tagTest</text></tag>
 594      </tags>
 595    </question>';
 596          $xmldata = xmlize($xml);
 597  
 598          $importer = new qformat_xml();
 599          $q = $importer->import_match($xmldata['question']);
 600  
 601          $expectedq = new stdClass();
 602          $expectedq->qtype = 'match';
 603          $expectedq->name = 'Matching question';
 604          $expectedq->questiontext = 'Match the upper and lower case letters.';
 605          $expectedq->questiontextformat = FORMAT_HTML;
 606          $expectedq->correctfeedback = array('text' => 'Well done.',
 607                  'format' => FORMAT_HTML);
 608          $expectedq->partiallycorrectfeedback = array('text' => 'Not entirely.',
 609                  'format' => FORMAT_HTML);
 610          $expectedq->shownumcorrect = false;
 611          $expectedq->incorrectfeedback = array('text' => 'Completely wrong!',
 612                  'format' => FORMAT_HTML);
 613          $expectedq->generalfeedback = 'The answer is A -> a, B -> b and C -> c.';
 614          $expectedq->generalfeedbackformat = FORMAT_HTML;
 615          $expectedq->defaultmark = 1;
 616          $expectedq->length = 1;
 617          $expectedq->penalty = 0.3333333;
 618          $expectedq->shuffleanswers = 0;
 619          $expectedq->subquestions = array(
 620              array('text' => 'A', 'format' => FORMAT_HTML),
 621              array('text' => 'B', 'format' => FORMAT_HTML),
 622              array('text' => 'C', 'format' => FORMAT_HTML),
 623              array('text' => '', 'format' => FORMAT_HTML));
 624          $expectedq->subanswers = array('a', 'b', 'c', 'd');
 625          $expectedq->hint = array(
 626              array('text' => 'Hint 1', 'format' => FORMAT_HTML),
 627              array('text' => '', 'format' => FORMAT_HTML),
 628          );
 629          $expectedq->hintshownumcorrect = array(true, true);
 630          $expectedq->hintclearwrong = array(false, true);
 631          $expectedq->tags = array('tagMatching', 'tagTest');
 632  
 633          $this->assert(new question_check_specified_fields_expectation($expectedq), $q);
 634      }
 635  
 636      public function test_export_match() {
 637          $qdata = new stdClass();
 638          $qdata->id = 123;
 639          $qdata->contextid = 0;
 640          $qdata->qtype = 'match';
 641          $qdata->name = 'Matching question';
 642          $qdata->questiontext = 'Match the upper and lower case letters.';
 643          $qdata->questiontextformat = FORMAT_HTML;
 644          $qdata->generalfeedback = 'The answer is A -> a, B -> b and C -> c.';
 645          $qdata->generalfeedbackformat = FORMAT_HTML;
 646          $qdata->defaultmark = 1;
 647          $qdata->length = 1;
 648          $qdata->penalty = 0.3333333;
 649          $qdata->hidden = 0;
 650  
 651          $qdata->options = new stdClass();
 652          $qdata->options->shuffleanswers = 1;
 653          $qdata->options->correctfeedback = 'Well done.';
 654          $qdata->options->correctfeedbackformat = FORMAT_HTML;
 655          $qdata->options->partiallycorrectfeedback = 'Not entirely.';
 656          $qdata->options->partiallycorrectfeedbackformat = FORMAT_HTML;
 657          $qdata->options->shownumcorrect = false;
 658          $qdata->options->incorrectfeedback = 'Completely wrong!';
 659          $qdata->options->incorrectfeedbackformat = FORMAT_HTML;
 660  
 661          $subq1 = new stdClass();
 662          $subq1->id = -4;
 663          $subq1->questiontext = 'A';
 664          $subq1->questiontextformat = FORMAT_HTML;
 665          $subq1->answertext = 'a';
 666  
 667          $subq2 = new stdClass();
 668          $subq2->id = -3;
 669          $subq2->questiontext = 'B';
 670          $subq2->questiontextformat = FORMAT_HTML;
 671          $subq2->answertext = 'b';
 672  
 673          $subq3 = new stdClass();
 674          $subq3->id = -2;
 675          $subq3->questiontext = 'C';
 676          $subq3->questiontextformat = FORMAT_HTML;
 677          $subq3->answertext = 'c';
 678  
 679          $subq4 = new stdClass();
 680          $subq4->id = -1;
 681          $subq4->questiontext = '';
 682          $subq4->questiontextformat = FORMAT_HTML;
 683          $subq4->answertext = 'd';
 684  
 685          $qdata->options->subquestions = array(
 686                  $subq1, $subq2, $subq3, $subq4);
 687  
 688          $qdata->hints = array(
 689              new question_hint_with_parts(0, 'Hint 1', FORMAT_HTML, true, false),
 690              new question_hint_with_parts(0, '', FORMAT_HTML, true, true),
 691          );
 692  
 693          $exporter = new qformat_xml();
 694          $xml = $exporter->writequestion($qdata);
 695  
 696          $expectedxml = '<!-- question: 123  -->
 697    <question type="matching">
 698      <name>
 699        <text>Matching question</text>
 700      </name>
 701      <questiontext format="html">
 702        <text>Match the upper and lower case letters.</text>
 703      </questiontext>
 704      <generalfeedback format="html">
 705        <text><![CDATA[The answer is A -> a, B -> b and C -> c.]]></text>
 706      </generalfeedback>
 707      <defaultgrade>1</defaultgrade>
 708      <penalty>0.3333333</penalty>
 709      <hidden>0</hidden>
 710      <shuffleanswers>true</shuffleanswers>
 711      <correctfeedback format="html">
 712        <text>Well done.</text>
 713      </correctfeedback>
 714      <partiallycorrectfeedback format="html">
 715        <text>Not entirely.</text>
 716      </partiallycorrectfeedback>
 717      <incorrectfeedback format="html">
 718        <text>Completely wrong!</text>
 719      </incorrectfeedback>
 720      <subquestion format="html">
 721        <text>A</text>
 722        <answer>
 723          <text>a</text>
 724        </answer>
 725      </subquestion>
 726      <subquestion format="html">
 727        <text>B</text>
 728        <answer>
 729          <text>b</text>
 730        </answer>
 731      </subquestion>
 732      <subquestion format="html">
 733        <text>C</text>
 734        <answer>
 735          <text>c</text>
 736        </answer>
 737      </subquestion>
 738      <subquestion format="html">
 739        <text></text>
 740        <answer>
 741          <text>d</text>
 742        </answer>
 743      </subquestion>
 744      <hint format="html">
 745        <text>Hint 1</text>
 746        <shownumcorrect/>
 747      </hint>
 748      <hint format="html">
 749        <text></text>
 750        <shownumcorrect/>
 751        <clearwrong/>
 752      </hint>
 753    </question>
 754  ';
 755  
 756          $this->assert_same_xml($expectedxml, $xml);
 757      }
 758  
 759      public function test_import_multichoice_19() {
 760          $xml = '  <question type="multichoice">
 761      <name>
 762        <text>Multiple choice question</text>
 763      </name>
 764      <questiontext format="html">
 765        <text>Which are the even numbers?</text>
 766      </questiontext>
 767      <generalfeedback>
 768        <text>The even numbers are 2 and 4.</text>
 769      </generalfeedback>
 770      <defaultgrade>2</defaultgrade>
 771      <penalty>0.3333333</penalty>
 772      <hidden>0</hidden>
 773      <single>false</single>
 774      <shuffleanswers>false</shuffleanswers>
 775      <answernumbering>abc</answernumbering>
 776      <correctfeedback>
 777        <text><![CDATA[<p>Your answer is correct.</p>]]></text>
 778      </correctfeedback>
 779      <partiallycorrectfeedback>
 780        <text><![CDATA[<p>Your answer is partially correct.</p>]]></text>
 781      </partiallycorrectfeedback>
 782      <incorrectfeedback>
 783        <text><![CDATA[<p>Your answer is incorrect.</p>]]></text>
 784      </incorrectfeedback>
 785      <shownumcorrect/>
 786      <answer fraction="0">
 787        <text>1</text>
 788        <feedback>
 789          <text></text>
 790        </feedback>
 791      </answer>
 792      <answer fraction="100">
 793        <text>2</text>
 794        <feedback>
 795          <text></text>
 796        </feedback>
 797      </answer>
 798      <answer fraction="0">
 799        <text>3</text>
 800        <feedback>
 801          <text></text>
 802        </feedback>
 803      </answer>
 804      <answer fraction="100">
 805        <text>4</text>
 806        <feedback>
 807          <text></text>
 808        </feedback>
 809      </answer>
 810      <hint>
 811        <text>Hint 1.</text>
 812      </hint>
 813      <hint>
 814        <text>Hint 2.</text>
 815      </hint>
 816    </question>';
 817          $xmldata = xmlize($xml);
 818  
 819          $importer = new qformat_xml();
 820          $q = $importer->import_multichoice($xmldata['question']);
 821  
 822          $expectedq = new stdClass();
 823          $expectedq->qtype = 'multichoice';
 824          $expectedq->name = 'Multiple choice question';
 825          $expectedq->questiontext = 'Which are the even numbers?';
 826          $expectedq->questiontextformat = FORMAT_HTML;
 827          $expectedq->correctfeedback = array(
 828                  'text'   => '<p>Your answer is correct.</p>',
 829                  'format' => FORMAT_HTML);
 830          $expectedq->shownumcorrect = false;
 831          $expectedq->partiallycorrectfeedback = array(
 832                  'text'   => '<p>Your answer is partially correct.</p>',
 833                  'format' => FORMAT_HTML);
 834          $expectedq->shownumcorrect = true;
 835          $expectedq->incorrectfeedback = array(
 836                  'text'   => '<p>Your answer is incorrect.</p>',
 837                  'format' => FORMAT_HTML);
 838          $expectedq->generalfeedback = 'The even numbers are 2 and 4.';
 839          $expectedq->defaultmark = 2;
 840          $expectedq->length = 1;
 841          $expectedq->penalty = 0.3333333;
 842          $expectedq->shuffleanswers = 0;
 843          $expectedq->single = false;
 844  
 845          $expectedq->answer = array(
 846              array('text' => '1', 'format' => FORMAT_HTML),
 847              array('text' => '2', 'format' => FORMAT_HTML),
 848              array('text' => '3', 'format' => FORMAT_HTML),
 849              array('text' => '4', 'format' => FORMAT_HTML));
 850          $expectedq->fraction = array(0, 1, 0, 1);
 851          $expectedq->feedback = array(
 852              array('text' => '', 'format' => FORMAT_HTML),
 853              array('text' => '', 'format' => FORMAT_HTML),
 854              array('text' => '', 'format' => FORMAT_HTML),
 855              array('text' => '', 'format' => FORMAT_HTML));
 856  
 857          $expectedq->hint = array(
 858              array('text' => 'Hint 1.', 'format' => FORMAT_HTML),
 859              array('text' => 'Hint 2.', 'format' => FORMAT_HTML),
 860          );
 861          $expectedq->hintshownumcorrect = array(false, false);
 862          $expectedq->hintclearwrong = array(false, false);
 863  
 864          $this->assert(new question_check_specified_fields_expectation($expectedq), $q);
 865      }
 866  
 867      public function test_export_multichoice() {
 868          $qdata = new stdClass();
 869          $qdata->id = 123;
 870          $qdata->contextid = 0;
 871          $qdata->qtype = 'multichoice';
 872          $qdata->name = 'Multiple choice question';
 873          $qdata->questiontext = 'Which are the even numbers?';
 874          $qdata->questiontextformat = FORMAT_HTML;
 875          $qdata->generalfeedback = 'The even numbers are 2 and 4.';
 876          $qdata->generalfeedbackformat = FORMAT_HTML;
 877          $qdata->defaultmark = 2;
 878          $qdata->length = 1;
 879          $qdata->penalty = 0.3333333;
 880          $qdata->hidden = 0;
 881  
 882          $qdata->options = new stdClass();
 883          $qdata->options->single = 0;
 884          $qdata->options->shuffleanswers = 0;
 885          $qdata->options->answernumbering = 'abc';
 886          $qdata->options->correctfeedback = '<p>Your answer is correct.</p>';
 887          $qdata->options->correctfeedbackformat = FORMAT_HTML;
 888          $qdata->options->partiallycorrectfeedback = '<p>Your answer is partially correct.</p>';
 889          $qdata->options->partiallycorrectfeedbackformat = FORMAT_HTML;
 890          $qdata->options->shownumcorrect = 1;
 891          $qdata->options->incorrectfeedback = '<p>Your answer is incorrect.</p>';
 892          $qdata->options->incorrectfeedbackformat = FORMAT_HTML;
 893  
 894          $qdata->options->answers = array(
 895              13 => new question_answer(13, '1', 0, '', FORMAT_HTML),
 896              14 => new question_answer(14, '2', 1, '', FORMAT_HTML),
 897              15 => new question_answer(15, '3', 0, '', FORMAT_HTML),
 898              16 => new question_answer(16, '4', 1, '', FORMAT_HTML),
 899          );
 900  
 901          $qdata->hints = array(
 902              new question_hint_with_parts(0, 'Hint 1.', FORMAT_HTML, false, false),
 903              new question_hint_with_parts(0, 'Hint 2.', FORMAT_HTML, false, false),
 904          );
 905  
 906          $exporter = new qformat_xml();
 907          $xml = $exporter->writequestion($qdata);
 908  
 909          $expectedxml = '<!-- question: 123  -->
 910    <question type="multichoice">
 911      <name>
 912        <text>Multiple choice question</text>
 913      </name>
 914      <questiontext format="html">
 915        <text>Which are the even numbers?</text>
 916      </questiontext>
 917      <generalfeedback format="html">
 918        <text>The even numbers are 2 and 4.</text>
 919      </generalfeedback>
 920      <defaultgrade>2</defaultgrade>
 921      <penalty>0.3333333</penalty>
 922      <hidden>0</hidden>
 923      <single>false</single>
 924      <shuffleanswers>false</shuffleanswers>
 925      <answernumbering>abc</answernumbering>
 926      <correctfeedback format="html">
 927        <text><![CDATA[<p>Your answer is correct.</p>]]></text>
 928      </correctfeedback>
 929      <partiallycorrectfeedback format="html">
 930        <text><![CDATA[<p>Your answer is partially correct.</p>]]></text>
 931      </partiallycorrectfeedback>
 932      <incorrectfeedback format="html">
 933        <text><![CDATA[<p>Your answer is incorrect.</p>]]></text>
 934      </incorrectfeedback>
 935      <shownumcorrect/>
 936      <answer fraction="0" format="plain_text">
 937        <text>1</text>
 938        <feedback format="html">
 939          <text></text>
 940        </feedback>
 941      </answer>
 942      <answer fraction="100" format="plain_text">
 943        <text>2</text>
 944        <feedback format="html">
 945          <text></text>
 946        </feedback>
 947      </answer>
 948      <answer fraction="0" format="plain_text">
 949        <text>3</text>
 950        <feedback format="html">
 951          <text></text>
 952        </feedback>
 953      </answer>
 954      <answer fraction="100" format="plain_text">
 955        <text>4</text>
 956        <feedback format="html">
 957          <text></text>
 958        </feedback>
 959      </answer>
 960      <hint format="html">
 961        <text>Hint 1.</text>
 962      </hint>
 963      <hint format="html">
 964        <text>Hint 2.</text>
 965      </hint>
 966    </question>
 967  ';
 968  
 969          $this->assert_same_xml($expectedxml, $xml);
 970      }
 971  
 972      public function test_import_numerical_19() {
 973          $xml = '  <question type="numerical">
 974      <name>
 975        <text>Numerical question</text>
 976      </name>
 977      <questiontext format="html">
 978        <text>What is the answer?</text>
 979      </questiontext>
 980      <generalfeedback>
 981        <text>General feedback: Think Hitch-hikers guide to the Galaxy.</text>
 982      </generalfeedback>
 983      <defaultgrade>1</defaultgrade>
 984      <penalty>0.1</penalty>
 985      <hidden>0</hidden>
 986      <answer fraction="100">
 987        <text>42</text>
 988        <feedback>
 989          <text>Well done!</text>
 990        </feedback>
 991        <tolerance>0.001</tolerance>
 992      </answer>
 993      <answer fraction="0">
 994        <text>13</text>
 995        <feedback>
 996          <text>What were you thinking?!</text>
 997        </feedback>
 998        <tolerance>1</tolerance>
 999      </answer>
1000      <answer fraction="0">
1001        <text>*</text>
1002        <feedback>
1003          <text>Completely wrong.</text>
1004        </feedback>
1005        <tolerance></tolerance>
1006      </answer>
1007    </question>';
1008          $xmldata = xmlize($xml);
1009  
1010          $importer = new qformat_xml();
1011          $q = $importer->import_numerical($xmldata['question']);
1012  
1013          $expectedq = new stdClass();
1014          $expectedq->qtype = 'numerical';
1015          $expectedq->name = 'Numerical question';
1016          $expectedq->questiontext = 'What is the answer?';
1017          $expectedq->questiontextformat = FORMAT_HTML;
1018          $expectedq->generalfeedback = 'General feedback: Think Hitch-hikers guide to the Galaxy.';
1019          $expectedq->generalfeedbackformat = FORMAT_HTML;
1020          $expectedq->defaultmark = 1;
1021          $expectedq->length = 1;
1022          $expectedq->penalty = 0.1;
1023  
1024          $expectedq->answer = array('42', '13', '*');
1025          $expectedq->fraction = array(1, 0, 0);
1026          $expectedq->feedback = array(
1027              array('text' => 'Well done!',
1028                      'format' => FORMAT_HTML),
1029              array('text' => 'What were you thinking?!',
1030                      'format' => FORMAT_HTML),
1031              array('text' => 'Completely wrong.',
1032                      'format' => FORMAT_HTML));
1033          $expectedq->tolerance = array(0.001, 1, 0);
1034  
1035          $this->assert(new question_check_specified_fields_expectation($expectedq), $q);
1036      }
1037  
1038      public function test_export_numerical() {
1039          question_bank::load_question_definition_classes('numerical');
1040  
1041          $qdata = new stdClass();
1042          $qdata->id = 123;
1043          $qdata->contextid = 0;
1044          $qdata->qtype = 'numerical';
1045          $qdata->name = 'Numerical question';
1046          $qdata->questiontext = 'What is the answer?';
1047          $qdata->questiontextformat = FORMAT_HTML;
1048          $qdata->generalfeedback = 'General feedback: Think Hitch-hikers guide to the Galaxy.';
1049          $qdata->generalfeedbackformat = FORMAT_HTML;
1050          $qdata->defaultmark = 1;
1051          $qdata->length = 1;
1052          $qdata->penalty = 0.1;
1053          $qdata->hidden = 0;
1054  
1055          $qdata->options = new stdClass();
1056          $qdata->options->answers = array(
1057              13 => new qtype_numerical_answer(13, '42', 1, 'Well done!',
1058                      FORMAT_HTML, 0.001),
1059              14 => new qtype_numerical_answer(14, '13', 0, 'What were you thinking?!',
1060                      FORMAT_HTML, 1),
1061              15 => new qtype_numerical_answer(15, '*', 0, 'Completely wrong.',
1062                      FORMAT_HTML, ''),
1063          );
1064  
1065          $qdata->options->units = array();
1066  
1067          $exporter = new qformat_xml();
1068          $xml = $exporter->writequestion($qdata);
1069  
1070          $expectedxml = '<!-- question: 123  -->
1071    <question type="numerical">
1072      <name>
1073        <text>Numerical question</text>
1074      </name>
1075      <questiontext format="html">
1076        <text>What is the answer?</text>
1077      </questiontext>
1078      <generalfeedback format="html">
1079        <text>General feedback: Think Hitch-hikers guide to the Galaxy.</text>
1080      </generalfeedback>
1081      <defaultgrade>1</defaultgrade>
1082      <penalty>0.1</penalty>
1083      <hidden>0</hidden>
1084      <answer fraction="100" format="plain_text">
1085        <text>42</text>
1086        <feedback format="html">
1087          <text>Well done!</text>
1088        </feedback>
1089        <tolerance>0.001</tolerance>
1090      </answer>
1091      <answer fraction="0" format="plain_text">
1092        <text>13</text>
1093        <feedback format="html">
1094          <text>What were you thinking?!</text>
1095        </feedback>
1096        <tolerance>1</tolerance>
1097      </answer>
1098      <answer fraction="0" format="plain_text">
1099        <text>*</text>
1100        <feedback format="html">
1101          <text>Completely wrong.</text>
1102        </feedback>
1103        <tolerance>0</tolerance>
1104      </answer>
1105    </question>
1106  ';
1107  
1108          $this->assert_same_xml($expectedxml, $xml);
1109      }
1110  
1111      public function test_import_shortanswer_19() {
1112          $xml = '  <question type="shortanswer">
1113      <name>
1114        <text>Short answer question</text>
1115      </name>
1116      <questiontext format="html">
1117        <text>Fill in the gap in this sequence: Alpha, ________, Gamma.</text>
1118      </questiontext>
1119      <generalfeedback>
1120        <text>The answer is Beta.</text>
1121      </generalfeedback>
1122      <defaultgrade>1</defaultgrade>
1123      <penalty>0.3333333</penalty>
1124      <hidden>0</hidden>
1125      <usecase>0</usecase>
1126      <answer fraction="100" format="plain_text">
1127        <text>Beta</text>
1128        <feedback>
1129          <text>Well done!</text>
1130        </feedback>
1131      </answer>
1132      <answer fraction="0" format="plain_text">
1133        <text>*</text>
1134        <feedback>
1135          <text>Doh!</text>
1136        </feedback>
1137      </answer>
1138      <hint>
1139        <text>Hint 1</text>
1140      </hint>
1141      <hint>
1142        <text>Hint 2</text>
1143      </hint>
1144    </question>';
1145          $xmldata = xmlize($xml);
1146  
1147          $importer = new qformat_xml();
1148          $q = $importer->import_shortanswer($xmldata['question']);
1149  
1150          $expectedq = new stdClass();
1151          $expectedq->qtype = 'shortanswer';
1152          $expectedq->name = 'Short answer question';
1153          $expectedq->questiontext = 'Fill in the gap in this sequence: Alpha, ________, Gamma.';
1154          $expectedq->questiontextformat = FORMAT_HTML;
1155          $expectedq->generalfeedback = 'The answer is Beta.';
1156          $expectedq->usecase = false;
1157          $expectedq->defaultmark = 1;
1158          $expectedq->length = 1;
1159          $expectedq->penalty = 0.3333333;
1160  
1161          $expectedq->answer = array('Beta', '*');
1162          $expectedq->fraction = array(1, 0);
1163          $expectedq->feedback = array(
1164              array('text' => 'Well done!', 'format' => FORMAT_HTML),
1165              array('text' => 'Doh!', 'format' => FORMAT_HTML));
1166  
1167          $this->assert(new question_check_specified_fields_expectation($expectedq), $q);
1168      }
1169  
1170      public function test_export_shortanswer() {
1171          $qdata = new stdClass();
1172          $qdata->id = 123;
1173          $qdata->contextid = 0;
1174          $qdata->qtype = 'shortanswer';
1175          $qdata->name = 'Short answer question';
1176          $qdata->questiontext = 'Fill in the gap in this sequence: Alpha, ________, Gamma.';
1177          $qdata->questiontextformat = FORMAT_HTML;
1178          $qdata->generalfeedback = 'The answer is Beta.';
1179          $qdata->generalfeedbackformat = FORMAT_HTML;
1180          $qdata->defaultmark = 1;
1181          $qdata->length = 1;
1182          $qdata->penalty = 0.3333333;
1183          $qdata->hidden = 0;
1184  
1185          $qdata->options = new stdClass();
1186          $qdata->options->usecase = 0;
1187  
1188          $qdata->options->answers = array(
1189              13 => new question_answer(13, 'Beta', 1, 'Well done!', FORMAT_HTML),
1190              14 => new question_answer(14, '*', 0, 'Doh!', FORMAT_HTML),
1191          );
1192  
1193          $qdata->hints = array(
1194              new question_hint(0, 'Hint 1', FORMAT_HTML),
1195              new question_hint(0, 'Hint 2', FORMAT_HTML),
1196          );
1197  
1198          $exporter = new qformat_xml();
1199          $xml = $exporter->writequestion($qdata);
1200  
1201          $expectedxml = '<!-- question: 123  -->
1202    <question type="shortanswer">
1203      <name>
1204        <text>Short answer question</text>
1205      </name>
1206      <questiontext format="html">
1207        <text>Fill in the gap in this sequence: Alpha, ________, Gamma.</text>
1208      </questiontext>
1209      <generalfeedback format="html">
1210        <text>The answer is Beta.</text>
1211      </generalfeedback>
1212      <defaultgrade>1</defaultgrade>
1213      <penalty>0.3333333</penalty>
1214      <hidden>0</hidden>
1215      <usecase>0</usecase>
1216      <answer fraction="100" format="plain_text">
1217        <text>Beta</text>
1218        <feedback format="html">
1219          <text>Well done!</text>
1220        </feedback>
1221      </answer>
1222      <answer fraction="0" format="plain_text">
1223        <text>*</text>
1224        <feedback format="html">
1225          <text>Doh!</text>
1226        </feedback>
1227      </answer>
1228      <hint format="html">
1229        <text>Hint 1</text>
1230      </hint>
1231      <hint format="html">
1232        <text>Hint 2</text>
1233      </hint>
1234    </question>
1235  ';
1236  
1237          $this->assert_same_xml($expectedxml, $xml);
1238      }
1239  
1240      public function test_import_truefalse_19() {
1241          $xml = '  <question type="truefalse">
1242      <name>
1243        <text>True false question</text>
1244      </name>
1245      <questiontext format="html">
1246        <text>The answer is true.</text>
1247      </questiontext>
1248      <generalfeedback>
1249        <text>General feedback: You should have chosen true.</text>
1250      </generalfeedback>
1251      <defaultgrade>1</defaultgrade>
1252      <penalty>1</penalty>
1253      <hidden>0</hidden>
1254      <answer fraction="100">
1255        <text>true</text>
1256        <feedback>
1257          <text>Well done!</text>
1258        </feedback>
1259      </answer>
1260      <answer fraction="0">
1261        <text>false</text>
1262        <feedback>
1263          <text>Doh!</text>
1264        </feedback>
1265      </answer>
1266    </question>';
1267          $xmldata = xmlize($xml);
1268  
1269          $importer = new qformat_xml();
1270          $q = $importer->import_truefalse($xmldata['question']);
1271  
1272          $expectedq = new stdClass();
1273          $expectedq->qtype = 'truefalse';
1274          $expectedq->name = 'True false question';
1275          $expectedq->questiontext = 'The answer is true.';
1276          $expectedq->questiontextformat = FORMAT_HTML;
1277          $expectedq->generalfeedback = 'General feedback: You should have chosen true.';
1278          $expectedq->defaultmark = 1;
1279          $expectedq->length = 1;
1280          $expectedq->penalty = 1;
1281  
1282          $expectedq->feedbacktrue = array('text' => 'Well done!',
1283                  'format' => FORMAT_HTML);
1284          $expectedq->feedbackfalse = array('text' => 'Doh!',
1285                  'format' => FORMAT_HTML);
1286          $expectedq->correctanswer = true;
1287  
1288          $this->assert(new question_check_specified_fields_expectation($expectedq), $q);
1289      }
1290  
1291      public function test_export_truefalse() {
1292          $qdata = new stdClass();
1293          $qdata->id = 12;
1294          $qdata->contextid = 0;
1295          $qdata->qtype = 'truefalse';
1296          $qdata->name = 'True false question';
1297          $qdata->questiontext = 'The answer is true.';
1298          $qdata->questiontextformat = FORMAT_HTML;
1299          $qdata->generalfeedback = 'General feedback: You should have chosen true.';
1300          $qdata->generalfeedbackformat = FORMAT_HTML;
1301          $qdata->defaultmark = 1;
1302          $qdata->length = 1;
1303          $qdata->penalty = 1;
1304          $qdata->hidden = 0;
1305  
1306          $qdata->options = new stdClass();
1307          $qdata->options->answers = array(
1308              1 => new question_answer(1, 'True', 1, 'Well done!', FORMAT_HTML),
1309              2 => new question_answer(2, 'False', 0, 'Doh!', FORMAT_HTML),
1310          );
1311          $qdata->options->trueanswer = 1;
1312          $qdata->options->falseanswer = 2;
1313  
1314          $exporter = new qformat_xml();
1315          $xml = $exporter->writequestion($qdata);
1316  
1317          $expectedxml = '<!-- question: 12  -->
1318    <question type="truefalse">
1319      <name>
1320        <text>True false question</text>
1321      </name>
1322      <questiontext format="html">
1323        <text>The answer is true.</text>
1324      </questiontext>
1325      <generalfeedback format="html">
1326        <text>General feedback: You should have chosen true.</text>
1327      </generalfeedback>
1328      <defaultgrade>1</defaultgrade>
1329      <penalty>1</penalty>
1330      <hidden>0</hidden>
1331      <answer fraction="100" format="plain_text">
1332        <text>true</text>
1333        <feedback format="html">
1334          <text>Well done!</text>
1335        </feedback>
1336      </answer>
1337      <answer fraction="0" format="plain_text">
1338        <text>false</text>
1339        <feedback format="html">
1340          <text>Doh!</text>
1341        </feedback>
1342      </answer>
1343    </question>
1344  ';
1345  
1346          $this->assert_same_xml($expectedxml, $xml);
1347      }
1348  
1349      public function test_import_multianswer() {
1350          $xml = '  <question type="cloze">
1351      <name>
1352        <text>Simple multianswer</text>
1353      </name>
1354      <questiontext format="html">
1355        <text><![CDATA[Complete this opening line of verse: "The {1:SHORTANSWER:Dog#Wrong, silly!~=Owl#Well done!~*#Wrong answer} and the {1:MULTICHOICE:Bow-wow#You seem to have a dog obsessions!~Wiggly worm#Now you are just being ridiculous!~=Pussy-cat#Well done!} went to sea".]]></text>
1356      </questiontext>
1357      <generalfeedback format="html">
1358        <text><![CDATA[General feedback: It\'s from "The Owl and the Pussy-cat" by Lear: "The owl and the pussycat went to sea".]]></text>
1359      </generalfeedback>
1360      <penalty>0.5</penalty>
1361      <hidden>0</hidden>
1362      <hint format="html">
1363        <text>Hint 1</text>
1364      </hint>
1365      <hint format="html">
1366        <text>Hint 2</text>
1367      </hint>
1368      <tags>
1369        <tag><text>tagCloze</text></tag>
1370        <tag><text>tagTest</text></tag>
1371      </tags>
1372    </question>
1373  ';
1374          $xmldata = xmlize($xml);
1375  
1376          $importer = new qformat_xml();
1377          $q = $importer->import_multianswer($xmldata['question']);
1378  
1379          // Annoyingly, import works in a weird way (it duplicates code, rather
1380          // than just calling save_question) so we cannot use
1381          // test_question_maker::get_question_form_data('multianswer', 'twosubq').
1382          $expectedqa = new stdClass();
1383          $expectedqa->name = 'Simple multianswer';
1384          $expectedqa->qtype = 'multianswer';
1385          $expectedqa->questiontext = 'Complete this opening line of verse: "The {#1} and the {#2} went to sea".';
1386          $expectedqa->generalfeedback =
1387                  'General feedback: It\'s from "The Owl and the Pussy-cat" by Lear: "The owl and the pussycat went to sea".';
1388          $expectedqa->defaultmark = 2;
1389          $expectedqa->penalty = 0.5;
1390  
1391          $expectedqa->hint = array(
1392              array('text' => 'Hint 1', 'format' => FORMAT_HTML),
1393              array('text' => 'Hint 2', 'format' => FORMAT_HTML),
1394          );
1395  
1396          $sa = new stdClass();
1397  
1398          $sa->questiontext = array('text' => '{1:SHORTANSWER:Dog#Wrong, silly!~=Owl#Well done!~*#Wrong answer}',
1399                  'format' => FORMAT_HTML, 'itemid' => null);
1400          $sa->generalfeedback = array('text' => '', 'format' => FORMAT_HTML, 'itemid' => null);
1401          $sa->defaultmark = 1.0;
1402          $sa->qtype = 'shortanswer';
1403          $sa->usecase = 0;
1404  
1405          $sa->answer = array('Dog', 'Owl', '*');
1406          $sa->fraction = array(0, 1, 0);
1407          $sa->feedback = array(
1408              array('text' => 'Wrong, silly!', 'format' => FORMAT_HTML, 'itemid' => null),
1409              array('text' => 'Well done!',    'format' => FORMAT_HTML, 'itemid' => null),
1410              array('text' => 'Wrong answer',  'format' => FORMAT_HTML, 'itemid' => null),
1411          );
1412  
1413          $mc = new stdClass();
1414  
1415          $mc->generalfeedback = '';
1416          $mc->questiontext = array('text' => '{1:MULTICHOICE:Bow-wow#You seem to have a dog obsessions!~' .
1417                  'Wiggly worm#Now you are just being ridiculous!~=Pussy-cat#Well done!}',
1418                  'format' => FORMAT_HTML, 'itemid' => null);
1419          $mc->generalfeedback = array('text' => '', 'format' => FORMAT_HTML, 'itemid' => null);
1420          $mc->defaultmark = 1.0;
1421          $mc->qtype = 'multichoice';
1422  
1423          $mc->layout = 0;
1424          $mc->single = 1;
1425          $mc->shuffleanswers = 0;
1426          $mc->correctfeedback =          array('text' => '', 'format' => FORMAT_HTML, 'itemid' => null);
1427          $mc->partiallycorrectfeedback = array('text' => '', 'format' => FORMAT_HTML, 'itemid' => null);
1428          $mc->incorrectfeedback =        array('text' => '', 'format' => FORMAT_HTML, 'itemid' => null);
1429          $mc->answernumbering = 0;
1430  
1431          $mc->answer = array(
1432              array('text' => 'Bow-wow',     'format' => FORMAT_HTML, 'itemid' => null),
1433              array('text' => 'Wiggly worm', 'format' => FORMAT_HTML, 'itemid' => null),
1434              array('text' => 'Pussy-cat',   'format' => FORMAT_HTML, 'itemid' => null),
1435          );
1436          $mc->fraction = array(0, 0, 1);
1437          $mc->feedback = array(
1438              array('text' => 'You seem to have a dog obsessions!', 'format' => FORMAT_HTML, 'itemid' => null),
1439              array('text' => 'Now you are just being ridiculous!', 'format' => FORMAT_HTML, 'itemid' => null),
1440              array('text' => 'Well done!',                         'format' => FORMAT_HTML, 'itemid' => null),
1441          );
1442  
1443          $expectedqa->options = new stdClass();
1444          $expectedqa->options->questions = array(
1445              1 => $sa,
1446              2 => $mc,
1447          );
1448          $expectedqa->tags = array('tagCloze', 'tagTest');
1449  
1450          $this->assertEquals($expectedqa->hint, $q->hint);
1451          $this->assertEquals($expectedqa->options->questions[1], $q->options->questions[1]);
1452          $this->assertEquals($expectedqa->options->questions[2], $q->options->questions[2]);
1453          $this->assert(new question_check_specified_fields_expectation($expectedqa), $q);
1454      }
1455  
1456      public function test_export_multianswer() {
1457          $qdata = test_question_maker::get_question_data('multianswer', 'twosubq');
1458  
1459          $exporter = new qformat_xml();
1460          $xml = $exporter->writequestion($qdata);
1461  
1462          $expectedxml = '<!-- question: 0  -->
1463    <question type="cloze">
1464      <name>
1465        <text>Simple multianswer</text>
1466      </name>
1467      <questiontext format="html">
1468        <text><![CDATA[Complete this opening line of verse: "The {1:SHORTANSWER:Dog#Wrong, silly!~=Owl#Well done!~*#Wrong answer} and the {1:MULTICHOICE:Bow-wow#You seem to have a dog obsessions!~Wiggly worm#Now you are just being ridiculous!~=Pussy-cat#Well done!} went to sea".]]></text>
1469      </questiontext>
1470      <generalfeedback format="html">
1471        <text><![CDATA[General feedback: It\'s from "The Owl and the Pussy-cat" by Lear: "The owl and the pussycat went to sea]]></text>
1472      </generalfeedback>
1473      <penalty>0.3333333</penalty>
1474      <hidden>0</hidden>
1475      <hint format="html">
1476        <text>Hint 1</text>
1477      </hint>
1478      <hint format="html">
1479        <text>Hint 2</text>
1480      </hint>
1481    </question>
1482  ';
1483  
1484          $this->assert_same_xml($expectedxml, $xml);
1485      }
1486  
1487      public function test_export_multianswer_withdollars() {
1488          $qdata = test_question_maker::get_question_data('multianswer', 'dollarsigns');
1489  
1490          $exporter = new qformat_xml();
1491          $xml = $exporter->writequestion($qdata);
1492  
1493          $expectedxml = '<!-- question: 0  -->
1494    <question type="cloze">
1495      <name>
1496        <text>Multianswer with $s</text>
1497      </name>
1498      <questiontext format="html">
1499        <text>Which is the right order? {1:MULTICHOICE:=y,y,$3~$3,y,y}</text>
1500      </questiontext>
1501      <generalfeedback format="html">
1502        <text></text>
1503      </generalfeedback>
1504      <penalty>0.3333333</penalty>
1505      <hidden>0</hidden>
1506    </question>
1507  ';
1508  
1509          $this->assert_same_xml($expectedxml, $xml);
1510      }
1511  
1512      public function test_import_files_as_draft() {
1513          $this->resetAfterTest();
1514          $this->setAdminUser();
1515  
1516          $xml = <<<END
1517  <questiontext format="html">
1518      <text><![CDATA[<p><a href="@@PLUGINFILE@@/moodle.txt">This text file</a> contains the word 'Moodle'.</p>]]></text>
1519      <file name="moodle.txt" encoding="base64">TW9vZGxl</file>
1520  </questiontext>
1521  END;
1522  
1523          $textxml = xmlize($xml);
1524          $qo = new stdClass();
1525  
1526          $importer = new qformat_xml();
1527          $draftitemid = $importer->import_files_as_draft($textxml['questiontext']['#']['file']);
1528          $files = file_get_drafarea_files($draftitemid);
1529  
1530          $this->assertEquals(1, count($files->list));
1531  
1532          $file = $files->list[0];
1533          $this->assertEquals('moodle.txt', $file->filename);
1534          $this->assertEquals('/',          $file->filepath);
1535          $this->assertEquals(6,            $file->size);
1536      }
1537  
1538      public function test_import_truefalse_wih_files() {
1539          $this->resetAfterTest();
1540          $this->setAdminUser();
1541  
1542          $xml = '<question type="truefalse">
1543      <name>
1544        <text>truefalse</text>
1545      </name>
1546      <questiontext format="html">
1547        <text><![CDATA[<p><a href="@@PLUGINFILE@@/myfolder/moodle.txt">This text file</a> contains the word Moodle.</p>]]></text>
1548  <file name="moodle.txt" path="/myfolder/" encoding="base64">TW9vZGxl</file>
1549      </questiontext>
1550      <generalfeedback format="html">
1551        <text><![CDATA[<p>For further information, see the documentation about Moodle.</p>]]></text>
1552  </generalfeedback>
1553      <defaultgrade>1.0000000</defaultgrade>
1554      <penalty>1.0000000</penalty>
1555      <hidden>0</hidden>
1556      <answer fraction="100" format="moodle_auto_format">
1557        <text>true</text>
1558        <feedback format="html">
1559          <text></text>
1560        </feedback>
1561      </answer>
1562      <answer fraction="0" format="moodle_auto_format">
1563        <text>false</text>
1564        <feedback format="html">
1565          <text></text>
1566        </feedback>
1567      </answer>
1568    </question>';
1569          $xmldata = xmlize($xml);
1570  
1571          $importer = new qformat_xml();
1572          $q = $importer->import_truefalse($xmldata['question']);
1573  
1574          $draftitemid = $q->questiontextitemid;
1575          $files = file_get_drafarea_files($draftitemid, '/myfolder/');
1576  
1577          $this->assertEquals(1, count($files->list));
1578  
1579          $file = $files->list[0];
1580          $this->assertEquals('moodle.txt', $file->filename);
1581          $this->assertEquals('/myfolder/', $file->filepath);
1582          $this->assertEquals(6,            $file->size);
1583      }
1584  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1