A multiple-choice, multiple-response question type with particular scoring rules.
Recommended if your question has more than one correct answer.
'; $string['privacy:metadata'] = 'Multiple response question type plugin allows question authors to set default options as user preferences.'; +$string['privacy:preference:answernumbering'] = 'Which numbering stye should be used (1., 2., 3., .../a., b., c., ... etc.)'; $string['privacy:preference:defaultmark'] = 'The default mark set for a given question.'; $string['privacy:preference:penalty'] = 'The penalty for each incorrect try when questions are run using the \'Interactive with multiple tries\' or \'Adaptive mode\' behaviour.'; -$string['privacy:preference:shuffleanswers'] = 'Whether the answers should be automatically shuffled.'; -$string['privacy:preference:answernumbering'] = 'Which numbering stye should be used (1., 2., 3., .../a., b., c., ... etc.)'; $string['privacy:preference:showstandardinstruction'] = 'Whether showing standard instruction.'; -$string['toomanyoptions'] = 'You have selected too many options.'; +$string['privacy:preference:shuffleanswers'] = 'Whether the answers should be automatically shuffled.'; $string['showeachanswerfeedback'] = 'Show the feedback for the selected responses.'; -$string['yougotnright'] = 'You have correctly selected {$a->num} options.'; -$string['yougot1right'] = 'You have correctly selected one option.'; $string['showstandardinstruction'] = 'Show standard instruction'; $string['showstandardinstruction_help'] = 'With this setting enabled, standard instruction will be supplied as part of the selection area (e.g. "Select one or more:"). If disabled, question authors can instead included instructions in the question content, if required.'; +$string['toomanyoptions'] = 'You have selected too many options.'; +$string['yougot1right'] = 'You have correctly selected one option.'; +$string['yougotnright'] = 'You have correctly selected {$a->num} options.'; diff --git a/lib.php b/lib.php index a9adc7a..bbbdded 100644 --- a/lib.php +++ b/lib.php @@ -25,7 +25,7 @@ /** * Checks file access for oumultiresponse questions. */ -function qtype_oumultiresponse_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options = array()) { +function qtype_oumultiresponse_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options = []) { global $CFG; require_once($CFG->libdir . '/questionlib.php'); question_pluginfile($course, $context, 'qtype_oumultiresponse', $filearea, $args, $forcedownload, $options); diff --git a/question.php b/question.php index e9dc0aa..385dc4d 100644 --- a/question.php +++ b/question.php @@ -52,6 +52,7 @@ public function get_renderer(moodle_page $page) { return $page->get_renderer('qtype_oumultiresponse'); } + #[\Override] public function make_behaviour(question_attempt $qa, $preferredbehaviour) { if ($preferredbehaviour == 'interactive') { return question_engine::make_behaviour( @@ -60,6 +61,7 @@ public function make_behaviour(question_attempt $qa, $preferredbehaviour) { return question_engine::make_archetypal_behaviour($preferredbehaviour, $qa); } + #[\Override] public function classify_response(array $response) { $choices = parent::classify_response($response); $numright = $this->get_num_correct_choices(); @@ -69,6 +71,9 @@ public function classify_response(array $response) { return $choices; } + /** + * Grade the response. + */ public function grade_response(array $response) { list($numright, $total) = $this->get_num_parts_right($response); $numwrong = $this->get_num_selected_choices($response) - $numright; @@ -81,17 +86,21 @@ public function grade_response(array $response) { $state = question_state::$gradedpartial; } - return array($fraction, $state); + return [$fraction, $state]; } + #[\Override] protected function disable_hint_settings_when_too_many_selected( question_hint_with_parts $hint) { parent::disable_hint_settings_when_too_many_selected($hint); $hint->showchoicefeedback = false; } + /** + * Compute the final grade. + */ public function compute_final_grade($responses, $totaltries) { - $responsehistories = array(); + $responsehistories = []; foreach ($this->order as $key => $ansid) { $fieldname = $this->field($key); $responsehistories[$ansid] = ''; @@ -123,7 +132,7 @@ public static function grade_computation($responsehistory, $answers, $penalty, $questionnumtries) { // First we reverse the strings to get the most recent responses to the start, then // distinguish right and wrong by replacing 1 with 2 for right answers. - $workspace = array(); + $workspace = []; $numright = 0; foreach ($responsehistory as $id => $string) { $workspace[$id] = strrev($string); @@ -151,7 +160,7 @@ public static function grade_computation($responsehistory, $answers, } if ($numselected > $numright) { $numtoclear = $numselected - $numright; - $newworkspace = array(); + $newworkspace = []; foreach ($workspace as $string) { if (substr($string, $try, 1) == '2' && $numtoclear > 0) { $string = self::replace_char_at($string, $try, '0'); @@ -183,6 +192,13 @@ public static function grade_computation($responsehistory, $answers, return array_sum($scores); } + /** + * Replace a character at a given position. + * + * @param string $string The string to modify. + * @param int $pos The position of the character to replace (0-based). + * @param string $newchar The new character to insert. + */ public static function replace_char_at($string, $pos, $newchar) { return substr($string, 0, $pos) . $newchar . substr($string, $pos + 1); } diff --git a/questiontype.php b/questiontype.php index 5f76bef..42380ac 100644 --- a/questiontype.php +++ b/questiontype.php @@ -43,21 +43,28 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class qtype_oumultiresponse extends question_type { + + #[\Override] public function has_html_answers() { return true; } + /** + * Get the name of this question type. + */ public function requires_qtypes() { - return array('multichoice'); + return ['multichoice']; } + #[\Override] public function get_question_options($question) { global $DB; $question->options = $DB->get_record('question_oumultiresponse', - array('questionid' => $question->id), '*', MUST_EXIST); + ['questionid' => $question->id], '*', MUST_EXIST); parent::get_question_options($question); } + #[\Override] public function save_defaults_for_new_questions(stdClass $fromform): void { parent::save_defaults_for_new_questions($fromform); $this->set_default_value('shuffleanswers', $fromform->shuffleanswers); @@ -65,13 +72,14 @@ public function save_defaults_for_new_questions(stdClass $fromform): void { $this->set_default_value('showstandardinstruction', $fromform->showstandardinstruction); } + #[\Override] public function save_question_options($question) { global $DB; $context = $question->context; $result = new stdClass(); $oldanswers = $DB->get_records('question_answers', - array('question' => $question->id), 'id ASC'); + ['question' => $question->id], 'id ASC'); // The following hack to checks that at least two answers exist. $answercount = 0; @@ -86,7 +94,7 @@ public function save_question_options($question) { } // Insert all the new answers. - $answers = array(); + $answers = []; foreach ($question->answer as $key => $answerdata) { if (trim($answerdata['text']) == '') { continue; @@ -118,11 +126,11 @@ public function save_question_options($question) { $fs = get_file_storage(); foreach ($oldanswers as $oldanswer) { $fs->delete_area_files($context->id, 'question', 'answerfeedback', $oldanswer->id); - $DB->delete_records('question_answers', array('id' => $oldanswer->id)); + $DB->delete_records('question_answers', ['id' => $oldanswer->id]); } $options = $DB->get_record('question_oumultiresponse', - array('questionid' => $question->id)); + ['questionid' => $question->id]); if (!$options) { $options = new stdClass(); $options->questionid = $question->id; @@ -142,12 +150,13 @@ public function save_question_options($question) { $this->save_hints($question, true); } + #[\Override] public function save_hints($formdata, $withparts = false) { global $DB; $context = $formdata->context; $oldhints = $DB->get_records('question_hints', - array('questionid' => $formdata->id), 'id ASC'); + ['questionid' => $formdata->id], 'id ASC'); if (!empty($formdata->hint)) { $numhints = max(array_keys($formdata->hint)) + 1; @@ -217,20 +226,23 @@ public function save_hints($formdata, $withparts = false) { $fs = get_file_storage(); foreach ($oldhints as $oldhint) { $fs->delete_area_files($context->id, 'question', 'hint', $oldhint->id); - $DB->delete_records('question_hints', array('id' => $oldhint->id)); + $DB->delete_records('question_hints', ['id' => $oldhint->id]); } } + #[\Override] protected function make_hint($hint) { return qtype_oumultiresponse_hint::load_from_record($hint); } + #[\Override] // phpcs:ignore Generic.CodeAnalysis.UselessOverridingMethod.Found public function make_answer($answer) { // Overridden just so we can make it public for use by question.php. return parent::make_answer($answer); } + #[\Override] protected function initialise_question_instance(question_definition $question, $questiondata) { parent::initialise_question_instance($question, $questiondata); $question->shuffleanswers = $questiondata->options->shuffleanswers; @@ -240,12 +252,18 @@ protected function initialise_question_instance(question_definition $question, $ $this->initialise_question_answers($question, $questiondata, false); } + #[\Override] public function delete_question($questionid, $contextid) { global $DB; - $DB->delete_records('question_oumultiresponse', array('questionid' => $questionid)); + $DB->delete_records('question_oumultiresponse', ['questionid' => $questionid]); return parent::delete_question($questionid, $contextid); } + /** + * Get the number of correct choices in the question. + * + * @param question_definition $questiondata The question data. + */ protected function get_num_correct_choices($questiondata) { $numright = 0; foreach ($questiondata->options->answers as $answer) { @@ -256,6 +274,7 @@ protected function get_num_correct_choices($questiondata) { return $numright; } + #[\Override] public function get_random_guess_score($questiondata) { // We compute the randome guess score here on the assumption we are using // the deferred feedback behaviour, and the question text tells the @@ -266,18 +285,20 @@ public function get_random_guess_score($questiondata) { count($questiondata->options->answers); } + #[\Override] public function get_possible_responses($questiondata) { $numright = $this->get_num_correct_choices($questiondata); - $parts = array(); + $parts = []; foreach ($questiondata->options->answers as $aid => $answer) { - $parts[$aid] = array($aid => - new question_possible_response($answer->answer, $answer->fraction / $numright)); + $parts[$aid] = [$aid => + new question_possible_response($answer->answer, $answer->fraction / $numright)]; } return $parts; } + #[\Override] public function import_from_xml($data, $question, qformat_xml $format, $extra=null) { if (!isset($data['@']['type']) || $data['@']['type'] != 'oumultiresponse') { return false; @@ -287,11 +308,11 @@ public function import_from_xml($data, $question, qformat_xml $format, $extra=nu $question->qtype = 'oumultiresponse'; $question->shuffleanswers = $format->trans_single( - $format->getpath($data, array('#', 'shuffleanswers', 0, '#'), 1)); + $format->getpath($data, ['#', 'shuffleanswers', 0, '#'], 1)); $question->answernumbering = $format->getpath($data, - array('#', 'answernumbering', 0, '#'), 'abc'); + ['#', 'answernumbering', 0, '#'], 'abc'); $question->showstandardinstruction = $format->getpath($data, - array('#', 'showstandardinstruction', 0, '#'), 1); + ['#', 'showstandardinstruction', 0, '#'], 1); $format->import_combined_feedback($question, $data, true); @@ -308,7 +329,7 @@ public function import_from_xml($data, $question, qformat_xml $format, $extra=nu if (array_key_exists('correctanswer', $answer['#'])) { $keys = array_keys($question->correctanswer); $question->correctanswer[end($keys)] = $format->getpath($answer, - array('#', 'correctanswer', 0, '#'), 0); + ['#', 'correctanswer', 0, '#'], 0); } } @@ -325,6 +346,7 @@ public function import_from_xml($data, $question, qformat_xml $format, $extra=nu return $question; } + #[\Override] public function export_to_xml($question, qformat_xml $format, $extra = null) { $output = ''; @@ -341,6 +363,7 @@ public function export_to_xml($question, qformat_xml $format, $extra = null) { return $output; } + #[\Override] public function move_files($questionid, $oldcontextid, $newcontextid) { $fs = get_file_storage(); @@ -356,6 +379,7 @@ public function move_files($questionid, $oldcontextid, $newcontextid) { $newcontextid, 'question', 'incorrectfeedback', $questionid); } + #[\Override] protected function delete_files($questionid, $contextid) { $fs = get_file_storage(); @@ -377,7 +401,7 @@ protected function delete_files($questionid, $contextid) { * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class qtype_oumultiresponse_hint extends question_hint_with_parts { - /** @var boolean whether to show the feedback for each choice. */ + /** @var bool whether to show the feedback for each choice. */ public $showchoicefeedback; /** @@ -403,10 +427,11 @@ public static function load_from_record($row) { $row->shownumcorrect, $row->clearwrong, !empty($row->options)); } + #[\Override] public function adjust_display_options(question_display_options $options) { parent::adjust_display_options($options); if (defined('qtype_multichoice::COMBINED_BUT_NOT_CHOICE_FEEDBACK')) { - // Newer Moodle versions/ + // Newer Moodle versions. if ($options->feedback && !$this->showchoicefeedback) { $options->feedback = qtype_multichoice::COMBINED_BUT_NOT_CHOICE_FEEDBACK; } diff --git a/renderer.php b/renderer.php index 8be7161..54587e3 100644 --- a/renderer.php +++ b/renderer.php @@ -28,6 +28,9 @@ require_once($CFG->dirroot . '/question/type/multichoice/renderer.php'); require_once($CFG->dirroot . '/question/type/oumultiresponse/lib.php'); +/** + * Class renderer for the OU multiple response question type. + */ class qtype_oumultiresponse_renderer extends qtype_multichoice_multi_renderer { /** diff --git a/tests/behat/backup_and_restore.feature b/tests/behat/backup_and_restore.feature index 1910466..c05f279 100644 --- a/tests/behat/backup_and_restore.feature +++ b/tests/behat/backup_and_restore.feature @@ -19,6 +19,8 @@ Feature: Test duplicating a quiz containing an OU multiple response question | quiz | Test quiz | C1 | quiz1 | And quiz "Test quiz" contains the following questions: | oumultiresponse 001 | 1 | + And the following config values are set as admin: + | enableasyncbackup | 0 | @javascript Scenario: Backup and restore a course containing an OU multiple response question diff --git a/tests/behat/preview.feature b/tests/behat/preview.feature index 34adc3b..ea0537e 100644 --- a/tests/behat/preview.feature +++ b/tests/behat/preview.feature @@ -25,7 +25,7 @@ Feature: Preview an OU multiple response question When I am on the "oumultiresponse 001" "core_question > preview" page logged in as teacher And I expand all fieldsets And I set the field "How questions behave" to "Immediate feedback" - And I press "Start again with these options" + And I press "id_saverestart" And I click on "One" "qtype_multichoice > Answer" And I click on "Two" "qtype_multichoice > Answer" And I press "Check" @@ -38,7 +38,7 @@ Feature: Preview an OU multiple response question When I am on the "oumultiresponse 001" "core_question > preview" page logged in as teacher And I expand all fieldsets And I set the field "How questions behave" to "Immediate feedback" - And I press "Start again with these options" + And I press "id_saverestart" And I click on "One" "qtype_multichoice > Answer" And I click on "Three" "qtype_multichoice > Answer" And I press "Check" @@ -60,7 +60,7 @@ Feature: Preview an OU multiple response question And I am on the "oumultiresponse 002" "core_question > preview" page And I expand all fieldsets And I set the field "How questions behave" to "Immediate feedback" - And I press "Start again with these options" + And I press "id_saverestart" And I click on "One" "qtype_multichoice > Answer" And I click on "Two" "qtype_multichoice > Answer" And I press "Check" diff --git a/tests/helper.php b/tests/helper.php index 6601397..f14b8ae 100644 --- a/tests/helper.php +++ b/tests/helper.php @@ -29,14 +29,22 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class qtype_oumultiresponse_test_helper { + + /** + * Get test question function. + * + * @return array + */ public function get_test_questions() { - return array('two_of_four', 'two_of_five'); + return ['two_of_four', 'two_of_five']; } /** + * Create a question of type oumultiresponse with two correct answers out of four. + * * @return qtype_oumultiresponse_question */ - public static function make_oumultiresponse_question_two_of_four() { + public static function make_oumultiresponse_question_two_of_four(): qtype_oumultiresponse_question { question_bank::load_question_definition_classes('oumultiresponse'); $mc = new qtype_oumultiresponse_question(); @@ -54,17 +62,17 @@ public static function make_oumultiresponse_question_two_of_four() { test_question_maker::set_standard_combined_feedback_fields($mc); - $mc->answers = array( + $mc->answers = [ 13 => new question_answer(13, 'One', 1, 'One is odd.', FORMAT_HTML), 14 => new question_answer(14, 'Two', 0, 'Two is even.', FORMAT_HTML), 15 => new question_answer(15, 'Three', 1, 'Three is odd.', FORMAT_HTML), 16 => new question_answer(16, 'Four', 0, 'Four is even.', FORMAT_HTML), - ); + ]; - $mc->hints = array( + $mc->hints = [ new qtype_oumultiresponse_hint(1, 'Hint 1.', FORMAT_HTML, true, false, false), new qtype_oumultiresponse_hint(2, 'Hint 2.', FORMAT_HTML, true, true, true), - ); + ]; return $mc; } @@ -115,67 +123,69 @@ public static function get_oumultiresponse_question_data_two_of_four() { test_question_maker::STANDARD_OVERALL_INCORRECT_FEEDBACK; $qdata->options->incorrectfeedbackformat = FORMAT_HTML; - $qdata->options->answers = array( - 13 => (object) array( + $qdata->options->answers = [ + 13 => (object) [ 'id' => 13, 'answer' => 'One', 'answerformat' => FORMAT_PLAIN, 'fraction' => 1, 'feedback' => 'One is odd.', 'feedbackformat' => FORMAT_HTML, - ), - 14 => (object) array( + ], + 14 => (object) [ 'id' => 14, 'answer' => 'Two', 'answerformat' => FORMAT_PLAIN, 'fraction' => 0, 'feedback' => 'Two is even.', 'feedbackformat' => FORMAT_HTML, - ), - 15 => (object) array( + ], + 15 => (object) [ 'id' => 15, 'answer' => 'Three', 'answerformat' => FORMAT_PLAIN, 'fraction' => 1, 'feedback' => 'Three is odd.', 'feedbackformat' => FORMAT_HTML, - ), - 16 => (object) array( + ], + 16 => (object) [ 'id' => 16, 'answer' => 'Four', 'answerformat' => FORMAT_PLAIN, 'fraction' => 0, 'feedback' => 'Four is even.', 'feedbackformat' => FORMAT_HTML, - ), - ); + ], + ]; - $qdata->hints = array( - 1 => (object) array( + $qdata->hints = [ + 1 => (object) [ 'id' => 1, 'hint' => 'Hint 1.', 'hintformat' => FORMAT_HTML, 'shownumcorrect' => 1, 'clearwrong' => 0, 'options' => 0, - ), - 2 => (object) array( + ], + 2 => (object) [ 'id' => 2, 'hint' => 'Hint 2.', 'hintformat' => FORMAT_HTML, 'shownumcorrect' => 1, 'clearwrong' => 1, 'options' => 1, - ), - ); + ], + ]; return $qdata; } /** + * Make oumultiresponse question with two correct answers out of five. + * * @return qtype_oumultiresponse_question */ - public static function make_oumultiresponse_question_two_of_five() { + public static function make_oumultiresponse_question_two_of_five(): qtype_oumultiresponse_question { question_bank::load_question_definition_classes('oumultiresponse'); $mc = new qtype_oumultiresponse_question(); @@ -192,53 +202,55 @@ public static function make_oumultiresponse_question_two_of_five() { test_question_maker::set_standard_combined_feedback_fields($mc); - $mc->answers = array( + $mc->answers = [ 13 => new question_answer(13, 'A', 1, '', FORMAT_HTML), 14 => new question_answer(14, 'B', 1, '', FORMAT_HTML), 15 => new question_answer(15, 'C', 0, '', FORMAT_HTML), 16 => new question_answer(16, 'D', 0, '', FORMAT_HTML), 17 => new question_answer(17, 'E', 0, '', FORMAT_HTML), - ); + ]; - $mc->hints = array( + $mc->hints = [ 1 => new qtype_oumultiresponse_hint(1, 'Hint 1.', FORMAT_HTML, true, false, false), 2 => new qtype_oumultiresponse_hint(2, 'Hint 2.', FORMAT_HTML, true, true, true), - ); + ]; return $mc; } /** + * Get oumultiresponse question form data for a question with two correct answers out of four. + * * @return stdClass date to create an oumultiresponse question. */ - public function get_oumultiresponse_question_form_data_two_of_four() { + public function get_oumultiresponse_question_form_data_two_of_four(): stdClass { $fromform = new stdClass(); $fromform->name = 'OU multiple response question'; - $fromform->questiontext = array('text' => 'Which are the odd numbers?', 'format' => FORMAT_HTML); + $fromform->questiontext = ['text' => 'Which are the odd numbers?', 'format' => FORMAT_HTML]; $fromform->defaultmark = 1.0; - $fromform->generalfeedback = array('text' => 'The odd numbers are One and Three.', 'format' => FORMAT_HTML); + $fromform->generalfeedback = ['text' => 'The odd numbers are One and Three.', 'format' => FORMAT_HTML]; $fromform->shuffleanswers = 0; $fromform->answernumbering = 'abc'; $fromform->showstandardinstruction = 0; - $fromform->answer = array( - 0 => array('text' => 'One', 'format' => FORMAT_PLAIN), - 1 => array('text' => 'Two', 'format' => FORMAT_PLAIN), - 2 => array('text' => 'Three', 'format' => FORMAT_PLAIN), - 3 => array('text' => 'Four', 'format' => FORMAT_PLAIN) - ); - $fromform->correctanswer = array( - 0 => 1, - 1 => 0, - 2 => 1, - 3 => 0 - ); - $fromform->feedback = array( - 0 => array('text' => 'One is odd.', 'format' => FORMAT_HTML), - 1 => array('text' => 'Two is even.', 'format' => FORMAT_HTML), - 2 => array('text' => 'Three is odd.', 'format' => FORMAT_HTML), - 3 => array('text' => 'Four is odd.', 'format' => FORMAT_HTML) - ); + $fromform->answer = [ + 0 => ['text' => 'One', 'format' => FORMAT_PLAIN], + 1 => ['text' => 'Two', 'format' => FORMAT_PLAIN], + 2 => ['text' => 'Three', 'format' => FORMAT_PLAIN], + 3 => ['text' => 'Four', 'format' => FORMAT_PLAIN], + ]; + $fromform->correctanswer = [ + 0 => 1, + 1 => 0, + 2 => 1, + 3 => 0, + ]; + $fromform->feedback = [ + 0 => ['text' => 'One is odd.', 'format' => FORMAT_HTML], + 1 => ['text' => 'Two is even.', 'format' => FORMAT_HTML], + 2 => ['text' => 'Three is odd.', 'format' => FORMAT_HTML], + 3 => ['text' => 'Four is odd.', 'format' => FORMAT_HTML], + ]; test_question_maker::set_standard_combined_feedback_form_data($fromform); $fromform->shownumcorrect = 0; $fromform->penalty = 0.3333333; diff --git a/tests/privacy_provider_test.php b/tests/privacy_provider_test.php index 55d8770..6790fb3 100644 --- a/tests/privacy_provider_test.php +++ b/tests/privacy_provider_test.php @@ -24,7 +24,7 @@ namespace qtype_oumultiresponse; use core_privacy\local\metadata\collection; -use \core_privacy\local\request\user_preference_provider; +use core_privacy\local\request\user_preference_provider; use qtype_oumultiresponse\privacy\provider; use core_privacy\local\request\writer; use core_privacy\local\request\transform; @@ -40,17 +40,18 @@ * @package qtype_oumultiresponse * @copyright 2021 The Open university * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @covers \qtype_oumultiresponse\privacy\provider */ -class privacy_provider_test extends \core_privacy\tests\provider_testcase { +final class privacy_provider_test extends \core_privacy\tests\provider_testcase { // Include the privacy helper which has assertions on it. - public function test_get_metadata() { + public function test_get_metadata(): void { $collection = new \core_privacy\local\metadata\collection('qtype_oumultiresponse'); $actual = \qtype_oumultiresponse\privacy\provider::get_metadata($collection); $this->assertEquals($collection, $actual); } - public function test_export_user_preferences_no_pref() { + public function test_export_user_preferences_no_pref(): void { $this->resetAfterTest(); $user = $this->getDataGenerator()->create_user(); @@ -67,7 +68,7 @@ public function test_export_user_preferences_no_pref() { * @param string $value The value stored in the database * @param string $expected The expected transformed value */ - public function test_export_user_preferences($name, $value, $expected) { + public function test_export_user_preferences($name, $value, $expected): void { $this->resetAfterTest(); $user = $this->getDataGenerator()->create_user(); set_user_preference("qtype_oumultiresponse_$name", $value, $user); @@ -91,7 +92,7 @@ public function test_export_user_preferences($name, $value, $expected) { * * @return array Array of valid user preferences. */ - public function user_preference_provider() { + public static function user_preference_provider(): array { return [ 'default mark 2' => ['defaultmark', 2, 2], 'penalty 33.33333%' => ['penalty', 0.3333333, '33.33333%'], @@ -103,7 +104,7 @@ public function user_preference_provider() { 'answernumbering iii' => ['answernumbering', 'iii', 'i., ii., iii., ...'], 'answernumbering III' => ['answernumbering', 'IIII', 'I., II., III., ...'], 'show standard instruction yes' => ['showstandardinstruction', 1, 'Yes'], - 'show standard instruction no' => ['showstandardinstruction', 0, 'No'] + 'show standard instruction no' => ['showstandardinstruction', 0, 'No'], ]; } } diff --git a/tests/question_test.php b/tests/question_test.php index f6733b5..3340068 100644 --- a/tests/question_test.php +++ b/tests/question_test.php @@ -41,207 +41,215 @@ * * @copyright 2008 The Open University * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @covers ::replace_char_at + * @covers ::grade_response + * @covers ::grade_computation */ +final class question_test extends \basic_testcase { -class question_test extends \basic_testcase { + /** + * Tolerance for floating point comparisons. + * + * @var float + */ private $tolerance = 0.000001; - public function test_replace_char_at() { + public function test_replace_char_at(): void { $this->assertEquals(qtype_oumultiresponse_question::replace_char_at('220', 0, '0'), '020'); } - public function test_grade_responses_right_right() { + public function test_grade_responses_right_right(): void { $mc = test_question_maker::make_question('oumultiresponse', 'two_of_four'); $mc->shuffleanswers = false; $mc->start_attempt(new question_attempt_step(), 1); - list($fraction, $state) = $mc->grade_response(array('choice0' => '1', 'choice2' => '1')); + list($fraction, $state) = $mc->grade_response(['choice0' => '1', 'choice2' => '1']); $this->assertEquals(1, $fraction, '', $this->tolerance); $this->assertEquals($state, question_state::$gradedright); } - public function test_grade_responses_right() { + public function test_grade_responses_right(): void { $mc = test_question_maker::make_question('oumultiresponse', 'two_of_four'); $mc->shuffleanswers = false; $mc->start_attempt(new question_attempt_step(), 1); - list($fraction, $state) = $mc->grade_response(array('choice0' => '1')); + list($fraction, $state) = $mc->grade_response(['choice0' => '1']); $this->assertEquals(0.5, $fraction, '', $this->tolerance); $this->assertEquals($state, question_state::$gradedpartial); } - public function test_grade_responses_wrong_wrong() { + public function test_grade_responses_wrong_wrong(): void { $mc = test_question_maker::make_question('oumultiresponse', 'two_of_four'); $mc->shuffleanswers = false; $mc->start_attempt(new question_attempt_step(), 1); - list($fraction, $state) = $mc->grade_response(array('choice1' => '1', 'choice3' => '1')); + list($fraction, $state) = $mc->grade_response(['choice1' => '1', 'choice3' => '1']); $this->assertEquals(0, $fraction, '', $this->tolerance); $this->assertEquals($state, question_state::$gradedwrong); } - public function test_grade_responses_right_wrong_wrong() { + public function test_grade_responses_right_wrong_wrong(): void { $mc = test_question_maker::make_question('oumultiresponse', 'two_of_four'); $mc->shuffleanswers = false; $mc->start_attempt(new question_attempt_step(), 1); list($fraction, $state) = $mc->grade_response( - array('choice0' => '1', 'choice1' => '1', 'choice3' => '1')); + ['choice0' => '1', 'choice1' => '1', 'choice3' => '1']); $this->assertEquals(0, $fraction, '', $this->tolerance); $this->assertEquals($state, question_state::$gradedpartial); } - public function test_grade_responses_right_wrong() { + public function test_grade_responses_right_wrong(): void { $mc = test_question_maker::make_question('oumultiresponse', 'two_of_four'); $mc->shuffleanswers = false; $mc->start_attempt(new question_attempt_step(), 1); - list($fraction, $state) = $mc->grade_response(array('choice0' => '1', 'choice1' => '1')); + list($fraction, $state) = $mc->grade_response(['choice0' => '1', 'choice1' => '1']); $this->assertEquals(0.5, $fraction, '', $this->tolerance); $this->assertEquals($state, question_state::$gradedpartial); } - public function test_grade_responses_right_right_wrong() { + public function test_grade_responses_right_right_wrong(): void { $mc = test_question_maker::make_question('oumultiresponse', 'two_of_four'); $mc->shuffleanswers = false; $mc->start_attempt(new question_attempt_step(), 1); - list($fraction, $state) = $mc->grade_response(array( - 'choice0' => '1', 'choice2' => '1', 'choice3' => '1')); + list($fraction, $state) = $mc->grade_response([ + 'choice0' => '1', 'choice2' => '1', 'choice3' => '1']); $this->assertEquals(0.5, $fraction, '', $this->tolerance); $this->assertEquals($state, question_state::$gradedpartial); } - public function test_grade_responses_right_right_wrong_wrong() { + public function test_grade_responses_right_right_wrong_wrong(): void { $mc = test_question_maker::make_question('oumultiresponse', 'two_of_four'); $mc->shuffleanswers = false; $mc->start_attempt(new question_attempt_step(), 1); - list($fraction, $state) = $mc->grade_response(array( - 'choice0' => '1', 'choice1' => '1', 'choice2' => '1', 'choice3' => '1')); + list($fraction, $state) = $mc->grade_response([ + 'choice0' => '1', 'choice1' => '1', 'choice2' => '1', 'choice3' => '1']); $this->assertEquals(0, $fraction, '', $this->tolerance); $this->assertEquals($state, question_state::$gradedpartial); } - public function test_grade_computation() { + public function test_grade_computation(): void { $right = new \stdClass(); $right->fraction = 1.0; $wrong = new \stdClass(); $wrong->fraction = 0.0; $penalty = 0.3333333; - $answers = array($right, $right, $right, $wrong, $wrong, $wrong); + $answers = [$right, $right, $right, $wrong, $wrong, $wrong]; - $responsehistory = array('111', '000', '000', '000', '000', '000'); + $responsehistory = ['111', '000', '000', '000', '000', '000']; $this->assertEqualsWithDelta(qtype_oumultiresponse_question::grade_computation( $responsehistory, $answers, $penalty, 3), 0.3333333, $this->tolerance, ''); - $responsehistory = array('111', '111', '000', '000', '000', '000'); + $responsehistory = ['111', '111', '000', '000', '000', '000']; $this->assertEqualsWithDelta(qtype_oumultiresponse_question::grade_computation( $responsehistory, $answers, $penalty, 3), 0.6666667, $this->tolerance, ''); - $responsehistory = array('1', '1', '1', '0', '0', '0'); + $responsehistory = ['1', '1', '1', '0', '0', '0']; $this->assertEqualsWithDelta(qtype_oumultiresponse_question::grade_computation( $responsehistory, $answers, $penalty, 3), 1.0, $this->tolerance, ''); - $responsehistory = array('111', '111', '111', '111', '000', '000'); + $responsehistory = ['111', '111', '111', '111', '000', '000']; $this->assertEqualsWithDelta(qtype_oumultiresponse_question::grade_computation( $responsehistory, $answers, $penalty, 3), 0.6666667, $this->tolerance, ''); - $responsehistory = array('111', '111', '111', '111', '111', '000'); + $responsehistory = ['111', '111', '111', '111', '111', '000']; $this->assertEqualsWithDelta(qtype_oumultiresponse_question::grade_computation( $responsehistory, $answers, $penalty, 3), 0.3333333, $this->tolerance, ''); - $responsehistory = array('111', '111', '111', '111', '111', '111'); + $responsehistory = ['111', '111', '111', '111', '111', '111']; $this->assertEqualsWithDelta(qtype_oumultiresponse_question::grade_computation( $responsehistory, $answers, $penalty, 3), 0.0, $this->tolerance, ''); - $responsehistory = array('011', '000', '000', '100', '111', '111'); + $responsehistory = ['011', '000', '000', '100', '111', '111']; $this->assertEqualsWithDelta(qtype_oumultiresponse_question::grade_computation( $responsehistory, $answers, $penalty, 3), 0.2222222, $this->tolerance, ''); - $responsehistory = array('001', '000', '000', '110', '111', '111'); + $responsehistory = ['001', '000', '000', '110', '111', '111']; $this->assertEqualsWithDelta(qtype_oumultiresponse_question::grade_computation( $responsehistory, $answers, $penalty, 3), 0.1111111, $this->tolerance, ''); - $responsehistory = array('111', '111', '001', '100', '010', '000'); + $responsehistory = ['111', '111', '001', '100', '010', '000']; $this->assertEqualsWithDelta(qtype_oumultiresponse_question::grade_computation( $responsehistory, $answers, $penalty, 3), 0.7777778, $this->tolerance, ''); - $responsehistory = array('100', '100', '001', '100', '011', '001'); + $responsehistory = ['100', '100', '001', '100', '011', '001']; $this->assertEqualsWithDelta(qtype_oumultiresponse_question::grade_computation( $responsehistory, $answers, $penalty, 3), 0.1111111, $this->tolerance, ''); - $responsehistory = array('101', '101', '001', '110', '011', '111'); + $responsehistory = ['101', '101', '001', '110', '011', '111']; $this->assertEqualsWithDelta(qtype_oumultiresponse_question::grade_computation( $responsehistory, $answers, $penalty, 3), 0.1111111, $this->tolerance, ''); - $responsehistory = array('011', '001', '001', '100', '110', '111'); + $responsehistory = ['011', '001', '001', '100', '110', '111']; $this->assertEqualsWithDelta(qtype_oumultiresponse_question::grade_computation( $responsehistory, $answers, $penalty, 3), 0.3333333, $this->tolerance, ''); - $responsehistory = array('111', '111', '111', '110', '110', '100'); + $responsehistory = ['111', '111', '111', '110', '110', '100']; $this->assertEqualsWithDelta(qtype_oumultiresponse_question::grade_computation( $responsehistory, $answers, $penalty, 3), 0.4444444, $this->tolerance, ''); - $responsehistory = array('111', '111', '111', '110', '100', '100'); + $responsehistory = ['111', '111', '111', '110', '100', '100']; $this->assertEqualsWithDelta(qtype_oumultiresponse_question::grade_computation( $responsehistory, $answers, $penalty, 3), 0.5555556, $this->tolerance, ''); - $responsehistory = array('110', '101', '101', '111', '110', '100'); + $responsehistory = ['110', '101', '101', '111', '110', '100']; $this->assertEqualsWithDelta(qtype_oumultiresponse_question::grade_computation( $responsehistory, $answers, $penalty, 3), 0.2222222, $this->tolerance, ''); - $responsehistory = array('111', '110', '110', '111', '111', '100'); + $responsehistory = ['111', '110', '110', '111', '111', '100']; $this->assertEqualsWithDelta(qtype_oumultiresponse_question::grade_computation( $responsehistory, $answers, $penalty, 3), 0.2222222, $this->tolerance, ''); - $responsehistory = array('011', '111', '110', '111', '111', '100'); + $responsehistory = ['011', '111', '110', '111', '111', '100']; $this->assertEqualsWithDelta(qtype_oumultiresponse_question::grade_computation( $responsehistory, $answers, $penalty, 3), 0.2222222, $this->tolerance, ''); - $responsehistory = array('110', '111', '110', '111', '111', '100'); + $responsehistory = ['110', '111', '110', '111', '111', '100']; $this->assertEqualsWithDelta(qtype_oumultiresponse_question::grade_computation( $responsehistory, $answers, $penalty, 3), 0.2222222, $this->tolerance, ''); - $responsehistory = array('111', '111', '111', '110', '110', '100'); + $responsehistory = ['111', '111', '111', '110', '110', '100']; $this->assertEqualsWithDelta(qtype_oumultiresponse_question::grade_computation( $responsehistory, $answers, $penalty, 3), 0.4444444, $this->tolerance, ''); - $responsehistory = array('110', '111', '110', '111', '111', '100'); + $responsehistory = ['110', '111', '110', '111', '111', '100']; $this->assertEqualsWithDelta(qtype_oumultiresponse_question::grade_computation( $responsehistory, $answers, $penalty, 3), 0.2222222, $this->tolerance, ''); - $responsehistory = array('011', '111', '110', '111', '111', '100'); + $responsehistory = ['011', '111', '110', '111', '111', '100']; $this->assertEqualsWithDelta(qtype_oumultiresponse_question::grade_computation( $responsehistory, $answers, $penalty, 3), 0.2222222, $this->tolerance, ''); - $responsehistory = array('011', '111', '110', '110', '111', '001'); + $responsehistory = ['011', '111', '110', '110', '111', '001']; $this->assertEqualsWithDelta(qtype_oumultiresponse_question::grade_computation( $responsehistory, $answers, $penalty, 3), 0.3333333, $this->tolerance, ''); - $responsehistory = array('11', '01', '01', '10', '10', '00'); + $responsehistory = ['11', '01', '01', '10', '10', '00']; $this->assertEqualsWithDelta(qtype_oumultiresponse_question::grade_computation( $responsehistory, $answers, $penalty, 3), 0.7777778, $this->tolerance, ''); $penalty = 0.2; - $answers = array($right, $right, $right, $right, $wrong, $wrong, $wrong, $wrong); - $responsehistory = array( - '11111', '10111', '11100', '11011', '10011', '01010', '01000', '00100'); + $answers = [$right, $right, $right, $right, $wrong, $wrong, $wrong, $wrong]; + $responsehistory = [ + '11111', '10111', '11100', '11011', '10011', '01010', '01000', '00100']; $this->assertEqualsWithDelta(qtype_oumultiresponse_question::grade_computation( $responsehistory, $answers, $penalty, 5), 0.45, $this->tolerance, ''); $penalty = 0.33334; - $answers = array($right, $right, $wrong, $wrong, $wrong); - $responsehistory = array('0', '0', '1', '1', '0'); + $answers = [$right, $right, $wrong, $wrong, $wrong]; + $responsehistory = ['0', '0', '1', '1', '0']; $this->assertEqualsWithDelta(qtype_oumultiresponse_question::grade_computation( $responsehistory, $answers, $penalty, 1), 0.0, $this->tolerance, ''); - $responsehistory = array('0', '1', '1', '0', '0'); + $responsehistory = ['0', '1', '1', '0', '0']; $this->assertEqualsWithDelta(qtype_oumultiresponse_question::grade_computation( $responsehistory, $answers, $penalty, 1), 0.5, $this->tolerance, ''); - $responsehistory = array('1', '1', '0', '0', '0'); + $responsehistory = ['1', '1', '0', '0', '0']; $this->assertEqualsWithDelta(qtype_oumultiresponse_question::grade_computation( $responsehistory, $answers, $penalty, 1), 1.0, $this->tolerance, ''); } diff --git a/tests/questiontype_test.php b/tests/questiontype_test.php index ae03f0c..cc8c7a3 100644 --- a/tests/questiontype_test.php +++ b/tests/questiontype_test.php @@ -42,27 +42,30 @@ * * @copyright 2008 The Open University * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @covers \qtype_oumultiresponse */ -class questiontype_test extends \question_testcase { +final class questiontype_test extends \question_testcase { /** * @var qtype_oumultiresponse */ private $qtype; public function setUp(): void { + parent::setUp(); $this->qtype = new qtype_oumultiresponse(); } - public function assert_same_xml($expectedxml, $xml) { + #[\Override] + public function assert_same_xml($expectedxml, $xml): void { $this->assertEquals(str_replace("\r\n", "\n", $expectedxml), str_replace("\r\n", "\n", $xml)); } - public function test_name() { + public function test_name(): void { $this->assertEquals($this->qtype->name(), 'oumultiresponse'); } - public function test_initialise_question_instance() { + public function test_initialise_question_instance(): void { $qdata = test_question_maker::get_question_data('oumultiresponse', 'two_of_four'); $expectedq = test_question_maker::make_question('oumultiresponse', 'two_of_four'); $qdata->stamp = $expectedq->stamp; @@ -75,36 +78,36 @@ public function test_initialise_question_instance() { $this->assertEquals($expectedq, $question); } - public function test_can_analyse_responses() { + public function test_can_analyse_responses(): void { $this->assertTrue($this->qtype->can_analyse_responses()); } - public function test_get_possible_responses() { + public function test_get_possible_responses(): void { $q = new \stdClass(); $q->id = 1; $q->options = new \stdClass(); $q->options->answers = [ - 1 => (object) array('answer' => 'frog', 'fraction' => 1), - 2 => (object) array('answer' => 'toad', 'fraction' => 1), - 3 => (object) array('answer' => 'newt', 'fraction' => 0), + 1 => (object) ['answer' => 'frog', 'fraction' => 1], + 2 => (object) ['answer' => 'toad', 'fraction' => 1], + 3 => (object) ['answer' => 'newt', 'fraction' => 0], ]; $responses = $this->qtype->get_possible_responses($q); - $this->assertEquals(array( - 1 => array(1 => new question_possible_response('frog', 0.5)), - 2 => array(2 => new question_possible_response('toad', 0.5)), - 3 => array(3 => new question_possible_response('newt', 0)), - ), $this->qtype->get_possible_responses($q)); + $this->assertEquals([ + 1 => [1 => new question_possible_response('frog', 0.5)], + 2 => [2 => new question_possible_response('toad', 0.5)], + 3 => [3 => new question_possible_response('newt', 0)], + ], $this->qtype->get_possible_responses($q)); } - public function test_get_random_guess_score() { + public function test_get_random_guess_score(): void { $questiondata = new \stdClass(); $questiondata->options = new \stdClass(); - $questiondata->options->answers = array( + $questiondata->options->answers = [ 1 => new question_answer(1, 'A', 1, '', FORMAT_HTML), 2 => new question_answer(2, 'B', 0, '', FORMAT_HTML), 3 => new question_answer(3, 'C', 0, '', FORMAT_HTML), - ); + ]; $this->assertEquals(1 / 3, $this->qtype->get_random_guess_score($questiondata), '', 0.000001); @@ -117,7 +120,7 @@ public function test_get_random_guess_score() { $this->qtype->get_random_guess_score($questiondata), '', 0.000001); } - public function test_xml_import() { + public function test_xml_import(): void { $xml = 'Specific feedback to correct answer.
', - 'format' => FORMAT_HTML), - array('text' => 'Specific feedback to correct answer.
', - 'format' => FORMAT_HTML), - array('text' => 'Specific feedback to wrong answer.
', - 'format' => FORMAT_HTML), - array('text' => 'Specific feedback to wrong answer.
', - 'format' => FORMAT_HTML), - ); - - $expectedq->hint = array( - array('text' => 'Hint 1.', 'format' => FORMAT_HTML), - array('text' => 'Hint 2.', 'format' => FORMAT_HTML)); - $expectedq->hintshownumcorrect = array(false, false); - $expectedq->hintclearwrong = array(false, false); - $expectedq->hintshowchoicefeedback = array(true, true); + $expectedq->incorrectfeedback = [ + 'text' => 'Incorrect overall feedback.', + 'format' => FORMAT_HTML, + ]; + + $expectedq->answer = [ + ['text' => 'eighta', 'format' => FORMAT_HTML], + ['text' => 'eightb', 'format' => FORMAT_HTML], + ['text' => 'one', 'format' => FORMAT_HTML], + ['text' => 'two', 'format' => FORMAT_HTML], + ]; + $expectedq->correctanswer = [1, 1, 0, 0]; + $expectedq->feedback = [ + ['text' => 'Specific feedback to correct answer.
', + 'format' => FORMAT_HTML], + ['text' => 'Specific feedback to correct answer.
', + 'format' => FORMAT_HTML], + ['text' => 'Specific feedback to wrong answer.
', + 'format' => FORMAT_HTML], + ['text' => 'Specific feedback to wrong answer.
', + 'format' => FORMAT_HTML], + ]; + + $expectedq->hint = [ + ['text' => 'Hint 1.', 'format' => FORMAT_HTML], + ['text' => 'Hint 2.', 'format' => FORMAT_HTML], + ]; + $expectedq->hintshownumcorrect = [false, false]; + $expectedq->hintclearwrong = [false, false]; + $expectedq->hintshowchoicefeedback = [true, true]; $this->assertEquals($expectedq->answer, $q->answer); $this->assert(new question_check_specified_fields_expectation($expectedq), $q); } - public function test_xml_export() { + public function test_xml_export(): void { $qdata = test_question_maker::get_question_data('oumultiresponse', 'two_of_four'); $qdata->defaultmark = 6; diff --git a/tests/walkthrough_test.php b/tests/walkthrough_test.php index 371ba10..b368d27 100644 --- a/tests/walkthrough_test.php +++ b/tests/walkthrough_test.php @@ -44,10 +44,11 @@ * * @copyright 2010 The Open University * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @covers \qtype_oumultiresponse_question */ -class walkthrough_test extends \qbehaviour_walkthrough_test_base { +final class walkthrough_test extends \qbehaviour_walkthrough_test_base { - public function test_shows_standrd_instruction_yes() { + public function test_shows_standrd_instruction_yes(): void { // Create a multichoice single question. $mc = test_question_maker::make_question('oumultiresponse', 'two_of_four'); @@ -61,7 +62,7 @@ public function test_shows_standrd_instruction_yes() { $this->assertStringContainsString($standardinstruction, $this->currentoutput); } - public function test_shows_standrd_instruction_no() { + public function test_shows_standrd_instruction_no(): void { // Create a multichoice single question. $mc = test_question_maker::make_question('oumultiresponse', 'two_of_four'); @@ -70,14 +71,18 @@ public function test_shows_standrd_instruction_no() { $this->start_attempt_at_question($mc, 'interactive', 3); $this->render(); + $standardinstructionclass = 'prompt h6 fw-normal visually-hidden'; + if (utils::moodle_version_is("<=" , "45")) { + $standardinstructionclass = 'prompt h6 font-weight-normal sr-only'; + } // Check for 'Show standard instruction'. $standardinstruction = \html_writer::tag('legend', get_string('answer'), [ - 'class' => 'prompt h6 font-weight-normal sr-only' + 'class' => $standardinstructionclass, ]); $this->assertStringContainsString($standardinstruction, $this->currentoutput); } - public function test_interactive_behaviour() { + public function test_interactive_behaviour(): void { // Create a multichoice single question. $mc = test_question_maker::make_question('oumultiresponse', 'two_of_four'); @@ -101,7 +106,7 @@ public function test_interactive_behaviour() { $this->get_no_hint_visible_expectation()); // Save the wrong answer. - $this->process_submission(array('choice1' => '1', 'choice3' => '1')); + $this->process_submission(['choice1' => '1', 'choice3' => '1']); // Verify. $this->check_current_state(question_state::$todo); @@ -119,7 +124,7 @@ public function test_interactive_behaviour() { $this->get_no_hint_visible_expectation()); // Submit the wrong answer. - $this->process_submission(array('choice1' => '1', 'choice3' => '1', '-submit' => '1')); + $this->process_submission(['choice1' => '1', 'choice3' => '1', '-submit' => '1']); // Verify. $this->check_current_state(question_state::$todo); @@ -144,7 +149,7 @@ public function test_interactive_behaviour() { $this->quba->get_field_prefix($this->slot) . 'choice3')); // Do try again. - $this->process_submission(array('-tryagain' => 1)); + $this->process_submission(['-tryagain' => 1]); // Verify. $this->check_current_state(question_state::$todo); @@ -162,7 +167,7 @@ public function test_interactive_behaviour() { $this->get_no_hint_visible_expectation()); // Submit a partially right answer. - $this->process_submission(array('choice0' => '1', 'choice3' => '1', '-submit' => '1')); + $this->process_submission(['choice0' => '1', 'choice3' => '1', '-submit' => '1']); // Verify. $this->check_current_state(question_state::$todo); @@ -187,7 +192,7 @@ public function test_interactive_behaviour() { $this->quba->get_field_prefix($this->slot) . 'choice3', '0')); // Do try again. - $this->process_submission(array('choice0' => '1', '-tryagain' => 1)); + $this->process_submission(['choice0' => '1', '-tryagain' => 1]); // Verify. $this->check_current_state(question_state::$todo); @@ -205,7 +210,7 @@ public function test_interactive_behaviour() { $this->get_no_hint_visible_expectation()); // Submit the right answer. - $this->process_submission(array('choice0' => '1', 'choice2' => '1', '-submit' => '1')); + $this->process_submission(['choice0' => '1', 'choice2' => '1', '-submit' => '1']); // Verify. $this->check_current_state(question_state::$gradedright); @@ -220,15 +225,15 @@ public function test_interactive_behaviour() { $this->get_contains_standard_correct_combined_feedback_expectation()); } - public function test_interactive_behaviour2() { + public function test_interactive_behaviour2(): void { // Create a multichoice single question. $mc = test_question_maker::make_question('oumultiresponse', 'two_of_four'); $mc->showstandardinstruction = 1; - $mc->hints = array( + $mc->hints = [ new qtype_oumultiresponse_hint(1, 'Hint 1', FORMAT_HTML, true, true, true), new qtype_oumultiresponse_hint(2, 'Hint 2', FORMAT_HTML, true, true, true), - ); + ]; $mc->shuffleanswers = false; $mc->showstandardinstruction = true; $this->start_attempt_at_question($mc, 'interactive', 3); @@ -251,8 +256,8 @@ public function test_interactive_behaviour2() { preg_quote(get_string('selectmulti', 'qtype_multichoice'), '/') . '/')); // Submit the wrong answer with too manu options selected. - $this->process_submission(array( - 'choice1' => '1', 'choice2' => '1', 'choice3' => '1', '-submit' => '1')); + $this->process_submission([ + 'choice1' => '1', 'choice2' => '1', 'choice3' => '1', '-submit' => '1']); // Verify. $this->check_current_state(question_state::$todo); @@ -281,14 +286,14 @@ public function test_interactive_behaviour2() { preg_quote(get_string('selectmulti', 'qtype_multichoice'), '/') . '/')); } - public function test_interactive_clear_wrong() { + public function test_interactive_clear_wrong(): void { // Create a multichoice single question. $mc = test_question_maker::make_question('oumultiresponse', 'two_of_four'); - $mc->hints = array( + $mc->hints = [ new qtype_oumultiresponse_hint(1, 'Hint 1', FORMAT_HTML, true, true, true), new qtype_oumultiresponse_hint(2, 'Hint 2', FORMAT_HTML, true, true, true), - ); + ]; $mc->shuffleanswers = false; $mc->showstandardinstruction = true; $this->start_attempt_at_question($mc, 'interactive', 3); @@ -310,7 +315,7 @@ public function test_interactive_clear_wrong() { $this->get_no_hint_visible_expectation()); // Submit a wrong answer. - $this->process_submission(array('choice1' => '1', 'choice3' => '1', '-submit' => '1')); + $this->process_submission(['choice1' => '1', 'choice3' => '1', '-submit' => '1']); // Verify. $this->check_current_state(question_state::$todo); @@ -332,7 +337,7 @@ public function test_interactive_clear_wrong() { $this->quba->get_field_prefix($this->slot) . 'choice3', '0')); // Try again. - $this->process_submission(array('choice1' => '0', 'choice3' => '0', '-tryagain' => '1')); + $this->process_submission(['choice1' => '0', 'choice3' => '0', '-tryagain' => '1']); // Vreify. $this->check_current_state(question_state::$todo); @@ -351,7 +356,7 @@ public function test_interactive_clear_wrong() { $this->get_no_hint_visible_expectation()); // Submit a partially right answer. - $this->process_submission(array('choice0' => '1', 'choice3' => '1', '-submit' => '1')); + $this->process_submission(['choice0' => '1', 'choice3' => '1', '-submit' => '1']); // Verify. $this->check_current_state(question_state::$todo); @@ -373,7 +378,7 @@ public function test_interactive_clear_wrong() { $this->quba->get_field_prefix($this->slot) . 'choice3', '0')); // Try again. - $this->process_submission(array('choice0' => '1', 'choice3' => '0', '-tryagain' => '1')); + $this->process_submission(['choice0' => '1', 'choice3' => '0', '-tryagain' => '1']); // Check the initial state. $this->check_current_state(question_state::$todo); @@ -392,7 +397,7 @@ public function test_interactive_clear_wrong() { $this->get_no_hint_visible_expectation()); } - public function test_interactive_bug_11263() { + public function test_interactive_bug_11263(): void { // Create a multichoice single question. $mc = test_question_maker::make_question('oumultiresponse', 'two_of_five'); @@ -406,28 +411,28 @@ public function test_interactive_bug_11263() { $this->get_tries_remaining_expectation(3)); // Submit a wrong answer. - $this->process_submission(array( + $this->process_submission([ 'choice0' => '0', 'choice1' => '0', 'choice2' => '0', 'choice3' => '1', 'choice4' => '1', - '-submit' => '1' - )); + '-submit' => '1', + ]); // Verify. $this->check_current_state(question_state::$todo); $this->check_current_mark(null); // Try again. - $this->process_submission(array( + $this->process_submission([ 'choice0' => '0', 'choice1' => '0', 'choice2' => '0', 'choice3' => '1', 'choice4' => '1', - '-tryagain' => '1' - )); + '-tryagain' => '1', + ]); // Verify. $this->check_current_state(question_state::$todo); @@ -436,28 +441,28 @@ public function test_interactive_bug_11263() { $this->get_tries_remaining_expectation(2)); // Submit a wrong answer again. - $this->process_submission(array( + $this->process_submission([ 'choice0' => '0', 'choice1' => '0', 'choice2' => '0', 'choice3' => '1', 'choice4' => '1', - '-submit' => '1' - )); + '-submit' => '1', + ]); // Verify. $this->check_current_state(question_state::$todo); $this->check_current_mark(null); // Try again - clears wrong. - $this->process_submission(array( + $this->process_submission([ 'choice0' => '0', 'choice1' => '0', 'choice2' => '0', 'choice3' => '0', 'choice4' => '0', - '-tryagain' => '1' - )); + '-tryagain' => '1', + ]); // Verify. $this->check_current_state(question_state::$todo); @@ -466,21 +471,21 @@ public function test_interactive_bug_11263() { $this->get_tries_remaining_expectation(1)); // Submit one right choice. - $this->process_submission(array( + $this->process_submission([ 'choice0' => '1', 'choice1' => '0', 'choice2' => '0', 'choice3' => '0', 'choice4' => '0', - '-submit' => '1' - )); + '-submit' => '1', + ]); // Verify. $this->check_current_state(question_state::$gradedpartial); $this->check_current_mark(0); } - public function test_interactive_regrade_changing_num_tries_leaving_open() { + public function test_interactive_regrade_changing_num_tries_leaving_open(): void { // Create a multichoice multiple question. $q = test_question_maker::make_question('oumultiresponse', 'two_of_five'); $this->start_attempt_at_question($q, 'interactive', 3); @@ -492,14 +497,14 @@ public function test_interactive_regrade_changing_num_tries_leaving_open() { $this->get_tries_remaining_expectation(3)); // Submit the right answer. - $this->process_submission(array( + $this->process_submission([ 'choice0' => '1', 'choice1' => '1', 'choice2' => '0', 'choice3' => '0', 'choice4' => '0', - '-submit' => '1' - )); + '-submit' => '1', + ]); // Verify. $this->check_current_state(question_state::$gradedright); @@ -515,7 +520,7 @@ public function test_interactive_regrade_changing_num_tries_leaving_open() { $this->check_current_mark(null); } - public function test_interactive_regrade_changing_num_tries_finished() { + public function test_interactive_regrade_changing_num_tries_finished(): void { // Create a multichoice multiple question. $q = test_question_maker::make_question('oumultiresponse', 'two_of_five'); $this->start_attempt_at_question($q, 'interactive', 3); @@ -527,14 +532,14 @@ public function test_interactive_regrade_changing_num_tries_finished() { $this->get_tries_remaining_expectation(3)); // Submit the right answer. - $this->process_submission(array( + $this->process_submission([ 'choice0' => '1', 'choice1' => '1', 'choice2' => '0', 'choice3' => '0', 'choice4' => '0', - '-submit' => '1' - )); + '-submit' => '1', + ]); // Verify. $this->check_current_state(question_state::$gradedright); @@ -550,6 +555,7 @@ public function test_interactive_regrade_changing_num_tries_finished() { $this->check_current_mark(2); } + #[\Override] protected function get_contains_num_parts_correct($num) { $a = new \stdClass(); if ($num == 1) { diff --git a/version.php b/version.php index 021d7f7..d4133ee 100644 --- a/version.php +++ b/version.php @@ -29,10 +29,10 @@ $plugin->requires = 2021051700; $plugin->component = 'qtype_oumultiresponse'; $plugin->maturity = MATURITY_STABLE; -$plugin->release = '2.4 for Moodle 3.11+'; +$plugin->release = '2.5 for Moodle 5.0+'; -$plugin->dependencies = array( +$plugin->dependencies = [ 'qtype_multichoice' => 2020061500, -); +]; $plugin->outestssufficient = true;