Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 3.9.x will end* 10 May 2021 (12 months).
  • Bug fixes for security issues in 3.9.x will end* 8 May 2023 (36 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

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

   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   * This file contains tests that walks a question through the interactive
  19   * behaviour.
  20   *
  21   * @package   qtype_match
  22   * @copyright 2010 The Open University
  23   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  
  27  defined('MOODLE_INTERNAL') || die();
  28  
  29  global $CFG;
  30  require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
  31  
  32  
  33  /**
  34   * Unit tests for the matching question type.
  35   *
  36   * @copyright 2010 The Open University
  37   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  38   */
  39  class qtype_match_walkthrough_test extends qbehaviour_walkthrough_test_base {
  40  
  41      public function test_deferred_feedback_unanswered() {
  42  
  43          // Create a matching question.
  44          $m = test_question_maker::make_question('match');
  45          $m->shufflestems = false;
  46          $this->start_attempt_at_question($m, 'deferredfeedback', 4);
  47  
  48          $choiceorder = $m->get_choice_order();
  49          $orderforchoice = array_combine(array_values($choiceorder), array_keys($choiceorder));
  50          $choices = array(0 => get_string('choose') . '...');
  51          foreach ($choiceorder as $key => $choice) {
  52              $choices[$key] = $m->choices[$choice];
  53          }
  54  
  55          // Check the initial state.
  56          $this->check_current_state(question_state::$todo);
  57          $this->check_current_mark(null);
  58          $this->check_current_output(
  59                  $this->get_contains_question_text_expectation($m),
  60                  $this->get_does_not_contain_feedback_expectation());
  61          $this->check_output_contains_selectoptions(
  62                  $this->get_contains_select_expectation('sub0', $choices, null, true),
  63                  $this->get_contains_select_expectation('sub1', $choices, null, true),
  64                  $this->get_contains_select_expectation('sub2', $choices, null, true),
  65                  $this->get_contains_select_expectation('sub3', $choices, null, true));
  66          $this->check_step_count(1);
  67  
  68          // Save a blank response.
  69          $this->process_submission(array('sub0' => '0', 'sub1' => '0',
  70                  'sub2' => '0', 'sub3' => '0'));
  71  
  72          // Verify.
  73          $this->check_current_state(question_state::$todo);
  74          $this->check_current_mark(null);
  75          $this->check_current_output(
  76                  $this->get_contains_question_text_expectation($m),
  77                  $this->get_does_not_contain_feedback_expectation());
  78          $this->check_output_contains_selectoptions(
  79                  $this->get_contains_select_expectation('sub0', $choices, null, true),
  80                  $this->get_contains_select_expectation('sub1', $choices, null, true),
  81                  $this->get_contains_select_expectation('sub2', $choices, null, true),
  82                  $this->get_contains_select_expectation('sub3', $choices, null, true));
  83          $this->check_step_count(1);
  84  
  85          // Finish the attempt.
  86          $this->quba->finish_all_questions();
  87  
  88          // Verify.
  89          $this->check_current_state(question_state::$gaveup);
  90          $this->check_current_mark(null);
  91          $this->check_output_contains_selectoptions(
  92                  $this->get_contains_select_expectation('sub0', $choices, null, false),
  93                  $this->get_contains_select_expectation('sub1', $choices, null, false),
  94                  $this->get_contains_select_expectation('sub2', $choices, null, false),
  95                  $this->get_contains_select_expectation('sub3', $choices, null, false));
  96      }
  97  
  98      public function test_deferred_feedback_partial_answer() {
  99  
 100          // Create a matching question.
 101          $m = test_question_maker::make_question('match');
 102          $m->shufflestems = false;
 103          $this->start_attempt_at_question($m, 'deferredfeedback', 4);
 104  
 105          $choiceorder = $m->get_choice_order();
 106          $orderforchoice = array_combine(array_values($choiceorder), array_keys($choiceorder));
 107          $choices = array(0 => get_string('choose') . '...');
 108          foreach ($choiceorder as $key => $choice) {
 109              $choices[$key] = $m->choices[$choice];
 110          }
 111  
 112          // Check the initial state.
 113          $this->check_current_state(question_state::$todo);
 114          $this->check_current_mark(null);
 115          $this->check_current_output(
 116                  $this->get_contains_question_text_expectation($m),
 117                  $this->get_does_not_contain_feedback_expectation());
 118          $this->check_output_contains_selectoptions(
 119                  $this->get_contains_select_expectation('sub0', $choices, null, true),
 120                  $this->get_contains_select_expectation('sub1', $choices, null, true),
 121                  $this->get_contains_select_expectation('sub2', $choices, null, true),
 122                  $this->get_contains_select_expectation('sub3', $choices, null, true));
 123  
 124          // Save a partial response.
 125          $this->process_submission(array('sub0' => $orderforchoice[1],
 126                  'sub1' => $orderforchoice[2], 'sub2' => '0', 'sub3' => '0'));
 127  
 128          // Verify.
 129          $this->check_current_state(question_state::$invalid);
 130          $this->check_current_mark(null);
 131          $this->check_current_output(
 132                  $this->get_contains_question_text_expectation($m),
 133                  $this->get_does_not_contain_feedback_expectation());
 134          $this->check_output_contains_selectoptions(
 135                  $this->get_contains_select_expectation('sub0', $choices, $orderforchoice[1], true),
 136                  $this->get_contains_select_expectation('sub1', $choices, $orderforchoice[2], true),
 137                  $this->get_contains_select_expectation('sub2', $choices, null, true),
 138                  $this->get_contains_select_expectation('sub3', $choices, null, true));
 139  
 140          // Finish the attempt.
 141          $this->quba->finish_all_questions();
 142  
 143          // Verify.
 144          $this->check_current_state(question_state::$gradedpartial);
 145          $this->check_current_mark(2);
 146          $this->check_current_output(
 147                  $this->get_contains_partcorrect_expectation());
 148          $this->check_output_contains_selectoptions(
 149                  $this->get_contains_select_expectation('sub0', $choices, $orderforchoice[1], false),
 150                  $this->get_contains_select_expectation('sub1', $choices, $orderforchoice[2], false),
 151                  $this->get_contains_select_expectation('sub2', $choices, null, false),
 152                  $this->get_contains_select_expectation('sub3', $choices, null, false));
 153      }
 154  
 155      public function test_interactive_correct_no_submit() {
 156  
 157          // Create a matching question.
 158          $m = test_question_maker::make_question('match');
 159          $m->hints = array(
 160              new question_hint_with_parts(11, 'This is the first hint.', FORMAT_HTML, false, false),
 161              new question_hint_with_parts(12, 'This is the second hint.', FORMAT_HTML, true, true),
 162          );
 163          $m->shufflestems = false;
 164          $this->start_attempt_at_question($m, 'interactive', 4);
 165  
 166          $choiceorder = $m->get_choice_order();
 167          $orderforchoice = array_combine(array_values($choiceorder), array_keys($choiceorder));
 168          $choices = array(0 => get_string('choose') . '...');
 169          foreach ($choiceorder as $key => $choice) {
 170              $choices[$key] = $m->choices[$choice];
 171          }
 172  
 173          // Check the initial state.
 174          $this->check_current_state(question_state::$todo);
 175          $this->check_current_mark(null);
 176          $this->check_current_output(
 177                  $this->get_contains_submit_button_expectation(true),
 178                  $this->get_does_not_contain_feedback_expectation(),
 179                  $this->get_tries_remaining_expectation(3),
 180                  $this->get_no_hint_visible_expectation());
 181          $this->check_output_contains_selectoptions(
 182                  $this->get_contains_select_expectation('sub0', $choices, null, true),
 183                  $this->get_contains_select_expectation('sub1', $choices, null, true),
 184                  $this->get_contains_select_expectation('sub2', $choices, null, true),
 185                  $this->get_contains_select_expectation('sub3', $choices, null, true));
 186  
 187          // Save the right answer.
 188          $this->process_submission(array('sub0' => $orderforchoice[1],
 189                  'sub1' => $orderforchoice[2], 'sub2' => $orderforchoice[2],
 190                  'sub3' => $orderforchoice[1]));
 191  
 192          // Finish the attempt without clicking check.
 193          $this->quba->finish_all_questions();
 194  
 195          // Verify.
 196          $this->check_current_state(question_state::$gradedright);
 197          $this->check_current_mark(4);
 198          $this->check_current_output(
 199                  $this->get_does_not_contain_submit_button_expectation(),
 200                  $this->get_contains_correct_expectation(),
 201                  $this->get_no_hint_visible_expectation());
 202          $this->check_output_contains_selectoptions(
 203                  $this->get_contains_select_expectation('sub0', $choices, $orderforchoice[1], false),
 204                  $this->get_contains_select_expectation('sub1', $choices, $orderforchoice[2], false),
 205                  $this->get_contains_select_expectation('sub2', $choices, $orderforchoice[2], false),
 206                  $this->get_contains_select_expectation('sub3', $choices, $orderforchoice[1], false));
 207      }
 208  
 209      public function test_interactive_partial_no_submit() {
 210  
 211          // Create a matching question.
 212          $m = test_question_maker::make_question('match');
 213          $m->hints = array(
 214              new question_hint_with_parts(11, 'This is the first hint.', FORMAT_HTML, false, false),
 215              new question_hint_with_parts(12, 'This is the second hint.', FORMAT_HTML, true, true),
 216          );
 217          $m->shufflestems = false;
 218          $this->start_attempt_at_question($m, 'interactive', 4);
 219  
 220          $choiceorder = $m->get_choice_order();
 221          $orderforchoice = array_combine(array_values($choiceorder), array_keys($choiceorder));
 222          $choices = array(0 => get_string('choose') . '...');
 223          foreach ($choiceorder as $key => $choice) {
 224              $choices[$key] = $m->choices[$choice];
 225          }
 226  
 227          // Check the initial state.
 228          $this->check_current_state(question_state::$todo);
 229          $this->check_current_mark(null);
 230          $this->check_current_output(
 231                  $this->get_contains_submit_button_expectation(true),
 232                  $this->get_does_not_contain_feedback_expectation(),
 233                  $this->get_tries_remaining_expectation(3),
 234                  $this->get_no_hint_visible_expectation());
 235          $this->check_output_contains_selectoptions(
 236                  $this->get_contains_select_expectation('sub0', $choices, null, true),
 237                  $this->get_contains_select_expectation('sub1', $choices, null, true),
 238                  $this->get_contains_select_expectation('sub2', $choices, null, true),
 239                  $this->get_contains_select_expectation('sub3', $choices, null, true));
 240  
 241          // Save the right answer.
 242          $this->process_submission(array('sub0' => $orderforchoice[1],
 243                  'sub1' => $orderforchoice[2], 'sub2' => $orderforchoice[1],
 244                  'sub3' => '0'));
 245  
 246          // Finish the attempt without clicking check.
 247          $this->quba->finish_all_questions();
 248  
 249          // Verify.
 250          $this->check_current_state(question_state::$gradedpartial);
 251          $this->check_current_mark(2);
 252          $this->check_current_output(
 253                  $this->get_does_not_contain_submit_button_expectation(),
 254                  $this->get_contains_partcorrect_expectation(),
 255                  $this->get_no_hint_visible_expectation());
 256          $this->check_output_contains_selectoptions(
 257                  $this->get_contains_select_expectation('sub0', $choices, $orderforchoice[1], false),
 258                  $this->get_contains_select_expectation('sub1', $choices, $orderforchoice[2], false),
 259                  $this->get_contains_select_expectation('sub2', $choices, $orderforchoice[1], false),
 260                  $this->get_contains_select_expectation('sub3', $choices, null, false));
 261      }
 262  
 263      public function test_interactive_with_invalid() {
 264  
 265          // Create a matching question.
 266          $m = test_question_maker::make_question('match');
 267          $m->hints = array(
 268              new question_hint_with_parts(11, 'This is the first hint.', FORMAT_HTML, false, false),
 269              new question_hint_with_parts(12, 'This is the second hint.', FORMAT_HTML, true, true),
 270          );
 271          $m->shufflestems = false;
 272          $this->start_attempt_at_question($m, 'interactive', 4);
 273  
 274          $choiceorder = $m->get_choice_order();
 275          $orderforchoice = array_combine(array_values($choiceorder), array_keys($choiceorder));
 276          $choices = array(0 => get_string('choose') . '...');
 277          foreach ($choiceorder as $key => $choice) {
 278              $choices[$key] = $m->choices[$choice];
 279          }
 280  
 281          // Check the initial state.
 282          $this->check_current_state(question_state::$todo);
 283          $this->check_current_mark(null);
 284          $this->check_current_output(
 285                  $this->get_contains_submit_button_expectation(true),
 286                  $this->get_does_not_contain_feedback_expectation(),
 287                  $this->get_tries_remaining_expectation(3),
 288                  $this->get_no_hint_visible_expectation());
 289          $this->check_output_contains_selectoptions(
 290                  $this->get_contains_select_expectation('sub0', $choices, null, true),
 291                  $this->get_contains_select_expectation('sub1', $choices, null, true),
 292                  $this->get_contains_select_expectation('sub2', $choices, null, true),
 293                  $this->get_contains_select_expectation('sub3', $choices, null, true));
 294  
 295          // Try to submit an invalid answer.
 296          $this->process_submission(array('sub0' => '0',
 297                  'sub1' => '0', 'sub2' => '0',
 298                  'sub3' => '0', '-submit' => '1'));
 299  
 300          // Verify.
 301          $this->check_current_state(question_state::$invalid);
 302          $this->check_current_mark(null);
 303          $this->check_current_output(
 304                  $this->get_contains_submit_button_expectation(true),
 305                  $this->get_does_not_contain_feedback_expectation(),
 306                  $this->get_invalid_answer_expectation(),
 307                  $this->get_no_hint_visible_expectation());
 308          $this->check_output_contains_selectoptions(
 309                  $this->get_contains_select_expectation('sub0', $choices, null, true),
 310                  $this->get_contains_select_expectation('sub1', $choices, null, true),
 311                  $this->get_contains_select_expectation('sub2', $choices, null, true),
 312                  $this->get_contains_select_expectation('sub3', $choices, null, true));
 313  
 314          // Now submit the right answer.
 315          $this->process_submission(array('sub0' => $orderforchoice[1],
 316                  'sub1' => $orderforchoice[2], 'sub2' => $orderforchoice[2],
 317                  'sub3' => $orderforchoice[1], '-submit' => '1'));
 318  
 319          // Verify.
 320          $this->check_current_state(question_state::$gradedright);
 321          $this->check_current_mark(4);
 322          $this->check_current_output(
 323                  $this->get_does_not_contain_submit_button_expectation(),
 324                  $this->get_contains_correct_expectation(),
 325                  $this->get_no_hint_visible_expectation());
 326          $this->check_output_contains_selectoptions(
 327                  $this->get_contains_select_expectation('sub0', $choices, $orderforchoice[1], false),
 328                  $this->get_contains_select_expectation('sub1', $choices, $orderforchoice[2], false),
 329                  $this->get_contains_select_expectation('sub2', $choices, $orderforchoice[2], false),
 330                  $this->get_contains_select_expectation('sub3', $choices, $orderforchoice[1], false));
 331      }
 332  
 333      public function test_match_with_tricky_html_choices() {
 334  
 335          // Create a matching question.
 336          $m = test_question_maker::make_question('match');
 337          $m->stems = array(
 338              1 => '(1, 2]',
 339              2 => '[1, 2]',
 340              3 => '[1, 2)',
 341          );
 342          $m->choices = array(
 343              1 => '1 < x ≤ 2',
 344              2 => '1 ≤ x ≤ 2',
 345              3 => '1 ≤ x < 2',
 346          );
 347          $m->right = array(1 => 1, 2 => 2, 3 => 3);
 348          $m->shufflestems = false;
 349          $this->start_attempt_at_question($m, 'deferredfeedback', 3);
 350  
 351          $choiceorder = $m->get_choice_order();
 352          $orderforchoice = array_combine(array_values($choiceorder), array_keys($choiceorder));
 353          $choices = array(0 => get_string('choose') . '...');
 354          foreach ($choiceorder as $key => $choice) {
 355              $choices[$key] = $m->choices[$choice];
 356          }
 357  
 358          // Check the initial state.
 359          $this->check_current_state(question_state::$todo);
 360          $this->check_current_mark(null);
 361          // Do not use check_output_contains_selectoptions as there are multibyte characters ('1 ≤ x ≤ 2') that
 362          // seem to be read as ascii ('1 ≤ x ≤ 2') in this test.
 363          $this->check_current_output(
 364                  $this->get_contains_select_expectation('sub0', $choices, null, true),
 365                  $this->get_contains_select_expectation('sub1', $choices, null, true),
 366                  $this->get_contains_select_expectation('sub2', $choices, null, true),
 367                  $this->get_contains_question_text_expectation($m),
 368                  $this->get_does_not_contain_feedback_expectation());
 369          $this->check_step_count(1);
 370  
 371          $rightresponse = array('sub0' => $orderforchoice[1],
 372                  'sub1' => $orderforchoice[2], 'sub2' => $orderforchoice[3]);
 373          $rightresponsesummary =
 374                  '(1, 2] -> 1 < x ≤ 2; [1, 2] -> 1 ≤ x ≤ 2; [1, 2) -> 1 ≤ x < 2';
 375  
 376          $this->process_submission($rightresponse);
 377          $this->finish();
 378  
 379          $this->assertEquals($rightresponsesummary, $m->summarise_response($rightresponse));
 380  
 381          $this->displayoptions->history = 1;
 382          $this->check_current_output(
 383                  new question_pattern_expectation('/' .
 384                          preg_quote(htmlspecialchars($rightresponsesummary), '/') . '/'));
 385      }
 386  
 387      public function test_match_clear_wrong() {
 388  
 389          // Create a matching question.
 390          $m = test_question_maker::make_question('match');
 391          $m->hints = array(
 392              new question_hint_with_parts(11, 'This is the first hint.', FORMAT_HTML, false, true),
 393              new question_hint_with_parts(12, 'This is the second hint.', FORMAT_HTML, true, true),
 394          );
 395          $m->shufflestems = false;
 396          $this->start_attempt_at_question($m, 'interactive', 4);
 397  
 398          $choiceorder = $m->get_choice_order();
 399          $orderforchoice = array_combine(array_values($choiceorder), array_keys($choiceorder));
 400          $choices = array(0 => get_string('choose') . '...');
 401          foreach ($choiceorder as $key => $choice) {
 402              $choices[$key] = $m->choices[$choice];
 403          }
 404  
 405          // Check the initial state.
 406          $this->check_current_state(question_state::$todo);
 407          $this->check_current_mark(null);
 408          $this->check_current_output(
 409                  $this->get_contains_submit_button_expectation(true),
 410                  $this->get_does_not_contain_feedback_expectation(),
 411                  $this->get_tries_remaining_expectation(3),
 412                  $this->get_no_hint_visible_expectation());
 413          $this->check_output_contains_selectoptions(
 414                  $this->get_contains_select_expectation('sub0', $choices, null, true),
 415                  $this->get_contains_select_expectation('sub1', $choices, null, true),
 416                  $this->get_contains_select_expectation('sub2', $choices, null, true),
 417                  $this->get_contains_select_expectation('sub3', $choices, null, true));
 418  
 419          // Submit a completely wrong response.
 420          $this->process_submission(array('sub0' => $orderforchoice[3],
 421                  'sub1' => $orderforchoice[3], 'sub2' => $orderforchoice[3],
 422                  'sub3' => $orderforchoice[3], '-submit' => 1));
 423  
 424          // Verify.
 425          $this->check_current_state(question_state::$todo);
 426          $this->check_current_mark(null);
 427          $this->check_current_output(
 428                  $this->get_contains_hidden_expectation(
 429                          $this->quba->get_field_prefix($this->slot) . 'sub0', '0'),
 430                  $this->get_contains_hidden_expectation(
 431                          $this->quba->get_field_prefix($this->slot) . 'sub1', '0'),
 432                  $this->get_contains_hidden_expectation(
 433                          $this->quba->get_field_prefix($this->slot) . 'sub2', '0'),
 434                  $this->get_contains_hidden_expectation(
 435                          $this->quba->get_field_prefix($this->slot) . 'sub3', '0'),
 436                  $this->get_does_not_contain_submit_button_expectation(),
 437                  $this->get_contains_hint_expectation('This is the first hint.'));
 438          $this->check_output_contains_selectoptions(
 439                  $this->get_contains_select_expectation('sub0', $choices, $orderforchoice[3], false),
 440                  $this->get_contains_select_expectation('sub1', $choices, $orderforchoice[3], false),
 441                  $this->get_contains_select_expectation('sub2', $choices, $orderforchoice[3], false),
 442                  $this->get_contains_select_expectation('sub3', $choices, $orderforchoice[3], false));
 443  
 444          // Try again.
 445          $this->process_submission(array('sub0' => 0,
 446                  'sub1' => 0, 'sub2' => 0,
 447                  'sub3' => 0, '-tryagain' => 1));
 448  
 449          // Verify.
 450          $this->check_current_state(question_state::$todo);
 451          $this->check_current_mark(null);
 452          $this->check_current_output(
 453                  $this->get_contains_submit_button_expectation(true),
 454                  $this->get_does_not_contain_feedback_expectation(),
 455                  $this->get_tries_remaining_expectation(2),
 456                  $this->get_no_hint_visible_expectation());
 457          $this->check_output_contains_selectoptions(
 458                  $this->get_contains_select_expectation('sub0', $choices, null, true),
 459                  $this->get_contains_select_expectation('sub1', $choices, null, true),
 460                  $this->get_contains_select_expectation('sub2', $choices, null, true),
 461                  $this->get_contains_select_expectation('sub3', $choices, null, true));
 462  
 463          // Submit a partially wrong response.
 464          $this->process_submission(array('sub0' => $orderforchoice[3],
 465                  'sub1' => $orderforchoice[3], 'sub2' => $orderforchoice[2],
 466                  'sub3' => $orderforchoice[1], '-submit' => 1));
 467  
 468          // Verify.
 469          $this->check_current_state(question_state::$todo);
 470          $this->check_current_mark(null);
 471          $this->check_current_output(
 472                  $this->get_contains_hidden_expectation(
 473                          $this->quba->get_field_prefix($this->slot) . 'sub0', '0'),
 474                  $this->get_contains_hidden_expectation(
 475                          $this->quba->get_field_prefix($this->slot) . 'sub1', '0'),
 476                  $this->get_contains_hidden_expectation(
 477                          $this->quba->get_field_prefix($this->slot) . 'sub2', $orderforchoice[2]),
 478                  $this->get_contains_hidden_expectation(
 479                          $this->quba->get_field_prefix($this->slot) . 'sub3', $orderforchoice[1]),
 480                  $this->get_does_not_contain_submit_button_expectation(),
 481                  $this->get_contains_hint_expectation('This is the second hint.'));
 482          $this->check_output_contains_selectoptions(
 483                  $this->get_contains_select_expectation('sub0', $choices, $orderforchoice[3], false),
 484                  $this->get_contains_select_expectation('sub1', $choices, $orderforchoice[3], false),
 485                  $this->get_contains_select_expectation('sub2', $choices, $orderforchoice[2], false),
 486                  $this->get_contains_select_expectation('sub3', $choices, $orderforchoice[1], false));
 487  
 488          // Try again.
 489          $this->process_submission(array('sub0' => 0,
 490                  'sub1' => 0, 'sub2' => $orderforchoice[2],
 491                  'sub3' => $orderforchoice[1], '-tryagain' => 1));
 492  
 493          // Verify.
 494          $this->check_current_state(question_state::$todo);
 495          $this->check_current_mark(null);
 496          $this->check_current_output(
 497                  $this->get_contains_submit_button_expectation(true),
 498                  $this->get_does_not_contain_feedback_expectation(),
 499                  $this->get_tries_remaining_expectation(1),
 500                  $this->get_no_hint_visible_expectation());
 501          $this->check_output_contains_selectoptions(
 502                  $this->get_contains_select_expectation('sub0', $choices, null, true),
 503                  $this->get_contains_select_expectation('sub1', $choices, null, true),
 504                  $this->get_contains_select_expectation('sub2', $choices, $orderforchoice[2], true),
 505                  $this->get_contains_select_expectation('sub3', $choices, $orderforchoice[1], true));
 506  
 507      }
 508  }