From be27fc0fe302a6953f8668ccc4b5aecfd830a325 Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Mon, 26 Nov 2018 12:49:47 +0000 Subject: [PATCH] MDL-63459 qtype_calculatedmulti: unit test should test this qtype This also demonstrates the bug to be fixed --- .../type/calculatedmulti/tests/helper.php | 87 +++++++++++--- .../tests/walkthrough_test.php | 112 ++++++++++++++---- 2 files changed, 158 insertions(+), 41 deletions(-) diff --git a/question/type/calculatedmulti/tests/helper.php b/question/type/calculatedmulti/tests/helper.php index 6fd63d752ec..25dddb1916a 100644 --- a/question/type/calculatedmulti/tests/helper.php +++ b/question/type/calculatedmulti/tests/helper.php @@ -27,8 +27,8 @@ defined('MOODLE_INTERNAL') || die(); global $CFG; -require_once($CFG->dirroot . '/question/type/calculated/question.php'); - +require_once($CFG->dirroot . '/question/type/calculatedmulti/question.php'); +require_once($CFG->dirroot . '/question/type/calculated/tests/helper.php'); /** * Test helper class for the calculated multiple-choice question type. @@ -38,32 +38,43 @@ require_once($CFG->dirroot . '/question/type/calculated/question.php'); */ class qtype_calculatedmulti_test_helper extends question_test_helper { public function get_test_questions() { - return array('sum'); + return array('singleresponse', 'multiresponse'); } /** * Makes a calculated multiple-choice question about summing two numbers. - * @return qtype_calculatedmulti_question + * @return qtype_calculatedmulti_single_question */ - public function make_calculatedmulti_question_sum() { - // TODO. + public function make_calculatedmulti_question_singleresponse() { question_bank::load_question_definition_classes('calculated'); - $q = new qtype_calculatedmulti_question(); + $q = new qtype_calculatedmulti_single_question(); test_question_maker::initialise_a_question($q); $q->name = 'Simple sum'; $q->questiontext = 'What is {a} + {b}?'; $q->generalfeedback = 'Generalfeedback: {={a} + {b}} is the right answer.'; + $q->shuffleanswers = 0; + $q->answernumbering = 'abc'; + $q->layout = 1; + $q->correctfeedback = test_question_maker::STANDARD_OVERALL_CORRECT_FEEDBACK; + $q->correctfeedbackformat = FORMAT_HTML; + $q->partiallycorrectfeedback = test_question_maker::STANDARD_OVERALL_PARTIALLYCORRECT_FEEDBACK; + $q->partiallycorrectfeedbackformat = FORMAT_HTML; + $q->shownumcorrect = 1; + $q->incorrectfeedback = test_question_maker::STANDARD_OVERALL_INCORRECT_FEEDBACK; + $q->incorrectfeedbackformat = FORMAT_HTML; + $q->shownumcorrect = 1; $q->answers = array( - 13 => new qtype_numerical_answer(13, '{a} + {b}', 1.0, 'Very good.', FORMAT_HTML, 0), - 14 => new qtype_numerical_answer(14, '{a} - {b}', 0.0, 'Add. not subtract!.', - FORMAT_HTML, 0), - 17 => new qtype_numerical_answer(17, '*', 0.0, 'Completely wrong.', FORMAT_HTML, 0), + 13 => new question_answer(13, '{={a} + {b}}', 1.0, 'Very good.', FORMAT_HTML), + 14 => new question_answer(14, '{={a} - {b}}', 0.0, 'Add. not subtract!', FORMAT_HTML), + 17 => new question_answer(17, '{={a} + 2 * {b}}', 0.0, 'Just add.', FORMAT_HTML), ); - $q->qtype = question_bank::get_qtype('calculated'); - $q->unitdisplay = qtype_numerical::UNITNONE; - $q->unitgradingtype = 0; - $q->unitpenalty = 0; - $q->ap = new qtype_numerical_answer_processor(array()); + $q->answers[13]->correctanswerlength = 2; + $q->answers[13]->correctanswerformat = 1; + $q->answers[14]->correctanswerlength = 2; + $q->answers[14]->correctanswerformat = 1; + $q->answers[17]->correctanswerlength = 2; + $q->answers[17]->correctanswerformat = 1; + $q->qtype = question_bank::get_qtype('calculatedmulti'); $q->datasetloader = new qtype_calculated_test_dataset_loader(0, array( array('a' => 1, 'b' => 5), @@ -72,4 +83,48 @@ class qtype_calculatedmulti_test_helper extends question_test_helper { return $q; } + + /** + * Makes a calculated multiple-choice question with multiple right answers. + * @return qtype_calculatedmulti_multi_question + */ + public function make_calculatedmulti_question_multiresponse() { + question_bank::load_question_definition_classes('calculated'); + $q = new qtype_calculatedmulti_multi_question(); + test_question_maker::initialise_a_question($q); + $q->name = 'Simple sum'; + $q->questiontext = 'What is {a} + {b}?'; + $q->generalfeedback = 'Generalfeedback: {={a} + {b}} is the right answer.'; + $q->shuffleanswers = 0; + $q->answernumbering = 'abc'; + $q->layout = 1; + $q->correctfeedback = test_question_maker::STANDARD_OVERALL_CORRECT_FEEDBACK; + $q->correctfeedbackformat = FORMAT_HTML; + $q->partiallycorrectfeedback = test_question_maker::STANDARD_OVERALL_PARTIALLYCORRECT_FEEDBACK; + $q->partiallycorrectfeedbackformat = FORMAT_HTML; + $q->shownumcorrect = 1; + $q->incorrectfeedback = test_question_maker::STANDARD_OVERALL_INCORRECT_FEEDBACK; + $q->incorrectfeedbackformat = FORMAT_HTML; + $q->shownumcorrect = 1; + $q->answers = array( + 13 => new qtype_numerical_answer(13, '{a} + {b}!', 0.5, 'Good', FORMAT_HTML, 0), + 14 => new qtype_numerical_answer(14, '{={a} + {b}}', 0.5, 'Good', + FORMAT_HTML, 0), + 17 => new qtype_numerical_answer(17, '{={a} - {b}}', -0.5, 'Wrong.', FORMAT_HTML, 0), + ); + $q->answers[13]->correctanswerlength = 2; + $q->answers[13]->correctanswerformat = 1; + $q->answers[14]->correctanswerlength = 2; + $q->answers[14]->correctanswerformat = 1; + $q->answers[17]->correctanswerlength = 2; + $q->answers[17]->correctanswerformat = 1; + $q->qtype = question_bank::get_qtype('calculatedmulti'); + + $q->datasetloader = new qtype_calculated_test_dataset_loader(0, array( + array('a' => 1, 'b' => 5), + array('a' => 3, 'b' => 4), + )); + + return $q; + } } diff --git a/question/type/calculatedmulti/tests/walkthrough_test.php b/question/type/calculatedmulti/tests/walkthrough_test.php index 00fddcaa575..10037d14af8 100644 --- a/question/type/calculatedmulti/tests/walkthrough_test.php +++ b/question/type/calculatedmulti/tests/walkthrough_test.php @@ -37,10 +37,12 @@ require_once($CFG->dirroot . '/question/engine/tests/helpers.php'); * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class qtype_calculatedmulti_walkthrough_test extends qbehaviour_walkthrough_test_base { - public function test_interactive() { + + public function test_interactive_single_response() { // Create a gapselect question. - $q = test_question_maker::make_question('calculated'); + $q = test_question_maker::make_question('calculatedmulti', 'singleresponse'); + $q->shuffleanswers = false; $q->hints = array( new question_hint(1, 'This is the first hint.', FORMAT_HTML), new question_hint(2, 'This is the second hint.', FORMAT_HTML), @@ -60,44 +62,104 @@ class qtype_calculatedmulti_walkthrough_test extends qbehaviour_walkthrough_test $this->get_does_not_contain_try_again_button_expectation(), $this->get_no_hint_visible_expectation()); - // Submit blank. - $this->process_submission(array('-submit' => 1, 'answer' => '')); + // Submit a wrong answer. + $this->process_submission(array('-submit' => 1, 'answer' => '1')); // Verify. - $this->check_current_state(question_state::$invalid); + $this->check_current_state(question_state::$todo); + $this->check_current_mark(null); + $this->check_current_output( + $this->get_contains_marked_out_of_summary(), + $this->get_does_not_contain_submit_button_expectation(), + $this->get_contains_try_again_button_expectation(true), + $this->get_contains_hint_expectation('This is the first hint.')); + + // Do try again. + $this->process_submission(array('-tryagain' => 1)); + + // Verify. + $this->check_current_state(question_state::$todo); $this->check_current_mark(null); $this->check_current_output( $this->get_contains_marked_out_of_summary(), $this->get_contains_submit_button_expectation(true), $this->get_does_not_contain_feedback_expectation(), - $this->get_contains_validation_error_expectation(), - $this->get_does_not_contain_try_again_button_expectation(), - $this->get_no_hint_visible_expectation()); - - // Sumit something that does not look like a number. - $this->process_submission(array('-submit' => 1, 'answer' => 'newt')); - - // Verify. - $this->check_current_state(question_state::$invalid); - $this->check_current_mark(null); - $this->check_current_output( - $this->get_contains_marked_out_of_summary(), - $this->get_contains_submit_button_expectation(true), - $this->get_does_not_contain_feedback_expectation(), - $this->get_contains_validation_error_expectation(), - new question_pattern_expectation('/' . - preg_quote(get_string('invalidnumber', 'qtype_numerical'), '/') . '/'), + $this->get_does_not_contain_validation_error_expectation(), $this->get_does_not_contain_try_again_button_expectation(), $this->get_no_hint_visible_expectation()); // Now get it right. - $this->process_submission(array('-submit' => 1, 'answer' => $values['a'] + $values['b'])); + $this->process_submission(array('-submit' => 1, 'answer' => '0')); // Verify. $this->check_current_state(question_state::$gradedright); - $this->check_current_mark(3); + $this->check_current_mark(2); $this->check_current_output( - $this->get_contains_mark_summary(3), + $this->get_contains_mark_summary(2), + $this->get_does_not_contain_submit_button_expectation(), + $this->get_contains_correct_expectation(), + $this->get_does_not_contain_validation_error_expectation(), + $this->get_no_hint_visible_expectation()); + } + + public function test_interactive_multi_response() { + + // Create a gapselect question. + $q = test_question_maker::make_question('calculatedmulti', 'multiresponse'); + $q->shuffleanswers = false; + $q->hints = array( + new question_hint(1, 'This is the first hint.', FORMAT_HTML), + new question_hint(2, 'This is the second hint.', FORMAT_HTML), + ); + $this->start_attempt_at_question($q, 'interactive', 3, 2); + $values = $q->vs->get_values(); + $this->assertEquals($values, $q->datasetloader->load_values(2)); + + // Check the initial state. + $this->check_current_state(question_state::$todo); + $this->check_current_mark(null); + $this->check_current_output( + $this->get_contains_marked_out_of_summary(), + $this->get_contains_submit_button_expectation(true), + $this->get_does_not_contain_feedback_expectation(), + $this->get_does_not_contain_validation_error_expectation(), + $this->get_does_not_contain_try_again_button_expectation(), + $this->get_no_hint_visible_expectation()); + + // Submit all boxes ticked. + $this->process_submission(array('-submit' => 1, 'choice0' => '1', 'choice1' => '1', 'choice2' => '1')); + + // Verify. + $this->check_current_state(question_state::$todo); + $this->check_current_mark(null); + $this->check_current_output( + $this->get_contains_marked_out_of_summary(), + $this->get_does_not_contain_submit_button_expectation(), + $this->get_contains_try_again_button_expectation(true), + $this->get_contains_hint_expectation('This is the first hint.')); + + // Do try again. + $this->process_submission(array('-tryagain' => 1)); + + // Verify. + $this->check_current_state(question_state::$todo); + $this->check_current_mark(null); + $this->check_current_output( + $this->get_contains_marked_out_of_summary(), + $this->get_contains_submit_button_expectation(true), + $this->get_does_not_contain_feedback_expectation(), + $this->get_does_not_contain_validation_error_expectation(), + $this->get_does_not_contain_try_again_button_expectation(), + $this->get_no_hint_visible_expectation()); + + // Now get it right. + $this->process_submission(array('-submit' => 1, 'choice0' => '1', 'choice1' => '1', 'choice2' => '0')); + + // Verify. + $this->check_current_state(question_state::$gradedright); + $this->check_current_mark(2); + $this->check_current_output( + $this->get_contains_mark_summary(2), $this->get_does_not_contain_submit_button_expectation(), $this->get_contains_correct_expectation(), $this->get_does_not_contain_validation_error_expectation(),