numerical and shortanswer question types: problems with compare_responses and test_response.

MDL-15315 The previous fix for this issue with wildcard answers in the item analysis report caused the following two regressions. This patch fixes it properly.

MDL-17247 This is basiclly pointing out the weridness in the previous fix and gave some useful clues as to a proper solution. Thanks Oleg.

MDL-17610 This was a report of a problem with each attempt builds on last, with a shortanswer question, where the sutdent's response contains a '.

Also, lots of unit tests to try to ensure the new code is right.
This commit is contained in:
tjhunt
2008-12-12 03:48:39 +00:00
parent f77b3caa37
commit be8563b63a
3 changed files with 146 additions and 26 deletions
-11
View File
@@ -273,17 +273,6 @@ class question_numerical_qtype extends question_shortanswer_qtype {
return ($answer->min <= $response && $response <= $answer->max);
}
// ULPGC ecastro
function check_response(&$question, &$state){
$answers = &$question->options->answers;
foreach($answers as $aid => $answer) {
if($this->test_response($question, $state, $answer)) {
return $aid;
}
}
return false;
}
function get_correct_responses(&$question, &$state) {
$correct = parent::get_correct_responses($question, $state);
$unit = $this->get_default_numerical_unit($question);
+3 -14
View File
@@ -184,14 +184,9 @@ class question_shortanswer_qtype extends default_questiontype {
include("$CFG->dirroot/question/type/shortanswer/display.html");
}
// ULPGC ecastro
function check_response(&$question, &$state) {
$answers = &$question->options->answers;
$testedstate = clone($state);
$teststate = clone($state);
foreach($answers as $aid => $answer) {
$teststate->responses[''] = trim($answer->answer);
if($this->compare_responses($question, $testedstate, $teststate)) {
foreach($question->options->answers as $aid => $answer) {
if ($this->test_response($question, $state, $answer)) {
return $aid;
}
}
@@ -200,13 +195,7 @@ class question_shortanswer_qtype extends default_questiontype {
function compare_responses($question, $state, $teststate) {
if (isset($state->responses['']) && isset($teststate->responses[''])) {
if ($question->options->usecase) {
return strcmp($state->responses[''], $teststate->responses['']) == 0;
} else {
$textlib = textlib_get_instance();
return strcmp($textlib->strtolower($state->responses['']),
$textlib->strtolower($teststate->responses[''])) == 0;
}
return $state->responses[''] === $teststate->responses[''];
}
return false;
}
@@ -63,11 +63,153 @@ class question_shortanswer_qtype_test extends MoodleUnitTestCase {
$this->assertTrue($this->qtype->compare_string_with_wildcard(' * ', '\*', false));
$this->assertTrue($this->qtype->compare_string_with_wildcard('*', '\*', false));
$this->assertTrue($this->qtype->compare_string_with_wildcard('Frog*toad', 'Frog\*toad', false));
$this->assertfalse($this->qtype->compare_string_with_wildcard('a', '[a-z]', false));
$this->assertFalse($this->qtype->compare_string_with_wildcard('a', '[a-z]', false));
$this->assertTrue($this->qtype->compare_string_with_wildcard('[a-z]', '[a-z]', false));
$this->assertTrue($this->qtype->compare_string_with_wildcard('\{}/', '\{}/', true));
}
function test_check_response() {
$answer1 = new stdClass;
$answer1->id = 17;
$answer1->answer = "celine";
$answer1->fraction = 1;
$answer2 = new stdClass;
$answer2->id = 23;
$answer2->answer = "c*line";
$answer2->fraction = 0.8;
$answer3 = new stdClass;
$answer3->id = 23;
$answer3->answer = "*line";
$answer3->fraction = 0.7;
$answer4 = new stdClass;
$answer4->id = 29;
$answer4->answer = "12\*13";
$answer4->fraction = 0.5;
$question = new stdClass;
$question->options->answers = array(
17 => $answer1,
23 => $answer2,
29 => $answer3,
31 => $answer4
);
$question->options->usecase = true;
$state = new stdClass;
$state->responses = array('' => 'celine');
$this->assertEqual($this->qtype->check_response($question, $state), 17);
$state->responses = array('' => 'caline');
$this->assertEqual($this->qtype->check_response($question, $state), 23);
$state->responses = array('' => 'aline');
$this->assertEqual($this->qtype->check_response($question, $state), 29);
$state->responses = array('' => 'frog');
$this->assertFalse($this->qtype->check_response($question, $state));
$state->responses = array('' => '12*13');
$this->assertEqual($this->qtype->check_response($question, $state), 31);
$question->options->usecase = false;
$answer1->answer = "Fred's";
$question->options->answers[17] = $answer1;
$state->responses = array('' => 'frog');
$this->assertFalse($this->qtype->check_response($question, $state));
$state->responses = array('' => "fred's");
$this->assertEqual($this->qtype->check_response($question, $state), 17);
$state->responses = array('' => '12*13');
$this->assertEqual($this->qtype->check_response($question, $state), 31);
$state->responses = array('' => 'caLINe');
$this->assertEqual($this->qtype->check_response($question, $state), 23);
$state->responses = array('' => 'ALIne');
$this->assertEqual($this->qtype->check_response($question, $state), 29);
}
function test_compare_responses() {
$question = new stdClass;
$question->options->usecase = false;
$state = new stdClass;
$teststate = new stdClass;
$this->assertFalse($this->qtype->compare_responses($question, $state, $teststate));
$state->responses = array('' => '');
$this->assertFalse($this->qtype->compare_responses($question, $state, $teststate));
$state = new stdClass;
$teststate->responses = array('' => '');
$this->assertFalse($this->qtype->compare_responses($question, $state, $teststate));
$state->responses = array('' => '');
$this->assertTrue($this->qtype->compare_responses($question, $state, $teststate));
$state->responses = array('' => 'frog');
$teststate->responses = array('' => 'frog');
$this->assertTrue($this->qtype->compare_responses($question, $state, $teststate));
$state->responses = array('' => 'frog');
$teststate->responses = array('' => 'Frog');
$this->assertFalse($this->qtype->compare_responses($question, $state, $teststate));
$state->responses = array('' => "\'");
$teststate->responses = array('' => "\'");
$this->assertTrue($this->qtype->compare_responses($question, $state, $teststate));
$state->responses = array('' => "'");
$teststate->responses = array('' => "'");
$this->assertTrue($this->qtype->compare_responses($question, $state, $teststate));
$state->responses = array('' => 'frog*toad');
$teststate->responses = array('' => 'frog*TOAD');
$this->assertFalse($this->qtype->compare_responses($question, $state, $teststate));
$state->responses = array('' => 'frog*');
$teststate->responses = array('' => 'frogs');
$this->assertFalse($this->qtype->compare_responses($question, $state, $teststate));
$state->responses = array('' => 'frogs');
$teststate->responses = array('' => 'frog*');
$this->assertFalse($this->qtype->compare_responses($question, $state, $teststate));
$question->options->usecase = true;
$state->responses = array('' => '');
$teststate->responses = array('' => '');
$this->assertTrue($this->qtype->compare_responses($question, $state, $teststate));
$state->responses = array('' => 'frog');
$teststate->responses = array('' => 'frog');
$this->assertTrue($this->qtype->compare_responses($question, $state, $teststate));
$state->responses = array('' => 'frog');
$teststate->responses = array('' => 'Frog');
$this->assertFalse($this->qtype->compare_responses($question, $state, $teststate));
$state->responses = array('' => "\'");
$teststate->responses = array('' => "\'");
$this->assertTrue($this->qtype->compare_responses($question, $state, $teststate));
$state->responses = array('' => 'frog*toad');
$teststate->responses = array('' => 'frog*toad');
$this->assertTrue($this->qtype->compare_responses($question, $state, $teststate));
$state->responses = array('' => 'frog*');
$teststate->responses = array('' => 'frogs');
$this->assertFalse($this->qtype->compare_responses($question, $state, $teststate));
$state->responses = array('' => 'frogs');
$teststate->responses = array('' => 'frog*');
$this->assertFalse($this->qtype->compare_responses($question, $state, $teststate));
}
function test_test_response() {
$answer = new stdClass;
$answer->id = 1;