numerical and shortanswer question types: problems with compare_responses and test_re...
authortjhunt <tjhunt>
Fri, 12 Dec 2008 03:48:39 +0000 (03:48 +0000)
committertjhunt <tjhunt>
Fri, 12 Dec 2008 03:48:39 +0000 (03:48 +0000)
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.

question/type/numerical/questiontype.php
question/type/shortanswer/questiontype.php
question/type/shortanswer/simpletest/testquestiontype.php

index 1308b3f0ccebb08ad922431a9c0772bb3f89184b..d74194eea6d2bc2143fc43267752384a1d33b85d 100644 (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);
index cdf6e149db3ddf92e8f86f13b4ae7b031c1f69d3..c588cc107a8db31e003728420faba4a6c890d6f4 100644 (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;
     }
index 3f7e9630f25a88339524913bd222dd540a1e5a4f..dacf5e06bbce9bc4ca951fefd57119b8f0f37450 100644 (file)
@@ -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;