[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/question/type/multianswer/tests/ -> walkthrough_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   * This file contains overall tests of multianswer questions.
  19   *
  20   * @package    qtype
  21   * @subpackage multianswer
  22   * @copyright  2011 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 multianswer question type.
  35   *
  36   * @copyright  2011 The Open University
  37   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  38   */
  39  class qtype_multianswer_walkthrough_test extends qbehaviour_walkthrough_test_base {
  40  
  41      protected function get_contains_subq_status(question_state $state) {
  42          return new question_pattern_expectation('~' .
  43                  preg_quote($state->default_string(true), '~') . '<br />~');
  44      }
  45  
  46      public function test_deferred_feedback() {
  47  
  48          // Create a multianswer question.
  49          $q = test_question_maker::make_question('multianswer', 'fourmc');
  50          $this->start_attempt_at_question($q, 'deferredfeedback', 4);
  51  
  52          // Check the initial state.
  53          $this->check_current_state(question_state::$todo);
  54          $this->check_current_mark(null);
  55          $this->check_current_output(
  56                  $this->get_contains_marked_out_of_summary(),
  57                  $this->get_does_not_contain_feedback_expectation(),
  58                  $this->get_does_not_contain_validation_error_expectation());
  59  
  60          // Save in incomplete answer.
  61          $this->process_submission(array('sub1_answer' => '1', 'sub2_answer' => '',
  62                  'sub3_answer' => '', 'sub4_answer' => ''));
  63  
  64          // Verify.
  65          $this->check_current_state(question_state::$invalid);
  66          $this->check_current_mark(null);
  67          $this->check_current_output(
  68                  $this->get_contains_marked_out_of_summary(),
  69                  $this->get_does_not_contain_feedback_expectation(),
  70                  $this->get_contains_validation_error_expectation());
  71  
  72          // Save a partially correct answer.
  73          $this->process_submission(array('sub1_answer' => '1', 'sub2_answer' => '1',
  74                  'sub3_answer' => '1', 'sub4_answer' => '1'));
  75  
  76          // Verify.
  77          $this->check_current_state(question_state::$complete);
  78          $this->check_current_mark(null);
  79          $this->check_current_output(
  80                  $this->get_contains_marked_out_of_summary(),
  81                  $this->get_does_not_contain_feedback_expectation(),
  82                  $this->get_does_not_contain_validation_error_expectation());
  83  
  84          // Now submit all and finish.
  85          $this->finish();
  86  
  87          // Verify.
  88          $this->check_current_state(question_state::$gradedpartial);
  89          $this->check_current_mark(2);
  90          $this->check_current_output(
  91                  $this->get_contains_mark_summary(2),
  92                  $this->get_contains_partcorrect_expectation(),
  93                  $this->get_does_not_contain_validation_error_expectation());
  94      }
  95  
  96      public function test_deferred_feedback_numericalzero_not_answered() {
  97          // Tests the situation found in MDL-35370.
  98  
  99          // Create a multianswer question with one numerical subquestion, right answer zero.
 100          $q = test_question_maker::make_question('multianswer', 'numericalzero');
 101          $this->start_attempt_at_question($q, 'deferredfeedback', 1);
 102  
 103          // Check the initial state.
 104          $this->check_current_state(question_state::$todo);
 105          $this->check_current_mark(null);
 106          $this->check_current_output(
 107                  $this->get_contains_marked_out_of_summary(),
 108                  $this->get_does_not_contain_feedback_expectation(),
 109                  $this->get_does_not_contain_validation_error_expectation());
 110  
 111          // Now submit all and finish.
 112          $this->finish();
 113  
 114          // Verify.
 115          $this->check_current_state(question_state::$gaveup);
 116          $this->check_current_mark(null);
 117          $this->check_current_output(
 118                  $this->get_contains_marked_out_of_summary(),
 119                  new question_pattern_expectation('~<input[^>]* class="incorrect" [^>]*/>~'),
 120                  $this->get_contains_subq_status(question_state::$gaveup),
 121                  $this->get_does_not_contain_validation_error_expectation());
 122      }
 123  
 124      public function test_deferred_feedback_numericalzero_0_answer() {
 125          // Tests the situation found in MDL-35370.
 126  
 127          // Create a multianswer question with one numerical subquestion, right answer zero.
 128          $q = test_question_maker::make_question('multianswer', 'numericalzero');
 129          $this->start_attempt_at_question($q, 'deferredfeedback', 1);
 130  
 131          // Check the initial state.
 132          $this->check_current_state(question_state::$todo);
 133          $this->check_current_mark(null);
 134          $this->check_current_output(
 135                  $this->get_contains_marked_out_of_summary(),
 136                  $this->get_does_not_contain_feedback_expectation(),
 137                  $this->get_does_not_contain_validation_error_expectation());
 138  
 139          // Save a the correct answer.
 140          $this->process_submission(array('sub1_answer' => '0'));
 141  
 142          // Verify.
 143          $this->check_current_state(question_state::$complete);
 144          $this->check_current_mark(null);
 145          $this->check_current_output(
 146                  $this->get_contains_marked_out_of_summary(),
 147                  $this->get_does_not_contain_feedback_expectation(),
 148                  $this->get_does_not_contain_validation_error_expectation());
 149  
 150          // Now submit all and finish.
 151          $this->finish();
 152  
 153          // Verify.
 154          $this->check_current_state(question_state::$gradedright);
 155          $this->check_current_mark(1);
 156          $this->check_current_output(
 157                  $this->get_contains_mark_summary(1),
 158                  $this->get_contains_correct_expectation(),
 159                  $this->get_contains_subq_status(question_state::$gradedright),
 160                  $this->get_does_not_contain_validation_error_expectation());
 161      }
 162  
 163      public function test_deferred_feedback_numericalzero_0_wrong() {
 164          // Tests the situation found in MDL-35370.
 165  
 166          // Create a multianswer question with one numerical subquestion, right answer zero.
 167          $q = test_question_maker::make_question('multianswer', 'numericalzero');
 168          $this->start_attempt_at_question($q, 'deferredfeedback', 1);
 169  
 170          // Check the initial state.
 171          $this->check_current_state(question_state::$todo);
 172          $this->check_current_mark(null);
 173          $this->check_current_output(
 174                  $this->get_contains_marked_out_of_summary(),
 175                  $this->get_does_not_contain_feedback_expectation(),
 176                  $this->get_does_not_contain_validation_error_expectation());
 177  
 178          // Save a the correct answer.
 179          $this->process_submission(array('sub1_answer' => '42'));
 180  
 181          // Verify.
 182          $this->check_current_state(question_state::$complete);
 183          $this->check_current_mark(null);
 184          $this->check_current_output(
 185                  $this->get_contains_marked_out_of_summary(),
 186                  $this->get_does_not_contain_feedback_expectation(),
 187                  $this->get_does_not_contain_validation_error_expectation());
 188  
 189          // Now submit all and finish.
 190          $this->finish();
 191  
 192          // Verify.
 193          $this->check_current_state(question_state::$gradedwrong);
 194          $this->check_current_mark(0);
 195          $this->check_current_output(
 196                  $this->get_contains_mark_summary(0),
 197                  $this->get_contains_incorrect_expectation(),
 198                  $this->get_contains_subq_status(question_state::$gradedwrong),
 199                  $this->get_does_not_contain_validation_error_expectation());
 200      }
 201  
 202      public function test_interactive_feedback() {
 203  
 204          // Create a multianswer question.
 205          $q = test_question_maker::make_question('multianswer', 'fourmc');
 206          $q->hints = array(
 207              new question_hint_with_parts(11, 'This is the first hint.', FORMAT_HTML, false, true),
 208              new question_hint_with_parts(12, 'This is the second hint.', FORMAT_HTML, true, true),
 209          );
 210          $choices = array('' => '', '0' => 'California', '1' => 'Arizona');
 211  
 212          $this->start_attempt_at_question($q, 'interactive', 4);
 213  
 214          // Check the initial state.
 215          $this->check_current_state(question_state::$todo);
 216          $this->check_current_mark(null);
 217          $this->assertEquals('interactivecountback',
 218                  $this->quba->get_question_attempt($this->slot)->get_behaviour_name());
 219          $this->check_current_output(
 220                  $this->get_contains_marked_out_of_summary(),
 221                  $this->get_contains_select_expectation('sub1_answer', $choices, null, true),
 222                  $this->get_contains_select_expectation('sub2_answer', $choices, null, true),
 223                  $this->get_contains_select_expectation('sub3_answer', $choices, null, true),
 224                  $this->get_contains_select_expectation('sub4_answer', $choices, null, true),
 225                  $this->get_contains_submit_button_expectation(true),
 226                  $this->get_does_not_contain_validation_error_expectation(),
 227                  $this->get_does_not_contain_feedback_expectation(),
 228                  $this->get_tries_remaining_expectation(3),
 229                  $this->get_does_not_contain_num_parts_correct(),
 230                  $this->get_no_hint_visible_expectation());
 231  
 232          // Submit a completely wrong response.
 233          $this->process_submission(array('sub1_answer' => '1', 'sub2_answer' => '0',
 234                  'sub3_answer' => '1', 'sub4_answer' => '0', '-submit' => 1));
 235  
 236          // Verify.
 237          $this->check_current_state(question_state::$todo);
 238          $this->check_current_mark(null);
 239          $this->check_current_output(
 240                  $this->get_contains_select_expectation('sub1_answer', $choices, 1, false),
 241                  $this->get_contains_select_expectation('sub2_answer', $choices, 0, false),
 242                  $this->get_contains_select_expectation('sub3_answer', $choices, 1, false),
 243                  $this->get_contains_select_expectation('sub4_answer', $choices, 0, false),
 244                  $this->get_does_not_contain_num_parts_correct(),
 245                  $this->get_contains_hidden_expectation(
 246                          $this->quba->get_field_prefix($this->slot) . 'sub1_answer', ''),
 247                  $this->get_contains_hidden_expectation(
 248                          $this->quba->get_field_prefix($this->slot) . 'sub2_answer', ''),
 249                  $this->get_contains_hidden_expectation(
 250                          $this->quba->get_field_prefix($this->slot) . 'sub3_answer', ''),
 251                  $this->get_contains_hidden_expectation(
 252                          $this->quba->get_field_prefix($this->slot) . 'sub4_answer', ''),
 253                  $this->get_does_not_contain_submit_button_expectation(),
 254                  $this->get_contains_try_again_button_expectation(true),
 255                  $this->get_does_not_contain_correctness_expectation(),
 256                  $this->get_contains_hint_expectation('This is the first hint.'));
 257  
 258          // Check that, if we review in this state, the try again button is disabled.
 259          $displayoptions = new question_display_options();
 260          $displayoptions->readonly = true;
 261          $html = $this->quba->render_question($this->slot, $displayoptions);
 262          $this->assert($this->get_contains_try_again_button_expectation(false), $html);
 263  
 264          // Try again.
 265          $this->process_submission(array('sub1_answer' => '',
 266                  'sub2_answer' => '', 'sub3_answer' => '',
 267                  'sub4_answer' => '', '-tryagain' => 1));
 268  
 269          // Verify.
 270          $this->check_current_state(question_state::$todo);
 271          $this->check_current_mark(null);
 272          $this->check_current_output(
 273                  $this->get_contains_select_expectation('sub1_answer', $choices, null, true),
 274                  $this->get_contains_select_expectation('sub2_answer', $choices, null, true),
 275                  $this->get_contains_select_expectation('sub3_answer', $choices, null, true),
 276                  $this->get_contains_select_expectation('sub4_answer', $choices, null, true),
 277                  $this->get_contains_submit_button_expectation(true),
 278                  $this->get_does_not_contain_feedback_expectation(),
 279                  $this->get_tries_remaining_expectation(2),
 280                  $this->get_no_hint_visible_expectation());
 281  
 282          // Submit a partially wrong response.
 283          $this->process_submission(array('sub1_answer' => '1', 'sub2_answer' => '1',
 284                  'sub3_answer' => '1', 'sub4_answer' => '1', '-submit' => 1));
 285  
 286          // Verify.
 287          $this->check_current_state(question_state::$todo);
 288          $this->check_current_mark(null);
 289          $this->check_current_output(
 290                  $this->get_contains_select_expectation('sub1_answer', $choices, 1, false),
 291                  $this->get_contains_select_expectation('sub2_answer', $choices, 1, false),
 292                  $this->get_contains_select_expectation('sub3_answer', $choices, 1, false),
 293                  $this->get_contains_select_expectation('sub4_answer', $choices, 1, false),
 294                  $this->get_contains_num_parts_correct(2),
 295                  $this->get_contains_hidden_expectation(
 296                          $this->quba->get_field_prefix($this->slot) . 'sub1_answer', ''),
 297                  $this->get_contains_hidden_expectation(
 298                          $this->quba->get_field_prefix($this->slot) . 'sub2_answer', '1'),
 299                  $this->get_contains_hidden_expectation(
 300                          $this->quba->get_field_prefix($this->slot) . 'sub3_answer', ''),
 301                  $this->get_contains_hidden_expectation(
 302                          $this->quba->get_field_prefix($this->slot) . 'sub4_answer', '1'),
 303                  $this->get_does_not_contain_submit_button_expectation(),
 304                  $this->get_contains_hint_expectation('This is the second hint.'));
 305  
 306          // Try again.
 307          $this->process_submission(array('sub1_answer' => '',
 308                  'sub2_answer' => '1', 'sub3_answer' => '',
 309                  'sub4_answer' => '1', '-tryagain' => 1));
 310  
 311          // Verify.
 312          $this->check_current_state(question_state::$todo);
 313          $this->check_current_mark(null);
 314          $this->check_current_output(
 315                  $this->get_contains_select_expectation('sub1_answer', $choices, '', true),
 316                  $this->get_contains_select_expectation('sub2_answer', $choices, '1', true),
 317                  $this->get_contains_select_expectation('sub3_answer', $choices, '', true),
 318                  $this->get_contains_select_expectation('sub4_answer', $choices, '1', true),
 319                  $this->get_contains_submit_button_expectation(true),
 320                  $this->get_does_not_contain_feedback_expectation(),
 321                  $this->get_tries_remaining_expectation(1),
 322                  $this->get_no_hint_visible_expectation());
 323      }
 324  
 325      public function test_interactive_partial_response_does_not_reveal_answer() {
 326  
 327          // Create a multianswer question.
 328          $q = test_question_maker::make_question('multianswer', 'fourmc');
 329          $q->hints = array(
 330                  new question_hint_with_parts(11, 'This is the first hint.', FORMAT_HTML, false, true),
 331                  new question_hint_with_parts(12, 'This is the second hint.', FORMAT_HTML, true, true),
 332          );
 333          $choices = array('' => '', '0' => 'California', '1' => 'Arizona');
 334  
 335          $this->start_attempt_at_question($q, 'interactive', 4);
 336  
 337          // Check the initial state.
 338          $this->check_current_state(question_state::$todo);
 339          $this->check_current_mark(null);
 340          $this->assertEquals('interactivecountback',
 341                  $this->quba->get_question_attempt($this->slot)->get_behaviour_name());
 342          $this->check_current_output(
 343                  $this->get_contains_marked_out_of_summary(),
 344                  $this->get_contains_select_expectation('sub1_answer', $choices, null, true),
 345                  $this->get_contains_select_expectation('sub2_answer', $choices, null, true),
 346                  $this->get_contains_select_expectation('sub3_answer', $choices, null, true),
 347                  $this->get_contains_select_expectation('sub4_answer', $choices, null, true),
 348                  $this->get_contains_submit_button_expectation(true),
 349                  $this->get_does_not_contain_validation_error_expectation(),
 350                  $this->get_does_not_contain_feedback_expectation(),
 351                  $this->get_tries_remaining_expectation(3),
 352                  $this->get_does_not_contain_num_parts_correct(),
 353                  $this->get_no_hint_visible_expectation());
 354  
 355          // Submit an incomplete response response.
 356          $this->process_submission(array('sub1_answer' => '1', 'sub2_answer' => '1', '-submit' => 1));
 357  
 358          // Verify.
 359          $this->check_current_state(question_state::$invalid);
 360          $this->check_current_mark(null);
 361          $this->check_current_output(
 362                  $this->get_contains_select_expectation('sub1_answer', $choices, 1, true),
 363                  $this->get_contains_select_expectation('sub2_answer', $choices, 1, true),
 364                  $this->get_contains_select_expectation('sub3_answer', $choices, null, true),
 365                  $this->get_contains_select_expectation('sub4_answer', $choices, null, true),
 366                  $this->get_does_not_contain_num_parts_correct(),
 367                  $this->get_contains_validation_error_expectation(),
 368                  $this->get_contains_submit_button_expectation(true),
 369                  $this->get_does_not_contain_try_again_button_expectation(),
 370                  $this->get_does_not_contain_correctness_expectation(),
 371                  $this->get_no_hint_visible_expectation());
 372          $this->render();
 373          $a = array('mark' => '0.00', 'max' => '1.00');
 374          $this->assertNotRegExp('~' . preg_quote(get_string('markoutofmax', 'question', $a), '~') . '~',
 375                  $this->currentoutput);
 376          $a['mark'] = '1.00';
 377          $this->assertNotRegExp('~' . preg_quote(get_string('markoutofmax', 'question', $a), '~') . '~',
 378                  $this->currentoutput);
 379      }
 380  
 381      public function test_interactivecountback_feedback() {
 382  
 383          // Create a multianswer question.
 384          $q = test_question_maker::make_question('multianswer', 'fourmc');
 385          $q->hints = array(
 386              new question_hint_with_parts(11, 'This is the first hint.', FORMAT_HTML, true, true),
 387              new question_hint_with_parts(12, 'This is the second hint.', FORMAT_HTML, true, true),
 388          );
 389          $choices = array('' => '', '0' => 'California', '1' => 'Arizona');
 390  
 391          $this->start_attempt_at_question($q, 'interactive', 12);
 392  
 393          // Check the initial state.
 394          $this->check_current_state(question_state::$todo);
 395          $this->check_current_mark(null);
 396          $this->assertEquals('interactivecountback',
 397                  $this->quba->get_question_attempt($this->slot)->get_behaviour_name());
 398          $this->check_current_output(
 399                  $this->get_contains_marked_out_of_summary(),
 400                  $this->get_contains_select_expectation('sub1_answer', $choices, null, true),
 401                  $this->get_contains_select_expectation('sub2_answer', $choices, null, true),
 402                  $this->get_contains_select_expectation('sub3_answer', $choices, null, true),
 403                  $this->get_contains_select_expectation('sub4_answer', $choices, null, true),
 404                  $this->get_contains_submit_button_expectation(true),
 405                  $this->get_does_not_contain_validation_error_expectation(),
 406                  $this->get_does_not_contain_feedback_expectation(),
 407                  $this->get_tries_remaining_expectation(3),
 408                  $this->get_no_hint_visible_expectation());
 409  
 410          // Submit an answer with two right, and two wrong.
 411          $this->process_submission(array('sub1_answer' => '1', 'sub2_answer' => '1',
 412                  'sub3_answer' => '1', 'sub4_answer' => '1', '-submit' => 1));
 413  
 414          // Verify.
 415          $this->check_current_state(question_state::$todo);
 416          $this->check_current_mark(null);
 417          $this->check_current_output(
 418                  $this->get_contains_select_expectation('sub1_answer', $choices, 1, false),
 419                  $this->get_contains_select_expectation('sub2_answer', $choices, 1, false),
 420                  $this->get_contains_select_expectation('sub3_answer', $choices, 1, false),
 421                  $this->get_contains_select_expectation('sub4_answer', $choices, 1, false),
 422                  $this->get_does_not_contain_submit_button_expectation(),
 423                  $this->get_contains_try_again_button_expectation(true),
 424                  $this->get_does_not_contain_correctness_expectation(),
 425                  new question_pattern_expectation('/Tries remaining: 2/'),
 426                  $this->get_contains_hint_expectation('This is the first hint.'));
 427  
 428          // Check that extract responses will return the reset data.
 429          $prefix = $this->quba->get_field_prefix($this->slot);
 430          $this->assertEquals(array('sub1_answer' => 1),
 431                  $this->quba->extract_responses($this->slot, array($prefix . 'sub1_answer' => 1)));
 432  
 433          // Do try again.
 434          $this->process_submission(array('sub1_answer' => '',
 435                  'sub2_answer' => '1', 'sub3_answer' => '',
 436                  'sub4_answer' => '1', '-tryagain' => 1));
 437  
 438          // Verify.
 439          $this->check_current_state(question_state::$todo);
 440          $this->check_current_mark(null);
 441          $this->check_current_output(
 442                  $this->get_contains_select_expectation('sub1_answer', $choices, '', true),
 443                  $this->get_contains_select_expectation('sub2_answer', $choices, '1', true),
 444                  $this->get_contains_select_expectation('sub3_answer', $choices, '', true),
 445                  $this->get_contains_select_expectation('sub4_answer', $choices, '1', true),
 446                  $this->get_contains_submit_button_expectation(true),
 447                  $this->get_does_not_contain_feedback_expectation(),
 448                  $this->get_tries_remaining_expectation(2),
 449                  $this->get_no_hint_visible_expectation());
 450  
 451          // Submit the right answer.
 452          $this->process_submission(array('sub1_answer' => '0', 'sub2_answer' => '1',
 453                  'sub3_answer' => '0', 'sub4_answer' => '1', '-submit' => 1));
 454  
 455          // Verify.
 456          $this->check_current_state(question_state::$gradedright);
 457          $this->check_current_mark(10);
 458          $this->check_current_output(
 459                  $this->get_contains_select_expectation('sub1_answer', $choices, '0', false),
 460                  $this->get_contains_select_expectation('sub2_answer', $choices, '1', false),
 461                  $this->get_contains_select_expectation('sub3_answer', $choices, '0', false),
 462                  $this->get_contains_select_expectation('sub4_answer', $choices, '1', false),
 463                  $this->get_does_not_contain_submit_button_expectation(),
 464                  $this->get_does_not_contain_try_again_button_expectation(),
 465                  $this->get_contains_correct_expectation(),
 466                  new question_no_pattern_expectation('/class="control\b[^"]*\bpartiallycorrect"/'));
 467      }
 468  }


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