Skip to content

Commit

Permalink
MDL-27413 unit tests for some of the new multianswer code.
Browse files Browse the repository at this point in the history
  • Loading branch information
timhunt committed May 23, 2011
1 parent ab50232 commit fa6c862
Show file tree
Hide file tree
Showing 8 changed files with 475 additions and 9 deletions.
27 changes: 25 additions & 2 deletions question/type/multianswer/question.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,30 @@ public function apply_attempt_state(question_attempt_step $step) {
}
}

// TODO get_question_summary ???
public function get_question_summary() {
$summary = $this->html_to_text($this->questiontext, $this->questiontextformat);
foreach ($this->subquestions as $i => $subq) {
switch ($subq->qtype->name()) {
case 'multichoice':
$choices = array();
$dummyqa = new question_attempt($subq, $this->contextid);
foreach ($subq->get_order($dummyqa) as $ansid) {
$choices[] = $this->html_to_text($subq->answers[$ansid]->answer,
$subq->answers[$ansid]->answerformat);
}
$answerbit = '{' . implode('; ', $choices) . '}';
break;
case 'numerical':
case 'shortanswer':
$answerbit = '_____';
break;
default:
$answerbit = '{ERR unknown sub-question type}';
}
$summary = str_replace('{#' . $i . '}', $answerbit, $summary);
}
return $summary;
}

public function get_min_fraction() {
$fractionsum = 0;
Expand All @@ -95,7 +118,7 @@ public function get_correct_response() {
$right = array();
foreach ($this->subquestions as $i => $subq) {
$substep = $this->get_substep(null, $i);
foreach ($subq->get_expected_data() as $name => $type) {
foreach ($subq->get_correct_response() as $name => $type) {
$right[$substep->add_prefix($name)] = $type;
}
}
Expand Down
3 changes: 2 additions & 1 deletion question/type/multianswer/questiontype.php
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ protected function initialise_question_instance($question, $questiondata) {
foreach ($questiondata->options->questions as $key => $subqdata) {
$subqdata->contextid = $questiondata->contextid;
$question->subquestions[$key] = question_bank::make_question($subqdata);
$question->subquestions[$key]->maxmark = $subqdata->defaultmark;
}
}

Expand Down Expand Up @@ -502,7 +503,7 @@ public function get_random_guess_score($questiondata) {
$fractionsum = 0;
$fractionmax = 0;
foreach ($questiondata->options->questions as $key => $subqdata) {
$fractionmax += $subqdata->maxmark;
$fractionmax += $subqdata->defaultmark;
$fractionsum += question_bank::get_qtype(
$subqdata->qtype)->get_random_guess_score($subqdata);
}
Expand Down
7 changes: 3 additions & 4 deletions question/type/multianswer/renderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,13 @@
* the task of display their input elements and status
* feedback, grade, correct answer(s)
*
* @copyright © 2009 The Open University
* @copyright 2010 Pierre Pichet
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class qtype_multianswer_renderer extends qtype_renderer {

public function formulation_and_controls(question_attempt $qa,
question_display_options $options) {

$question = $qa->get_question();

$result = '';
Expand Down Expand Up @@ -84,7 +83,7 @@ public function formulation_and_controls(question_attempt $qa,


public function correct_response(question_attempt $qa) {
return '' ;
return '';
}

}
Expand All @@ -94,7 +93,7 @@ public function correct_response(question_attempt $qa) {
* Subclass for generating the bits of output specific to shortanswer
* subquestions.
*
* @copyright © 2009 The Open University
* @copyright 2009 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once($CFG->dirroot . '/question/type/shortanswer/renderer.php');
Expand Down
107 changes: 107 additions & 0 deletions question/type/multianswer/simpletest/helper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

/**
* Test helpers for the multianswer question type.
*
* @package qtype
* @subpackage multianswer
* @copyright 2011 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/


defined('MOODLE_INTERNAL') || die();

require_once($CFG->dirroot . '/question/type/multianswer/question.php');


/**
* Test helper class for the multianswer question type.
*
* @copyright 2011 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class qtype_multianswer_test_helper extends question_test_helper {
public function get_test_questions() {
return array('twosubq');
}

/**
* Makes a multianswer question about summing two numbers.
* @return qtype_multianswer_question
*/
public function make_multianswer_question_twosubq() {
question_bank::load_question_definition_classes('multianswer');
$q = new qtype_multianswer_question();
test_question_maker::initialise_a_question($q);
$q->name = 'Simple multianswer';
$q->questiontext =
'Complete this opening line of verse: "The {#1} and the {#2} went to sea".';
$q->generalfeedback = 'Generalfeedback: It\'s from "The Owl and the Pussy-cat" by Lear: ' .
'"The owl and the pussycat went to see';
$q->questiontextformat = FORMAT_HTML;
$q->generalfeedbackformat = FORMAT_HTML;

// Shortanswer subquestion.
question_bank::load_question_definition_classes('shortanswer');
$sa = new qtype_shortanswer_question();
test_question_maker::initialise_a_question($sa);
$sa->name = 'Simple multianswer';
$sa->questiontext = '{1:SHORTANSWER:Dog#Wrong, silly!~=Owl#Well done!~*#Wrong answer}';
$sa->questiontextformat = FORMAT_HTML;
$sa->generalfeedback = '';
$sa->generalfeedbackformat = FORMAT_HTML;
$sa->usecase = true;
$sa->answers = array(
13 => new question_answer(13, 'Dog', 0.0, 'Wrong, silly!', FORMAT_HTML),
14 => new question_answer(14, 'Owl', 1.0, 'Well done!', FORMAT_HTML),
15 => new question_answer(15, '*', 0.0, 'Wrong answer', FORMAT_HTML),
);
$sa->qtype = question_bank::get_qtype('shortanswer');
$sa->maxmark = 1;

// Multiple-choice subquestion.
question_bank::load_question_definition_classes('multichoice');
$mc = new qtype_multichoice_single_question();
test_question_maker::initialise_a_question($mc);
$mc->name = 'Simple multianswer';
$mc->questiontext = '{1:MULTICHOICE:Bow-wow#You seem to have a dog obsessions!' .
'~Wiggly worm#Now you are just being rediculous!~=Pussy-cat#Well done!}';
$mc->questiontextformat = FORMAT_HTML;
$mc->generalfeedback = '';
$mc->generalfeedbackformat = FORMAT_HTML;

$mc->shuffleanswers = 1;
$mc->answernumbering = 'none';
$mc->layout = 1;

$mc->answers = array(
13 => new question_answer(13, 'Bow-wow', 0, 'You seem to have a dog obsessions!', FORMAT_HTML),
14 => new question_answer(14, 'Wiggly worm', 0, 'Now you are just being rediculous!', FORMAT_HTML),
15 => new question_answer(15, 'Pussy-cat', 1, 'Well done!', FORMAT_HTML),
);
$mc->qtype = question_bank::get_qtype('multichoice');
$mc->maxmark = 1;

$q->subquestions = array(
1 => $sa,
2 => $mc,
);

return $q;
}
}
117 changes: 117 additions & 0 deletions question/type/multianswer/simpletest/testquestion.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.


/**
* Unit tests for the multianswer question definition class.
*
* @package qtype
* @subpackage multianswer
* @copyright 2011 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/


require_once($CFG->dirroot . '/question/engine/simpletest/helpers.php');


/**
* Unit tests for qtype_multianswer_question.
*
* @copyright 2011 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class qtype_multianswer_question_test extends UnitTestCase {
public function test_get_expected_data() {
$question = test_question_maker::make_question('multianswer');
$this->assertEqual(array('sub1_answer' => PARAM_RAW_TRIMMED, 'sub2_answer' => PARAM_INT),
$question->get_expected_data());
}

public function test_is_complete_response() {
$question = test_question_maker::make_question('multianswer');

$this->assertFalse($question->is_complete_response(array()));
$this->assertTrue($question->is_complete_response(array('sub1_answer' => 'Owl',
'sub2_answer' => '2')));
$this->assertTrue($question->is_complete_response(array('sub1_answer' => '0',
'sub2_answer' => 0)));
$this->assertFalse($question->is_complete_response(array('sub1_answer' => 'Owl')));
}

public function test_is_gradable_response() {
$question = test_question_maker::make_question('multianswer');

$this->assertFalse($question->is_gradable_response(array()));
$this->assertTrue($question->is_gradable_response(array('sub1_answer' => 'Owl',
'sub2_answer' => '2')));
$this->assertTrue($question->is_gradable_response(array('sub1_answer' => '0',
'sub2_answer' => 0)));
$this->assertTrue($question->is_gradable_response(array('sub1_answer' => 'Owl')));
}

public function test_grading() {
$question = test_question_maker::make_question('multianswer');
$question->start_attempt(new question_attempt_step());

$rightchoice = $question->subquestions[2]->get_correct_response();

$this->assertEqual(array(1, question_state::$gradedright), $question->grade_response(
array('sub1_answer' => 'Owl', 'sub2_answer' => reset($rightchoice))));
$this->assertEqual(array(0.5, question_state::$gradedpartial), $question->grade_response(
array('sub1_answer' => 'Owl')));
$this->assertEqual(array(0.5, question_state::$gradedpartial), $question->grade_response(
array('sub1_answer' => 'Goat', 'sub2_answer' => reset($rightchoice))));
$this->assertEqual(array(0, question_state::$gradedwrong), $question->grade_response(
array('sub1_answer' => 'Dog')));
}

public function test_get_correct_response() {
$question = test_question_maker::make_question('multianswer');
$question->start_attempt(new question_attempt_step());

$rightchoice = $question->subquestions[2]->get_correct_response();

$this->assertEqual(array('sub1_answer' => 'Owl', 'sub2_answer' => reset($rightchoice)),
$question->get_correct_response());
}

public function test_get_question_summary() {
$question = test_question_maker::make_question('multianswer');

// Bit of a hack to make testing easier.
$question->subquestions[2]->shuffleanswers = false;

$question->start_attempt(new question_attempt_step());

$qsummary = $question->get_question_summary();
$this->assertEqual('Complete this opening line of verse: "The _____ and the ' .
'{Bow-wow; Wiggly worm; Pussy-cat} went to sea".', $qsummary);
}

public function test_summarise_response() {
$question = test_question_maker::make_question('multianswer');
$question->start_attempt(new question_attempt_step());

$rightchoice = $question->subquestions[2]->get_correct_response();

$this->assertEqual(get_string('subqresponse', 'qtype_multianswer',
array('i' => 1, 'response' => 'Owl')) . '; ' .
get_string('subqresponse', 'qtype_multianswer',
array('i' => 2, 'response' => 'Pussy-cat')), $question->summarise_response(
array('sub1_answer' => 'Owl', 'sub2_answer' => reset($rightchoice))));
}
}
Loading

0 comments on commit fa6c862

Please sign in to comment.