Commit 3f81fe01 by Will Daly

Implemented tests for ImageResponse

parent 53b3b79f
...@@ -362,15 +362,15 @@ class FormulaResponseXMLFactory(ResponseXMLFactory): ...@@ -362,15 +362,15 @@ class FormulaResponseXMLFactory(ResponseXMLFactory):
# that we used previously. # that we used previously.
formulahint_element.set("samples", sample_str) formulahint_element.set("samples", sample_str)
formulahint_element.set("answer", hint_prompt) formulahint_element.set("answer", str(hint_prompt))
formulahint_element.set("name", hint_name) formulahint_element.set("name", str(hint_name))
# For each hint, create a <hintpart> element # For each hint, create a <hintpart> element
# corresponding to the <formulahint> # corresponding to the <formulahint>
hintpart_element = etree.SubElement(hintgroup_element, "hintpart") hintpart_element = etree.SubElement(hintgroup_element, "hintpart")
hintpart_element.set("on", hint_name) hintpart_element.set("on", str(hint_name))
text_element = etree.SubElement(hintpart_element, "text") text_element = etree.SubElement(hintpart_element, "text")
text_element.text = hint_text text_element.text = str(hint_text)
return response_element return response_element
...@@ -392,11 +392,63 @@ class FormulaResponseXMLFactory(ResponseXMLFactory): ...@@ -392,11 +392,63 @@ class FormulaResponseXMLFactory(ResponseXMLFactory):
return sample_str return sample_str
class ImageResponseXMLFactory(ResponseXMLFactory): class ImageResponseXMLFactory(ResponseXMLFactory):
""" Factory for producing <imageresponse> XML """
def create_response_element(self, **kwargs): def create_response_element(self, **kwargs):
raise NotImplemented """ Create the <imageresponse> element."""
return etree.Element("imageresponse")
def create_input_element(self, **kwargs): def create_input_element(self, **kwargs):
raise NotImplemented """ Create the <imageinput> element.
Uses **kwargs:
*src*: URL for the image file [DEFAULT: "/static/image.jpg"]
*width*: Width of the image [DEFAULT: 100]
*height*: Height of the image [DEFAULT: 100]
*rectangle*: String representing the rectangles the user should select.
Take the form "(x1,y1)-(x2,y2)", where the two (x,y)
tuples define the corners of the rectangle.
Can include multiple rectangles separated by a semicolon, e.g.
"(490,11)-(556,98);(242,202)-(296,276)"
*regions*: String representing the regions a user can select
Take the form "[ [[x1,y1], [x2,y2], [x3,y3]],
[[x1,y1], [x2,y2], [x3,y3]] ]"
(Defines two regions, each with 3 points)
REQUIRED: Either *rectangle* or *region* (or both)
"""
# Get the **kwargs
src = kwargs.get("src", "/static/image.jpg")
width = kwargs.get("width", 100)
height = kwargs.get("height", 100)
rectangle = kwargs.get('rectangle', None)
regions = kwargs.get('regions', None)
assert(rectangle or regions)
# Create the <imageinput> element
input_element = etree.Element("imageinput")
input_element.set("src", str(src))
input_element.set("width", str(width))
input_element.set("height", str(height))
if rectangle:
input_element.set("rectangle", rectangle)
if regions:
input_element.set("regions", regions)
return input_element
class JavascriptResponseXMLFactory(ResponseXMLFactory): class JavascriptResponseXMLFactory(ResponseXMLFactory):
def create_response_element(self, **kwargs): def create_response_element(self, **kwargs):
......
...@@ -37,11 +37,13 @@ class ResponseTest(unittest.TestCase): ...@@ -37,11 +37,13 @@ class ResponseTest(unittest.TestCase):
def assert_multiple_grade(self, problem, correct_answers, incorrect_answers): def assert_multiple_grade(self, problem, correct_answers, incorrect_answers):
for input_str in correct_answers: for input_str in correct_answers:
result = problem.grade_answers({'1_2_1': input_str}).get_correctness('1_2_1') result = problem.grade_answers({'1_2_1': input_str}).get_correctness('1_2_1')
self.assertEqual(result, 'correct') self.assertEqual(result, 'correct',
msg="%s should be marked correct" % str(input_str))
for input_str in incorrect_answers: for input_str in incorrect_answers:
result = problem.grade_answers({'1_2_1': input_str}).get_correctness('1_2_1') result = problem.grade_answers({'1_2_1': input_str}).get_correctness('1_2_1')
self.assertEqual(result, 'incorrect') self.assertEqual(result, 'incorrect',
msg="%s should be marked incorrect" % str(input_str))
class MultiChoiceResponseTest(ResponseTest): class MultiChoiceResponseTest(ResponseTest):
from response_xml_factory import MultipleChoiceResponseXMLFactory from response_xml_factory import MultipleChoiceResponseXMLFactory
...@@ -104,60 +106,61 @@ class TrueFalseResponseTest(ResponseTest): ...@@ -104,60 +106,61 @@ class TrueFalseResponseTest(ResponseTest):
self.assert_grade(problem, 'choice_foil_4', 'incorrect') self.assert_grade(problem, 'choice_foil_4', 'incorrect')
self.assert_grade(problem, 'not_a_choice', 'incorrect') self.assert_grade(problem, 'not_a_choice', 'incorrect')
class ImageResponseTest(unittest.TestCase): class ImageResponseTest(ResponseTest):
def test_ir_grade(self): from response_xml_factory import ImageResponseXMLFactory
imageresponse_file = os.path.dirname(__file__) + "/test_files/imageresponse.xml" xml_factory_class = ImageResponseXMLFactory
test_lcp = lcp.LoncapaProblem(open(imageresponse_file).read(), '1', system=test_system)
# testing regions only def test_rectangle_grade(self):
correct_answers = { # Define a rectangle with corners (10,10) and (20,20)
#regions problem = self.build_problem(rectangle="(10,10)-(20,20)")
'1_2_1': '(490,11)-(556,98)',
'1_2_2': '(242,202)-(296,276)', # Anything inside the rectangle (and along the borders) is correct
'1_2_3': '(490,11)-(556,98);(242,202)-(296,276)', # Everything else is incorrect
'1_2_4': '(490,11)-(556,98);(242,202)-(296,276)', correct_inputs = ["[12,19]", "[10,10]", "[20,20]",
'1_2_5': '(490,11)-(556,98);(242,202)-(296,276)', "[10,15]", "[20,15]", "[15,10]", "[15,20]"]
#testing regions and rectanges incorrect_inputs = ["[4,6]", "[25,15]", "[15,40]", "[15,4]"]
'1_3_1': 'rectangle="(490,11)-(556,98)" \ self.assert_multiple_grade(problem, correct_inputs, incorrect_inputs)
regions="[[[10,10], [20,10], [20, 30]], [[100,100], [120,100], [120,150]]]"',
'1_3_2': 'rectangle="(490,11)-(556,98)" \ def test_multiple_rectangles_grade(self):
regions="[[[10,10], [20,10], [20, 30]], [[100,100], [120,100], [120,150]]]"', # Define two rectangles
'1_3_3': 'regions="[[[10,10], [20,10], [20, 30]], [[100,100], [120,100], [120,150]]]"', rectangle_str = "(10,10)-(20,20);(100,100)-(200,200)"
'1_3_4': 'regions="[[[10,10], [20,10], [20, 30]], [[100,100], [120,100], [120,150]]]"',
'1_3_5': 'regions="[[[10,10], [20,10], [20, 30]]]"', # Expect that only points inside the rectangles are marked correct
'1_3_6': 'regions="[[10,10], [30,30], [15, 15]]"', problem = self.build_problem(rectangle=rectangle_str)
'1_3_7': 'regions="[[10,10], [30,30], [10, 30], [30, 10]]"', correct_inputs = ["[12,19]", "[120, 130]"]
} incorrect_inputs = ["[4,6]", "[25,15]", "[15,40]", "[15,4]",
test_answers = { "[50,55]", "[300, 14]", "[120, 400]"]
'1_2_1': '[500,20]', self.assert_multiple_grade(problem, correct_inputs, incorrect_inputs)
'1_2_2': '[250,300]',
'1_2_3': '[500,20]', def test_region_grade(self):
'1_2_4': '[250,250]', # Define a triangular region with corners (0,0), (5,10), and (0, 10)
'1_2_5': '[10,10]', region_str = "[ [1,1], [5,10], [0,10] ]"
'1_3_1': '[500,20]', # Expect that only points inside the triangle are marked correct
'1_3_2': '[15,15]', problem = self.build_problem(regions=region_str)
'1_3_3': '[500,20]', correct_inputs = ["[2,4]", "[1,3]"]
'1_3_4': '[115,115]', incorrect_inputs = ["[0,0]", "[3,5]", "[5,15]", "[30, 12]"]
'1_3_5': '[15,15]', self.assert_multiple_grade(problem, correct_inputs, incorrect_inputs)
'1_3_6': '[20,20]',
'1_3_7': '[20,15]', def test_multiple_regions_grade(self):
} # Define multiple regions that the user can select
region_str="[[[10,10], [20,10], [20, 30]], [[100,100], [120,100], [120,150]]]"
# regions
self.assertEquals(test_lcp.grade_answers(test_answers).get_correctness('1_2_1'), 'correct') # Expect that only points inside the regions are marked correct
self.assertEquals(test_lcp.grade_answers(test_answers).get_correctness('1_2_2'), 'incorrect') problem = self.build_problem(regions=region_str)
self.assertEquals(test_lcp.grade_answers(test_answers).get_correctness('1_2_3'), 'correct') correct_inputs = ["[15,12]", "[110,112]"]
self.assertEquals(test_lcp.grade_answers(test_answers).get_correctness('1_2_4'), 'correct') incorrect_inputs = ["[0,0]", "[600,300]"]
self.assertEquals(test_lcp.grade_answers(test_answers).get_correctness('1_2_5'), 'incorrect') self.assert_multiple_grade(problem, correct_inputs, incorrect_inputs)
# regions and rectangles def test_region_and_rectangle_grade(self):
self.assertEquals(test_lcp.grade_answers(test_answers).get_correctness('1_3_1'), 'correct') rectangle_str = "(100,100)-(200,200)"
self.assertEquals(test_lcp.grade_answers(test_answers).get_correctness('1_3_2'), 'correct') region_str="[[10,10], [20,10], [20, 30]]"
self.assertEquals(test_lcp.grade_answers(test_answers).get_correctness('1_3_3'), 'incorrect')
self.assertEquals(test_lcp.grade_answers(test_answers).get_correctness('1_3_4'), 'correct') # Expect that only points inside the rectangle or region are marked correct
self.assertEquals(test_lcp.grade_answers(test_answers).get_correctness('1_3_5'), 'correct') problem = self.build_problem(regions=region_str, rectangle=rectangle_str)
self.assertEquals(test_lcp.grade_answers(test_answers).get_correctness('1_3_6'), 'incorrect') correct_inputs = ["[13,12]", "[110,112]"]
self.assertEquals(test_lcp.grade_answers(test_answers).get_correctness('1_3_7'), 'correct') incorrect_inputs = ["[0,0]", "[600,300]"]
self.assert_multiple_grade(problem, correct_inputs, incorrect_inputs)
class SymbolicResponseTest(unittest.TestCase): class SymbolicResponseTest(unittest.TestCase):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment