From 261abe282b3e0bc0ce4b518776a05f4523082b65 Mon Sep 17 00:00:00 2001 From: Philipp Imhof <52650214+PhilippImhof@users.noreply.github.com> Date: Wed, 12 Mar 2025 07:41:42 +0100 Subject: [PATCH 1/5] add unit test for backup and restore (#166) --- tests/backup_restore_test.php | 195 +++++++++++++++++ tests/behat/export.feature | 2 +- tests/behat/mobile.feature | 2 +- tests/behat/quiz.feature | 2 +- tests/helper.php | 397 +++++++++++++++++++++------------- 5 files changed, 449 insertions(+), 149 deletions(-) create mode 100644 tests/backup_restore_test.php diff --git a/tests/backup_restore_test.php b/tests/backup_restore_test.php new file mode 100644 index 00000000..c27af3cf --- /dev/null +++ b/tests/backup_restore_test.php @@ -0,0 +1,195 @@ +. + +/** + * Unit tests for backup and restore. + * + * @package qtype_formulas + * @copyright 2025 Philipp Imhof + * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace qtype_formulas; + +use backup; +use backup_controller; +use context_course; +use core_question_generator; +use qtype_formulas; +use qtype_formulas_question; +use restore_controller; +use test_question_maker; + +defined('MOODLE_INTERNAL') || die(); + +global $CFG; +require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php'); +require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php'); +require_once($CFG->dirroot . '/mod/quiz/locallib.php'); +require_once($CFG->dirroot . '/mod/quiz/tests/quiz_question_helper_test_trait.php'); +require_once($CFG->dirroot . '/question/engine/tests/helpers.php'); +require_once($CFG->dirroot . '/question/type/formulas/questiontype.php'); +require_once($CFG->dirroot . '/question/type/formulas/tests/helper.php'); + +/** + * Unit tests for backup and restore. + * + * @copyright 2025 Philipp Imhof + * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * + * @covers \restore_qtype_formulas_plugin + * @covers \backup_qtype_formulas_plugin + * @covers \qtype_formulas + * @covers \qtype_formulas_question + * @covers \qtype_formulas_part + */ +final class backup_restore_test extends \advanced_testcase { + use \quiz_question_helper_test_trait; + + /** + * Create a question object of a certain type, as defined in the helper.php file. + * + * @return qtype_formulas_question + */ + protected function get_test_formulas_question($which = null) { + return test_question_maker::make_question('formulas', $which); + } + + /** + * Data provider. + * + * @return array + */ + public static function provide_question_names(): array { + return [ + ['testsinglenum'], + ['testsinglenumunit'], + ['testsinglenumunitsep'], + ['testtwonums'], + ['testthreeparts'], + ['test4'], + ['testmethodsinparts'], + ['testalgebraic'], + ]; + } + + /** + * Backup and restore a question and check whether the data matches. + * + * @param string $questionname name of the test question (e. g. testsinglenum) + * @dataProvider provide_question_names + */ + public function test_backup_and_restore(string $questionname): void { + global $USER, $DB; + + // Login as admin user. + $this->resetAfterTest(true); + $this->setAdminUser(); + + // Create a course and a quiz with a Formulas question. + $generator = $this->getDataGenerator(); + /** @var \core_question_generator $questiongenerator */ + $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question'); + $course = $generator->create_course(); + $context = context_course::instance($course->id); + $cat = $questiongenerator->create_question_category(['contextid' => $context->id]); + $question = $questiongenerator->create_question('formulas', $questionname, ['category' => $cat->id]); + quiz_add_quiz_question($question->id, $this->create_test_quiz($course)); + + // Backup course. By using MODE_IMPORT, we avoid the backup being zipped. + $bc = new backup_controller( + backup::TYPE_1COURSE, $course->id, backup::FORMAT_MOODLE, backup::INTERACTIVE_NO, backup::MODE_IMPORT, $USER->id + ); + $backupid = $bc->get_backupid(); + $bc->execute_plan(); + $bc->destroy(); + + // Delete the current course to make sure there is no data. + delete_course($course, false); + + // Create a new course and restore the backup. + $newcourse = $generator->create_course(); + $context = context_course::instance($newcourse->id); + $rc = new restore_controller( + $backupid, $newcourse->id, backup::INTERACTIVE_NO, backup::MODE_IMPORT, $USER->id, backup::TARGET_NEW_COURSE + ); + $rc->execute_precheck(); + $rc->execute_plan(); + $rc->destroy(); + + // Fetch the quiz and question ID. + $modules = get_fast_modinfo($newcourse->id)->get_instances_of('quiz'); + $quiz = reset($modules); + $structure = \mod_quiz\question\bank\qbank_helper::get_question_structure($quiz->instance, $quiz->context); + $question = reset($structure); + + // Fetch the question and its additional data (random vars, global vars, parts) from the DB. + $questionrecord = $DB->get_record('question', ['id' => $question->questionid], '*', MUST_EXIST); + $qtype = new qtype_formulas(); + $qtype->get_question_options($questionrecord); + + // Fetch the reference data for the given question. + $referencedata = test_question_maker::make_question('formulas', $questionname); + + // First, we check the data for the main question, i. e. basic fields plus custom data for the + // Formulas question like varsrandom or varsglobal. + $basicfields = [ + 'name', + 'questiontext', + 'questiontextformat', + 'generalfeedback', + 'generalfeedbackformat', + 'defaultmark', + 'penalty', + ]; + $questionfields = $basicfields + array_slice($qtype->extra_question_fields(), 1); + foreach ($questionfields as $field) { + self::assertEquals($referencedata->$field, $questionrecord->$field, $field); + } + + // Next, we check the fields for each part. + $partfields = qtype_formulas::PART_BASIC_FIELDS + ['subqtext', 'subqtextformat', 'feedback', 'feedbackformat']; + foreach ($partfields as $field) { + foreach ($questionrecord->options->answers as $i => $part) { + self::assertEquals($referencedata->parts[$i]->$field, $part->$field, $field); + } + } + + // Finally, we check the combined feedback fields for the parts and the main question. + $feedbackfields = ['correctfeedback', 'partiallycorrectfeedback', 'incorrectfeedback']; + foreach ($feedbackfields as $field) { + self::assertEquals($referencedata->$field, $questionrecord->options->$field, $field); + $fieldformat = $field . 'format'; + self::assertEquals($referencedata->$fieldformat, $questionrecord->options->$fieldformat, $fieldformat); + $origfield = $field; + foreach ($questionrecord->options->answers as $i => $part) { + $field = 'part' . str_replace('feedback', 'fb', $origfield); + self::assertEquals($referencedata->parts[$i]->$field, $part->$field, $field); + $fieldformat = $field . 'format'; + self::assertEquals($referencedata->parts[$i]->$fieldformat, $part->$fieldformat); + } + } + + // Finally, compare the hints. + $hintfields = ['hint', 'hintformat', 'shownumcorrect', 'clearwrong']; + $keys = array_keys($questionrecord->hints); + foreach ($referencedata->hints as $i => $hint) { + foreach ($hintfields as $field) { + self::assertEquals($hint->$field, $questionrecord->hints[$keys[$i]]->$field, $field); + } + } + } +} diff --git a/tests/behat/export.feature b/tests/behat/export.feature index 29c9a43c..1bdc0839 100644 --- a/tests/behat/export.feature +++ b/tests/behat/export.feature @@ -27,7 +27,7 @@ Feature: Test exporting Formulas questions When I am on the "Course 1" "core_question > course question export" page And I set the field "id_format_xml" to "1" And I press "Export questions to file" - Then following "click here" should download between "5400" and "5600" bytes + Then following "click here" should download between "6250" and "6500" bytes # If the download step is the last in the scenario then we can sometimes run # into the situation where the download page causes a http redirect but behat # has already conducted its reset (generating an error). By putting a logout diff --git a/tests/behat/mobile.feature b/tests/behat/mobile.feature index 49f8d8a7..67abcb6d 100644 --- a/tests/behat/mobile.feature +++ b/tests/behat/mobile.feature @@ -98,7 +98,7 @@ Feature: Mobile compatibility And I press "Submit" in the app And I press "Submit all and finish" in the app And I press "Submit" near "Once you submit" in the app - Then I should find "Your answer is correct." in the app + Then I should find "Correct answer, well done." in the app Scenario: Try to answer a question with one answer + one unit field When I press "Quiz 4" in the app diff --git a/tests/behat/quiz.feature b/tests/behat/quiz.feature index 26811045..1caf70e8 100644 --- a/tests/behat/quiz.feature +++ b/tests/behat/quiz.feature @@ -99,7 +99,7 @@ Feature: Usage in quiz And I press "Finish attempt" And I press "Submit all and finish" # And I confirm the quiz submission in the modal dialog - Then I should see "Your answer is correct." + Then I should see "Correct answer, well done." Scenario: Try to answer a question with one answer + one unit field When I follow "Quiz 4" diff --git a/tests/helper.php b/tests/helper.php index f087226f..89955ef3 100644 --- a/tests/helper.php +++ b/tests/helper.php @@ -113,7 +113,91 @@ protected static function make_a_formulas_part() { } /** - * @return qtype_formulas_question question, single part, one number as answer, no unit + * Create a single-part test question with answer type algebraic formula. + * + * @return qtype_formulas_question + */ + public static function make_formulas_question_testalgebraic() { + $q = self::make_a_formulas_question(); + + $q->name = 'test-algebraic'; + $q->questiontext = '
This is a minimal question. The answer is "5*x^2".
'; + + $q->penalty = 0.2; + $q->textfragments = [0 => 'This is a minimal question. The answer is "5*x^2".
', + 1 => '']; + $q->numparts = 1; + $q->defaultmark = 1; + $q->varsglobal = 'a=5;'; + $q->generalfeedback = ''; + $p = self::make_a_formulas_part(); + $p->id = 1; + $p->placeholder = ''; + $p->answermark = 1; + $p->vars1 = 'x={1:10}'; + $p->answer = '"a*x^2"'; + $p->answertype = strval(qtype_formulas::ANSWER_TYPE_ALGEBRAIC); + $p->answernotunique = '1'; + $p->correctness = '_err < 0.01'; + $p->subqtext = ''; + $p->partcorrectfb = 'Your answer is correct.'; + $p->partpartiallycorrectfb = 'Your answer is partially correct.'; + $p->partincorrectfb = 'Your answer is incorrect.'; + $q->parts[0] = $p; + return $q; + } + + /** + * Gets the question form data for the algebraic formulas question + * @return stdClass + */ + public function get_formulas_question_form_data_testalgebraic() { + $form = new stdClass(); + + $form->name = 'test-algebraic'; + $form->noanswers = 1; + $form->answer = ['"a*x^2"']; + $form->answernotunique = ['1']; + $form->answermark = [1]; + $form->answertype = [strval(qtype_formulas::ANSWER_TYPE_ALGEBRAIC)]; + $form->correctness = ['_err < 0.01']; + $form->numbox = [1]; + $form->placeholder = ['']; + $form->vars1 = ['x={1:10}']; + $form->vars2 = ['']; + $form->postunit = ['']; + $form->otherrule = ['']; + $form->subqtext = [['text' => '', 'format' => FORMAT_HTML]]; + $form->feedback = [['text' => '', 'format' => FORMAT_HTML]]; + $form->partcorrectfb = [['text' => 'Your answer is correct.', 'format' => FORMAT_HTML]]; + $form->partpartiallycorrectfb = [['text' => 'Your answer is partially correct.', 'format' => FORMAT_HTML]]; + $form->partincorrectfb = [['text' => 'Your answer is incorrect.', 'format' => FORMAT_HTML]]; + $form->questiontext = [ + 'text' => 'This is a minimal question. The answer is "5*x^2".
', + 'format' => FORMAT_HTML, + ]; + $form->generalfeedback = ['text' => '', 'format' => FORMAT_HTML]; + $form->defaultmark = 2; + $form->penalty = 0.2; + $form->varsrandom = ''; + $form->varsglobal = 'a=5;'; + $form->answernumbering = 'abc'; + $form->globalunitpenalty = 1; + $form->globalruleid = 1; + $form->correctfeedback = ['text' => test_question_maker::STANDARD_OVERALL_CORRECT_FEEDBACK, 'format' => FORMAT_HTML]; + $form->partiallycorrectfeedback = [ + 'text' => test_question_maker::STANDARD_OVERALL_PARTIALLYCORRECT_FEEDBACK, + 'format' => FORMAT_HTML, + ]; + $form->incorrectfeedback = ['text' => test_question_maker::STANDARD_OVERALL_INCORRECT_FEEDBACK, 'format' => FORMAT_HTML]; + $form->shownumcorrect = '1'; + return $form; + } + + /** + * Create a single-part test question with answer type number. + * + * @return qtype_formulas_question */ public static function make_formulas_question_testsinglenum() { $q = self::make_a_formulas_question(); @@ -187,10 +271,19 @@ public function get_formulas_question_form_data_testsinglenum() { $form->answernumbering = 'abc'; $form->globalunitpenalty = 1; $form->globalruleid = 1; - $form->correctfeedback = array('text' => '', 'format' => FORMAT_HTML); - $form->partiallycorrectfeedback = array('text' => '', 'format' => FORMAT_HTML); - $form->shownumcorrect = '0'; - $form->incorrectfeedback = array('text' => '', 'format' => FORMAT_HTML); + $form->correctfeedback = ['text' => test_question_maker::STANDARD_OVERALL_CORRECT_FEEDBACK, 'format' => FORMAT_HTML]; + $form->partiallycorrectfeedback = [ + 'text' => test_question_maker::STANDARD_OVERALL_PARTIALLYCORRECT_FEEDBACK, + 'format' => FORMAT_HTML, + ]; + $form->incorrectfeedback = ['text' => test_question_maker::STANDARD_OVERALL_INCORRECT_FEEDBACK, 'format' => FORMAT_HTML]; + $form->shownumcorrect = '1'; + $form->hint = [ + ['text' => 'Hint 1.', 'format' => FORMAT_HTML], + ['text' => 'Hint 2.', 'format' => FORMAT_HTML], + ]; + $form->hintclearwrong = [0, 1]; + $form->hintshownumcorrect = [1, 1]; return $form; } @@ -232,37 +325,35 @@ public function get_formulas_question_form_data_testsinglenumunit() { $form->name = 'test-0'; $form->noanswers = 1; - $form->answer = array('5'); - $form->answernotunique = array('1'); - $form->answermark = array(2); - $form->answertype = array(0); - $form->correctness = array('_relerr < 0.01'); - $form->numbox = array(1); - $form->placeholder = array(''); - $form->vars1 = array(''); - $form->vars2 = array(''); - $form->ruleid = array(1); - $form->unitpenalty = array(1); - $form->postunit = array('m/s'); - $form->otherrule = array(''); - $form->subqtext = array( - array('text' => '{_0}{_u}', 'format' => FORMAT_HTML) - ); - $form->feedback = array( - array('text' => '', 'format' => FORMAT_HTML) - ); - $form->partcorrectfb = array( - array('text' => 'Your answer is correct.', 'format' => FORMAT_HTML) - ); - $form->partpartiallycorrectfb = array( - array('text' => 'Your answer is partially correct.', 'format' => FORMAT_HTML) - ); - $form->partincorrectfb = array( - array('text' => 'Your answer is incorrect.', 'format' => FORMAT_HTML) - ); - $form->questiontext = array('text' => 'One part, one number plus unit, answer is 5 m/s
', - 'format' => FORMAT_HTML); - $form->generalfeedback = array('text' => '', 'format' => FORMAT_HTML); + $form->answer = ['5']; + $form->answernotunique = ['1']; + $form->answermark = [2]; + $form->answertype = ['0']; + $form->correctness = ['_relerr < 0.01']; + $form->numbox = [1]; + $form->placeholder = ['']; + $form->vars1 = ['']; + $form->vars2 = ['']; + $form->postunit = ['m/s']; + $form->otherrule = ['']; + $form->subqtext = [ + ['text' => '{_0}{_u}', 'format' => FORMAT_HTML], + ]; + $form->feedback = [ + ['text' => '', 'format' => FORMAT_HTML], + ]; + $form->partcorrectfb = [ + ['text' => 'Correct answer, well done.
', 'format' => FORMAT_HTML], + ]; + $form->partpartiallycorrectfb = [ + ['text' => 'Your answer is partially correct.
', 'format' => FORMAT_HTML], + ]; + $form->partincorrectfb = [ + ['text' => 'Incorrect answer.
', 'format' => FORMAT_HTML], + ]; + $form->questiontext = ['text' => 'One part, one number plus unit, answer is 5 m/s
', + 'format' => FORMAT_HTML]; + $form->generalfeedback = ['text' => '', 'format' => FORMAT_HTML]; $form->defaultmark = 2; $form->penalty = 0.3; $form->varsrandom = ''; @@ -270,10 +361,13 @@ public function get_formulas_question_form_data_testsinglenumunit() { $form->answernumbering = 'abc'; $form->globalunitpenalty = 1; $form->globalruleid = 1; - $form->correctfeedback = array('text' => '', 'format' => FORMAT_HTML); - $form->partiallycorrectfeedback = array('text' => '', 'format' => FORMAT_HTML); + $form->correctfeedback = ['text' => 'Well done!', 'format' => FORMAT_HTML]; + $form->partiallycorrectfeedback = [ + 'text' => 'Parts, but only parts, of your response are correct.', + 'format' => FORMAT_HTML, + ]; $form->shownumcorrect = '0'; - $form->incorrectfeedback = array('text' => '', 'format' => FORMAT_HTML); + $form->incorrectfeedback = ['text' => 'That is not right at all.', 'format' => FORMAT_HTML]; return $form; } @@ -313,7 +407,7 @@ public static function make_formulas_question_testsinglenumunitsep() { public function get_formulas_question_form_data_testsinglenumunitsep() { $form = new stdClass(); - $form->name = 'test-0'; + $form->name = 'test-singlenumunitsep'; $form->noanswers = 1; $form->answer = array('5'); $form->answernotunique = array('1'); @@ -353,10 +447,13 @@ public function get_formulas_question_form_data_testsinglenumunitsep() { $form->answernumbering = 'abc'; $form->globalunitpenalty = 1; $form->globalruleid = 1; - $form->correctfeedback = array('text' => '', 'format' => FORMAT_HTML); - $form->partiallycorrectfeedback = array('text' => '', 'format' => FORMAT_HTML); + $form->correctfeedback = ['text' => 'Well done!', 'format' => FORMAT_HTML]; + $form->partiallycorrectfeedback = [ + 'text' => 'Parts, but only parts, of your response are correct.', + 'format' => FORMAT_HTML, + ]; $form->shownumcorrect = '0'; - $form->incorrectfeedback = array('text' => '', 'format' => FORMAT_HTML); + $form->incorrectfeedback = ['text' => 'That is not right at all.', 'format' => FORMAT_HTML]; return $form; } @@ -379,6 +476,7 @@ public static function make_formulas_question_testtwonums() { $p->placeholder = ''; $p->answermark = 2; $p->answer = '[2, 3]'; + $p->numbox = 2; $p->answernotunique = '1'; $p->subqtext = ''; $p->partcorrectfb = 'Your answer is correct.'; @@ -397,37 +495,35 @@ public function get_formulas_question_form_data_testtwonums() { $form->name = 'test-1'; $form->noanswers = 1; - $form->answer = array('[2, 3]'); - $form->answernotunique = array('1'); - $form->answermark = array(2); - $form->answertype = array(0); - $form->correctness = array('_relerr < 0.01'); - $form->numbox = array(1, 1); - $form->placeholder = array(''); - $form->vars1 = array(''); - $form->vars2 = array(''); - $form->ruleid = array(1); - $form->unitpenalty = array(1); - $form->postunit = array(''); - $form->otherrule = array(''); - $form->subqtext = array( - array('text' => '', 'format' => FORMAT_HTML) - ); - $form->feedback = array( - array('text' => '', 'format' => FORMAT_HTML) - ); - $form->partcorrectfb = array( - array('text' => 'Your answer is correct.', 'format' => FORMAT_HTML) - ); - $form->partpartiallycorrectfb = array( - array('text' => 'Your answer is partially correct.', 'format' => FORMAT_HTML) - ); - $form->partincorrectfb = array( - array('text' => 'Your answer is incorrect.', 'format' => FORMAT_HTML) - ); - $form->questiontext = array('text' => 'Question with two numbers. The answers are 2 and 3.
', - 'format' => FORMAT_HTML); - $form->generalfeedback = array('text' => '', 'format' => FORMAT_HTML); + $form->answer = ['[2, 3]']; + $form->answernotunique = ['1']; + $form->answermark = [2]; + $form->answertype = ['0']; + $form->correctness = ['_relerr < 0.01']; + $form->numbox = [2]; + $form->placeholder = ['']; + $form->vars1 = ['']; + $form->vars2 = ['']; + $form->postunit = ['']; + $form->otherrule = ['']; + $form->subqtext = [ + ['text' => '', 'format' => FORMAT_HTML], + ]; + $form->feedback = [ + ['text' => '', 'format' => FORMAT_HTML], + ]; + $form->partcorrectfb = [ + ['text' => 'Your answer is correct.', 'format' => FORMAT_HTML], + ]; + $form->partpartiallycorrectfb = [ + ['text' => 'Your answer is partially correct.', 'format' => FORMAT_HTML], + ]; + $form->partincorrectfb = [ + ['text' => 'Your answer is incorrect.', 'format' => FORMAT_HTML], + ]; + $form->questiontext = ['text' => 'Question with two numbers. The answers are 2 and 3.
', + 'format' => FORMAT_HTML]; + $form->generalfeedback = ['text' => '', 'format' => FORMAT_HTML]; $form->defaultmark = 2; $form->penalty = 0.3; $form->varsrandom = ''; @@ -435,10 +531,13 @@ public function get_formulas_question_form_data_testtwonums() { $form->answernumbering = ''; $form->globalunitpenalty = 1; $form->globalruleid = 1; - $form->correctfeedback = array('text' => '', 'format' => FORMAT_HTML); - $form->partiallycorrectfeedback = array('text' => '', 'format' => FORMAT_HTML); + $form->correctfeedback = ['text' => 'Well done!', 'format' => FORMAT_HTML]; + $form->partiallycorrectfeedback = [ + 'text' => 'Parts, but only parts, of your response are correct.', + 'format' => FORMAT_HTML, + ]; $form->shownumcorrect = '0'; - $form->incorrectfeedback = array('text' => '', 'format' => FORMAT_HTML); + $form->incorrectfeedback = ['text' => 'That is not right at all.', 'format' => FORMAT_HTML]; return $form; } @@ -529,35 +628,38 @@ public function get_formulas_question_form_data_testthreeparts() { $form->otherrule = array('', '', ''); $form->globalunitpenalty = 1; $form->globalruleid = 1; - $form->subqtext = array( - array('text' => 'This is first part.', 'format' => FORMAT_HTML), - array('text' => 'This is second part.', 'format' => FORMAT_HTML), - array('text' => 'This is third part.', 'format' => FORMAT_HTML), - ); - $form->feedback = array( - array('text' => '', 'format' => FORMAT_HTML), - array('text' => '', 'format' => FORMAT_HTML), - array('text' => '', 'format' => FORMAT_HTML), - ); - $form->partcorrectfb = array( - array('text' => 'Part 1 correct feedback.', 'format' => FORMAT_HTML), - array('text' => 'Part 2 correct feedback.', 'format' => FORMAT_HTML), - array('text' => 'Part 3 correct feedback.', 'format' => FORMAT_HTML), - ); - $form->partpartiallycorrectfb = array( - array('text' => 'Part 1 partially correct feedback.', 'format' => FORMAT_HTML), - array('text' => 'Part 2 partially correct feedback.', 'format' => FORMAT_HTML), - array('text' => 'Part 3 partially correct feedback.', 'format' => FORMAT_HTML), - ); - $form->partincorrectfb = array( - array('text' => 'Part 1 incorrect feedback.', 'format' => FORMAT_HTML), - array('text' => 'Part 2 incorrect feedback.', 'format' => FORMAT_HTML), - array('text' => 'Part 3 incorrect feedback.', 'format' => FORMAT_HTML), - ); - $form->correctfeedback = array('text' => '', 'format' => FORMAT_HTML); - $form->partiallycorrectfeedback = array('text' => '', 'format' => FORMAT_HTML); + $form->subqtext = [ + ['text' => 'This is first part.', 'format' => FORMAT_HTML], + ['text' => 'This is second part.', 'format' => FORMAT_HTML], + ['text' => 'This is third part.', 'format' => FORMAT_HTML], + ]; + $form->feedback = [ + ['text' => '', 'format' => FORMAT_HTML], + ['text' => '', 'format' => FORMAT_HTML], + ['text' => '', 'format' => FORMAT_HTML], + ]; + $form->partcorrectfb = [ + ['text' => 'Part 1 correct feedback.', 'format' => FORMAT_HTML], + ['text' => 'Part 2 correct feedback.', 'format' => FORMAT_HTML], + ['text' => 'Part 3 correct feedback.', 'format' => FORMAT_HTML], + ]; + $form->partpartiallycorrectfb = [ + ['text' => 'Part 1 partially correct feedback.', 'format' => FORMAT_HTML], + ['text' => 'Part 2 partially correct feedback.', 'format' => FORMAT_HTML], + ['text' => 'Part 3 partially correct feedback.', 'format' => FORMAT_HTML], + ]; + $form->partincorrectfb = [ + ['text' => 'Part 1 incorrect feedback.', 'format' => FORMAT_HTML], + ['text' => 'Part 2 incorrect feedback.', 'format' => FORMAT_HTML], + ['text' => 'Part 3 incorrect feedback.', 'format' => FORMAT_HTML], + ]; + $form->correctfeedback = ['text' => 'Well done!', 'format' => FORMAT_HTML]; + $form->partiallycorrectfeedback = [ + 'text' => 'Parts, but only parts, of your response are correct.', + 'format' => FORMAT_HTML, + ]; $form->shownumcorrect = '0'; - $form->incorrectfeedback = array('text' => '', 'format' => FORMAT_HTML); + $form->incorrectfeedback = ['text' => 'That is not right at all.', 'format' => FORMAT_HTML]; $form->numhints = 2; $form->hint = array( array('text' => '', 'format' => FORMAT_HTML), @@ -580,7 +682,8 @@ public static function make_formulas_question_testmethodsinparts() { $q->defaultmark = 8; $q->penalty = 0.3; // Non-zero and not the default. $q->numpart = 4; - $q->textfragments = array(0 => 'This question shows different display methods of the answer and unit box.
', + $q->generalfeedback = 'This is the general feedback.'; + $q->textfragments = [0 => 'This question shows different display methods of the answer and unit box.
', 1 => '', 2 => '', 3 => '', @@ -643,9 +746,7 @@ public static function get_formulas_question_data_testmethodsinparts() { $qdata->qtype = 'formulas'; $qdata->name = 'test-2'; $qdata->questiontext = 'This question shows different display methods of the answer and unit box.
'; - $qdata->questiontextformat = FORMAT_HTML; - $qdata->generalfeedback = ''; - $qdata->generalfeedbackformat = FORMAT_HTML; + $qdata->generalfeedback = 'This is the general feedback.'; $qdata->defaultmark = 8; $qdata->length = 1; $qdata->penalty = 0.3; @@ -943,12 +1044,12 @@ public function get_formulas_question_form_data_testmethodsinparts() { $form->shownumcorrect = '0'; $form->incorrectfeedback = array('text' => '', 'format' => FORMAT_HTML); $form->numhints = 2; - $form->hint = array( - array('text' => '', 'format' => FORMAT_HTML), - array('text' => '', 'format' => FORMAT_HTML), - ); - $form->hintclearwrong = array('0', '0'); - $form->hintshownumcorrect = array('0', '0'); + $form->hint = [ + ['text' => 'Hint 1.', 'format' => FORMAT_HTML], + ['text' => 'Hint 2.', 'format' => FORMAT_HTML], + ]; + $form->hintclearwrong = [0, 1]; + $form->hintshownumcorrect = [1, 1]; return $form; } @@ -1042,7 +1143,8 @@ public static function make_formulas_question_test4() { $q->defaultmark = 8; $q->penalty = 0.3; // Non-zero and not the default. $q->numpart = 4; - $q->textfragments = array(0 => 'This question shows different display methods of the answer and unit box.
', + $q->generalfeedback = 'This is the general feedback.'; + $q->textfragments = [0 => 'This question shows different display methods of the answer and unit box.
', 1 => '', 2 => '', 3 => '', @@ -1139,37 +1241,40 @@ public function get_formulas_question_form_data_test4() { ), array( 'text' => 'If a car travels {s} m in {dt} s, what is the speed of the car? speed = {_0}{_u}
', - 'format' => FORMAT_HTML - ), - ); - $form->feedback = array( - array('text' => '', 'format' => FORMAT_HTML), - array('text' => '', 'format' => FORMAT_HTML), - array('text' => '', 'format' => FORMAT_HTML), - array('text' => '', 'format' => FORMAT_HTML), - ); - $form->partcorrectfb = array( - array('text' => '', 'format' => FORMAT_HTML), - array('text' => '', 'format' => FORMAT_HTML), - array('text' => '', 'format' => FORMAT_HTML), - array('text' => '', 'format' => FORMAT_HTML), - ); - $form->partpartiallycorrectfb = array( - array('text' => '', 'format' => FORMAT_HTML), - array('text' => '', 'format' => FORMAT_HTML), - array('text' => '', 'format' => FORMAT_HTML), - array('text' => '', 'format' => FORMAT_HTML), - ); - $form->partincorrectfb = array( - array('text' => '', 'format' => FORMAT_HTML), - array('text' => '', 'format' => FORMAT_HTML), - array('text' => '', 'format' => FORMAT_HTML), - array('text' => '', 'format' => FORMAT_HTML), - ); - $form->correctfeedback = array('text' => '', 'format' => FORMAT_HTML); - $form->partiallycorrectfeedback = array('text' => '', 'format' => FORMAT_HTML); + 'format' => FORMAT_HTML, + ], + ]; + $form->feedback = [ + ['text' => '', 'format' => FORMAT_HTML], + ['text' => '', 'format' => FORMAT_HTML], + ['text' => '', 'format' => FORMAT_HTML], + ['text' => '', 'format' => FORMAT_HTML], + ]; + $form->partcorrectfb = [ + ['text' => self::DEFAULT_CORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ['text' => self::DEFAULT_CORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ['text' => self::DEFAULT_CORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ['text' => self::DEFAULT_CORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ]; + $form->partpartiallycorrectfb = [ + ['text' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ['text' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ['text' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ['text' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ]; + $form->partincorrectfb = [ + ['text' => self::DEFAULT_INCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ['text' => self::DEFAULT_INCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ['text' => self::DEFAULT_INCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ['text' => self::DEFAULT_INCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ]; + $form->correctfeedback = ['text' => 'Well done!', 'format' => FORMAT_HTML]; + $form->partiallycorrectfeedback = [ + 'text' => 'Parts, but only parts, of your response are correct.', + 'format' => FORMAT_HTML, + ]; $form->shownumcorrect = '0'; - $form->incorrectfeedback = array('text' => '', 'format' => FORMAT_HTML); + $form->incorrectfeedback = ['text' => 'That is not right at all.', 'format' => FORMAT_HTML]; $form->numhints = 2; $form->hint = array( array('text' => '', 'format' => FORMAT_HTML), From cea5d345a1c4c6166a6f79d3b60737af8c884370 Mon Sep 17 00:00:00 2001 From: Philipp Imhof <52650214+PhilippImhof@users.noreply.github.com> Date: Sun, 16 Mar 2025 11:12:07 +0100 Subject: [PATCH 2/5] add unit test for backup and restore --- tests/backup_restore_test.php | 2 +- tests/helper.php | 1582 +++++++++++++++++++++------------ 2 files changed, 990 insertions(+), 594 deletions(-) diff --git a/tests/backup_restore_test.php b/tests/backup_restore_test.php index c27af3cf..646efd39 100644 --- a/tests/backup_restore_test.php +++ b/tests/backup_restore_test.php @@ -161,7 +161,7 @@ public function test_backup_and_restore(string $questionname): void { } // Next, we check the fields for each part. - $partfields = qtype_formulas::PART_BASIC_FIELDS + ['subqtext', 'subqtextformat', 'feedback', 'feedbackformat']; + $partfields = $qtype->part_tags() + ['subqtext', 'subqtextformat', 'feedback', 'feedbackformat']; foreach ($partfields as $field) { foreach ($questionrecord->options->answers as $i => $part) { self::assertEquals($referencedata->parts[$i]->$field, $part->$field, $field); diff --git a/tests/helper.php b/tests/helper.php index 89955ef3..88a80f42 100644 --- a/tests/helper.php +++ b/tests/helper.php @@ -14,41 +14,59 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, seeCorrect answer, well done.
'; + /** @var string */ + const DEFAULT_CORRECT_FEEDBACK = 'Correct answer, well done.
'; + + /** @var string */ const DEFAULT_PARTIALLYCORRECT_FEEDBACK = 'Your answer is partially correct.
'; - const DEFAULT_INCORRECT_FEEDBACK = 'Incorrect answer.
'; - - public function get_test_questions() { - return array( - 'testsinglenum', // Minimal formulas question : one part, not randomised (answer = 5), - 'testtwonums', // Minimal formulas question : one part, two numbers (2 and 3), - 'testsinglenumunit', // one part, one number with unit (answer: 5 m/s), - 'testsinglenumunitsep', // one part, one number plus separate unit (answer: 5 m/s), - 'testzero', // one part, not randomized, answer = 0 (to test problem with 0 as answer), - 'testmce', // One part not randomized drowdown multichoice answer. - 'testmc', // One part not randomized radiobutton multichoice answer. - 'testthreeparts', // 3 parts, not randomised. (answers = 5, 6, 7), - 'testmethodsinparts', // 4 parts, separated and combined unit field, not ramdomized, - 'testmcetwoparts', // 2 parts, each one with an MCE (dropdown) question - 'testmctwoparts', // 2 parts, each one with an MC (radio) question - 'testtwoandtwo', // 2 parts, each one with 2 numbers - 'test4', // 4 parts, separated and combined unit field, ramdomized. - ); + + /** @var string */ + const DEFAULT_INCORRECT_FEEDBACK = 'Incorrect answer.
'; + + /** + * Return a list of possible test questions. + * + * @return array + */ + public function get_test_questions(): array { + return [ + // Minimal formulas question: one part, not randomised, answer = 5. + 'testsinglenum', + // Formulas question with algebraic answer. + 'testalgebraic', + // Minimal formulas question: one part, two numbers, answer = 2 and 3. + 'testtwonums', + // Formulas question with one part, one number with unit (combined), answer = 5 m/s. + 'testsinglenumunit', + // Formulas question with one part, one number with unit (separate), answer = 5 m/s. + 'testsinglenumunitsep', + // Formulas question with one part, not randomized, answer = 0, used to test for problems with 0 as answer. + 'testzero', + // Formulas question with one part, not randomized, drowdown multichoice answer. + 'testmce', + // Formulas question with one part, not randomized, radio button multichoice answer. + 'testmc', + // Formulas question with 3 parts, not randomised, answers = 5, 6, 7. + 'testthreeparts', + // Formulas question with 4 parts, not randomised, separate and combined unit fields. + 'testmethodsinparts', + // Formulas question with 2 parts, each with a drowdown multichoice answer. + 'testmcetwoparts', + // Formulas question with 2 parts, each with a radio button multichoice answer. + 'testmctwoparts', + // Formulas question with 2 parts, each one with 2 numbers. + 'testtwoandtwo', + // Formulas question with 4 parts, randomised, separate and combined unit fields. + 'test4', + ]; } /** @@ -65,28 +83,29 @@ protected static function make_a_formulas_question() { $q->contextid = context_system::instance()->id; $q->varsrandom = ''; $q->varsglobal = ''; - $q->shownumcorrect = 0; $q->answernumbering = 'abc'; - $q->qv = new qtype_formulas\variables(); - $q->penalty = 0.2; // The default. + $q->penalty = 0.2; + $q->generalfeedback = ''; test_question_maker::set_standard_combined_feedback_fields($q); + $q->shownumcorrect = 1; $q->numpart = 0; // This is of course invalid but should be changed by all tests. - $q->parts = array(); - $q->evaluatedanswer = array(); - $q->fractions = array(); - $q->anscorrs = array(); - $q->unitcorrs = array(); + $q->parts = []; return $q; } - protected static function make_a_formulas_part() { + /** + * Create a qtype_formulas_part object for testing. + * + * @return qtype_formulas_part + */ + protected static function make_a_formulas_part(): qtype_formulas_part { question_bank::load_question_definition_classes('formulas'); $p = new qtype_formulas_part(); $p->id = 0; $p->placeholder = ''; $p->answermark = 1; - $p->answertype = 0; + $p->answertype = '0'; $p->numbox = 1; $p->vars1 = ''; $p->vars2 = ''; @@ -98,15 +117,15 @@ protected static function make_a_formulas_part() { $p->ruleid = 1; $p->otherrule = ''; $p->subqtext = ''; - $p->subqtextformat = 1; + $p->subqtextformat = FORMAT_HTML; $p->feedback = ''; - $p->feedbackformat = 1; - $p->partcorrectfb = ''; - $p->partcorrectfbformat = 1; - $p->partpartiallycorrectfb = ''; - $p->partpartiallycorrectfbformat = 1; - $p->partincorrectfb = ''; - $p->partincorrectfbformat = 1; + $p->feedbackformat = FORMAT_HTML; + $p->partcorrectfb = self::DEFAULT_CORRECT_FEEDBACK; + $p->partcorrectfbformat = FORMAT_HTML; + $p->partpartiallycorrectfb = self::DEFAULT_PARTIALLYCORRECT_FEEDBACK; + $p->partpartiallycorrectfbformat = FORMAT_HTML; + $p->partincorrectfb = self::DEFAULT_INCORRECT_FEEDBACK; + $p->partincorrectfbformat = FORMAT_HTML; $p->partindex = 0; return $p; @@ -126,7 +145,7 @@ public static function make_formulas_question_testalgebraic() { $q->penalty = 0.2; $q->textfragments = [0 => 'This is a minimal question. The answer is "5*x^2".
', 1 => '']; - $q->numparts = 1; + $q->numpart = 1; $q->defaultmark = 1; $q->varsglobal = 'a=5;'; $q->generalfeedback = ''; @@ -136,7 +155,7 @@ public static function make_formulas_question_testalgebraic() { $p->answermark = 1; $p->vars1 = 'x={1:10}'; $p->answer = '"a*x^2"'; - $p->answertype = strval(qtype_formulas::ANSWER_TYPE_ALGEBRAIC); + $p->answertype = '1000'; $p->answernotunique = '1'; $p->correctness = '_err < 0.01'; $p->subqtext = ''; @@ -159,7 +178,7 @@ public function get_formulas_question_form_data_testalgebraic() { $form->answer = ['"a*x^2"']; $form->answernotunique = ['1']; $form->answermark = [1]; - $form->answertype = [strval(qtype_formulas::ANSWER_TYPE_ALGEBRAIC)]; + $form->answertype = ['1000']; $form->correctness = ['_err < 0.01']; $form->numbox = [1]; $form->placeholder = ['']; @@ -202,68 +221,71 @@ public function get_formulas_question_form_data_testalgebraic() { public static function make_formulas_question_testsinglenum() { $q = self::make_a_formulas_question(); - $q->name = 'test-0'; + $q->name = 'test-singlenum'; $q->questiontext = 'This is a minimal question. The answer is 5.
'; $q->penalty = 0.3; // Non-zero and not the default. - $q->textfragments = array(0 => 'This is a minimal question. The answer is 5.
', - 1 => ''); + $q->textfragments = [0 => 'This is a minimal question. The answer is 5.
', + 1 => '']; $q->numpart = 1; $q->defaultmark = 2; + $q->generalfeedback = ''; $p = self::make_a_formulas_part(); + $p->questionid = $q->id; $p->id = 14; $p->placeholder = ''; $p->answermark = 2; $p->answer = '5'; $p->answernotunique = '1'; $p->subqtext = ''; - $p->partcorrectfb = 'Your answer is correct.'; - $p->partpartiallycorrectfb = 'Your answer is partially correct.'; - $p->partincorrectfb = 'Your answer is incorrect.'; $q->parts[0] = $p; + + $q->hints = [ + new question_hint_with_parts(101, 'Hint 1.', FORMAT_HTML, 1, 0), + new question_hint_with_parts(102, 'Hint 2.', FORMAT_HTML, 1, 1), + ]; return $q; } /** * Gets the question form data for the singlenum formulas question + * * @return stdClass */ - public function get_formulas_question_form_data_testsinglenum() { + public function get_formulas_question_form_data_testsinglenum(): stdClass { $form = new stdClass(); - $form->name = 'test-0'; + $form->name = 'test-singlenum'; $form->noanswers = 1; - $form->answer = array('5'); - $form->answernotunique = array('1'); - $form->answermark = array(2); - $form->answertype = array(0); - $form->correctness = array('_relerr < 0.01'); - $form->numbox = array(1); - $form->placeholder = array(''); - $form->vars1 = array(''); - $form->vars2 = array(''); - $form->ruleid = array(1); - $form->unitpenalty = array(1); - $form->postunit = array(''); - $form->otherrule = array(''); - $form->subqtext = array( - array('text' => '', 'format' => FORMAT_HTML) - ); - $form->feedback = array( - array('text' => '', 'format' => FORMAT_HTML) - ); - $form->partcorrectfb = array( - array('text' => 'Your answer is correct.', 'format' => FORMAT_HTML) - ); - $form->partpartiallycorrectfb = array( - array('text' => 'Your answer is partially correct.', 'format' => FORMAT_HTML) - ); - $form->partincorrectfb = array( - array('text' => 'Your answer is incorrect.', 'format' => FORMAT_HTML) - ); - $form->questiontext = array('text' => 'This is a minimal question. The answer is 5.
', - 'format' => FORMAT_HTML); - $form->generalfeedback = array('text' => '', 'format' => FORMAT_HTML); + $form->answer = ['5']; + $form->answernotunique = ['1']; + $form->answermark = [2]; + $form->answertype = ['0']; + $form->correctness = ['_relerr < 0.01']; + $form->numbox = [1]; + $form->placeholder = ['']; + $form->vars1 = ['']; + $form->vars2 = ['']; + $form->postunit = ['']; + $form->otherrule = ['']; + $form->subqtext = [ + ['text' => '', 'format' => FORMAT_HTML], + ]; + $form->feedback = [ + ['text' => '', 'format' => FORMAT_HTML], + ]; + $form->partcorrectfb = [ + ['text' => self::DEFAULT_CORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ]; + $form->partpartiallycorrectfb = [ + ['text' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ]; + $form->partincorrectfb = [ + ['text' => self::DEFAULT_INCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ]; + $form->questiontext = ['text' => 'This is a minimal question. The answer is 5.
', + 'format' => FORMAT_HTML]; + $form->generalfeedback = ['text' => '', 'format' => FORMAT_HTML]; $form->defaultmark = 2; $form->penalty = 0.3; $form->varsrandom = ''; @@ -288,30 +310,118 @@ public function get_formulas_question_form_data_testsinglenum() { } /** - * @return qtype_formulas_question one part, one number with unit + * Return question data for a single-part question with answer type number. + * + * @return stdClass */ - public static function make_formulas_question_testsinglenumunit() { + public static function get_formulas_question_data_testsinglenum(): stdClass { + $qdata = new stdClass(); + test_question_maker::initialise_question_data($qdata); + + $qdata->qtype = 'formulas'; + $qdata->name = 'test-singlenum'; + $qdata->questiontext = 'This is a minimal question. The answer is 5.
'; + $qdata->generalfeedback = ''; + $qdata->defaultmark = 2; + $qdata->penalty = 0.3; + + $qdata->options = new stdClass(); + $qdata->contextid = context_system::instance()->id; + $qdata->options->varsrandom = ''; + $qdata->options->varsglobal = ''; + $qdata->options->answernumbering = 'abc'; + $qdata->options->shownumcorrect = 1; + $qdata->options->correctfeedback = + test_question_maker::STANDARD_OVERALL_CORRECT_FEEDBACK; + $qdata->options->correctfeedbackformat = FORMAT_HTML; + $qdata->options->partiallycorrectfeedback = + test_question_maker::STANDARD_OVERALL_PARTIALLYCORRECT_FEEDBACK; + $qdata->options->partiallycorrectfeedbackformat = FORMAT_HTML; + $qdata->options->incorrectfeedback = + test_question_maker::STANDARD_OVERALL_INCORRECT_FEEDBACK; + $qdata->options->incorrectfeedbackformat = FORMAT_HTML; + + $qdata->options->answers = [ + 14 => (object) [ + 'id' => 14, + 'questionid' => $qdata->id, + 'placeholder' => '', + 'answermark' => 2, + 'answertype' => '0', + 'numbox' => 1, + 'vars1' => '', + 'vars2' => '', + 'answer' => '5', + 'answernotunique' => '1', + 'correctness' => '_relerr < 0.01', + 'unitpenalty' => 1, + 'postunit' => '', + 'ruleid' => 1, + 'otherrule' => '', + 'subqtext' => '', + 'subqtextformat' => FORMAT_HTML, + 'feedback' => '', + 'feedbackformat' => FORMAT_HTML, + 'partcorrectfb' => self::DEFAULT_CORRECT_FEEDBACK, + 'partcorrectfbformat' => FORMAT_HTML, + 'partpartiallycorrectfb' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, + 'partpartiallycorrectfbformat' => FORMAT_HTML, + 'partincorrectfb' => self::DEFAULT_INCORRECT_FEEDBACK, + 'partincorrectfbformat' => FORMAT_HTML, + 'partindex' => 0, + ], + ]; + + $qdata->options->numpart = 1; + + $qdata->hints = [ + (object) [ + 'id' => '101', + 'hint' => 'Hint 1.', + 'hintformat' => FORMAT_HTML, + 'shownumcorrect' => 1, + 'clearwrong' => 0, + 'options' => 0, + ], + (object) [ + 'id' => '102', + 'hint' => 'Hint 2.', + 'hintformat' => FORMAT_HTML, + 'shownumcorrect' => 1, + 'clearwrong' => 1, + 'options' => 1, + ], + ]; + + return $qdata; + } + + /** + * Return Formulas question with one part, one number with unit (combined), answer = 5 m/s. + * + * @return qtype_formulas_question + */ + public static function make_formulas_question_testsinglenumunit(): qtype_formulas_question { $q = self::make_a_formulas_question(); - $q->name = 'test-0'; + $q->name = 'test-singlenumunit'; $q->questiontext = 'One part, one number plus unit, answer is 5 m/s
'; $q->penalty = 0.3; - $q->textfragments = array(0 => 'One part, one number plus unit, answer is 5 m/s
', - 1 => ''); + $q->textfragments = [0 => 'One part, one number plus unit, answer is 5 m/s
', + 1 => '']; $q->numpart = 1; $q->defaultmark = 2; $p = self::make_a_formulas_part(); $p->id = 14; + $p->questionid = $q->id; $p->placeholder = ''; $p->answermark = 2; $p->answer = '5'; $p->answernotunique = '1'; $p->postunit = 'm/s'; $p->subqtext = '{_0}{_u}'; - $p->partcorrectfb = 'Your answer is correct.'; - $p->partpartiallycorrectfb = 'Your answer is partially correct.'; - $p->partincorrectfb = 'Your answer is incorrect.'; + $q->parts[0] = $p; return $q; } @@ -323,7 +433,7 @@ public static function make_formulas_question_testsinglenumunit() { public function get_formulas_question_form_data_testsinglenumunit() { $form = new stdClass(); - $form->name = 'test-0'; + $form->name = 'test-singlenumunit'; $form->noanswers = 1; $form->answer = ['5']; $form->answernotunique = ['1']; @@ -372,30 +482,104 @@ public function get_formulas_question_form_data_testsinglenumunit() { } /** - * @return qtype_formulas_question one part, one number plus unit + * Get question data for the testsinglenumunit question. + * + * @return stdClass */ - public static function make_formulas_question_testsinglenumunitsep() { + public static function get_formulas_question_data_testsinglenumunit(): stdClass { + $qdata = new stdClass(); + test_question_maker::initialise_question_data($qdata); + + $qdata->qtype = 'formulas'; + $qdata->name = 'test-singlenumunit'; + $qdata->questiontext = 'One part, one number plus unit, answer is 5 m/s
'; + $qdata->generalfeedback = ''; + $qdata->defaultmark = 2; + $qdata->penalty = 0.3; + + $qdata->options = new stdClass(); + $qdata->contextid = context_system::instance()->id; + $qdata->options->varsrandom = ''; + $qdata->options->varsglobal = ''; + $qdata->options->answernumbering = 'abc'; + $qdata->options->shownumcorrect = 1; + $qdata->options->correctfeedback = + test_question_maker::STANDARD_OVERALL_CORRECT_FEEDBACK; + $qdata->options->correctfeedbackformat = FORMAT_HTML; + $qdata->options->partiallycorrectfeedback = + test_question_maker::STANDARD_OVERALL_PARTIALLYCORRECT_FEEDBACK; + $qdata->options->partiallycorrectfeedbackformat = FORMAT_HTML; + $qdata->options->incorrectfeedback = + test_question_maker::STANDARD_OVERALL_INCORRECT_FEEDBACK; + $qdata->options->incorrectfeedbackformat = FORMAT_HTML; + + $qdata->options->answers = [ + 14 => (object) [ + 'id' => 14, + 'questionid' => $qdata->id, + 'placeholder' => '', + 'answermark' => 2, + 'answertype' => '0', + 'numbox' => 1, + 'vars1' => '', + 'vars2' => '', + 'answer' => '5', + 'answernotunique' => '1', + 'correctness' => '_relerr < 0.01', + 'unitpenalty' => 1, + 'postunit' => 'm/s', + 'ruleid' => 1, + 'otherrule' => '', + 'subqtext' => '{_0}{_u}', + 'subqtextformat' => FORMAT_HTML, + 'feedback' => '', + 'feedbackformat' => FORMAT_HTML, + 'partcorrectfb' => self::DEFAULT_CORRECT_FEEDBACK, + 'partcorrectfbformat' => FORMAT_HTML, + 'partpartiallycorrectfb' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, + 'partpartiallycorrectfbformat' => FORMAT_HTML, + 'partincorrectfb' => self::DEFAULT_INCORRECT_FEEDBACK, + 'partincorrectfbformat' => FORMAT_HTML, + 'partindex' => 0, + ], + ]; + + $qdata->options->numpart = 1; + + return $qdata; + } + + /** + * Return Formulas question with one part, one number with unit (separate), answer = 5 m/s. + * + * @return qtype_formulas_question + */ + public static function make_formulas_question_testsinglenumunitsep(): qtype_formulas_question { $q = self::make_a_formulas_question(); - $q->name = 'test-0'; + $q->name = 'test-singlenumunitsep'; $q->questiontext = 'One part, one number plus unit, answer is 5 m/s
'; $q->penalty = 0.3; - $q->textfragments = array(0 => 'One part, one number plus unit, answer is 5 m/s
', - 1 => ''); + $q->textfragments = [ + 0 => 'One part, one number plus unit, answer is 5 m/s
', + 1 => '', + ]; $q->numpart = 1; $q->defaultmark = 2; + $p = self::make_a_formulas_part(); $p->id = 14; + $p->questionid = $q->id; $p->placeholder = ''; $p->answermark = 2; $p->answer = '5'; $p->answernotunique = '1'; $p->postunit = 'm/s'; $p->subqtext = '{_0} {_u}'; - $p->partcorrectfb = 'Your answer is correct.'; - $p->partpartiallycorrectfb = 'Your answer is partially correct.'; - $p->partincorrectfb = 'Your answer is incorrect.'; + $p->partcorrectfb = self::DEFAULT_CORRECT_FEEDBACK; + $p->partpartiallycorrectfb = self::DEFAULT_PARTIALLYCORRECT_FEEDBACK; + $p->partincorrectfb = self::DEFAULT_INCORRECT_FEEDBACK; $q->parts[0] = $p; return $q; } @@ -409,37 +593,37 @@ public function get_formulas_question_form_data_testsinglenumunitsep() { $form->name = 'test-singlenumunitsep'; $form->noanswers = 1; - $form->answer = array('5'); - $form->answernotunique = array('1'); - $form->answermark = array(2); - $form->answertype = array(0); - $form->correctness = array('_relerr < 0.01'); - $form->numbox = array(1); - $form->placeholder = array(''); - $form->vars1 = array(''); - $form->vars2 = array(''); - $form->ruleid = array(1); - $form->unitpenalty = array(1); - $form->postunit = array('m/s'); - $form->otherrule = array(''); - $form->subqtext = array( - array('text' => '{_0} {_u}', 'format' => FORMAT_HTML) - ); - $form->feedback = array( - array('text' => '', 'format' => FORMAT_HTML) - ); - $form->partcorrectfb = array( - array('text' => 'Your answer is correct.', 'format' => FORMAT_HTML) - ); - $form->partpartiallycorrectfb = array( - array('text' => 'Your answer is partially correct.', 'format' => FORMAT_HTML) - ); - $form->partincorrectfb = array( - array('text' => 'Your answer is incorrect.', 'format' => FORMAT_HTML) - ); - $form->questiontext = array('text' => 'One part, one number plus unit, answer is 5 m/s
', - 'format' => FORMAT_HTML); - $form->generalfeedback = array('text' => '', 'format' => FORMAT_HTML); + $form->answer = ['5']; + $form->answernotunique = ['1']; + $form->answermark = [2]; + $form->answertype = ['0']; + $form->correctness = ['_relerr < 0.01']; + $form->numbox = [1]; + $form->placeholder = ['']; + $form->vars1 = ['']; + $form->vars2 = ['']; + $form->postunit = ['m/s']; + $form->otherrule = ['']; + $form->subqtext = [ + ['text' => '{_0} {_u}', 'format' => FORMAT_HTML], + ]; + $form->feedback = [ + ['text' => '', 'format' => FORMAT_HTML], + ]; + $form->partcorrectfb = [ + ['text' => self::DEFAULT_CORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ]; + $form->partpartiallycorrectfb = [ + ['text' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ]; + $form->partincorrectfb = [ + ['text' => self::DEFAULT_INCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ]; + $form->questiontext = [ + 'text' => 'One part, one number plus unit, answer is 5 m/s
', + 'format' => FORMAT_HTML, + ]; + $form->generalfeedback = ['text' => '', 'format' => FORMAT_HTML]; $form->defaultmark = 2; $form->penalty = 0.3; $form->varsrandom = ''; @@ -458,21 +642,92 @@ public function get_formulas_question_form_data_testsinglenumunitsep() { } /** - * @return qtype_formulas_question question, single part, one number as answer, no unit + * Return question data for the testsinglenumunitsep question. + * + * @return stdClass + */ + public static function get_formulas_question_data_testsinglenumunitsep(): stdClass { + $qdata = new stdClass(); + test_question_maker::initialise_question_data($qdata); + + $qdata->qtype = 'formulas'; + $qdata->name = 'test-singlenumunitsep'; + $qdata->questiontext = 'One part, one number plus unit, answer is 5 m/s
'; + $qdata->generalfeedback = ''; + $qdata->defaultmark = 2; + $qdata->penalty = 0.3; + + $qdata->options = new stdClass(); + $qdata->contextid = context_system::instance()->id; + $qdata->options->varsrandom = ''; + $qdata->options->varsglobal = ''; + $qdata->options->answernumbering = 'abc'; + $qdata->options->shownumcorrect = 1; + $qdata->options->correctfeedback = test_question_maker::STANDARD_OVERALL_CORRECT_FEEDBACK; + $qdata->options->correctfeedbackformat = FORMAT_HTML; + $qdata->options->partiallycorrectfeedback = test_question_maker::STANDARD_OVERALL_PARTIALLYCORRECT_FEEDBACK; + $qdata->options->partiallycorrectfeedbackformat = FORMAT_HTML; + $qdata->options->incorrectfeedback = test_question_maker::STANDARD_OVERALL_INCORRECT_FEEDBACK; + $qdata->options->incorrectfeedbackformat = FORMAT_HTML; + + $qdata->options->answers = [ + 14 => (object)[ + 'id' => 14, + 'questionid' => $qdata->id, + 'placeholder' => '', + 'answermark' => 2, + 'answertype' => '0', + 'numbox' => 1, + 'vars1' => '', + 'vars2' => '', + 'answer' => '5', + 'answernotunique' => '1', + 'correctness' => '_relerr < 0.01', + 'unitpenalty' => 1, + 'postunit' => 'm/s', + 'ruleid' => 1, + 'otherrule' => '', + 'subqtext' => '{_0} {_u}', + 'subqtextformat' => FORMAT_HTML, + 'feedback' => '', + 'feedbackformat' => FORMAT_HTML, + 'partcorrectfb' => self::DEFAULT_CORRECT_FEEDBACK, + 'partcorrectfbformat' => FORMAT_HTML, + 'partpartiallycorrectfb' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, + 'partpartiallycorrectfbformat' => FORMAT_HTML, + 'partincorrectfb' => self::DEFAULT_INCORRECT_FEEDBACK, + 'partincorrectfbformat' => FORMAT_HTML, + 'partindex' => 0, + ], + ]; + + $qdata->options->numpart = 1; + + return $qdata; + } + + /** + * Return Formulas question: one part, two numbers, answer = 2 and 3. + * + * @return qtype_formulas_question */ - public static function make_formulas_question_testtwonums() { + public static function make_formulas_question_testtwonums(): qtype_formulas_question { $q = self::make_a_formulas_question(); $q->name = 'test-1'; $q->questiontext = 'Question with two numbers. The answers are 2 and 3.
'; $q->penalty = 0.3; // Non-zero and not the default. - $q->textfragments = array(0 => 'Question with two numbers. The answers are 2 and 3.
', - 1 => ''); + $q->textfragments = [ + 0 => 'Question with two numbers. The answers are 2 and 3.
', + 1 => '', + ]; $q->numpart = 1; $q->defaultmark = 2; + $p = self::make_a_formulas_part(); $p->id = 14; + $p->questionid = $q->id; $p->placeholder = ''; $p->answermark = 2; $p->answer = '[2, 3]'; @@ -542,19 +797,20 @@ public function get_formulas_question_form_data_testtwonums() { } /** + * Return Formulas question with 3 parts, not randomised, answers = 5, 6, 7. + * * @return qtype_formulas_question with 3 parts. - * this version is non randomized to ease testing */ - public static function make_formulas_question_testthreeparts() { + public static function make_formulas_question_testthreeparts(): qtype_formulas_question { $q = self::make_a_formulas_question(); $q->name = 'test-1'; $q->questiontext = 'Multiple parts : --{#1}--{#2}--{#3}
'; $q->penalty = 0.3; // Non-zero and not the default. - $q->textfragments = array(0 => 'Multiple parts : --', + $q->textfragments = [0 => '
Multiple parts : --', 1 => '--', 2 => '--', - 3 => '
'); + 3 => '']; $q->numpart = 3; $q->defaultmark = 6; $p0 = self::make_a_formulas_part(); @@ -604,28 +860,26 @@ public function get_formulas_question_form_data_testthreeparts() { $form = new stdClass(); $form->name = 'test-1'; - $form->questiontext = array('text' => 'Multiple parts : --{#1}--{#2}--{#3}
', - 'format' => FORMAT_HTML); - $form->generalfeedback = array('text' => '', 'format' => FORMAT_HTML); + $form->questiontext = ['text' => 'Multiple parts : --{#1}--{#2}--{#3}
', + 'format' => FORMAT_HTML]; + $form->generalfeedback = ['text' => '', 'format' => FORMAT_HTML]; $form->defaultmark = 6; $form->penalty = 0.3; $form->varsrandom = ''; $form->varsglobal = ''; $form->answernumbering = 'abc'; $form->noanswers = 3; - $form->answer = array('5', '6', '7'); - $form->answernotunique = array('1', '1', '1'); - $form->answermark = array('2', '2', '2'); - $form->numbox = array(1, 1, 1); - $form->placeholder = array('#1', '#2', '#3'); - $form->postunit = array('', '', ''); - $form->answertype = array(0, 0, 0); - $form->vars1 = array('', '', ''); - $form->correctness = array('_relerr < 0.01', '_relerr < 0.01', '_relerr < 0.01'); - $form->vars2 = array('', '', ''); - $form->unitpenalty = array(1, 1, 1); - $form->ruleid = array('1', '1', '1'); - $form->otherrule = array('', '', ''); + $form->answer = ['5', '6', '7']; + $form->answernotunique = ['1', '1', '1']; + $form->answermark = ['2', '2', '2']; + $form->numbox = [1, 1, 1]; + $form->placeholder = ['#1', '#2', '#3']; + $form->postunit = ['', '', '']; + $form->answertype = ['0', '0', '0']; + $form->vars1 = ['', '', '']; + $form->correctness = ['_relerr < 0.01', '_relerr < 0.01', '_relerr < 0.01']; + $form->vars2 = ['', '', '']; + $form->otherrule = ['', '', '']; $form->globalunitpenalty = 1; $form->globalruleid = 1; $form->subqtext = [ @@ -661,23 +915,24 @@ public function get_formulas_question_form_data_testthreeparts() { $form->shownumcorrect = '0'; $form->incorrectfeedback = ['text' => 'That is not right at all.', 'format' => FORMAT_HTML]; $form->numhints = 2; - $form->hint = array( - array('text' => '', 'format' => FORMAT_HTML), - array('text' => '', 'format' => FORMAT_HTML), - ); - $form->hintclearwrong = array('0', '0'); - $form->hintshownumcorrect = array('0', '0'); + $form->hint = [ + ['text' => '', 'format' => FORMAT_HTML], + ['text' => '', 'format' => FORMAT_HTML], + ]; + $form->hintclearwrong = ['0', '0']; + $form->hintshownumcorrect = ['0', '0']; return $form; } /** - * @return qtype_formulas_question the question from the test1.xml file. - * Non randomized version for Behat tests. + * Return Formulas question with 4 parts, not randomised, separate and combined unit fields. + * + * @return qtype_formulas_question */ - public static function make_formulas_question_testmethodsinparts() { + public static function make_formulas_question_testmethodsinparts(): qtype_formulas_question { $q = self::make_a_formulas_question(); - $q->name = 'test-2'; + $q->name = 'test-methodsinparts'; $q->questiontext = 'This question shows different display methods of the answer and unit box.
'; $q->defaultmark = 8; $q->penalty = 0.3; // Non-zero and not the default. @@ -688,10 +943,12 @@ public static function make_formulas_question_testmethodsinparts() { 2 => '', 3 => '', 4 => '', - ); + ]; $q->varsrandom = ''; $q->varsglobal = 'v = 40;dt = 3;s = v*dt;'; + $p0 = self::make_a_formulas_part(); + $p0->questionid = $q->id; $p0->id = 14; $p0->partindex = 0; $p0->answermark = 2; @@ -700,7 +957,9 @@ public static function make_formulas_question_testmethodsinparts() { $p0->answernotunique = '1'; $p0->postunit = 'm/s'; $q->parts[0] = $p0; + $p1 = self::make_a_formulas_part(); + $p1->questionid = $q->id; $p1->id = 15; $p1->partindex = 1; $p1->answermark = 2; @@ -709,7 +968,9 @@ public static function make_formulas_question_testmethodsinparts() { $p1->answernotunique = '1'; $p1->postunit = 'm/s'; $q->parts[1] = $p1; + $p2 = self::make_a_formulas_part(); + $p2->questionid = $q->id; $p2->id = 16; $p2->partindex = 2; $p2->answermark = 2; @@ -719,7 +980,9 @@ public static function make_formulas_question_testmethodsinparts() { $p2->answernotunique = '1'; $p2->postunit = ''; $q->parts[2] = $p2; + $p3 = self::make_a_formulas_part(); + $p3->questionid = $q->id; $p3->id = 17; $p3->partindex = 3; $p3->answermark = 2; @@ -730,6 +993,11 @@ public static function make_formulas_question_testmethodsinparts() { $p3->postunit = ''; $q->parts[3] = $p3; + $q->hints = [ + new question_hint_with_parts(101, 'Hint 1.', FORMAT_HTML, 1, 0), + new question_hint_with_parts(102, 'Hint 2.', FORMAT_HTML, 1, 1), + ]; + return $q; } @@ -738,25 +1006,22 @@ public static function make_formulas_question_testmethodsinparts() { * @return object */ public static function get_formulas_question_data_testmethodsinparts() { - global $USER; - $qdata = new stdClass(); test_question_maker::initialise_question_data($qdata); $qdata->qtype = 'formulas'; - $qdata->name = 'test-2'; + $qdata->name = 'test-methodsinparts'; $qdata->questiontext = 'This question shows different display methods of the answer and unit box.
'; $qdata->generalfeedback = 'This is the general feedback.'; $qdata->defaultmark = 8; - $qdata->length = 1; $qdata->penalty = 0.3; - $qdata->hidden = 0; $qdata->options = new stdClass(); + $qdata->contextid = context_system::instance()->id; $qdata->options->varsrandom = ''; $qdata->options->varsglobal = 'v = 40;dt = 3;s = v*dt;'; $qdata->options->answernumbering = 'abc'; - $qdata->options->shownumcorrect = 0; + $qdata->options->shownumcorrect = 1; $qdata->options->correctfeedback = test_question_maker::STANDARD_OVERALL_CORRECT_FEEDBACK; $qdata->options->correctfeedbackformat = FORMAT_HTML; @@ -767,12 +1032,13 @@ public static function get_formulas_question_data_testmethodsinparts() { test_question_maker::STANDARD_OVERALL_INCORRECT_FEEDBACK; $qdata->options->incorrectfeedbackformat = FORMAT_HTML; - $qdata->options->answers = array( - 14 => (object) array( + $qdata->options->answers = [ + 14 => (object) [ 'id' => 14, + 'questionid' => $qdata->id, 'placeholder' => '', 'answermark' => 2, - 'answertype' => 0, + 'answertype' => '0', 'numbox' => 1, 'vars1' => '', 'vars2' => '', @@ -787,19 +1053,20 @@ public static function get_formulas_question_data_testmethodsinparts() { 'subqtextformat' => FORMAT_HTML, 'feedback' => '', 'feedbackformat' => FORMAT_HTML, - 'partcorrectfb' => '', + 'partcorrectfb' => self::DEFAULT_CORRECT_FEEDBACK, 'partcorrectfbformat' => FORMAT_HTML, - 'partpartiallycorrectfb' => '', + 'partpartiallycorrectfb' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, 'partpartiallycorrectfbformat' => FORMAT_HTML, - 'partincorrectfb' => '', + 'partincorrectfb' => self::DEFAULT_INCORRECT_FEEDBACK, 'partincorrectfbformat' => FORMAT_HTML, 'partindex' => 0, - ), - 15 => (object) array( + ], + 15 => (object) [ 'id' => 15, + 'questionid' => $qdata->id, 'placeholder' => '', 'answermark' => 2, - 'answertype' => 0, + 'answertype' => '0', 'numbox' => 1, 'vars1' => '', 'vars2' => '', @@ -814,19 +1081,20 @@ public static function get_formulas_question_data_testmethodsinparts() { 'subqtextformat' => FORMAT_HTML, 'feedback' => '', 'feedbackformat' => FORMAT_HTML, - 'partcorrectfb' => '', + 'partcorrectfb' => self::DEFAULT_CORRECT_FEEDBACK, 'partcorrectfbformat' => FORMAT_HTML, - 'partpartiallycorrectfb' => '', + 'partpartiallycorrectfb' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, 'partpartiallycorrectfbformat' => FORMAT_HTML, - 'partincorrectfb' => '', + 'partincorrectfb' => self::DEFAULT_INCORRECT_FEEDBACK, 'partincorrectfbformat' => FORMAT_HTML, 'partindex' => 1, - ), - 16 => (object) array( + ], + 16 => (object) [ 'id' => 16, + 'questionid' => $qdata->id, 'placeholder' => '', 'answermark' => 2, - 'answertype' => 0, + 'answertype' => '0', 'numbox' => 1, 'vars1' => '', 'vars2' => '', @@ -841,19 +1109,20 @@ public static function get_formulas_question_data_testmethodsinparts() { 'subqtextformat' => FORMAT_HTML, 'feedback' => '', 'feedbackformat' => FORMAT_HTML, - 'partcorrectfb' => '', + 'partcorrectfb' => self::DEFAULT_CORRECT_FEEDBACK, 'partcorrectfbformat' => FORMAT_HTML, - 'partpartiallycorrectfb' => '', + 'partpartiallycorrectfb' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, 'partpartiallycorrectfbformat' => FORMAT_HTML, - 'partincorrectfb' => '', + 'partincorrectfb' => self::DEFAULT_INCORRECT_FEEDBACK, 'partincorrectfbformat' => FORMAT_HTML, 'partindex' => 2, - ), - 17 => (object) array( + ], + 17 => (object) [ 'id' => 17, + 'questionid' => $qdata->id, 'placeholder' => '', 'answermark' => 2, - 'answertype' => 0, + 'answertype' => '0', 'numbox' => 1, 'vars1' => '', 'vars2' => '', @@ -864,38 +1133,40 @@ public static function get_formulas_question_data_testmethodsinparts() { 'postunit' => '', 'ruleid' => 1, 'otherrule' => '', - 'subqtext' => 'If a car travels {s} m in {dt} s, what is the speed of the car? speed = {_0}{_u}', + 'subqtext' => '
If a car travels {s} m in {dt} s, what is the speed of the car? speed = {_0}{_u}
', 'subqtextformat' => FORMAT_HTML, 'feedback' => '', 'feedbackformat' => FORMAT_HTML, - 'partcorrectfb' => '', + 'partcorrectfb' => self::DEFAULT_CORRECT_FEEDBACK, 'partcorrectfbformat' => FORMAT_HTML, - 'partpartiallycorrectfb' => '', + 'partpartiallycorrectfb' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, 'partpartiallycorrectfbformat' => FORMAT_HTML, - 'partincorrectfb' => '', + 'partincorrectfb' => self::DEFAULT_INCORRECT_FEEDBACK, 'partincorrectfbformat' => FORMAT_HTML, 'partindex' => 3, - ), - ); + ], + ]; $qdata->options->numpart = 4; - $qdata->hints = array( - 1 => (object) array( + $qdata->hints = [ + 1 => (object) [ + 'id' => 101, 'hint' => 'Hint 1.', 'hintformat' => FORMAT_HTML, 'shownumcorrect' => 1, 'clearwrong' => 0, 'options' => 0, - ), - 2 => (object) array( + ], + 2 => (object) [ + 'id' => 102, 'hint' => 'Hint 2.', 'hintformat' => FORMAT_HTML, 'shownumcorrect' => 1, 'clearwrong' => 1, 'options' => 1, - ), - ); + ], + ]; return $qdata; } @@ -907,142 +1178,133 @@ public static function get_formulas_question_data_testmethodsinparts() { public function get_formulas_question_form_data_testmethodsinparts() { $form = new stdClass(); - $form->name = 'test-2'; - $form->questiontext = array('text' => 'This question shows different display methods of the answer and unit box.
', - 'format' => FORMAT_HTML); - $form->generalfeedback = array('text' => 'This is the general feedback.', 'format' => FORMAT_HTML); + $form->name = 'test-methodsinparts'; + $form->questiontext = ['text' => 'This question shows different display methods of the answer and unit box.
', + 'format' => FORMAT_HTML]; + $form->generalfeedback = ['text' => 'This is the general feedback.', 'format' => FORMAT_HTML]; $form->defaultmark = 8; $form->penalty = 0.3; $form->varsrandom = ''; $form->varsglobal = 'v = 40;dt = 3;s = v*dt;'; $form->answernumbering = 'abc'; $form->noanswers = 4; - $form->answer = array( + $form->answer = [ 0 => 'v', 1 => 'v', 2 => 'v', 3 => 'v', - ); - $form->answernotunique = array( + ]; + $form->answernotunique = [ 0 => '1', 1 => '1', 2 => '1', 3 => '1', - ); - $form->answermark = array( + ]; + $form->answermark = [ 0 => 2, 1 => 2, 2 => 2, 3 => 2, - ); - $form->numbox = array( + ]; + $form->numbox = [ 0 => 1, 1 => 1, 2 => 1, 3 => 1, - ); - $form->placeholder = array( + ]; + $form->placeholder = [ 0 => '', 1 => '', 2 => '', 3 => '', - ); - $form->postunit = array( + ]; + $form->postunit = [ 0 => 'm/s', 1 => 'm/s', 2 => '', 3 => '', - ); - $form->answertype = array( - 0 => 0, - 1 => 0, - 2 => 0, - 3 => 0, - ); - $form->vars1 = array( + ]; + $form->answertype = [ + 0 => '0', + 1 => '0', + 2 => '0', + 3 => '0', + ]; + $form->vars1 = [ 0 => '', 1 => '', 2 => '', 3 => '', - ); - $form->correctness = array( + ]; + $form->correctness = [ 0 => '_relerr < 0.01', 1 => '_relerr < 0.01', 2 => '_relerr < 0.01', - 3 => '_relerr < 0.01' - ); - $form->vars2 = array( + 3 => '_relerr < 0.01', + ]; + $form->vars2 = [ 0 => '', 1 => '', 2 => '', 3 => '', - ); - $form->unitpenalty = array( - 0 => '1.0', - 1 => '1.0', - 2 => '1.0', - 3 => '1.0', - ); - $form->ruleid = array( - 0 => 1, - 1 => 1, - 2 => 1, - 3 => 1, - ); - $form->otherrule = array( + ]; + $form->otherrule = [ 0 => '', 1 => '', 2 => '', 3 => '', - ); + ]; $form->globalunitpenalty = 1; $form->globalruleid = 1; - $form->subqtext = array( - 0 => array( + $form->subqtext = [ + 0 => [ 'text' => 'If a car travels {s} m in {dt} s, what is the speed of the car? {_0}{_u}
', - 'format' => FORMAT_HTML - ), - 1 => array( + 'format' => FORMAT_HTML, + ], + 1 => [ 'text' => 'If a car travels {s} m in {dt} s, what is the speed of the car? {_0} {_u}
', - 'format' => FORMAT_HTML - ), - 2 => array( + 'format' => FORMAT_HTML, + ], + 2 => [ 'text' => 'If a car travels {s} m in {dt} s, what is the speed of the car? {_0} {_u}
', - 'format' => FORMAT_HTML - ), - 3 => array( + 'format' => FORMAT_HTML, + ], + 3 => [ 'text' => 'If a car travels {s} m in {dt} s, what is the speed of the car? speed = {_0}{_u}
', - 'format' => FORMAT_HTML - ), - ); - $form->feedback = array( - 0 => array('text' => '', 'format' => FORMAT_HTML), - 1 => array('text' => '', 'format' => FORMAT_HTML), - 2 => array('text' => '', 'format' => FORMAT_HTML), - 3 => array('text' => '', 'format' => FORMAT_HTML), - ); - $form->partcorrectfb = array( - 0 => array('text' => '', 'format' => FORMAT_HTML), - 1 => array('text' => '', 'format' => FORMAT_HTML), - 2 => array('text' => '', 'format' => FORMAT_HTML), - 3 => array('text' => '', 'format' => FORMAT_HTML), - ); - $form->partpartiallycorrectfb = array( - 0 => array('text' => '', 'format' => FORMAT_HTML), - 1 => array('text' => '', 'format' => FORMAT_HTML), - 2 => array('text' => '', 'format' => FORMAT_HTML), - 3 => array('text' => '', 'format' => FORMAT_HTML), - ); - $form->partincorrectfb = array( - 0 => array('text' => '', 'format' => FORMAT_HTML), - 1 => array('text' => '', 'format' => FORMAT_HTML), - 2 => array('text' => '', 'format' => FORMAT_HTML), - 3 => array('text' => '', 'format' => FORMAT_HTML), - ); - $form->correctfeedback = array('text' => '', 'format' => FORMAT_HTML); - $form->partiallycorrectfeedback = array('text' => '', 'format' => FORMAT_HTML); - $form->shownumcorrect = '0'; - $form->incorrectfeedback = array('text' => '', 'format' => FORMAT_HTML); + 'format' => FORMAT_HTML, + ], + ]; + $form->feedback = [ + 0 => ['text' => '', 'format' => FORMAT_HTML], + 1 => ['text' => '', 'format' => FORMAT_HTML], + 2 => ['text' => '', 'format' => FORMAT_HTML], + 3 => ['text' => '', 'format' => FORMAT_HTML], + ]; + $form->partcorrectfb = [ + 0 => ['text' => self::DEFAULT_CORRECT_FEEDBACK, 'format' => FORMAT_HTML], + 1 => ['text' => self::DEFAULT_CORRECT_FEEDBACK, 'format' => FORMAT_HTML], + 2 => ['text' => self::DEFAULT_CORRECT_FEEDBACK, 'format' => FORMAT_HTML], + 3 => ['text' => self::DEFAULT_CORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ]; + $form->partpartiallycorrectfb = [ + 0 => ['text' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + 1 => ['text' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + 2 => ['text' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + 3 => ['text' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ]; + $form->partincorrectfb = [ + 0 => ['text' => self::DEFAULT_INCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + 1 => ['text' => self::DEFAULT_INCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + 2 => ['text' => self::DEFAULT_INCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + 3 => ['text' => self::DEFAULT_INCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ]; + $form->correctfeedback = ['text' => test_question_maker::STANDARD_OVERALL_CORRECT_FEEDBACK, 'format' => FORMAT_HTML]; + $form->partiallycorrectfeedback = [ + 'text' => test_question_maker::STANDARD_OVERALL_PARTIALLYCORRECT_FEEDBACK, + 'format' => FORMAT_HTML, + ]; + $form->incorrectfeedback = ['text' => test_question_maker::STANDARD_OVERALL_INCORRECT_FEEDBACK, 'format' => FORMAT_HTML]; + $form->shownumcorrect = '1'; $form->numhints = 2; $form->hint = [ ['text' => 'Hint 1.', 'format' => FORMAT_HTML], @@ -1054,17 +1316,19 @@ public function get_formulas_question_form_data_testmethodsinparts() { } /** - * @return qtype_formulas_question the question with 0 as answer. + * Return Formulas question with one part, not randomized, answer = 0, used to test for problems with 0 as answer. + * + * @return qtype_formulas_question */ - public static function make_formulas_question_testzero() { + public static function make_formulas_question_testzero(): qtype_formulas_question { $q = self::make_a_formulas_question(); $q->name = 'test-3'; $q->questiontext = 'This question has 0 as answer to test problem when answer is equal to 0.
'; $q->penalty = 0.3; // Non-zero and not the default. - $q->textfragments = array(0 => 'This question has 0 as answer to test problem when answer is equal to 0.
', - 1 => ''); + $q->textfragments = [0 => 'This question has 0 as answer to test problem when answer is equal to 0.
', + 1 => '']; $q->numpart = 1; $q->defaultmark = 2; $p = self::make_a_formulas_part(); @@ -1086,37 +1350,35 @@ public function get_formulas_question_form_data_testzero() { $form->name = 'test-3'; $form->noanswers = 1; - $form->answer = array('0'); - $form->answernotunique = array('1'); - $form->answermark = array(2); - $form->answertype = array(0); - $form->correctness = array('_relerr < 0.01'); - $form->numbox = array(1); - $form->placeholder = array(''); - $form->vars1 = array(''); - $form->vars2 = array(''); - $form->ruleid = array(1); - $form->unitpenalty = array(1); - $form->postunit = array(''); - $form->otherrule = array(''); - $form->subqtext = array( - array('text' => '', 'format' => FORMAT_HTML) - ); - $form->feedback = array( - array('text' => '', 'format' => FORMAT_HTML) - ); - $form->partcorrectfb = array( - array('text' => 'Your answer is correct.', 'format' => FORMAT_HTML) - ); - $form->partpartiallycorrectfb = array( - array('text' => 'Your answer is partially correct.', 'format' => FORMAT_HTML) - ); - $form->partincorrectfb = array( - array('text' => 'Your answer is incorrect.', 'format' => FORMAT_HTML) - ); - $form->questiontext = array('text' => 'This question has 0 as answer to test problem when answer is equal to 0.
', - 'format' => FORMAT_HTML); - $form->generalfeedback = array('text' => '', 'format' => FORMAT_HTML); + $form->answer = ['0']; + $form->answernotunique = ['1']; + $form->answermark = [2]; + $form->answertype = ['0']; + $form->correctness = ['_relerr < 0.01']; + $form->numbox = [1]; + $form->placeholder = ['']; + $form->vars1 = ['']; + $form->vars2 = ['']; + $form->postunit = ['']; + $form->otherrule = ['']; + $form->subqtext = [ + ['text' => '', 'format' => FORMAT_HTML], + ]; + $form->feedback = [ + ['text' => '', 'format' => FORMAT_HTML], + ]; + $form->partcorrectfb = [ + ['text' => self::DEFAULT_CORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ]; + $form->partpartiallycorrectfb = [ + ['text' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ]; + $form->partincorrectfb = [ + ['text' => self::DEFAULT_INCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ]; + $form->questiontext = ['text' => 'This question has 0 as answer to test problem when answer is equal to 0.
', + 'format' => FORMAT_HTML]; + $form->generalfeedback = ['text' => '', 'format' => FORMAT_HTML]; $form->defaultmark = 2; $form->penalty = 0.3; $form->varsrandom = ''; @@ -1124,18 +1386,22 @@ public function get_formulas_question_form_data_testzero() { $form->answernumbering = ''; $form->globalunitpenalty = 1; $form->globalruleid = 1; - $form->correctfeedback = array('text' => '', 'format' => FORMAT_HTML); - $form->partiallycorrectfeedback = array('text' => '', 'format' => FORMAT_HTML); + $form->correctfeedback = ['text' => 'Well done!', 'format' => FORMAT_HTML]; + $form->partiallycorrectfeedback = [ + 'text' => 'Parts, but only parts, of your response are correct.', + 'format' => FORMAT_HTML, + ]; $form->shownumcorrect = '0'; - $form->incorrectfeedback = array('text' => '', 'format' => FORMAT_HTML); + $form->incorrectfeedback = ['text' => 'That is not right at all.', 'format' => FORMAT_HTML]; return $form; } /** - * @return qtype_formulas_question the question from the test1.xml file. - * Randomized version. + * Return Formulas question with 4 parts, randomised, separate and combined unit fields. + * + * @return qtype_formulas_question */ - public static function make_formulas_question_test4() { + public static function make_formulas_question_test4(): qtype_formulas_question { $q = self::make_a_formulas_question(); $q->name = 'test-4'; @@ -1149,7 +1415,7 @@ public static function make_formulas_question_test4() { 2 => '', 3 => '', 4 => '', - ); + ]; $q->varsrandom = 'v = {20:100:10}; dt = {2:6};'; $q->varsglobal = 's = v*dt;'; $p0 = self::make_a_formulas_part(); @@ -1202,44 +1468,42 @@ public function get_formulas_question_form_data_test4() { $form = new stdClass(); $form->name = 'test-4'; - $form->questiontext = array('text' => 'This question shows different display methods of the answer and unit box.
', - 'format' => FORMAT_HTML); - $form->generalfeedback = array('text' => 'This is the general feedback.', 'format' => FORMAT_HTML); + $form->questiontext = ['text' => 'This question shows different display methods of the answer and unit box.
', + 'format' => FORMAT_HTML]; + $form->generalfeedback = ['text' => 'This is the general feedback.', 'format' => FORMAT_HTML]; $form->defaultmark = 8; $form->penalty = 0.3; $form->varsrandom = 'v = {20:100:10}; dt = {2:6};'; $form->varsglobal = 's = v*dt;'; $form->answernumbering = 'abc'; $form->noanswers = 4; - $form->answer = array('v', 'v', 'v', 'v'); - $form->answernotunique = array('1', '1', '1', '1'); - $form->answermark = array('2', '2', '2', '2'); - $form->numbox = array(1, 1, 1, 1); - $form->placeholder = array('', '', '', ''); - $form->postunit = array('m/s', 'm/s', '', ''); - $form->answertype = array(0, 0, 0, 0); - $form->vars1 = array('', '', '', ''); - $form->correctness = array('_relerr < 0.01', '_relerr < 0.01', '_relerr < 0.01', '_relerr < 0.01'); - $form->vars2 = array('', '', '', ''); - $form->unitpenalty = array(1, 1, 1, 1); - $form->ruleid = array('1', '1', '1', '1'); - $form->otherrule = array('', '', '', ''); + $form->answer = ['v', 'v', 'v', 'v']; + $form->answernotunique = ['1', '1', '1', '1']; + $form->answermark = ['2', '2', '2', '2']; + $form->numbox = [1, 1, 1, 1]; + $form->placeholder = ['', '', '', '']; + $form->postunit = ['m/s', 'm/s', '', '']; + $form->answertype = ['0', '0', '0', '0']; + $form->vars1 = ['', '', '', '']; + $form->correctness = ['_relerr < 0.01', '_relerr < 0.01', '_relerr < 0.01', '_relerr < 0.01']; + $form->vars2 = ['', '', '', '']; + $form->otherrule = ['', '', '', '']; $form->globalunitpenalty = 1; $form->globalruleid = 1; - $form->subqtext = array( - array( + $form->subqtext = [ + [ 'text' => 'If a car travels {s} m in {dt} s, what is the speed of the car? {_0}{_u}
', - 'format' => FORMAT_HTML - ), - array( + 'format' => FORMAT_HTML, + ], + [ 'text' => 'If a car travels {s} m in {dt} s, what is the speed of the car? {_0} {_u}
', - 'format' => FORMAT_HTML - ), - array( + 'format' => FORMAT_HTML, + ], + [ 'text' => 'If a car travels {s} m in {dt} s, what is the speed of the car? {_0} {_u}
', - 'format' => FORMAT_HTML - ), - array( + 'format' => FORMAT_HTML, + ], + [ 'text' => 'If a car travels {s} m in {dt} s, what is the speed of the car? speed = {_0}{_u}
', 'format' => FORMAT_HTML, ], @@ -1276,35 +1540,37 @@ public function get_formulas_question_form_data_test4() { $form->shownumcorrect = '0'; $form->incorrectfeedback = ['text' => 'That is not right at all.', 'format' => FORMAT_HTML]; $form->numhints = 2; - $form->hint = array( - array('text' => '', 'format' => FORMAT_HTML), - array('text' => '', 'format' => FORMAT_HTML), - ); - $form->hintclearwrong = array('0', '0'); - $form->hintshownumcorrect = array('0', '0'); + $form->hint = [ + ['text' => '', 'format' => FORMAT_HTML], + ['text' => '', 'format' => FORMAT_HTML], + ]; + $form->hintclearwrong = ['0', '0']; + $form->hintshownumcorrect = ['0', '0']; return $form; } /** - * @return qtype_formulas_question with a (radio button) multichoice answer. + * Return Formulas question with one part, not randomized, radio button multichoice answer. + * + * @return qtype_formulas_question */ - public static function make_formulas_question_testmc() { + public static function make_formulas_question_testmc(): qtype_formulas_question { $q = self::make_a_formulas_question(); $q->name = 'test-5'; $q->questiontext = 'This question has a multichoice answer.
'; $q->varsglobal = 'mychoices=["Dog","Cat","Bird","Fish"];'; $q->penalty = 0.3; // Non-zero and not the default. - $q->textfragments = array(0 => 'This question has a multichoice answer.
', - 1 => ''); + $q->textfragments = [0 => 'This question has a multichoice answer.
', + 1 => '']; $q->numpart = 1; $q->defaultmark = 2; $p = self::make_a_formulas_part(); $p->id = 14; - $p->answermark = 1; + $p->answermark = 2; $p->answer = '1'; $p->answernotunique = '1'; - $p->subqtext = '{_0:mychoices:MC}'; + $p->subqtext = '{_0:mychoices}'; $q->parts[0] = $p; return $q; @@ -1319,37 +1585,35 @@ public function get_formulas_question_form_data_testmc() { $form->name = 'test-5'; $form->noanswers = 1; - $form->answer = array('1'); - $form->answernotunique = array('1'); - $form->answermark = array(1); - $form->answertype = array(0); - $form->correctness = array('_relerr < 0.01'); - $form->numbox = array(1); - $form->placeholder = array(''); - $form->vars1 = array(''); - $form->vars2 = array(''); - $form->ruleid = array(1); - $form->unitpenalty = array(1); - $form->postunit = array(''); - $form->otherrule = array(''); - $form->subqtext = array( - array('text' => '{_0:mychoices:MC}', 'format' => FORMAT_HTML) - ); - $form->feedback = array( - array('text' => '', 'format' => FORMAT_HTML) - ); - $form->partcorrectfb = array( - array('text' => 'Your answer is correct.', 'format' => FORMAT_HTML) - ); - $form->partpartiallycorrectfb = array( - array('text' => 'Your answer is partially correct.', 'format' => FORMAT_HTML) - ); - $form->partincorrectfb = array( - array('text' => 'Your answer is incorrect.', 'format' => FORMAT_HTML) - ); - $form->questiontext = array('text' => 'This question has a multichoice answer.
', - 'format' => FORMAT_HTML); - $form->generalfeedback = array('text' => '', 'format' => FORMAT_HTML); + $form->answer = ['1']; + $form->answernotunique = ['1']; + $form->answermark = [2]; + $form->answertype = ['0']; + $form->correctness = ['_relerr < 0.01']; + $form->numbox = [1]; + $form->placeholder = ['']; + $form->vars1 = ['']; + $form->vars2 = ['']; + $form->postunit = ['']; + $form->otherrule = ['']; + $form->subqtext = [ + ['text' => '{_0:mychoices}', 'format' => FORMAT_HTML], + ]; + $form->feedback = [ + ['text' => '', 'format' => FORMAT_HTML], + ]; + $form->partcorrectfb = [ + ['text' => self::DEFAULT_CORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ]; + $form->partpartiallycorrectfb = [ + ['text' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ]; + $form->partincorrectfb = [ + ['text' => self::DEFAULT_INCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ]; + $form->questiontext = ['text' => 'This question has a multichoice answer.
', + 'format' => FORMAT_HTML]; + $form->generalfeedback = ['text' => '', 'format' => FORMAT_HTML]; $form->defaultmark = 2; $form->penalty = 0.3; $form->varsrandom = ''; @@ -1357,31 +1621,36 @@ public function get_formulas_question_form_data_testmc() { $form->answernumbering = ''; $form->globalunitpenalty = 1; $form->globalruleid = 1; - $form->correctfeedback = array('text' => '', 'format' => FORMAT_HTML); - $form->partiallycorrectfeedback = array('text' => '', 'format' => FORMAT_HTML); + $form->correctfeedback = ['text' => 'Well done!', 'format' => FORMAT_HTML]; + $form->partiallycorrectfeedback = [ + 'text' => 'Parts, but only parts, of your response are correct.', + 'format' => FORMAT_HTML, + ]; $form->shownumcorrect = '0'; - $form->incorrectfeedback = array('text' => '', 'format' => FORMAT_HTML); + $form->incorrectfeedback = ['text' => 'That is not right at all.', 'format' => FORMAT_HTML]; $form->numhints = 0; return $form; } /** - * @return qtype_formulas_question with a dropdown multichoice answer. + * Return Formulas question with one part, not randomized, drowdown multichoice answer. + * + * @return qtype_formulas_question */ - public static function make_formulas_question_testmce() { + public static function make_formulas_question_testmce(): qtype_formulas_question { $q = self::make_a_formulas_question(); $q->name = 'test-5'; $q->questiontext = 'This question has a multichoice answer.
'; $q->varsglobal = 'mychoices=["Dog","Cat","Bird","Fish"];'; $q->penalty = 0.3; // Non-zero and not the default. - $q->textfragments = array(0 => 'This question has a multichoice answer.
', - 1 => ''); + $q->textfragments = [0 => 'This question has a multichoice answer.
', + 1 => '']; $q->numpart = 1; $q->defaultmark = 2; $p = self::make_a_formulas_part(); $p->id = 14; - $p->answermark = 1; + $p->answermark = 2; $p->answer = '1'; $p->answernotunique = '1'; $p->subqtext = '{_0:mychoices:MCE}'; @@ -1399,37 +1668,35 @@ public function get_formulas_question_form_data_testmce() { $form->name = 'test-5'; $form->noanswers = 1; - $form->answer = array('1'); - $form->answernotunique = array('1'); - $form->answermark = array(1); - $form->answertype = array(0); - $form->correctness = array('_relerr < 0.01'); - $form->numbox = array(1); - $form->placeholder = array(''); - $form->vars1 = array(''); - $form->vars2 = array(''); - $form->ruleid = array(1); - $form->unitpenalty = array(1); - $form->postunit = array(''); - $form->otherrule = array(''); - $form->subqtext = array( - array('text' => '{_0:mychoices:MCE}', 'format' => FORMAT_HTML) - ); - $form->feedback = array( - array('text' => '', 'format' => FORMAT_HTML) - ); - $form->partcorrectfb = array( - array('text' => 'Your answer is correct.', 'format' => FORMAT_HTML) - ); - $form->partpartiallycorrectfb = array( - array('text' => 'Your answer is partially correct.', 'format' => FORMAT_HTML) - ); - $form->partincorrectfb = array( - array('text' => 'Your answer is incorrect.', 'format' => FORMAT_HTML) - ); - $form->questiontext = array('text' => 'This question has a multichoice answer.
', - 'format' => FORMAT_HTML); - $form->generalfeedback = array('text' => '', 'format' => FORMAT_HTML); + $form->answer = ['1']; + $form->answernotunique = ['1']; + $form->answermark = [2]; + $form->answertype = ['0']; + $form->correctness = ['_relerr < 0.01']; + $form->numbox = [1]; + $form->placeholder = ['']; + $form->vars1 = ['']; + $form->vars2 = ['']; + $form->postunit = ['']; + $form->otherrule = ['']; + $form->subqtext = [ + ['text' => '{_0:mychoices:MCE}', 'format' => FORMAT_HTML], + ]; + $form->feedback = [ + ['text' => '', 'format' => FORMAT_HTML], + ]; + $form->partcorrectfb = [ + ['text' => self::DEFAULT_CORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ]; + $form->partpartiallycorrectfb = [ + ['text' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ]; + $form->partincorrectfb = [ + ['text' => self::DEFAULT_INCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ]; + $form->questiontext = ['text' => 'This question has a multichoice answer.
', + 'format' => FORMAT_HTML]; + $form->generalfeedback = ['text' => '', 'format' => FORMAT_HTML]; $form->defaultmark = 2; $form->penalty = 0.3; $form->varsrandom = ''; @@ -1437,18 +1704,23 @@ public function get_formulas_question_form_data_testmce() { $form->answernumbering = 'abc'; $form->globalunitpenalty = 1; $form->globalruleid = 1; - $form->correctfeedback = array('text' => '', 'format' => FORMAT_HTML); - $form->partiallycorrectfeedback = array('text' => '', 'format' => FORMAT_HTML); + $form->correctfeedback = ['text' => 'Well done!', 'format' => FORMAT_HTML]; + $form->partiallycorrectfeedback = [ + 'text' => 'Parts, but only parts, of your response are correct.', + 'format' => FORMAT_HTML, + ]; $form->shownumcorrect = '0'; - $form->incorrectfeedback = array('text' => '', 'format' => FORMAT_HTML); + $form->incorrectfeedback = ['text' => 'That is not right at all.', 'format' => FORMAT_HTML]; $form->numhints = 0; return $form; } /** - * @return qtype_formulas_question with two dropdown multichoice answers in separate parts. + * Return Formulas question with 2 parts, each with a drowdown multichoice answer. + * + * @return qtype_formulas_question */ - public static function make_formulas_question_testmcetwoparts() { + public static function make_formulas_question_testmcetwoparts(): qtype_formulas_question { $q = self::make_a_formulas_question(); $q->name = 'testmcetwoparts'; @@ -1456,10 +1728,10 @@ public static function make_formulas_question_testmcetwoparts() { $q->varsglobal = 'choices1=["Dog","Cat","Bird","Fish"];'; $q->varsglobal .= 'choices2=["Red","Blue","Green","Yellow"];'; $q->penalty = 0.3; // Non-zero and not the default. - $q->textfragments = array(0 => 'This question has two parts with a multichoice answer in each of them.
', + $q->textfragments = [0 => 'This question has two parts with a multichoice answer in each of them.
', 1 => '{_0:choices1:MCE}', - 2 => '{_0:choices2:MCE}' - ); + 2 => '{_0:choices2:MCE}', + ]; $q->numpart = 1; $q->defaultmark = 2; $p1 = self::make_a_formulas_part(); @@ -1468,6 +1740,7 @@ public static function make_formulas_question_testmcetwoparts() { $p1->answer = '1'; $p1->answernotunique = '1'; $p1->subqtext = '{_0:choices1:MCE}'; + $p1->partcorrectfb = 'Your first answer is correct.'; $q->parts[0] = $p1; $p2 = self::make_a_formulas_part(); $p2->id = 15; @@ -1475,6 +1748,7 @@ public static function make_formulas_question_testmcetwoparts() { $p2->answer = '1'; $p2->answernotunique = '1'; $p2->subqtext = '{_0:choices2:MCE}'; + $p2->partcorrectfb = 'Your second answer is correct.'; $q->parts[1] = $p2; return $q; @@ -1489,42 +1763,40 @@ public function get_formulas_question_form_data_testmcetwoparts() { $form->name = 'testmcetwoparts'; $form->noanswers = 2; - $form->answer = array('1', '1'); - $form->answernotunique = array('1', '1'); - $form->answermark = array(1, 1); - $form->answertype = array(0, 0); - $form->correctness = array('_relerr < 0.01', '_relerr < 0.01'); - $form->numbox = array(1, 1); - $form->placeholder = array('', ''); - $form->vars1 = array('', ''); - $form->vars2 = array('', ''); - $form->ruleid = array(1, 1); - $form->unitpenalty = array(1, 1); - $form->postunit = array('', ''); - $form->otherrule = array('', ''); - $form->subqtext = array( - 0 => array('text' => '{_0:choices1:MCE}', 'format' => FORMAT_HTML), - 1 => array('text' => '{_0:choices2:MCE}', 'format' => FORMAT_HTML) - ); - $form->feedback = array( - 0 => array('text' => '', 'format' => FORMAT_HTML), - 1 => array('text' => '', 'format' => FORMAT_HTML) - ); - $form->partcorrectfb = array( - 0 => array('text' => 'Your first answer is correct.', 'format' => FORMAT_HTML), - 1 => array('text' => 'Your second answer is correct.', 'format' => FORMAT_HTML) - ); - $form->partpartiallycorrectfb = array( - 0 => array('text' => 'Your answer is partially correct.', 'format' => FORMAT_HTML), - 1 => array('text' => 'Your answer is partially correct.', 'format' => FORMAT_HTML) - ); - $form->partincorrectfb = array( - 0 => array('text' => 'Your answer is incorrect.', 'format' => FORMAT_HTML), - 1 => array('text' => 'Your answer is incorrect.', 'format' => FORMAT_HTML) - ); - $form->questiontext = array('text' => 'This question has a multichoice answer.
', - 'format' => FORMAT_HTML); - $form->generalfeedback = array('text' => '', 'format' => FORMAT_HTML); + $form->answer = ['1', '1']; + $form->answernotunique = ['1', '1']; + $form->answermark = [1, 1]; + $form->answertype = ['0', '0']; + $form->correctness = ['_relerr < 0.01', '_relerr < 0.01']; + $form->numbox = [1, 1]; + $form->placeholder = ['', '']; + $form->vars1 = ['', '']; + $form->vars2 = ['', '']; + $form->postunit = ['', '']; + $form->otherrule = ['', '']; + $form->subqtext = [ + 0 => ['text' => '{_0:choices1:MCE}', 'format' => FORMAT_HTML], + 1 => ['text' => '{_0:choices2:MCE}', 'format' => FORMAT_HTML], + ]; + $form->feedback = [ + 0 => ['text' => '', 'format' => FORMAT_HTML], + 1 => ['text' => '', 'format' => FORMAT_HTML], + ]; + $form->partcorrectfb = [ + 0 => ['text' => 'Your first answer is correct.', 'format' => FORMAT_HTML], + 1 => ['text' => 'Your second answer is correct.', 'format' => FORMAT_HTML], + ]; + $form->partpartiallycorrectfb = [ + 0 => ['text' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + 1 => ['text' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ]; + $form->partincorrectfb = [ + 0 => ['text' => self::DEFAULT_INCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + 1 => ['text' => self::DEFAULT_INCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ]; + $form->questiontext = ['text' => 'This question has two parts with a multichoice answer in each of them.
', + 'format' => FORMAT_HTML]; + $form->generalfeedback = ['text' => '', 'format' => FORMAT_HTML]; $form->defaultmark = 2; $form->penalty = 0.3; $form->varsrandom = ''; @@ -1533,18 +1805,23 @@ public function get_formulas_question_form_data_testmcetwoparts() { $form->answernumbering = ''; $form->globalunitpenalty = 1; $form->globalruleid = 1; - $form->correctfeedback = array('text' => '', 'format' => FORMAT_HTML); - $form->partiallycorrectfeedback = array('text' => '', 'format' => FORMAT_HTML); + $form->correctfeedback = ['text' => 'Well done!', 'format' => FORMAT_HTML]; + $form->partiallycorrectfeedback = [ + 'text' => 'Parts, but only parts, of your response are correct.', + 'format' => FORMAT_HTML, + ]; $form->shownumcorrect = '0'; - $form->incorrectfeedback = array('text' => '', 'format' => FORMAT_HTML); + $form->incorrectfeedback = ['text' => 'That is not right at all.', 'format' => FORMAT_HTML]; $form->numhints = 0; return $form; } /** - * @return qtype_formulas_question with two radio button multichoice answers in separate parts. + * Formulas question with 2 parts, each with a radio button multichoice answer. + * + * @return qtype_formulas_question */ - public static function make_formulas_question_testmctwoparts() { + public static function make_formulas_question_testmctwoparts(): qtype_formulas_question { $q = self::make_a_formulas_question(); $q->name = 'testmcetwoparts'; @@ -1552,10 +1829,10 @@ public static function make_formulas_question_testmctwoparts() { $q->varsglobal = 'choices1=["Dog","Cat","Bird","Fish"];'; $q->varsglobal .= 'choices2=["Red","Blue","Green","Yellow"];'; $q->penalty = 0.3; // Non-zero and not the default. - $q->textfragments = array(0 => 'This question has two parts with a multichoice answer in each of them.
', - 1 => 'Part 1 -- {_0:choices1:MC}', - 2 => 'Part 2 -- {_0:choices2:MC}' - ); + $q->textfragments = [0 => 'This question has two parts with a multichoice answer in each of them.
', + 1 => 'Part 1 -- {_0:choices1}', + 2 => 'Part 2 -- {_0:choices2}', + ]; $q->numpart = 1; $q->defaultmark = 2; $p1 = self::make_a_formulas_part(); @@ -1563,14 +1840,16 @@ public static function make_formulas_question_testmctwoparts() { $p1->answermark = 1; $p1->answer = '1'; $p1->answernotunique = '1'; - $p1->subqtext = 'Part 1 -- {_0:choices1:MCE}'; + $p1->subqtext = 'Part 1 -- {_0:choices1}'; + $p1->partcorrectfb = 'Your first answer is correct.'; $q->parts[0] = $p1; $p2 = self::make_a_formulas_part(); $p2->id = 15; $p2->answermark = 1; $p2->answer = '1'; $p2->answernotunique = '1'; - $p2->subqtext = 'Part 2 -- {_0:choices2:MCE}'; + $p2->subqtext = 'Part 2 -- {_0:choices2}'; + $p2->partcorrectfb = 'Your second answer is correct.'; $q->parts[1] = $p2; return $q; @@ -1585,42 +1864,40 @@ public function get_formulas_question_form_data_testmctwoparts() { $form->name = 'testmcetwoparts'; $form->noanswers = 2; - $form->answer = array('1', '1'); - $form->answernotunique = array('1', '1'); - $form->answermark = array(1, 1); - $form->answertype = array(0, 0); - $form->correctness = array('_relerr < 0.01', '_relerr < 0.01'); - $form->numbox = array(1, 1); - $form->placeholder = array('', ''); - $form->vars1 = array('', ''); - $form->vars2 = array('', ''); - $form->ruleid = array(1, 1); - $form->unitpenalty = array(1, 1); - $form->postunit = array('', ''); - $form->otherrule = array('', ''); - $form->subqtext = array( - 0 => array('text' => 'Part 1 -- {_0:choices1:MC}', 'format' => FORMAT_HTML), - 1 => array('text' => 'Part 2 -- {_0:choices2:MC}', 'format' => FORMAT_HTML) - ); - $form->feedback = array( - 0 => array('text' => '', 'format' => FORMAT_HTML), - 1 => array('text' => '', 'format' => FORMAT_HTML) - ); - $form->partcorrectfb = array( - 0 => array('text' => 'Your first answer is correct.', 'format' => FORMAT_HTML), - 1 => array('text' => 'Your second answer is correct.', 'format' => FORMAT_HTML) - ); - $form->partpartiallycorrectfb = array( - 0 => array('text' => 'Your answer is partially correct.', 'format' => FORMAT_HTML), - 1 => array('text' => 'Your answer is partially correct.', 'format' => FORMAT_HTML) - ); - $form->partincorrectfb = array( - 0 => array('text' => 'Your answer is incorrect.', 'format' => FORMAT_HTML), - 1 => array('text' => 'Your answer is incorrect.', 'format' => FORMAT_HTML) - ); - $form->questiontext = array('text' => 'This question has two parts with a multichoice answer in each of them.
', - 'format' => FORMAT_HTML); - $form->generalfeedback = array('text' => '', 'format' => FORMAT_HTML); + $form->answer = ['1', '1']; + $form->answernotunique = ['1', '1']; + $form->answermark = [1, 1]; + $form->answertype = ['0', '0']; + $form->correctness = ['_relerr < 0.01', '_relerr < 0.01']; + $form->numbox = [1, 1]; + $form->placeholder = ['', '']; + $form->vars1 = ['', '']; + $form->vars2 = ['', '']; + $form->postunit = ['', '']; + $form->otherrule = ['', '']; + $form->subqtext = [ + 0 => ['text' => 'Part 1 -- {_0:choices1}', 'format' => FORMAT_HTML], + 1 => ['text' => 'Part 2 -- {_0:choices2}', 'format' => FORMAT_HTML], + ]; + $form->feedback = [ + 0 => ['text' => '', 'format' => FORMAT_HTML], + 1 => ['text' => '', 'format' => FORMAT_HTML], + ]; + $form->partcorrectfb = [ + 0 => ['text' => 'Your first answer is correct.', 'format' => FORMAT_HTML], + 1 => ['text' => 'Your second answer is correct.', 'format' => FORMAT_HTML], + ]; + $form->partpartiallycorrectfb = [ + 0 => ['text' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + 1 => ['text' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ]; + $form->partincorrectfb = [ + 0 => ['text' => self::DEFAULT_INCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + 1 => ['text' => self::DEFAULT_INCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ]; + $form->questiontext = ['text' => 'This question has two parts with a multichoice answer in each of them.
', + 'format' => FORMAT_HTML]; + $form->generalfeedback = ['text' => '', 'format' => FORMAT_HTML]; $form->defaultmark = 2; $form->penalty = 0.3; $form->varsrandom = ''; @@ -1629,43 +1906,57 @@ public function get_formulas_question_form_data_testmctwoparts() { $form->answernumbering = ''; $form->globalunitpenalty = 1; $form->globalruleid = 1; - $form->correctfeedback = array('text' => '', 'format' => FORMAT_HTML); - $form->partiallycorrectfeedback = array('text' => '', 'format' => FORMAT_HTML); + $form->correctfeedback = ['text' => 'Well done!', 'format' => FORMAT_HTML]; + $form->partiallycorrectfeedback = [ + 'text' => 'Parts, but only parts, of your response are correct.', + 'format' => FORMAT_HTML, + ]; $form->shownumcorrect = '0'; - $form->incorrectfeedback = array('text' => '', 'format' => FORMAT_HTML); + $form->incorrectfeedback = ['text' => 'That is not right at all.', 'format' => FORMAT_HTML]; $form->numhints = 0; return $form; } /** - * @return qtype_formulas_question with two parts and two numbers in each of them. + * Return Formulas question with 2 parts, each one with 2 numbers. + * + * @return qtype_formulas_question */ - public static function make_formulas_question_testtwoandtwo() { + public static function make_formulas_question_testtwoandtwo(): qtype_formulas_question { $q = self::make_a_formulas_question(); $q->name = 'testtwoandtwo'; $q->questiontext = 'This question has two parts with two numbers in each of them.
'; - $q->varsglobal = ''; $q->penalty = 0.3; // Non-zero and not the default. - $q->textfragments = array(0 => 'This question has two parts with two numbers in each of them.
', - 1 => 'Part 1 -- {_0} -- {_1}', - 2 => 'Part 2 -- {_0} -- {_1}' - ); - $q->numpart = 1; + $q->textfragments = [ + 0 => 'This question has two parts with two numbers in each of them.
', + 1 => '', + 2 => '', + ]; + $q->numpart = 2; $q->defaultmark = 2; + $p1 = self::make_a_formulas_part(); $p1->id = 14; + $p1->questionid = $q->id; $p1->answermark = 1; - $p1->answer = ['1', '2']; + $p1->answer = '[1, 2]'; + $p1->numbox = 2; $p1->answernotunique = '1'; $p1->subqtext = 'Part 1 -- {_0} -- {_1}'; + $p1->partcorrectfb = 'Your answers in part 1 are correct.'; $q->parts[0] = $p1; + $p2 = self::make_a_formulas_part(); $p2->id = 15; + $p2->partindex = 1; + $p2->questionid = $q->id; $p2->answermark = 1; - $p2->answer = ['3', '4']; + $p2->answer = '[3, 4]'; + $p2->numbox = 2; $p2->answernotunique = '1'; $p2->subqtext = 'Part 2 -- {_0} -- {_1}'; + $p2->partcorrectfb = 'Your answers in part 2 are correct.'; $q->parts[1] = $p2; return $q; @@ -1679,55 +1970,160 @@ public function get_formulas_question_form_data_testtwoandtwo() { $form = new stdClass(); $form->name = 'testtwoandtwo'; - $form->noanswers = 4; - $form->answer = array(0 => '[1, 2]', 1 => '[3, 4]'); - $form->answernotunique = array('1', '1'); - $form->answermark = array(0 => 1, 1 => 1); - $form->answertype = array(0, 0); - $form->correctness = array('_relerr < 0.01', '_relerr < 0.01'); - $form->numbox = array(1, 1); - $form->placeholder = array('', ''); - $form->vars1 = array('', ''); - $form->vars2 = array('', ''); - $form->ruleid = array(1, 1); - $form->unitpenalty = array(1, 1); - $form->postunit = array('', ''); - $form->otherrule = array('', ''); - $form->subqtext = array( - 0 => array('text' => 'Part 1 -- {_0} -- {_1}', 'format' => FORMAT_HTML), - 1 => array('text' => 'Part 2 -- {_0} -- {_1}', 'format' => FORMAT_HTML) - ); - $form->feedback = array( - 0 => array('text' => '', 'format' => FORMAT_HTML), - 1 => array('text' => '', 'format' => FORMAT_HTML) - ); - $form->partcorrectfb = array( - 0 => array('text' => 'Your answers in part 1 are correct.', 'format' => FORMAT_HTML), - 1 => array('text' => 'Your answers in part 2 are correct.', 'format' => FORMAT_HTML) - ); - $form->partpartiallycorrectfb = array( - 0 => array('text' => 'Your answer is partially correct.', 'format' => FORMAT_HTML), - 1 => array('text' => 'Your answer is partially correct.', 'format' => FORMAT_HTML) - ); - $form->partincorrectfb = array( - 0 => array('text' => 'Your answer is incorrect.', 'format' => FORMAT_HTML), - 1 => array('text' => 'Your answer is incorrect.', 'format' => FORMAT_HTML) - ); - $form->questiontext = array('text' => 'This question has two parts with two numbers in each of them.
', - 'format' => FORMAT_HTML); - $form->generalfeedback = array('text' => '', 'format' => FORMAT_HTML); + $form->noanswers = 2; + $form->answer = [0 => '[1, 2]', 1 => '[3, 4]']; + $form->answernotunique = ['1', '1']; + $form->answermark = [0 => 1, 1 => 1]; + $form->answertype = ['0', '0']; + $form->correctness = ['_relerr < 0.01', '_relerr < 0.01']; + $form->numbox = [2, 2]; + $form->placeholder = ['', '']; + $form->vars1 = ['', '']; + $form->vars2 = ['', '']; + $form->postunit = ['', '']; + $form->otherrule = ['', '']; + $form->subqtext = [ + 0 => ['text' => 'Part 1 -- {_0} -- {_1}', 'format' => FORMAT_HTML], + 1 => ['text' => 'Part 2 -- {_0} -- {_1}', 'format' => FORMAT_HTML], + ]; + $form->feedback = [ + 0 => ['text' => '', 'format' => FORMAT_HTML], + 1 => ['text' => '', 'format' => FORMAT_HTML], + ]; + $form->partcorrectfb = [ + 0 => ['text' => 'Your answers in part 1 are correct.', 'format' => FORMAT_HTML], + 1 => ['text' => 'Your answers in part 2 are correct.', 'format' => FORMAT_HTML], + ]; + $form->partpartiallycorrectfb = [ + 0 => ['text' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + 1 => ['text' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ]; + $form->partincorrectfb = [ + 0 => ['text' => self::DEFAULT_INCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + 1 => ['text' => self::DEFAULT_INCORRECT_FEEDBACK, 'format' => FORMAT_HTML], + ]; + $form->questiontext = [ + 'text' => 'This question has two parts with two numbers in each of them.
', + 'format' => FORMAT_HTML, + ]; + $form->generalfeedback = ['text' => '', 'format' => FORMAT_HTML]; $form->defaultmark = 2; $form->penalty = 0.3; $form->varsrandom = ''; $form->varsglobal = ''; - $form->answernumbering = ''; + $form->answernumbering = 'abc'; $form->globalunitpenalty = 1; $form->globalruleid = 1; - $form->correctfeedback = array('text' => '', 'format' => FORMAT_HTML); - $form->partiallycorrectfeedback = array('text' => '', 'format' => FORMAT_HTML); - $form->shownumcorrect = '0'; - $form->incorrectfeedback = array('text' => '', 'format' => FORMAT_HTML); - $form->numhints = 0; + $form->correctfeedback = [ + 'text' => test_question_maker::STANDARD_OVERALL_CORRECT_FEEDBACK, + 'format' => FORMAT_HTML, + ]; + $form->partiallycorrectfeedback = [ + 'text' => test_question_maker::STANDARD_OVERALL_PARTIALLYCORRECT_FEEDBACK, + 'format' => FORMAT_HTML, + ]; + $form->incorrectfeedback = [ + 'text' => test_question_maker::STANDARD_OVERALL_INCORRECT_FEEDBACK, + 'format' => FORMAT_HTML, + ]; + $form->shownumcorrect = 1; + return $form; } -} + + /** + * Return question data for the testtwoandtwo Formulas question. + * + * @return stdClass + */ + public static function get_formulas_question_data_testtwoandtwo(): stdClass { + $qdata = new stdClass(); + test_question_maker::initialise_question_data($qdata); + + $qdata->qtype = 'formulas'; + $qdata->name = 'testtwoandtwo'; + $qdata->questiontext = 'This question has two parts with two numbers in each of them.
'; + $qdata->generalfeedback = ''; + $qdata->defaultmark = 2; + $qdata->penalty = 0.3; + + $qdata->options = new stdClass(); + $qdata->contextid = context_system::instance()->id; + $qdata->options->varsrandom = ''; + $qdata->options->varsglobal = ''; + $qdata->options->answernumbering = 'abc'; + $qdata->options->shownumcorrect = 1; + $qdata->options->correctfeedback = + test_question_maker::STANDARD_OVERALL_CORRECT_FEEDBACK; + $qdata->options->correctfeedbackformat = FORMAT_HTML; + $qdata->options->partiallycorrectfeedback = + test_question_maker::STANDARD_OVERALL_PARTIALLYCORRECT_FEEDBACK; + $qdata->options->partiallycorrectfeedbackformat = FORMAT_HTML; + $qdata->options->incorrectfeedback = + test_question_maker::STANDARD_OVERALL_INCORRECT_FEEDBACK; + $qdata->options->incorrectfeedbackformat = FORMAT_HTML; + + $qdata->options->answers = [ + 14 => (object)[ + 'id' => 14, + 'questionid' => $qdata->id, + 'placeholder' => '', + 'answermark' => 1, + 'answertype' => '0', + 'numbox' => 2, + 'vars1' => '', + 'vars2' => '', + 'answer' => '[1, 2]', + 'answernotunique' => '1', + 'correctness' => '_relerr < 0.01', + 'unitpenalty' => 1, + 'postunit' => '', + 'ruleid' => 1, + 'otherrule' => '', + 'subqtext' => 'Part 1 -- {_0} -- {_1}', + 'subqtextformat' => FORMAT_HTML, + 'feedback' => '', + 'feedbackformat' => FORMAT_HTML, + 'partcorrectfb' => 'Your answers in part 1 are correct.', + 'partcorrectfbformat' => FORMAT_HTML, + 'partpartiallycorrectfb' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, + 'partpartiallycorrectfbformat' => FORMAT_HTML, + 'partincorrectfb' => self::DEFAULT_INCORRECT_FEEDBACK, + 'partincorrectfbformat' => FORMAT_HTML, + 'partindex' => 0, + ], + 15 => (object)[ + 'id' => 15, + 'questionid' => $qdata->id, + 'placeholder' => '', + 'answermark' => 1, + 'answertype' => '0', + 'numbox' => 2, + 'vars1' => '', + 'vars2' => '', + 'answer' => '[3, 4]', + 'answernotunique' => '1', + 'correctness' => '_relerr < 0.01', + 'unitpenalty' => 1, + 'postunit' => '', + 'ruleid' => 1, + 'otherrule' => '', + 'subqtext' => 'Part 2 -- {_0} -- {_1}', + 'subqtextformat' => FORMAT_HTML, + 'feedback' => '', + 'feedbackformat' => FORMAT_HTML, + 'partcorrectfb' => 'Your answers in part 2 are correct.', + 'partcorrectfbformat' => FORMAT_HTML, + 'partpartiallycorrectfb' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, + 'partpartiallycorrectfbformat' => FORMAT_HTML, + 'partincorrectfb' => self::DEFAULT_INCORRECT_FEEDBACK, + 'partincorrectfbformat' => FORMAT_HTML, + 'partindex' => 1, + ], + ]; + + $qdata->options->numpart = 2; + + return $qdata; + } +} \ No newline at end of file From a53ca06140da13670c1f40d87c5387a82f612ee1 Mon Sep 17 00:00:00 2001 From: Philipp Imhof <52650214+PhilippImhof@users.noreply.github.com> Date: Sun, 16 Mar 2025 11:43:13 +0100 Subject: [PATCH 3/5] fix failing tests --- tests/behat/quiz.feature | 10 +++++----- tests/helper.php | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/behat/quiz.feature b/tests/behat/quiz.feature index 1caf70e8..f5240b55 100644 --- a/tests/behat/quiz.feature +++ b/tests/behat/quiz.feature @@ -37,7 +37,7 @@ Feature: Usage in quiz | quiz | Quiz 7 | C1 | quiz7 | | quiz | Quiz 8 | C1 | quiz8 | | quiz | Quiz 9 | C1 | quiz9 | - | quiz | Quiz 10 | C1 | quiz9 | + | quiz | Quiz 10 | C1 | quiz10 | And quiz "Quiz 1" contains the following questions: | question | page | | singlenum | 1 | @@ -80,7 +80,7 @@ Feature: Usage in quiz # And I click on "Submit all and finish" "button" in the "Confirmation" "dialogue" # And I click on "Submit all and finish" "button" in the "Submit all your answers and finish?" "dialogue" # And I confirm the quiz submission in the modal dialog - Then I should see "Your answer is correct." + Then I should see "Correct answer, well done." Scenario: Try to answer a question with one part and two answer fields When I follow "Quiz 2" @@ -109,7 +109,7 @@ Feature: Usage in quiz And I press "Finish attempt" And I press "Submit all and finish" # And I confirm the quiz submission in the modal dialog - Then I should see "Your answer is correct." + Then I should see "Correct answer, well done." Scenario: Try to answer a question with three parts and one answer field each When I follow "Quiz 5" @@ -134,7 +134,7 @@ Feature: Usage in quiz And I press "Finish attempt" And I press "Submit all and finish" And I confirm the quiz submission in the modal dialog for the formulas plugin - Then I should see "Your answer is correct." + Then I should see "Correct answer, well done." Scenario: Try to answer a drowdown multiple choice formula question When I follow "Quiz 7" @@ -143,7 +143,7 @@ Feature: Usage in quiz And I press "Finish attempt" And I press "Submit all and finish" # And I confirm the quiz submission in the modal dialog - Then I should see "Your answer is correct." + Then I should see "Correct answer, well done." Scenario: Try to answer a question with two parts, one drowdown multiple choice in each of them When I follow "Quiz 8" diff --git a/tests/helper.php b/tests/helper.php index 88a80f42..17c0f850 100644 --- a/tests/helper.php +++ b/tests/helper.php @@ -84,6 +84,7 @@ protected static function make_a_formulas_question() { $q->varsrandom = ''; $q->varsglobal = ''; $q->answernumbering = 'abc'; + $q->qv = new qtype_formulas\variables(); $q->penalty = 0.2; $q->generalfeedback = ''; test_question_maker::set_standard_combined_feedback_fields($q); From 2689dd31ca13145b8110849b9b4a6f54e14e20c1 Mon Sep 17 00:00:00 2001 From: Philipp Imhof <52650214+PhilippImhof@users.noreply.github.com> Date: Sun, 16 Mar 2025 13:27:32 +0100 Subject: [PATCH 4/5] add workaround for Moodle < 4.0 --- tests/backup_restore_test.php | 11 ++++++-- tests/behat/mobile.feature | 10 +++---- .../dummy_quiz_question_helper_test_trait.php | 28 +++++++++++++++++++ 3 files changed, 42 insertions(+), 7 deletions(-) create mode 100644 tests/dummy_quiz_question_helper_test_trait.php diff --git a/tests/backup_restore_test.php b/tests/backup_restore_test.php index 646efd39..aa47cd4c 100644 --- a/tests/backup_restore_test.php +++ b/tests/backup_restore_test.php @@ -39,11 +39,18 @@ require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php'); require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php'); require_once($CFG->dirroot . '/mod/quiz/locallib.php'); -require_once($CFG->dirroot . '/mod/quiz/tests/quiz_question_helper_test_trait.php'); require_once($CFG->dirroot . '/question/engine/tests/helpers.php'); require_once($CFG->dirroot . '/question/type/formulas/questiontype.php'); require_once($CFG->dirroot . '/question/type/formulas/tests/helper.php'); +if (file_exists($CFG->dirroot . '/mod/quiz/tests/quiz_question_helper_test_trait.php')) { + require_once($CFG->dirroot . '/mod/quiz/tests/quiz_question_helper_test_trait.php'); + class_alias('\quiz_question_helper_test_trait', '\trait_class_alias'); +} else { + require_once($CFG->dirroot . '/question/type/formulas/tests/dummy_quiz_question_helper_test_trait.php'); + class_alias('\qtype_formulas\dummy_quiz_question_helper_test_trait', '\trait_class_alias'); +} + /** * Unit tests for backup and restore. * @@ -57,7 +64,7 @@ * @covers \qtype_formulas_part */ final class backup_restore_test extends \advanced_testcase { - use \quiz_question_helper_test_trait; + use \trait_class_alias; /** * Create a question object of a certain type, as defined in the helper.php file. diff --git a/tests/behat/mobile.feature b/tests/behat/mobile.feature index 67abcb6d..9ce2111d 100644 --- a/tests/behat/mobile.feature +++ b/tests/behat/mobile.feature @@ -37,7 +37,7 @@ Feature: Mobile compatibility | quiz | Quiz 7 | C1 | quiz7 | | quiz | Quiz 8 | C1 | quiz8 | | quiz | Quiz 9 | C1 | quiz9 | - | quiz | Quiz 10 | C1 | quiz9 | + | quiz | Quiz 10 | C1 | quiz10 | And quiz "Quiz 1" contains the following questions: | question | page | | singlenum | 1 | @@ -79,7 +79,7 @@ Feature: Mobile compatibility And I press "Submit" in the app And I press "Submit all and finish" in the app And I press "Submit" near "Once you submit" in the app - Then I should find "Your answer is correct." in the app + Then I should find "Correct answer, well done." in the app Scenario: Try to answer a question with one part and two answer fields When I press "Quiz 2" in the app @@ -108,7 +108,7 @@ Feature: Mobile compatibility And I press "Submit" in the app And I press "Submit all and finish" in the app And I press "Submit" near "Once you submit" in the app - Then I should find "Your answer is correct." in the app + Then I should find "Correct answer, well done." in the app Scenario: Try to answer a question with three parts and one answer field each When I press "Quiz 5" in the app @@ -130,7 +130,7 @@ Feature: Mobile compatibility And I press "Submit" in the app And I press "Submit all and finish" in the app And I press "Submit" near "Once you submit" in the app - Then I should find "Your answer is correct." in the app + Then I should find "Correct answer, well done." in the app Scenario: Try to answer a drowdown multiple choice formula question When I press "Quiz 7" in the app @@ -140,7 +140,7 @@ Feature: Mobile compatibility And I press "Submit" in the app And I press "Submit all and finish" in the app And I press "Submit" near "Once you submit" in the app - Then I should find "Your answer is correct." in the app + Then I should find "Correct answer, well done." in the app Scenario: Try to answer a question with two parts, one drowdown multiple choice in each of them When I press "Quiz 8" in the app diff --git a/tests/dummy_quiz_question_helper_test_trait.php b/tests/dummy_quiz_question_helper_test_trait.php new file mode 100644 index 00000000..c677810f --- /dev/null +++ b/tests/dummy_quiz_question_helper_test_trait.php @@ -0,0 +1,28 @@ +. + +namespace qtype_formulas; + +/** + * Empty dummy trait for Moodle < 4.0 where the real quiz_question_helper_test_trait is not available. + * + * @package qtype_formulas + * @category test + * @copyright 2025 Philipp Imhof + * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +trait dummy_quiz_question_helper_test_trait { +} From 5c2b3d891ea158d89df79e93cf795b426f330fdb Mon Sep 17 00:00:00 2001 From: Philipp Imhof <52650214+PhilippImhof@users.noreply.github.com> Date: Sun, 16 Mar 2025 13:48:13 +0100 Subject: [PATCH 5/5] cleanup, skip test for Moodle < 4.0 --- tests/backup_restore_test.php | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/tests/backup_restore_test.php b/tests/backup_restore_test.php index aa47cd4c..729fc2c6 100644 --- a/tests/backup_restore_test.php +++ b/tests/backup_restore_test.php @@ -66,15 +66,6 @@ class_alias('\qtype_formulas\dummy_quiz_question_helper_test_trait', '\trait_cla final class backup_restore_test extends \advanced_testcase { use \trait_class_alias; - /** - * Create a question object of a certain type, as defined in the helper.php file. - * - * @return qtype_formulas_question - */ - protected function get_test_formulas_question($which = null) { - return test_question_maker::make_question('formulas', $which); - } - /** * Data provider. * @@ -100,7 +91,11 @@ public static function provide_question_names(): array { * @dataProvider provide_question_names */ public function test_backup_and_restore(string $questionname): void { - global $USER, $DB; + global $CFG, $USER, $DB; + + if ($CFG->branch < 400) { + $this->markTestSkipped('Not testing backup and restore in Moodle < 4.0'); + } // Login as admin user. $this->resetAfterTest(true);