From 2020628f6dabcb2819fc54dd7cf16a93c0084cb2 Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Thu, 1 Nov 2018 16:22:55 +0000 Subject: [PATCH] MDL-79863 qtype_ordering: Implement data generator code for creating test questions --- question/type/ordering/tests/helper.php | 186 +++++++++++++++++++++ question/type/ordering/tests/question_test.php | 52 ++++++ question/type/ordering/tests/questiontype_test.php | 107 ++++++++++++ 3 files changed, 345 insertions(+) create mode 100644 question/type/ordering/tests/helper.php create mode 100644 question/type/ordering/tests/question_test.php create mode 100644 question/type/ordering/tests/questiontype_test.php diff --git a/question/type/ordering/tests/helper.php b/question/type/ordering/tests/helper.php new file mode 100644 index 00000000000..58778b330db --- /dev/null +++ b/question/type/ordering/tests/helper.php @@ -0,0 +1,186 @@ +. + +/** + * Test helper for the ordering question type. + * + * @package qtype_ordering + * @copyright 2018 The Open University + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + + +/** + * Test helper for the ordering question type. + * + * The class has code to generate question data structures for sample ordering questions. + * + * @copyright 2018 The Open University + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class qtype_ordering_test_helper extends question_test_helper { + public function get_test_questions() { + return array('moodle'); + } + + /** + * Makes an ordering question to sort the words Modular Object Oriented Dynamic Learning Environment. + * + * @return qtype_ordering_question the question instance. + */ + public function make_ordering_question_moodle() { + question_bank::load_question_definition_classes('ordering'); + $q = new qtype_ordering_question(); + $q->questionid = $q->id; + test_question_maker::initialise_a_question($q); + $q->qtype = question_bank::get_qtype('ordering'); + $q->name = 'Moodle'; + $q->questiontext = 'Put these words in order'; + $q->generalfeedback = 'The correct answer is "Modular Object Oriented Dynamic Learning Environment".'; + test_question_maker::set_standard_combined_feedback_fields($q); + $q->answers = [ + 13 => $this->make_answer(13, 'Modular', FORMAT_HTML, 1, true), + 14 => $this->make_answer(14, 'Object', FORMAT_HTML, 2, true), + 15 => $this->make_answer(15, 'Oriented', FORMAT_HTML, 3, true), + 16 => $this->make_answer(16, 'Dynamic', FORMAT_HTML, 4, true), + 17 => $this->make_answer(17, 'Learning', FORMAT_HTML, 5, true), + 18 => $this->make_answer(18, 'Environment', FORMAT_HTML, 6, true), + ]; + $q->options = new stdClass(); + $q->options->layouttype = qtype_ordering_question::LAYOUT_HORIZONTAL; + $q->options->selecttype = qtype_ordering_question::SELECT_ALL; + $q->options->selectcount = 0; + $q->options->gradingtype = qtype_ordering_question::GRADING_RELATIVE_ALL_PREVIOUS_AND_NEXT; + $q->options->showgrading = true; + + return $q; + } + + /** + * Create an answer record to use in a test question. + * + * @param int $id the id to set. + * @param string $text + * @param int $textformat one of the FORMAT_... constanst. + * @param int $order the position in order, numbered from 1. + * @param bool $addmd5 whether to add the md5key property. + * @return stdClass the answer. + */ + protected function make_answer($id, $text, $textformat, $order, $addmd5 = false) { + global $CFG; + + $answer = new stdClass(); + $answer->id = $id; + $answer->question = 0; + $answer->answer = $text; + $answer->answerformat = $textformat; + $answer->fraction = $order; + $answer->feedback = ''; + $answer->feedbackformat = FORMAT_MOODLE; + + if ($addmd5) { + if (isset($CFG->passwordsaltmain)) { + $salt = $CFG->passwordsaltmain; + } else { + $salt = ''; + } + $answer->md5key = 'ordering_item_' . md5($salt . $answer->answer); + } + + return $answer; + } + + /** + * Get the form data that corresponds an ordering question. + * + * The question is to sort the words Modular Object Oriented Dynamic Learning Environment. + * + * @return stdClass simulated question form data. + */ + public function get_ordering_question_form_data_moodle() { + $form = new stdClass(); + $form->name = 'Moodle'; + $form->questiontext = ['text' => 'Put these words in order.', 'format' => FORMAT_HTML]; + $form->defaultmark = 1; + $form->generalfeedback = [ + 'text' => 'The correct answer is "Modular Object Oriented Dynamic Learning Environment".', + 'format' => FORMAT_HTML + ]; + + $form->layouttype = qtype_ordering_question::LAYOUT_HORIZONTAL; + $form->selecttype = qtype_ordering_question::SELECT_ALL; + $form->selectcount = 0; + $form->gradingtype = qtype_ordering_question::GRADING_RELATIVE_ALL_PREVIOUS_AND_NEXT; + $form->showgrading = true; + + $form->countanswers = 6; + $form->answer = [ + ['text' => 'Modular', 'format' => FORMAT_HTML], + ['text' => 'Object', 'format' => FORMAT_HTML], + ['text' => 'Oriented', 'format' => FORMAT_HTML], + ['text' => 'Dynamic', 'format' => FORMAT_HTML], + ['text' => 'Learning', 'format' => FORMAT_HTML], + ['text' => 'Environment', 'format' => FORMAT_HTML], + ]; + + test_question_maker::set_standard_combined_feedback_form_data($form); + + $form->penalty = '0.3333333'; + $form->numhints = 0; + $form->hint = []; + + $form->qtype = 'ordering'; + return $form; + } + + /** + * Get the raw data that corresponds an ordering question. + * + * The question is to sort the words Modular Object Oriented Dynamic Learning Environment. + * + * @return stdClass simulated question form data. + */ + public function get_ordering_question_data_moodle() { + $questiondata = new stdClass(); + test_question_maker::initialise_question_data($questiondata); + $questiondata->qtype = 'ordering'; + $questiondata->name = 'Moodle'; + $questiondata->questiontext = 'Put these words in order'; + $questiondata->generalfeedback = 'The correct answer is "Modular Object Oriented Dynamic Learning Environment".'; + + $questiondata->options = new stdClass(); + test_question_maker::set_standard_combined_feedback_fields($questiondata->options); + unset($questiondata->options->shownumcorrect); + $questiondata->options->layouttype = qtype_ordering_question::LAYOUT_HORIZONTAL; + $questiondata->options->selecttype = qtype_ordering_question::SELECT_ALL; + $questiondata->options->selectcount = 0; + $questiondata->options->gradingtype = qtype_ordering_question::GRADING_RELATIVE_ALL_PREVIOUS_AND_NEXT; + $questiondata->options->showgrading = true; + + $questiondata->options->answers = [ + 13 => $this->make_answer(13, 'Modular', FORMAT_HTML, 1), + 14 => $this->make_answer(14, 'Object', FORMAT_HTML, 2), + 15 => $this->make_answer(15, 'Oriented', FORMAT_HTML, 3), + 16 => $this->make_answer(16, 'Dynamic', FORMAT_HTML, 4), + 17 => $this->make_answer(17, 'Learning', FORMAT_HTML, 5), + 18 => $this->make_answer(18, 'Environment', FORMAT_HTML, 6), + ]; + + return $questiondata; + } +} diff --git a/question/type/ordering/tests/question_test.php b/question/type/ordering/tests/question_test.php new file mode 100644 index 00000000000..eb9f2e689e2 --- /dev/null +++ b/question/type/ordering/tests/question_test.php @@ -0,0 +1,52 @@ +. + + +/** + * Unit tests for the ordering question definition class. + * + * @package qtype_ordering + * @copyright 2018 The Open University + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + + +global $CFG; +require_once($CFG->dirroot . '/question/engine/tests/helpers.php'); + + +/** + * Unit tests for the ordering question definition class. + * + * @copyright 2018 The Open University + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class qtype_ordering_question_test extends advanced_testcase { + + public function test_grading() { + /** @var qtype_ordering_question $question */ + $question = test_question_maker::make_question('ordering'); + $question->start_attempt(new question_attempt_pending_step(), 1); + + $ids = []; + foreach ($question->answers as $answer) { + $ids[] = $answer->md5key; + } + + $this->assertEquals([1, question_state::$gradedright], + $question->grade_response(['response_' . $question->id => implode(',', $ids)])); + } +} diff --git a/question/type/ordering/tests/questiontype_test.php b/question/type/ordering/tests/questiontype_test.php new file mode 100644 index 00000000000..2267fb20a02 --- /dev/null +++ b/question/type/ordering/tests/questiontype_test.php @@ -0,0 +1,107 @@ +. + +/** + * Unit tests for the ordering question type class. + * + * @package qtype_ordering + * @copyright 2018 The Open University + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + + +defined('MOODLE_INTERNAL') || die(); + +global $CFG; +require_once($CFG->dirroot . '/question/engine/tests/helpers.php'); +require_once($CFG->dirroot . '/question/type/ordering/questiontype.php'); +require_once($CFG->dirroot . '/question/type/edit_question_form.php'); +require_once($CFG->dirroot . '/question/type/ordering/edit_ordering_form.php'); + + +/** + * Unit tests for the ordering question type class. + * + * @copyright 20018 The Open University + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class qtype_ordering_test extends advanced_testcase { + /** @var qtype_ordering instance of the question type class to test. */ + protected $qtype; + + protected function setUp() { + $this->qtype = new qtype_ordering(); + } + + protected function tearDown() { + $this->qtype = null; + } + + public function test_name() { + $this->assertEquals($this->qtype->name(), 'ordering'); + } + + public function test_can_analyse_responses() { + $this->assertTrue($this->qtype->can_analyse_responses()); + } + + public function test_question_saving() { + $this->resetAfterTest(); + $this->setAdminUser(); + + $questiondata = test_question_maker::get_question_data('ordering'); + $formdata = test_question_maker::get_question_form_data('ordering'); + + /** @var core_question_generator $generator */ + $generator = $this->getDataGenerator()->get_plugin_generator('core_question'); + $cat = $generator->create_question_category([]); + + $formdata->category = "{$cat->id},{$cat->contextid}"; + + qtype_ordering_edit_form::mock_submit((array) $formdata); + + $form = qtype_ordering_test_helper::get_question_editing_form($cat, $questiondata); + $this->assertTrue($form->is_validated()); + + $fromform = $form->get_data(); + + $returnedfromsave = $this->qtype->save_question($questiondata, $fromform); + $actualquestiondata = question_bank::load_question_data($returnedfromsave->id); + + foreach ($questiondata as $property => $value) { + if (!in_array($property, array('id', 'version', 'timemodified', 'timecreated', 'options', 'stamp'))) { + $this->assertAttributeEquals($value, $property, $actualquestiondata); + } + } + + foreach ($questiondata->options as $optionname => $value) { + if ($optionname != 'answers') { + $this->assertAttributeEquals($value, $optionname, $actualquestiondata->options); + } + } + + foreach ($questiondata->options->answers as $answer) { + $actualanswer = array_shift($actualquestiondata->options->answers); + foreach ($answer as $ansproperty => $ansvalue) { + if ($ansproperty === 'question') { + $this->assertAttributeEquals($returnedfromsave->id, $ansproperty, $actualanswer); + } else if ($ansproperty !== 'id') { + $this->assertAttributeEquals($ansvalue, $ansproperty, $actualanswer); + } + } + } + } +} -- 2.11.4.GIT