Commit 0d4a06ac by Tim Krones

Address upstream review comments.

parent d2a9f6e2
pyyaml git+https://github.com/edx/XBlock.git@xblock-0.4.2#egg=XBlock
-e git+https://github.com/edx/XBlock.git@tag-master-2015-05-22#egg=XBlock git+https://github.com/edx/xblock-utils.git@b4f9b51146c7fafa12f41d54af752b8f1516dffd#egg=xblock-utils
-e git+https://github.com/edx/xblock-utils.git@b4f9b51146c7fafa12f41d54af752b8f1516dffd#egg=xblock-utils
-e . -e .
django>=1.4, <1.5 Django>=1.8, <1.9
-r requirements.txt -r requirements.txt
-e git+https://github.com/edx/xblock-sdk.git@629650ed6fc1b77d1a5287debeace0b29db7c0fd#egg=xblock-sdk -e git+https://github.com/edx/xblock-sdk.git@8eb5f174dc59c0f4e40e10eaab56753958651d17#egg=xblock-sdk
ddt ddt
selenium==2.47.3 # 2.48 is not working atm selenium==2.47.3 # 2.48 is not working atm
...@@ -29,11 +29,11 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -29,11 +29,11 @@ class TestVectorDraw(StudioEditableBaseTest):
else: else:
self.fail(errmsg) self.fail(errmsg)
def check_hidden_text(self, selector, expected_text): def assert_hidden_text(self, selector, expected_text):
hidden_text = self.browser.execute_script("return $('{}').text();".format(selector)) hidden_text = self.browser.execute_script("return $('{}').text();".format(selector))
self.assertEquals(hidden_text, expected_text) self.assertEquals(hidden_text, expected_text)
def check_title_and_description(self, expected_title="Vector Drawing", expected_description=None): def assert_title_and_description(self, expected_title="Vector Drawing", expected_description=None):
title = self.exercise.find_element_by_css_selector("h2") title = self.exercise.find_element_by_css_selector("h2")
self.assertEquals(title.text, expected_title) self.assertEquals(title.text, expected_title)
if expected_description: if expected_description:
...@@ -46,18 +46,18 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -46,18 +46,18 @@ class TestVectorDraw(StudioEditableBaseTest):
"Description element present even though no description has been set by user." "Description element present even though no description has been set by user."
) )
def check_dimensions(self, board, expected_width="550px", expected_height="400px"): def assert_dimensions(self, board, expected_width="550px", expected_height="400px"):
width = board.value_of_css_property("width") width = board.value_of_css_property("width")
height = board.value_of_css_property("height") height = board.value_of_css_property("height")
self.assertEquals(width, expected_width) self.assertEquals(width, expected_width)
self.assertEquals(height, expected_height) self.assertEquals(height, expected_height)
def check_axis(self, board, is_present=False): def assert_axis(self, board, is_present=False):
text_elements = board.find_elements_by_css_selector(".JXGtext") text_elements = board.find_elements_by_css_selector(".JXGtext")
ticks = any("ticks" in text_element.get_attribute("id") for text_element in text_elements) ticks = any("ticks" in text_element.get_attribute("id") for text_element in text_elements)
self.assertEquals(ticks, is_present) self.assertEquals(ticks, is_present)
def check_navigation_bar(self, board, is_present=False): def assert_navigation_bar(self, board, is_present=False):
if is_present: if is_present:
navigation_bar = board.find_element_by_css_selector("#jxgboard1_navigationbar") navigation_bar = board.find_element_by_css_selector("#jxgboard1_navigationbar")
self.assertTrue(navigation_bar.is_displayed()) self.assertTrue(navigation_bar.is_displayed())
...@@ -68,7 +68,7 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -68,7 +68,7 @@ class TestVectorDraw(StudioEditableBaseTest):
"Navigation bar should be hidden by default." "Navigation bar should be hidden by default."
) )
def check_background(self, board, is_present=False): def assert_background(self, board, is_present=False):
if is_present: if is_present:
background = board.find_element_by_css_selector("image") background = board.find_element_by_css_selector("image")
self.assertTrue(background.is_displayed()) self.assertTrue(background.is_displayed())
...@@ -83,7 +83,7 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -83,7 +83,7 @@ class TestVectorDraw(StudioEditableBaseTest):
"Board should not contain background image by default." "Board should not contain background image by default."
) )
def check_buttons(self, controls, add_vector_label="Add Selected Force"): def assert_buttons(self, controls, add_vector_label="Add Selected Force"):
# "Add vector" button # "Add vector" button
add_vector = controls.find_element_by_css_selector(".add-vector") add_vector = controls.find_element_by_css_selector(".add-vector")
self.assertEquals(add_vector.text, add_vector_label) self.assertEquals(add_vector.text, add_vector_label)
...@@ -91,19 +91,19 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -91,19 +91,19 @@ class TestVectorDraw(StudioEditableBaseTest):
reset = controls.find_element_by_css_selector(".reset") reset = controls.find_element_by_css_selector(".reset")
self.assertEquals(reset.text, "Reset") self.assertEquals(reset.text, "Reset")
reset.find_element_by_css_selector(".sr") reset.find_element_by_css_selector(".sr")
self.check_hidden_text(".reset > .sr", "Reset board to initial state") self.assert_hidden_text(".reset > .sr", "Reset board to initial state")
# "Redo" button # "Redo" button
redo = controls.find_element_by_css_selector(".redo") redo = controls.find_element_by_css_selector(".redo")
redo.find_element_by_css_selector(".fa.fa-repeat") redo.find_element_by_css_selector(".fa.fa-repeat")
redo.find_element_by_css_selector(".sr") redo.find_element_by_css_selector(".sr")
self.check_hidden_text(".redo > .sr", "Redo last action") self.assert_hidden_text(".redo > .sr", "Redo last action")
# "Undo" button # "Undo" button
undo = controls.find_element_by_css_selector(".undo") undo = controls.find_element_by_css_selector(".undo")
undo.find_element_by_css_selector(".fa.fa-undo") undo.find_element_by_css_selector(".fa.fa-undo")
undo.find_element_by_css_selector(".sr") undo.find_element_by_css_selector(".sr")
self.check_hidden_text(".undo > .sr", "Undo last action") self.assert_hidden_text(".undo > .sr", "Undo last action")
def check_vector_properties( def assert_vector_properties(
self, menu, is_present=False, expected_label="Vector Properties", self, menu, is_present=False, expected_label="Vector Properties",
expected_name=None, expected_tail=None, expected_length=None, expected_angle=None, expected_name=None, expected_tail=None, expected_length=None, expected_angle=None,
input_fields_disabled=True input_fields_disabled=True
...@@ -113,22 +113,22 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -113,22 +113,22 @@ class TestVectorDraw(StudioEditableBaseTest):
vector_properties_label = vector_properties.find_element_by_css_selector("h3") vector_properties_label = vector_properties.find_element_by_css_selector("h3")
self.assertEquals(vector_properties_label.text, expected_label) self.assertEquals(vector_properties_label.text, expected_label)
# Name # Name
self.check_vector_property( self.assert_vector_property(
vector_properties, "name", "select", "name:", expected_name or "-", vector_properties, "name", "select", "name:", expected_name or "-",
field_disabled=input_fields_disabled field_disabled=input_fields_disabled
) )
# Tail # Tail
self.check_vector_property( self.assert_vector_property(
vector_properties, "tail", "input", "tail position:", expected_tail or "", vector_properties, "tail", "input", "tail position:", expected_tail or "",
field_disabled=input_fields_disabled field_disabled=input_fields_disabled
) )
# Length # Length
self.check_vector_property( self.assert_vector_property(
vector_properties, "length", "input", "length:", expected_length or "", vector_properties, "length", "input", "length:", expected_length or "",
field_disabled=input_fields_disabled field_disabled=input_fields_disabled
) )
# Angle # Angle
self.check_vector_property( self.assert_vector_property(
vector_properties, "angle", "input", "angle:", expected_angle or "", vector_properties, "angle", "input", "angle:", expected_angle or "",
field_disabled=input_fields_disabled field_disabled=input_fields_disabled
) )
...@@ -146,7 +146,7 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -146,7 +146,7 @@ class TestVectorDraw(StudioEditableBaseTest):
"If show_vector_properties is set to False, menu should not show vector properties." "If show_vector_properties is set to False, menu should not show vector properties."
) )
def check_vector_property( def assert_vector_property(
self, vector_properties, property_name, input_type, expected_label, expected_value=None, self, vector_properties, property_name, input_type, expected_label, expected_value=None,
field_disabled=False field_disabled=False
): ):
...@@ -169,15 +169,15 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -169,15 +169,15 @@ class TestVectorDraw(StudioEditableBaseTest):
selected_option = vector_property_input.find_element_by_css_selector('option[selected="selected"]') selected_option = vector_property_input.find_element_by_css_selector('option[selected="selected"]')
self.assertEquals(selected_option.text, expected_value) self.assertEquals(selected_option.text, expected_value)
def check_actions(self): def assert_actions(self):
actions = self.exercise.find_element_by_css_selector(".action") actions = self.exercise.find_element_by_css_selector(".action")
self.assertTrue(actions.is_displayed()) self.assertTrue(actions.is_displayed())
check = actions.find_element_by_css_selector(".check") check = actions.find_element_by_css_selector(".check")
self.assertEquals(check.text, "CHECK") self.assertEquals(check.text, "CHECK")
check.find_element_by_css_selector(".sr") check.find_element_by_css_selector(".sr")
self.check_hidden_text(".check > .sr", "Check your answer") self.assert_hidden_text(".check > .sr", "Check your answer")
def check_add_dropdown(self, controls, vectors=[], points=[]): def assert_add_dropdown(self, controls, vectors=[], points=[]):
# Check dropdown # Check dropdown
dropdown = controls.find_element_by_css_selector("select") dropdown = controls.find_element_by_css_selector("select")
if not vectors and not points: if not vectors and not points:
...@@ -187,17 +187,17 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -187,17 +187,17 @@ class TestVectorDraw(StudioEditableBaseTest):
"Dropdown should not list any vectors or points by default." "Dropdown should not list any vectors or points by default."
) )
else: else:
self.check_add_options(dropdown, vectors, "vector") self.assert_add_options(dropdown, vectors, "vector")
non_fixed_points = [point for point in points if not point["fixed"]] non_fixed_points = [point for point in points if not point["fixed"]]
self.check_add_options(dropdown, non_fixed_points, "point") self.assert_add_options(dropdown, non_fixed_points, "point")
# Check label # Check label
label_id = "element-list-add-label" label_id = "element-list-add-label"
label_selector = "#" + label_id label_selector = "#" + label_id
controls.find_element_by_css_selector(label_selector) controls.find_element_by_css_selector(label_selector)
self.check_hidden_text(label_selector, "Select element to add to board") self.assert_hidden_text(label_selector, "Select element to add to board")
self.assertEquals(dropdown.get_attribute("aria-labelledby"), label_id) self.assertEquals(dropdown.get_attribute("aria-labelledby"), label_id)
def check_add_options(self, dropdown, elements, element_type): def assert_add_options(self, dropdown, elements, element_type):
element_options = dropdown.find_elements_by_css_selector('option[value^="{}-"]'.format(element_type)) element_options = dropdown.find_elements_by_css_selector('option[value^="{}-"]'.format(element_type))
self.assertEquals(len(element_options), len(elements)) self.assertEquals(len(element_options), len(elements))
for element, element_option in zip(elements, element_options): for element, element_option in zip(elements, element_options):
...@@ -205,7 +205,7 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -205,7 +205,7 @@ class TestVectorDraw(StudioEditableBaseTest):
option_disabled = element_option.get_attribute("disabled") option_disabled = element_option.get_attribute("disabled")
self.assertEquals(bool(option_disabled), element["render"]) self.assertEquals(bool(option_disabled), element["render"])
def check_edit_dropdown(self, menu, vectors=[], points=[]): def assert_edit_dropdown(self, menu, vectors=[], points=[]):
vector_properties = menu.find_element_by_css_selector(".vector-properties") vector_properties = menu.find_element_by_css_selector(".vector-properties")
# Check dropdown # Check dropdown
dropdown = vector_properties.find_element_by_css_selector("select") dropdown = vector_properties.find_element_by_css_selector("select")
...@@ -216,12 +216,12 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -216,12 +216,12 @@ class TestVectorDraw(StudioEditableBaseTest):
self.assertEquals(default_option.get_attribute("value"), "-") self.assertEquals(default_option.get_attribute("value"), "-")
else: else:
if vectors: if vectors:
self.check_edit_options(dropdown, vectors, "vector") self.assert_edit_options(dropdown, vectors, "vector")
if points: if points:
non_fixed_points = [point for point in points if not point["fixed"]] non_fixed_points = [point for point in points if not point["fixed"]]
self.check_edit_options(dropdown, non_fixed_points, "point") self.assert_edit_options(dropdown, non_fixed_points, "point")
def check_edit_options(self, dropdown, elements, element_type): def assert_edit_options(self, dropdown, elements, element_type):
element_options = dropdown.find_elements_by_css_selector('option[value^="{}-"]'.format(element_type)) element_options = dropdown.find_elements_by_css_selector('option[value^="{}-"]'.format(element_type))
self.assertEquals(len(element_options), len(elements)) self.assertEquals(len(element_options), len(elements))
for element, element_option in zip(elements, element_options): for element, element_option in zip(elements, element_options):
...@@ -229,7 +229,7 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -229,7 +229,7 @@ class TestVectorDraw(StudioEditableBaseTest):
option_disabled = element_option.get_attribute("disabled") option_disabled = element_option.get_attribute("disabled")
self.assertNotEquals(bool(option_disabled), element["render"]) self.assertNotEquals(bool(option_disabled), element["render"])
def check_vectors(self, board, vectors): def assert_vectors(self, board, vectors):
line_elements = board.find_elements_by_css_selector("line") line_elements = board.find_elements_by_css_selector("line")
point_elements = board.find_elements_by_css_selector("ellipse") point_elements = board.find_elements_by_css_selector("ellipse")
for vector in vectors: for vector in vectors:
...@@ -253,7 +253,7 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -253,7 +253,7 @@ class TestVectorDraw(StudioEditableBaseTest):
self.assertFalse(board_has_tip) self.assertFalse(board_has_tip)
self.assertFalse(board_has_label) self.assertFalse(board_has_label)
def check_points(self, board, points): def assert_points(self, board, points):
point_elements = board.find_elements_by_css_selector("ellipse") point_elements = board.find_elements_by_css_selector("ellipse")
for point in points: for point in points:
board_has_point = self.board_has_point(point["expected_position"], point_elements) board_has_point = self.board_has_point(point["expected_position"], point_elements)
...@@ -313,14 +313,14 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -313,14 +313,14 @@ class TestVectorDraw(StudioEditableBaseTest):
add_vector.click() add_vector.click()
# Board should now show vector # Board should now show vector
vectors[0]["render"] = True vectors[0]["render"] = True
self.check_vectors(board, vectors) self.assert_vectors(board, vectors)
# "Vector Properties" should display correct info # "Vector Properties" should display correct info
self.check_vector_properties( self.assert_vector_properties(
menu, is_present=True, expected_label="Custom properties label", menu, is_present=True, expected_label="Custom properties label",
expected_name="N", expected_tail="2.00, 2.00", expected_length="4.00", expected_angle="45.00", expected_name="N", expected_tail="2.00, 2.00", expected_length="4.00", expected_angle="45.00",
input_fields_disabled=False input_fields_disabled=False
) )
self.check_edit_dropdown(menu, vectors) self.assert_edit_dropdown(menu, vectors)
def add_point(self, board, points): def add_point(self, board, points):
menu = self.exercise.find_element_by_css_selector(".menu") menu = self.exercise.find_element_by_css_selector(".menu")
...@@ -329,7 +329,7 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -329,7 +329,7 @@ class TestVectorDraw(StudioEditableBaseTest):
add_vector.click() add_vector.click()
# Board should now show point # Board should now show point
points[0]["render"] = True points[0]["render"] = True
self.check_points(board, points) self.assert_points(board, points)
def undo(self, board, vectors): def undo(self, board, vectors):
menu = self.exercise.find_element_by_css_selector(".menu") menu = self.exercise.find_element_by_css_selector(".menu")
...@@ -338,7 +338,7 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -338,7 +338,7 @@ class TestVectorDraw(StudioEditableBaseTest):
undo.click() undo.click()
# Board should not show vector anymore # Board should not show vector anymore
vectors[0]["render"] = False vectors[0]["render"] = False
self.check_vectors(board, vectors) self.assert_vectors(board, vectors)
def redo(self, board, vectors): def redo(self, board, vectors):
menu = self.exercise.find_element_by_css_selector(".menu") menu = self.exercise.find_element_by_css_selector(".menu")
...@@ -347,9 +347,9 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -347,9 +347,9 @@ class TestVectorDraw(StudioEditableBaseTest):
redo.click() redo.click()
# Board should now show vector # Board should now show vector
vectors[0]["render"] = True vectors[0]["render"] = True
self.check_vectors(board, vectors) self.assert_vectors(board, vectors)
# "Vector Properties" should display correct info # "Vector Properties" should display correct info
self.check_vector_properties( self.assert_vector_properties(
menu, is_present=True, expected_label="Custom properties label", menu, is_present=True, expected_label="Custom properties label",
expected_name="N", expected_tail="2.00, 2.00", expected_length="4.00", expected_angle="45.00", expected_name="N", expected_tail="2.00, 2.00", expected_length="4.00", expected_angle="45.00",
input_fields_disabled=False input_fields_disabled=False
...@@ -362,17 +362,17 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -362,17 +362,17 @@ class TestVectorDraw(StudioEditableBaseTest):
reset.click() reset.click()
# Board should not show vector anymore # Board should not show vector anymore
vectors[0]["render"] = False vectors[0]["render"] = False
self.check_vectors(board, vectors) self.assert_vectors(board, vectors)
# Board should not show point anymore # Board should not show point anymore
points[0]["render"] = False points[0]["render"] = False
self.check_points(board, points) self.assert_points(board, points)
def submit_answer(self): def submit_answer(self):
actions = self.exercise.find_element_by_css_selector(".action") actions = self.exercise.find_element_by_css_selector(".action")
check = actions.find_element_by_css_selector(".check") check = actions.find_element_by_css_selector(".check")
check.click() check.click()
def check_status(self, answer_correct=True, expected_message="Test passed"): def assert_status(self, answer_correct=True, expected_message="Test passed"):
status = self.exercise.find_element_by_css_selector(".vectordraw-status") status = self.exercise.find_element_by_css_selector(".vectordraw-status")
self.assertTrue(status.is_displayed()) self.assertTrue(status.is_displayed())
correctness = status.find_element_by_css_selector(".correctness") correctness = status.find_element_by_css_selector(".correctness")
...@@ -402,14 +402,14 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -402,14 +402,14 @@ class TestVectorDraw(StudioEditableBaseTest):
self.load_scenario("xml/defaults.xml") self.load_scenario("xml/defaults.xml")
# Check title and description # Check title and description
self.check_title_and_description() self.assert_title_and_description()
# Check board # Check board
board = self.exercise.find_element_by_css_selector("#jxgboard1") board = self.exercise.find_element_by_css_selector("#jxgboard1")
self.check_dimensions(board) self.assert_dimensions(board)
self.check_axis(board) self.assert_axis(board)
self.check_navigation_bar(board) self.assert_navigation_bar(board)
self.check_background(board) self.assert_background(board)
# - Vectors # - Vectors
self.assert_not_present( self.assert_not_present(
board, board,
...@@ -426,13 +426,13 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -426,13 +426,13 @@ class TestVectorDraw(StudioEditableBaseTest):
# Check menu # Check menu
menu = self.exercise.find_element_by_css_selector(".menu") menu = self.exercise.find_element_by_css_selector(".menu")
controls = menu.find_element_by_css_selector(".controls") controls = menu.find_element_by_css_selector(".controls")
self.check_add_dropdown(controls) self.assert_add_dropdown(controls)
self.check_buttons(controls) self.assert_buttons(controls)
self.check_vector_properties(menu, is_present=True) self.assert_vector_properties(menu, is_present=True)
self.check_edit_dropdown(menu) self.assert_edit_dropdown(menu)
# Check actions # Check actions
self.check_actions() self.assert_actions()
@data( @data(
{ {
...@@ -502,35 +502,35 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -502,35 +502,35 @@ class TestVectorDraw(StudioEditableBaseTest):
self.load_scenario("xml/custom.xml", params=params) self.load_scenario("xml/custom.xml", params=params)
# Check title and description # Check title and description
self.check_title_and_description( self.assert_title_and_description(
expected_title="Custom Exercise", expected_description="Custom exercise description" expected_title="Custom Exercise", expected_description="Custom exercise description"
) )
# Check board # Check board
board = self.exercise.find_element_by_css_selector("#jxgboard1") board = self.exercise.find_element_by_css_selector("#jxgboard1")
self.check_dimensions(board, expected_width="600px", expected_height="450px") self.assert_dimensions(board, expected_width="600px", expected_height="450px")
self.check_axis(board, is_present=True) self.assert_axis(board, is_present=True)
self.check_navigation_bar(board, is_present=True) self.assert_navigation_bar(board, is_present=True)
self.check_background(board, is_present=True) self.assert_background(board, is_present=True)
# - Vectors # - Vectors
self.check_vectors(board, vectors) self.assert_vectors(board, vectors)
# - Points # - Points
self.check_points(board, points) self.assert_points(board, points)
# Check menu # Check menu
menu = self.exercise.find_element_by_css_selector(".menu") menu = self.exercise.find_element_by_css_selector(".menu")
controls = menu.find_element_by_css_selector(".controls") controls = menu.find_element_by_css_selector(".controls")
self.check_add_dropdown(controls, vectors, points) self.assert_add_dropdown(controls, vectors, points)
self.check_buttons(controls, add_vector_label="Custom button label") self.assert_buttons(controls, add_vector_label="Custom button label")
show_vector_properties = params["show_vector_properties"] show_vector_properties = params["show_vector_properties"]
if show_vector_properties: if show_vector_properties:
self.check_vector_properties(menu, is_present=True, expected_label="Custom properties label") self.assert_vector_properties(menu, is_present=True, expected_label="Custom properties label")
self.check_edit_dropdown(menu, vectors, points) self.assert_edit_dropdown(menu, vectors, points)
else: else:
self.check_vector_properties(menu) self.assert_vector_properties(menu)
# Check actions # Check actions
self.check_actions() self.assert_actions()
@data("line", "tail", "tip") @data("line", "tail", "tip")
def test_select_vector(self, click_target): def test_select_vector(self, click_target):
...@@ -572,7 +572,7 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -572,7 +572,7 @@ class TestVectorDraw(StudioEditableBaseTest):
tip.click() tip.click()
# Check if "Vector Properties" shows correct info # Check if "Vector Properties" shows correct info
menu = self.exercise.find_element_by_css_selector(".menu") menu = self.exercise.find_element_by_css_selector(".menu")
self.check_vector_properties( self.assert_vector_properties(
menu, is_present=True, expected_label="Custom properties label", menu, is_present=True, expected_label="Custom properties label",
expected_name="N", expected_tail="2.00, 2.00", expected_length="4.00", expected_angle="45.00", expected_name="N", expected_tail="2.00, 2.00", expected_length="4.00", expected_angle="45.00",
input_fields_disabled=False input_fields_disabled=False
...@@ -603,7 +603,7 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -603,7 +603,7 @@ class TestVectorDraw(StudioEditableBaseTest):
board = self.exercise.find_element_by_css_selector("#jxgboard1") board = self.exercise.find_element_by_css_selector("#jxgboard1")
# Board should not show vector initially # Board should not show vector initially
vectors = json.loads(params["vectors"]) vectors = json.loads(params["vectors"])
self.check_vectors(board, vectors) self.assert_vectors(board, vectors)
# Add vector # Add vector
self.add_vector(board, vectors) self.add_vector(board, vectors)
...@@ -629,7 +629,7 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -629,7 +629,7 @@ class TestVectorDraw(StudioEditableBaseTest):
board = self.exercise.find_element_by_css_selector("#jxgboard1") board = self.exercise.find_element_by_css_selector("#jxgboard1")
# Board should not show point initially # Board should not show point initially
points = json.loads(params["points"]) points = json.loads(params["points"])
self.check_points(board, points) self.assert_points(board, points)
# Add point # Add point
self.add_point(board, points) self.add_point(board, points)
...@@ -658,7 +658,7 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -658,7 +658,7 @@ class TestVectorDraw(StudioEditableBaseTest):
board = self.exercise.find_element_by_css_selector("#jxgboard1") board = self.exercise.find_element_by_css_selector("#jxgboard1")
# Board should not show vector initially # Board should not show vector initially
vectors = json.loads(params["vectors"]) vectors = json.loads(params["vectors"])
self.check_vectors(board, vectors) self.assert_vectors(board, vectors)
# Add vector # Add vector
self.add_vector(board, vectors) self.add_vector(board, vectors)
# Undo # Undo
...@@ -689,7 +689,7 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -689,7 +689,7 @@ class TestVectorDraw(StudioEditableBaseTest):
board = self.exercise.find_element_by_css_selector("#jxgboard1") board = self.exercise.find_element_by_css_selector("#jxgboard1")
# Board should not show vector initially # Board should not show vector initially
vectors = json.loads(params["vectors"]) vectors = json.loads(params["vectors"])
self.check_vectors(board, vectors) self.assert_vectors(board, vectors)
# Add vector # Add vector
self.add_vector(board, vectors) self.add_vector(board, vectors)
# Undo # Undo
...@@ -731,10 +731,10 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -731,10 +731,10 @@ class TestVectorDraw(StudioEditableBaseTest):
board = self.exercise.find_element_by_css_selector("#jxgboard1") board = self.exercise.find_element_by_css_selector("#jxgboard1")
# Board should not show vector initially # Board should not show vector initially
vectors = json.loads(params["vectors"]) vectors = json.loads(params["vectors"])
self.check_vectors(board, vectors) self.assert_vectors(board, vectors)
# Board should not show point initially # Board should not show point initially
points = json.loads(params["points"]) points = json.loads(params["points"])
self.check_points(board, points) self.assert_points(board, points)
# Add vector # Add vector
self.add_vector(board, vectors) self.add_vector(board, vectors)
# Add point # Add point
...@@ -775,7 +775,7 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -775,7 +775,7 @@ class TestVectorDraw(StudioEditableBaseTest):
# Submit answer # Submit answer
self.submit_answer() self.submit_answer()
# Check status # Check status
self.check_status() self.assert_status()
@data( @data(
{ {
...@@ -810,7 +810,7 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -810,7 +810,7 @@ class TestVectorDraw(StudioEditableBaseTest):
# Submit answer # Submit answer
self.submit_answer() self.submit_answer()
# Check status # Check status
self.check_status( self.assert_status(
answer_correct=False, expected_message="Vector N does not start at correct point." answer_correct=False, expected_message="Vector N does not start at correct point."
) )
...@@ -863,7 +863,7 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -863,7 +863,7 @@ class TestVectorDraw(StudioEditableBaseTest):
board = self.exercise.find_element_by_css_selector("#jxgboard1") board = self.exercise.find_element_by_css_selector("#jxgboard1")
vectors = json.loads(params["vectors"]) vectors = json.loads(params["vectors"])
# Board should not show vector initially # Board should not show vector initially
self.check_vectors(board, vectors) self.assert_vectors(board, vectors)
# Add vector # Add vector
self.add_vector(board, vectors) self.add_vector(board, vectors)
# Submit answer # Submit answer
...@@ -874,12 +874,12 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -874,12 +874,12 @@ class TestVectorDraw(StudioEditableBaseTest):
board = self.exercise.find_element_by_css_selector("#jxgboard1") board = self.exercise.find_element_by_css_selector("#jxgboard1")
# Board should show vector # Board should show vector
vectors[0]["render"] = True vectors[0]["render"] = True
self.check_vectors(board, vectors) self.assert_vectors(board, vectors)
# Status should show last result # Status should show last result
if params["answer_correct"]: if params["answer_correct"]:
self.check_status() self.assert_status()
else: else:
self.check_status( self.assert_status(
answer_correct=False, expected_message="Vector N does not start at correct point." answer_correct=False, expected_message="Vector N does not start at correct point."
) )
...@@ -908,7 +908,7 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -908,7 +908,7 @@ class TestVectorDraw(StudioEditableBaseTest):
board = self.exercise.find_element_by_css_selector("#jxgboard1") board = self.exercise.find_element_by_css_selector("#jxgboard1")
# Board should not show vector initially # Board should not show vector initially
vectors = json.loads(params["vectors"]) vectors = json.loads(params["vectors"])
self.check_vectors(board, vectors) self.assert_vectors(board, vectors)
# Add vector # Add vector
self.add_vector(board, vectors) self.add_vector(board, vectors)
# Change tail # Change tail
...@@ -917,7 +917,7 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -917,7 +917,7 @@ class TestVectorDraw(StudioEditableBaseTest):
vectors[0]["expected_line_position"] = {'x1': 370, 'y1': 159, 'x2': 425, 'y2': 102} vectors[0]["expected_line_position"] = {'x1': 370, 'y1': 159, 'x2': 425, 'y2': 102}
vectors[0]["expected_tail_position"] = {'cx': 370, 'cy': 159} vectors[0]["expected_tail_position"] = {'cx': 370, 'cy': 159}
vectors[0]["expected_tip_position"] = {'cx': 434, 'cy': 94} vectors[0]["expected_tip_position"] = {'cx': 434, 'cy': 94}
self.check_vectors(board, vectors) self.assert_vectors(board, vectors)
@data( @data(
{ {
...@@ -944,7 +944,7 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -944,7 +944,7 @@ class TestVectorDraw(StudioEditableBaseTest):
board = self.exercise.find_element_by_css_selector("#jxgboard1") board = self.exercise.find_element_by_css_selector("#jxgboard1")
# Board should not show vector initially # Board should not show vector initially
vectors = json.loads(params["vectors"]) vectors = json.loads(params["vectors"])
self.check_vectors(board, vectors) self.assert_vectors(board, vectors)
# Add vector # Add vector
self.add_vector(board, vectors) self.add_vector(board, vectors)
# Change tail # Change tail
...@@ -953,7 +953,7 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -953,7 +953,7 @@ class TestVectorDraw(StudioEditableBaseTest):
vectors[0]["expected_line_position"] = {'x1': 347, 'y1': 181, 'x2': 434, 'y2': 93} vectors[0]["expected_line_position"] = {'x1': 347, 'y1': 181, 'x2': 434, 'y2': 93}
vectors[0]["expected_tail_position"] = {'cx': 347, 'cy': 181} vectors[0]["expected_tail_position"] = {'cx': 347, 'cy': 181}
vectors[0]["expected_tip_position"] = {'cx': 443, 'cy': 85} vectors[0]["expected_tip_position"] = {'cx': 443, 'cy': 85}
self.check_vectors(board, vectors) self.assert_vectors(board, vectors)
@data( @data(
{ {
...@@ -980,7 +980,7 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -980,7 +980,7 @@ class TestVectorDraw(StudioEditableBaseTest):
board = self.exercise.find_element_by_css_selector("#jxgboard1") board = self.exercise.find_element_by_css_selector("#jxgboard1")
# Board should not show vector initially # Board should not show vector initially
vectors = json.loads(params["vectors"]) vectors = json.loads(params["vectors"])
self.check_vectors(board, vectors) self.assert_vectors(board, vectors)
# Add vector # Add vector
self.add_vector(board, vectors) self.add_vector(board, vectors)
# Change tail # Change tail
...@@ -989,7 +989,7 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -989,7 +989,7 @@ class TestVectorDraw(StudioEditableBaseTest):
vectors[0]["expected_line_position"] = {'x1': 347, 'y1': 181, 'x2': 269, 'y2': 167} vectors[0]["expected_line_position"] = {'x1': 347, 'y1': 181, 'x2': 269, 'y2': 167}
vectors[0]["expected_tail_position"] = {'cx': 347, 'cy': 181} vectors[0]["expected_tail_position"] = {'cx': 347, 'cy': 181}
vectors[0]["expected_tip_position"] = {'cx': 258, 'cy': 165} vectors[0]["expected_tip_position"] = {'cx': 258, 'cy': 165}
self.check_vectors(board, vectors) self.assert_vectors(board, vectors)
@data( @data(
{ {
...@@ -1016,7 +1016,7 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -1016,7 +1016,7 @@ class TestVectorDraw(StudioEditableBaseTest):
board = self.exercise.find_element_by_css_selector("#jxgboard1") board = self.exercise.find_element_by_css_selector("#jxgboard1")
# Board should not show vector initially # Board should not show vector initially
vectors = json.loads(params["vectors"]) vectors = json.loads(params["vectors"])
self.check_vectors(board, vectors) self.assert_vectors(board, vectors)
# Add vector # Add vector
self.add_vector(board, vectors) self.add_vector(board, vectors)
# Change tail # Change tail
...@@ -1025,7 +1025,7 @@ class TestVectorDraw(StudioEditableBaseTest): ...@@ -1025,7 +1025,7 @@ class TestVectorDraw(StudioEditableBaseTest):
vectors[0]["expected_line_position"] = {'x1': 347, 'y1': 181, 'x2': 402, 'y2': 125} vectors[0]["expected_line_position"] = {'x1': 347, 'y1': 181, 'x2': 402, 'y2': 125}
vectors[0]["expected_tail_position"] = {'cx': 347, 'cy': 181} vectors[0]["expected_tail_position"] = {'cx': 347, 'cy': 181}
vectors[0]["expected_tip_position"] = {'cx': 411, 'cy': 117} vectors[0]["expected_tip_position"] = {'cx': 411, 'cy': 117}
self.check_vectors(board, vectors) self.assert_vectors(board, vectors)
# Check error message # Check error message
error_message = self.exercise.find_element_by_css_selector(".update-error"); error_message = self.exercise.find_element_by_css_selector(".update-error");
self.wait_until_visible(error_message) self.wait_until_visible(error_message)
......
...@@ -7,9 +7,6 @@ class VectorDrawTest(unittest.TestCase): ...@@ -7,9 +7,6 @@ class VectorDrawTest(unittest.TestCase):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(VectorDrawTest, self).__init__(*args, **kwargs) super(VectorDrawTest, self).__init__(*args, **kwargs)
# Alias assertions to make tests read better.
self.assertPasses = self.assertIsNone
self.assertFails = self.assertEquals
# Helpers # Helpers
...@@ -22,205 +19,223 @@ class VectorDrawTest(unittest.TestCase): ...@@ -22,205 +19,223 @@ class VectorDrawTest(unittest.TestCase):
def vector(self, x1=0, y1=0, x2=1, y2=1, name='vec'): def vector(self, x1=0, y1=0, x2=1, y2=1, name='vec'):
return Vector(name, x1, y1, x2, y2) return Vector(name, x1, y1, x2, y2)
def assertPasses(self, check_function, check, vectors):
try:
check_function(check, vectors)
except ValueError:
self.fail('{check_function} should not raise an error for check {check} and vectors {vectors}.'.format(
check_function=check_function.__name__, check=check, vectors=vectors
))
def assertFails(self, check_function, check, vectors, error_message):
try:
check_function(check, vectors)
except ValueError as e:
self.assertEquals(e.message, error_message)
else:
self.fail('{check_function} should raise an error for check {check} and vectors {vectors}.'.format(
check_function=check_function.__name__, check=check, vectors=vectors
))
# Test built-in checks # Test built-in checks
def test_check_presence(self): def test_check_presence(self):
errmsg = 'You need to use the othervec vector.' errmsg = 'You need to use the othervec vector.'
vectors = {'myvec': self.vector(name='myvec')} vectors = {'myvec': self.vector(name='myvec')}
self.assertPasses(grader.check_presence(self.check(vector='myvec'), vectors)) self.assertPasses(grader.check_presence, self.check(vector='myvec'), vectors)
self.assertFails(grader.check_presence(self.check(vector='othervec'), vectors), errmsg) self.assertFails(grader.check_presence, self.check(vector='othervec'), vectors, errmsg)
custom_errmsg = 'Use {name}, please!' custom_errmsg = 'Use {name}, please!'
self.assertFails( self.assertFails(
grader.check_presence(self.check(vector='vec X', errmsg=custom_errmsg), vectors), grader.check_presence, self.check(vector='vec X', errmsg=custom_errmsg), vectors,
custom_errmsg.format(name='vec X') custom_errmsg.format(name='vec X')
) )
def test_check_tail(self): def test_check_tail(self):
errmsg = 'Vector vec does not start at correct point.' errmsg = 'Vector vec does not start at correct point.'
vectors = {'vec': self.vector(3, 3, 4, 4)} vectors = {'vec': self.vector(3, 3, 4, 4)}
self.assertPasses(grader.check_tail(self.check([3, 3], 0), vectors)) self.assertPasses(grader.check_tail, self.check([3, 3], 0), vectors)
self.assertPasses(grader.check_tail(self.check([4, 4], 1.5), vectors)) self.assertPasses(grader.check_tail, self.check([4, 4], 1.5), vectors)
self.assertFails(grader.check_tail(self.check([3.1, 3], 0), vectors), errmsg) self.assertFails(grader.check_tail, self.check([3.1, 3], 0), vectors, errmsg)
self.assertFails(grader.check_tail(self.check([4, 4], 1.0), vectors), errmsg) self.assertFails(grader.check_tail, self.check([4, 4], 1.0), vectors, errmsg)
custom_errmsg = 'Bad start point: [{tail_x}, {tail_y}]' custom_errmsg = 'Bad start point: [{tail_x}, {tail_y}]'
self.assertFails( self.assertFails(
grader.check_tail(self.check([1, 2], errmsg=custom_errmsg), vectors), grader.check_tail, self.check([1, 2], errmsg=custom_errmsg), vectors,
custom_errmsg.format(tail_x=3, tail_y=3) custom_errmsg.format(tail_x=3, tail_y=3)
) )
def test_check_tip(self): def test_check_tip(self):
errmsg = 'Vector vec does not end at correct point.' errmsg = 'Vector vec does not end at correct point.'
vectors = {'vec': self.vector(3, 3, 4, 4)} vectors = {'vec': self.vector(3, 3, 4, 4)}
self.assertPasses(grader.check_tip(self.check([4, 4], 0), vectors)) self.assertPasses(grader.check_tip, self.check([4, 4], 0), vectors)
self.assertPasses(grader.check_tip(self.check([3, 3], 1.5), vectors)) self.assertPasses(grader.check_tip, self.check([3, 3], 1.5), vectors)
self.assertFails(grader.check_tip(self.check([4.1, 4], 0), vectors), errmsg) self.assertFails(grader.check_tip, self.check([4.1, 4], 0), vectors, errmsg)
self.assertFails(grader.check_tip(self.check([3, 3], 1.0), vectors), errmsg) self.assertFails(grader.check_tip, self.check([3, 3], 1.0), vectors, errmsg)
custom_errmsg = '{name} does not start at correct point.' custom_errmsg = '{name} does not start at correct point.'
self.assertFails( self.assertFails(
grader.check_tip(self.check([3, 3], errmsg=custom_errmsg), vectors), grader.check_tip, self.check([3, 3], errmsg=custom_errmsg), vectors,
custom_errmsg.format(name='vec') custom_errmsg.format(name='vec')
) )
def test_check_tail_x(self): def test_check_tail_x(self):
errmsg = 'Vector vec does not start at correct point.' errmsg = 'Vector vec does not start at correct point.'
vectors = {'vec': self.vector(3, 12, 4, 40)} vectors = {'vec': self.vector(3, 12, 4, 40)}
self.assertPasses(grader.check_tail_x(self.check(3, 0), vectors)) self.assertPasses(grader.check_tail_x, self.check(3, 0), vectors)
self.assertPasses(grader.check_tail_x(self.check(4, 1), vectors)) self.assertPasses(grader.check_tail_x, self.check(4, 1), vectors)
self.assertFails(grader.check_tail_x(self.check(5, 0), vectors), errmsg) self.assertFails(grader.check_tail_x, self.check(5, 0), vectors, errmsg)
self.assertFails(grader.check_tail_x(self.check(5, 1.5), vectors), errmsg) self.assertFails(grader.check_tail_x, self.check(5, 1.5), vectors, errmsg)
custom_errmsg = 'Bad starting point for {name}.' custom_errmsg = 'Bad starting point for {name}.'
self.assertFails( self.assertFails(
grader.check_tail_x(self.check(5, 1.5, errmsg=custom_errmsg), vectors), grader.check_tail_x, self.check(5, 1.5, errmsg=custom_errmsg), vectors,
custom_errmsg.format(name='vec') custom_errmsg.format(name='vec')
) )
def test_check_tail_y(self): def test_check_tail_y(self):
errmsg = 'Vector vec does not start at correct point.' errmsg = 'Vector vec does not start at correct point.'
vectors = {'vec': self.vector(3, 12, 4, 40)} vectors = {'vec': self.vector(3, 12, 4, 40)}
self.assertPasses(grader.check_tail_y(self.check(12, 0), vectors)) self.assertPasses(grader.check_tail_y, self.check(12, 0), vectors)
self.assertPasses(grader.check_tail_y(self.check(13, 1), vectors)) self.assertPasses(grader.check_tail_y, self.check(13, 1), vectors)
self.assertFails(grader.check_tail_y(self.check(13, 0), vectors), errmsg) self.assertFails(grader.check_tail_y, self.check(13, 0), vectors, errmsg)
self.assertFails(grader.check_tail_y(self.check(10, 1.5), vectors), errmsg) self.assertFails(grader.check_tail_y, self.check(10, 1.5), vectors, errmsg)
custom_errmsg = 'Tail y should not be {tail_y:.1f}.' custom_errmsg = 'Tail y should not be {tail_y:.1f}.'
self.assertFails( self.assertFails(
grader.check_tail_y(self.check(10, 1.5, errmsg=custom_errmsg), vectors), grader.check_tail_y, self.check(10, 1.5, errmsg=custom_errmsg), vectors,
custom_errmsg.format(tail_y=12) custom_errmsg.format(tail_y=12)
) )
def test_check_tip_x(self): def test_check_tip_x(self):
errmsg = 'Vector vec does not end at correct point.' errmsg = 'Vector vec does not end at correct point.'
vectors = {'vec': self.vector(3, 12, 4, 40)} vectors = {'vec': self.vector(3, 12, 4, 40)}
self.assertPasses(grader.check_tip_x(self.check(4, 0), vectors)) self.assertPasses(grader.check_tip_x, self.check(4, 0), vectors)
self.assertPasses(grader.check_tip_x(self.check(5, 1), vectors)) self.assertPasses(grader.check_tip_x, self.check(5, 1), vectors)
self.assertFails(grader.check_tip_x(self.check(5, 0), vectors), errmsg) self.assertFails(grader.check_tip_x, self.check(5, 0), vectors, errmsg)
self.assertFails(grader.check_tip_x(self.check(2, 1.5), vectors), errmsg) self.assertFails(grader.check_tip_x, self.check(2, 1.5), vectors, errmsg)
custom_errmsg = 'Adjust the x tip coordinate.' custom_errmsg = 'Adjust the x tip coordinate.'
self.assertFails( self.assertFails(
grader.check_tip_x(self.check(2, 1.5, errmsg=custom_errmsg), vectors), grader.check_tip_x, self.check(2, 1.5, errmsg=custom_errmsg), vectors,
custom_errmsg custom_errmsg
) )
def test_check_tip_y(self): def test_check_tip_y(self):
errmsg = 'Vector vec does not end at correct point.' errmsg = 'Vector vec does not end at correct point.'
vectors = {'vec': self.vector(3, 12, 4, 40)} vectors = {'vec': self.vector(3, 12, 4, 40)}
self.assertPasses(grader.check_tip_y(self.check(40, 0), vectors)) self.assertPasses(grader.check_tip_y, self.check(40, 0), vectors)
self.assertPasses(grader.check_tip_y(self.check(33, 10), vectors)) self.assertPasses(grader.check_tip_y, self.check(33, 10), vectors)
self.assertFails(grader.check_tip_y(self.check(41, 0), vectors), errmsg) self.assertFails(grader.check_tip_y, self.check(41, 0), vectors, errmsg)
self.assertFails(grader.check_tip_y(self.check(29, 10), vectors), errmsg) self.assertFails(grader.check_tip_y, self.check(29, 10), vectors, errmsg)
custom_errmsg = 'Adjust the y tip coordinate of {name}.' custom_errmsg = 'Adjust the y tip coordinate of {name}.'
self.assertFails( self.assertFails(
grader.check_tip_y(self.check(29, 10, errmsg=custom_errmsg), vectors), grader.check_tip_y, self.check(29, 10, errmsg=custom_errmsg), vectors,
custom_errmsg.format(name='vec') custom_errmsg.format(name='vec')
) )
def test_check_coords(self): def test_check_coords(self):
errmsg = 'Vector vec coordinates are not correct.' errmsg = 'Vector vec coordinates are not correct.'
vectors = {'vec': self.vector(1, 2, 3, 4)} vectors = {'vec': self.vector(1, 2, 3, 4)}
self.assertPasses(grader.check_coords(self.check([[1, 2], [3, 4]], 0), vectors)) self.assertPasses(grader.check_coords, self.check([[1, 2], [3, 4]], 0), vectors)
self.assertPasses(grader.check_coords(self.check([[1, 3], [4, 4]], 2), vectors)) self.assertPasses(grader.check_coords, self.check([[1, 3], [4, 4]], 2), vectors)
self.assertPasses(grader.check_coords(self.check([['_', 2], [3, '_']], 0), vectors)) self.assertPasses(grader.check_coords, self.check([['_', 2], [3, '_']], 0), vectors)
self.assertPasses(grader.check_coords(self.check([[3, '_'], ['_', 5]], 2), vectors)) self.assertPasses(grader.check_coords, self.check([[3, '_'], ['_', 5]], 2), vectors)
self.assertPasses(grader.check_coords(self.check([['_', '_'], ['_', 3]], 2), vectors)) self.assertPasses(grader.check_coords, self.check([['_', '_'], ['_', 3]], 2), vectors)
self.assertPasses(grader.check_coords(self.check([['_', '_'], ['_', '_']], 0), vectors)) self.assertPasses(grader.check_coords, self.check([['_', '_'], ['_', '_']], 0), vectors)
self.assertFails(grader.check_coords(self.check([[2, 1], [3, 4]], 0), vectors), errmsg) self.assertFails(grader.check_coords, self.check([[2, 1], [3, 4]], 0), vectors, errmsg)
self.assertFails(grader.check_coords(self.check([[3, 4], [1, 2]], 0), vectors), errmsg) self.assertFails(grader.check_coords, self.check([[3, 4], [1, 2]], 0), vectors, errmsg)
self.assertFails(grader.check_coords(self.check([[1, 2], [4, 3]], 1), vectors), errmsg) self.assertFails(grader.check_coords, self.check([[1, 2], [4, 3]], 1), vectors, errmsg)
self.assertFails(grader.check_coords(self.check([[3, 4], [1, 2]], 0), vectors), errmsg) self.assertFails(grader.check_coords, self.check([[3, 4], [1, 2]], 0), vectors, errmsg)
self.assertFails(grader.check_coords(self.check([['_', 5], [3, 4]], 1), vectors), errmsg) self.assertFails(grader.check_coords, self.check([['_', 5], [3, 4]], 1), vectors, errmsg)
self.assertFails(grader.check_coords(self.check([['_', 2], [1, '_']], 1), vectors), errmsg) self.assertFails(grader.check_coords, self.check([['_', 2], [1, '_']], 1), vectors, errmsg)
self.assertFails(grader.check_coords(self.check([['_', 4], [2, '_']], 1), vectors), errmsg) self.assertFails(grader.check_coords, self.check([['_', 4], [2, '_']], 1), vectors, errmsg)
self.assertFails(grader.check_coords(self.check([['_', 4], ['_', '_']], 1), vectors), errmsg) self.assertFails(grader.check_coords, self.check([['_', 4], ['_', '_']], 1), vectors, errmsg)
custom_errmsg = 'Wrong coordinates: [{tail_x:.1f},{tail_y:.1f}, {tip_x:.1f},{tip_y:.1f}]' custom_errmsg = 'Wrong coordinates: [{tail_x:.1f},{tail_y:.1f}, {tip_x:.1f},{tip_y:.1f}]'
self.assertFails( self.assertFails(
grader.check_coords(self.check([['_', '_'], ['_', -4]], errmsg=custom_errmsg), vectors), grader.check_coords, self.check([['_', '_'], ['_', -4]], errmsg=custom_errmsg), vectors,
custom_errmsg.format(tail_x=1, tail_y=2, tip_x=3, tip_y=4) custom_errmsg.format(tail_x=1, tail_y=2, tip_x=3, tip_y=4)
) )
def test_check_segment_coords(self): def test_check_segment_coords(self):
errmsg = 'Segment vec coordinates are not correct.' errmsg = 'Segment vec coordinates are not correct.'
vectors = {'vec': self.vector(1, 2, 3, 4)} vectors = {'vec': self.vector(1, 2, 3, 4)}
self.assertPasses(grader.check_segment_coords(self.check([[1, 3], [4, 4]], 2), vectors)) self.assertPasses(grader.check_segment_coords, self.check([[1, 3], [4, 4]], 2), vectors)
self.assertPasses(grader.check_segment_coords(self.check([[4, 4], [1, 3]], 2), vectors)) self.assertPasses(grader.check_segment_coords, self.check([[4, 4], [1, 3]], 2), vectors)
self.assertPasses(grader.check_segment_coords(self.check([['_', 2], [3, '_']], 0), vectors)) self.assertPasses(grader.check_segment_coords, self.check([['_', 2], [3, '_']], 0), vectors)
self.assertPasses(grader.check_segment_coords(self.check([[3, '_'], ['_', 2]], 0), vectors)) self.assertPasses(grader.check_segment_coords, self.check([[3, '_'], ['_', 2]], 0), vectors)
self.assertPasses(grader.check_segment_coords(self.check([[3, '_'], ['_', 5]], 2), vectors)) self.assertPasses(grader.check_segment_coords, self.check([[3, '_'], ['_', 5]], 2), vectors)
self.assertPasses(grader.check_segment_coords(self.check([['_', 5], [3, '_']], 2), vectors)) self.assertPasses(grader.check_segment_coords, self.check([['_', 5], [3, '_']], 2), vectors)
self.assertPasses(grader.check_segment_coords(self.check([['_', '_'], ['_', 3]], 2), vectors)) self.assertPasses(grader.check_segment_coords, self.check([['_', '_'], ['_', 3]], 2), vectors)
self.assertPasses(grader.check_segment_coords(self.check([['_', '_'], ['_', '_']], 0), vectors)) self.assertPasses(grader.check_segment_coords, self.check([['_', '_'], ['_', '_']], 0), vectors)
self.assertPasses(grader.check_segment_coords(self.check([[1, 2], [3, 4]], 0), vectors)) self.assertPasses(grader.check_segment_coords, self.check([[1, 2], [3, 4]], 0), vectors)
self.assertPasses(grader.check_segment_coords(self.check([[3, 4], [1, 2]], 0), vectors)) self.assertPasses(grader.check_segment_coords, self.check([[3, 4], [1, 2]], 0), vectors)
self.assertPasses(grader.check_segment_coords(self.check([['_', 4], ['_', '_']], 1), vectors)) self.assertPasses(grader.check_segment_coords, self.check([['_', 4], ['_', '_']], 1), vectors)
self.assertPasses(grader.check_segment_coords(self.check([['_', 4], [2, '_']], 1), vectors)) self.assertPasses(grader.check_segment_coords, self.check([['_', 4], [2, '_']], 1), vectors)
self.assertFails(grader.check_segment_coords(self.check([[2, 1], [3, 4]], 0), vectors), errmsg) self.assertFails(grader.check_segment_coords, self.check([[2, 1], [3, 4]], 0), vectors, errmsg)
self.assertFails(grader.check_segment_coords(self.check([[-1, -2], [-3, -4]], 0), vectors), errmsg) self.assertFails(grader.check_segment_coords, self.check([[-1, -2], [-3, -4]], 0), vectors, errmsg)
self.assertFails(grader.check_segment_coords(self.check([[1, 2], [4, 3]], 1), vectors), errmsg) self.assertFails(grader.check_segment_coords, self.check([[1, 2], [4, 3]], 1), vectors, errmsg)
self.assertFails(grader.check_segment_coords(self.check([['_', 5], [3, 4]], 1), vectors), errmsg) self.assertFails(grader.check_segment_coords, self.check([['_', 5], [3, 4]], 1), vectors, errmsg)
self.assertFails(grader.check_segment_coords(self.check([['_', 2], [1, '_']], 1), vectors), errmsg) self.assertFails(grader.check_segment_coords, self.check([['_', 2], [1, '_']], 1), vectors, errmsg)
self.assertFails(grader.check_segment_coords(self.check([['_', '_'], ['_', 5.5]], 1), vectors), errmsg) self.assertFails(grader.check_segment_coords, self.check([['_', '_'], ['_', 5.5]], 1), vectors, errmsg)
custom_errmsg = 'Coordinates of {name} are wrong!' custom_errmsg = 'Coordinates of {name} are wrong!'
self.assertFails( self.assertFails(
grader.check_segment_coords(self.check([['_', '_'], ['_', 5.5]], errmsg=custom_errmsg), vectors), grader.check_segment_coords, self.check([['_', '_'], ['_', 5.5]], errmsg=custom_errmsg), vectors,
custom_errmsg.format(name='vec') custom_errmsg.format(name='vec')
) )
def test_check_length(self): def test_check_length(self):
errmsg = 'The length of vec is incorrect. Your length: 5.0' errmsg = 'The length of vec is incorrect. Your length: 5.0'
vectors = {'vec': self.vector(0, 0, 3, 4)} vectors = {'vec': self.vector(0, 0, 3, 4)}
self.assertPasses(grader.check_length(self.check(5, 0), vectors)) self.assertPasses(grader.check_length, self.check(5, 0), vectors)
self.assertPasses(grader.check_length(self.check(7, 2.5), vectors)) self.assertPasses(grader.check_length, self.check(7, 2.5), vectors)
self.assertFails(grader.check_length(self.check(4.5, 0), vectors), errmsg) self.assertFails(grader.check_length, self.check(4.5, 0), vectors, errmsg)
self.assertFails(grader.check_length(self.check(5.5, 0.25), vectors), errmsg) self.assertFails(grader.check_length, self.check(5.5, 0.25), vectors, errmsg)
custom_errmsg = 'Bad length of {length:.2f}' custom_errmsg = 'Bad length of {length:.2f}'
self.assertFails( self.assertFails(
grader.check_length(self.check(5.5, 0.25, errmsg=custom_errmsg), vectors), grader.check_length, self.check(5.5, 0.25, errmsg=custom_errmsg), vectors,
custom_errmsg.format(length=5.00) custom_errmsg.format(length=5.00)
) )
def test_check_angle(self): def test_check_angle(self):
errmsg = 'The angle of vec is incorrect. Your angle: 45.0' errmsg = 'The angle of vec is incorrect. Your angle: 45.0'
vectors = {'vec': self.vector(1, 1, 5, 5)} vectors = {'vec': self.vector(1, 1, 5, 5)}
self.assertPasses(grader.check_angle(self.check(45, 0.1), vectors)) self.assertPasses(grader.check_angle, self.check(45, 0.1), vectors)
self.assertPasses(grader.check_angle(self.check(-315, 0.1), vectors)) self.assertPasses(grader.check_angle, self.check(-315, 0.1), vectors)
self.assertPasses(grader.check_angle(self.check(405, 0.1), vectors)) self.assertPasses(grader.check_angle, self.check(405, 0.1), vectors)
self.assertPasses(grader.check_angle(self.check(-5, 55), vectors)) self.assertPasses(grader.check_angle, self.check(-5, 55), vectors)
self.assertPasses(grader.check_angle(self.check(42, 5), vectors)) self.assertPasses(grader.check_angle, self.check(42, 5), vectors)
self.assertFails(grader.check_angle(self.check(315, 0.1), vectors), errmsg) self.assertFails(grader.check_angle, self.check(315, 0.1), vectors, errmsg)
self.assertFails(grader.check_angle(self.check(30, 9), vectors), errmsg) self.assertFails(grader.check_angle, self.check(30, 9), vectors, errmsg)
custom_errmsg = 'Adjust angle of {name}. Currently: {angle:.0f}.' custom_errmsg = 'Adjust angle of {name}. Currently: {angle:.0f}.'
self.assertFails( self.assertFails(
grader.check_angle(self.check(30, 9, errmsg=custom_errmsg), vectors), grader.check_angle, self.check(30, 9, errmsg=custom_errmsg), vectors,
custom_errmsg.format(name='vec', angle=45.0) custom_errmsg.format(name='vec', angle=45.0)
) )
def test_check_segment_angle(self): def test_check_segment_angle(self):
errmsg = 'The angle of vec is incorrect. Your angle: 45.0' errmsg = 'The angle of vec is incorrect. Your angle: 45.0'
vectors = {'vec': self.vector(1, 1, 5, 5)} vectors = {'vec': self.vector(1, 1, 5, 5)}
self.assertPasses(grader.check_segment_angle(self.check(45, 0.1), vectors)) self.assertPasses(grader.check_segment_angle, self.check(45, 0.1), vectors)
self.assertPasses(grader.check_segment_angle(self.check(-315, 0.1), vectors)) self.assertPasses(grader.check_segment_angle, self.check(-315, 0.1), vectors)
self.assertPasses(grader.check_segment_angle(self.check(405, 0.1), vectors)) self.assertPasses(grader.check_segment_angle, self.check(405, 0.1), vectors)
self.assertPasses(grader.check_segment_angle(self.check(42, 5), vectors)) self.assertPasses(grader.check_segment_angle, self.check(42, 5), vectors)
self.assertFails(grader.check_segment_angle(self.check(-405, 0.1), vectors), errmsg) self.assertFails(grader.check_segment_angle, self.check(-405, 0.1), vectors, errmsg)
self.assertFails(grader.check_segment_angle(self.check(315, 0.1), vectors), errmsg) self.assertFails(grader.check_segment_angle, self.check(315, 0.1), vectors, errmsg)
self.assertFails(grader.check_segment_angle(self.check(-45, 9), vectors), errmsg) self.assertFails(grader.check_segment_angle, self.check(-45, 9), vectors, errmsg)
custom_errmsg = 'Segment angle is incorrect.' custom_errmsg = 'Segment angle is incorrect.'
self.assertFails( self.assertFails(
grader.check_segment_angle(self.check(-45, 9, errmsg=custom_errmsg), vectors), grader.check_segment_angle, self.check(-45, 9, errmsg=custom_errmsg), vectors,
custom_errmsg custom_errmsg
) )
def test_check_points_on_line(self): def test_check_points_on_line(self):
errmsg = 'The line vec does not pass through the correct points.' errmsg = 'The line vec does not pass through the correct points.'
vectors = {'vec': self.vector(1, 1, 5, 5)} vectors = {'vec': self.vector(1, 1, 5, 5)}
self.assertPasses(grader.check_points_on_line(self.check([[1, 1], [5, 5]]), vectors)) self.assertPasses(grader.check_points_on_line, self.check([[1, 1], [5, 5]]), vectors)
self.assertPasses(grader.check_points_on_line(self.check([[1, 2], [5, 4]]), vectors)) self.assertPasses(grader.check_points_on_line, self.check([[1, 2], [5, 4]]), vectors)
self.assertPasses(grader.check_points_on_line(self.check([[3.7, 2.3], [2.3, 3.7]]), vectors)) self.assertPasses(grader.check_points_on_line, self.check([[3.7, 2.3], [2.3, 3.7]]), vectors)
self.assertPasses(grader.check_points_on_line(self.check([[-1, -.5], [98, 99]]), vectors)) self.assertPasses(grader.check_points_on_line, self.check([[-1, -.5], [98, 99]]), vectors)
self.assertFails(grader.check_points_on_line(self.check([[1, -1]]), vectors), errmsg) self.assertFails(grader.check_points_on_line, self.check([[1, -1]]), vectors, errmsg)
self.assertFails(grader.check_points_on_line(self.check([[3.8, 2.2]]), vectors), errmsg) self.assertFails(grader.check_points_on_line, self.check([[3.8, 2.2]]), vectors, errmsg)
self.assertFails(grader.check_points_on_line(self.check([[18, 13]]), vectors), errmsg) self.assertFails(grader.check_points_on_line, self.check([[18, 13]]), vectors, errmsg)
vectors = {'vec': self.vector(1, 1, 1, 5)} # vertical line vectors = {'vec': self.vector(1, 1, 1, 5)} # vertical line
self.assertPasses(grader.check_points_on_line(self.check([[1, 3], [1, 99], [1.9, 55]]), vectors)) self.assertPasses(grader.check_points_on_line, self.check([[1, 3], [1, 99], [1.9, 55]]), vectors)
self.assertFails(grader.check_points_on_line(self.check([[2.1, 3]]), vectors), errmsg) self.assertFails(grader.check_points_on_line, self.check([[2.1, 3]]), vectors, errmsg)
vectors = {'vec': self.vector(1, 1, 5, 1)} # horizontal line vectors = {'vec': self.vector(1, 1, 5, 1)} # horizontal line
self.assertPasses(grader.check_points_on_line(self.check([[3, 1], [99, 1], [55, 1.9]]), vectors)) self.assertPasses(grader.check_points_on_line, self.check([[3, 1], [99, 1], [55, 1.9]]), vectors)
self.assertFails(grader.check_points_on_line(self.check([[3, 2.1]]), vectors), errmsg) self.assertFails(grader.check_points_on_line, self.check([[3, 2.1]]), vectors, errmsg)
...@@ -77,7 +77,7 @@ def check_presence(check, vectors): ...@@ -77,7 +77,7 @@ def check_presence(check, vectors):
""" """
if check['vector'] not in vectors: if check['vector'] not in vectors:
errmsg = check.get('errmsg', 'You need to use the {name} vector.') errmsg = check.get('errmsg', 'You need to use the {name} vector.')
return errmsg.format(name=check['vector']) raise ValueError(errmsg.format(name=check['vector']))
def _check_vector_endpoint(check, vectors, endpoint): def _check_vector_endpoint(check, vectors, endpoint):
...@@ -91,11 +91,11 @@ def _check_vector_endpoint(check, vectors, endpoint): ...@@ -91,11 +91,11 @@ def _check_vector_endpoint(check, vectors, endpoint):
endpoint = getattr(vec, endpoint) endpoint = getattr(vec, endpoint)
dist = math.hypot(expected[0] - endpoint.x, expected[1] - endpoint.y) dist = math.hypot(expected[0] - endpoint.x, expected[1] - endpoint.y)
if dist > tolerance: if dist > tolerance:
return _errmsg( raise ValueError(_errmsg(
'Vector {name} does not {verb} at correct point.'.format(name='{name}', verb=verb), 'Vector {name} does not {verb} at correct point.'.format(name='{name}', verb=verb),
check, check,
vectors vectors
) ))
def check_tail(check, vectors): def check_tail(check, vectors):
...@@ -127,7 +127,7 @@ def check_tail_x(check, vectors): ...@@ -127,7 +127,7 @@ def check_tail_x(check, vectors):
""" """
vec = vectors[check['vector']] vec = vectors[check['vector']]
if _check_coordinate(check, vec.tail.x): if _check_coordinate(check, vec.tail.x):
return _errmsg('Vector {name} does not start at correct point.', check, vectors) raise ValueError(_errmsg('Vector {name} does not start at correct point.', check, vectors))
def check_tail_y(check, vectors): def check_tail_y(check, vectors):
...@@ -136,7 +136,7 @@ def check_tail_y(check, vectors): ...@@ -136,7 +136,7 @@ def check_tail_y(check, vectors):
""" """
vec = vectors[check['vector']] vec = vectors[check['vector']]
if _check_coordinate(check, vec.tail.y): if _check_coordinate(check, vec.tail.y):
return _errmsg('Vector {name} does not start at correct point.', check, vectors) raise ValueError(_errmsg('Vector {name} does not start at correct point.', check, vectors))
def check_tip_x(check, vectors): def check_tip_x(check, vectors):
...@@ -145,7 +145,7 @@ def check_tip_x(check, vectors): ...@@ -145,7 +145,7 @@ def check_tip_x(check, vectors):
""" """
vec = vectors[check['vector']] vec = vectors[check['vector']]
if _check_coordinate(check, vec.tip.x): if _check_coordinate(check, vec.tip.x):
return _errmsg('Vector {name} does not end at correct point.', check, vectors) raise ValueError(_errmsg('Vector {name} does not end at correct point.', check, vectors))
def check_tip_y(check, vectors): def check_tip_y(check, vectors):
...@@ -154,7 +154,7 @@ def check_tip_y(check, vectors): ...@@ -154,7 +154,7 @@ def check_tip_y(check, vectors):
""" """
vec = vectors[check['vector']] vec = vectors[check['vector']]
if _check_coordinate(check, vec.tip.y): if _check_coordinate(check, vec.tip.y):
return _errmsg('Vector {name} does not end at correct point.', check, vectors) raise ValueError(_errmsg('Vector {name} does not end at correct point.', check, vectors))
def _coord_delta(expected, actual): def _coord_delta(expected, actual):
...@@ -187,7 +187,7 @@ def check_coords(check, vectors): ...@@ -187,7 +187,7 @@ def check_coords(check, vectors):
expected = check['expected'] expected = check['expected']
tolerance = check.get('tolerance', 1.0) tolerance = check.get('tolerance', 1.0)
if not _coords_within_tolerance(vec, expected, tolerance): if not _coords_within_tolerance(vec, expected, tolerance):
return _errmsg('Vector {name} coordinates are not correct.', check, vectors) raise ValueError(_errmsg('Vector {name} coordinates are not correct.', check, vectors))
def check_segment_coords(check, vectors): def check_segment_coords(check, vectors):
...@@ -199,7 +199,7 @@ def check_segment_coords(check, vectors): ...@@ -199,7 +199,7 @@ def check_segment_coords(check, vectors):
tolerance = check.get('tolerance', 1.0) tolerance = check.get('tolerance', 1.0)
if not (_coords_within_tolerance(vec, expected, tolerance) or if not (_coords_within_tolerance(vec, expected, tolerance) or
_coords_within_tolerance(vec.opposite(), expected, tolerance)): _coords_within_tolerance(vec.opposite(), expected, tolerance)):
return _errmsg('Segment {name} coordinates are not correct.', check, vectors) raise ValueError(_errmsg('Segment {name} coordinates are not correct.', check, vectors))
def check_length(check, vectors): def check_length(check, vectors):
...@@ -209,9 +209,9 @@ def check_length(check, vectors): ...@@ -209,9 +209,9 @@ def check_length(check, vectors):
vec = vectors[check['vector']] vec = vectors[check['vector']]
tolerance = check.get('tolerance', 1.0) tolerance = check.get('tolerance', 1.0)
if abs(vec.length - check['expected']) > tolerance: if abs(vec.length - check['expected']) > tolerance:
return _errmsg( raise ValueError(_errmsg(
'The length of {name} is incorrect. Your length: {length:.1f}', check, vectors 'The length of {name} is incorrect. Your length: {length:.1f}', check, vectors
) ))
def _angle_within_tolerance(vec, expected, tolerance): def _angle_within_tolerance(vec, expected, tolerance):
...@@ -236,7 +236,9 @@ def check_angle(check, vectors): ...@@ -236,7 +236,9 @@ def check_angle(check, vectors):
tolerance = check.get('tolerance', 2.0) tolerance = check.get('tolerance', 2.0)
expected = math.radians(check['expected']) expected = math.radians(check['expected'])
if not _angle_within_tolerance(vec, expected, tolerance): if not _angle_within_tolerance(vec, expected, tolerance):
return _errmsg('The angle of {name} is incorrect. Your angle: {angle:.1f}', check, vectors) raise ValueError(
_errmsg('The angle of {name} is incorrect. Your angle: {angle:.1f}', check, vectors)
)
def check_segment_angle(check, vectors): def check_segment_angle(check, vectors):
...@@ -250,7 +252,9 @@ def check_segment_angle(check, vectors): ...@@ -250,7 +252,9 @@ def check_segment_angle(check, vectors):
expected = math.radians(check['expected']) expected = math.radians(check['expected'])
if not (_angle_within_tolerance(vec, expected, tolerance) or if not (_angle_within_tolerance(vec, expected, tolerance) or
_angle_within_tolerance(vec.opposite(), expected, tolerance)): _angle_within_tolerance(vec.opposite(), expected, tolerance)):
return _errmsg('The angle of {name} is incorrect. Your angle: {angle:.1f}', check, vectors) raise ValueError(
_errmsg('The angle of {name} is incorrect. Your angle: {angle:.1f}', check, vectors)
)
def _dist_line_point(line, point): def _dist_line_point(line, point):
...@@ -275,9 +279,9 @@ def check_points_on_line(check, vectors): ...@@ -275,9 +279,9 @@ def check_points_on_line(check, vectors):
for point in points: for point in points:
point = Point(point[0], point[1]) point = Point(point[0], point[1])
if _dist_line_point(line, point) > tolerance: if _dist_line_point(line, point) > tolerance:
return _errmsg( raise ValueError(_errmsg(
'The line {name} does not pass through the correct points.', check, vectors 'The line {name} does not pass through the correct points.', check, vectors
) ))
def check_point_coords(check, points): def check_point_coords(check, points):
...@@ -358,10 +362,11 @@ class Grader(object): ...@@ -358,10 +362,11 @@ class Grader(object):
check_data['check'] = check check_data['check'] = check
check_fn = self.check_registry[check['check']] check_fn = self.check_registry[check['check']]
args = [check_data[arg] for arg in inspect.getargspec(check_fn).args] args = [check_data[arg] for arg in inspect.getargspec(check_fn).args]
result = check_fn(*args) try:
if result: check_fn(*args)
return {'ok': False, 'msg': result} except ValueError as e:
return {'ok': True, 'msg': self.success_message} return {'correct': False, 'msg': e.message}
return {'correct': True, 'msg': self.success_message}
def _get_vectors(self, answer): # pylint: disable=no-self-use def _get_vectors(self, answer): # pylint: disable=no-self-use
""" """
......
...@@ -4,7 +4,7 @@ function StudioEditableXBlockMixin(runtime, element) { ...@@ -4,7 +4,7 @@ function StudioEditableXBlockMixin(runtime, element) {
var fields = []; var fields = [];
var tinyMceAvailable = (typeof $.fn.tinymce !== 'undefined'); // Studio includes a copy of tinyMCE and its jQuery plugin var tinyMceAvailable = (typeof $.fn.tinymce !== 'undefined'); // Studio includes a copy of tinyMCE and its jQuery plugin
var errorMessage = gettext("This may be happening because of an error with our server or your internet connection. Try refreshing the page or making sure you are online."); var errorMessage = gettext("This may be happening because of an error with our server or your internet connection. Make sure you are online, and try refreshing the page.");
$(element).find('.field-data-control').each(function() { $(element).find('.field-data-control').each(function() {
var $field = $(this); var $field = $(this);
...@@ -18,11 +18,11 @@ function StudioEditableXBlockMixin(runtime, element) { ...@@ -18,11 +18,11 @@ function StudioEditableXBlockMixin(runtime, element) {
val: function() { val: function() {
var val = $field.val(); var val = $field.val();
// Cast values to the appropriate type so that we send nice clean JSON over the wire: // Cast values to the appropriate type so that we send nice clean JSON over the wire:
if (type == 'boolean') if (type === 'boolean')
return (val == 'true' || val == '1'); return (val === 'true' || val === '1');
if (type == "integer") if (type === "integer")
return parseInt(val, 10); return parseInt(val, 10);
if (type == "float") if (type === "float")
return parseFloat(val); return parseFloat(val);
return val; return val;
}, },
...@@ -41,7 +41,7 @@ function StudioEditableXBlockMixin(runtime, element) { ...@@ -41,7 +41,7 @@ function StudioEditableXBlockMixin(runtime, element) {
$wrapper.removeClass('is-set'); $wrapper.removeClass('is-set');
$resetButton.removeClass('active').addClass('inactive'); $resetButton.removeClass('active').addClass('inactive');
}); });
if (type == 'html' && tinyMceAvailable) { if (type === 'html' && tinyMceAvailable) {
tinyMCE.baseURL = baseUrl + "/js/vendor/tinymce/js/tinymce"; tinyMCE.baseURL = baseUrl + "/js/vendor/tinymce/js/tinymce";
$field.tinymce({ $field.tinymce({
theme: 'modern', theme: 'modern',
...@@ -72,16 +72,17 @@ function StudioEditableXBlockMixin(runtime, element) { ...@@ -72,16 +72,17 @@ function StudioEditableXBlockMixin(runtime, element) {
url: handlerUrl, url: handlerUrl,
data: JSON.stringify(data), data: JSON.stringify(data),
dataType: "json", dataType: "json",
global: false // Disable Studio's error handling that conflicts with studio's notify('save') and notify('cancel') :-/ notifyOnError: false
}).done(function(response) { }).done(function(response) {
runtime.notify('save', {state: 'end'}); runtime.notify('save', {state: 'end'});
}).fail(function(jqXHR) { }).fail(function(jqXHR) {
if (jqXHR.responseText) { // Is there a more specific error message we can show? if (jqXHR.responseText) { // Is there a more specific error message we can show?
try { try {
errorMessage = JSON.parse(jqXHR.responseText).error; errorMessage = JSON.parse(jqXHR.responseText).error;
if (typeof errorMessage === "object" && errorMessage.messages) { if (_.isObject(errorMessage) && errorMessage.messages) {
// e.g. {"error": {"messages": [{"text": "Unknown user 'bob'!", "type": "error"}, ...]}} etc. // e.g. {"error": {"messages": [{"text": "Unknown user 'bob'!", "type": "error"}, ...]}} etc.
errorMessage = $.map(errorMessage.messages, function(msg) { return msg.text; }).join(", "); var errorMessages = _.pluck(errorMessage.messages, "text");
errorMessage = errorMessages.join(", ");
} }
} catch (error) { errorMessage = jqXHR.responseText.substr(0, 300); } } catch (error) { errorMessage = jqXHR.responseText.substr(0, 300); }
} }
...@@ -98,8 +99,7 @@ function StudioEditableXBlockMixin(runtime, element) { ...@@ -98,8 +99,7 @@ function StudioEditableXBlockMixin(runtime, element) {
save: function(data) { save: function(data) {
var values = {}; var values = {};
var notSet = []; // List of field names that should be set to default values var notSet = []; // List of field names that should be set to default values
for (var i in fields) { _.each(fields, function(field) {
var field = fields[i];
if (field.isSet()) { if (field.isSet()) {
values[field.name] = field.val(); values[field.name] = field.val();
} else { } else {
...@@ -110,7 +110,7 @@ function StudioEditableXBlockMixin(runtime, element) { ...@@ -110,7 +110,7 @@ function StudioEditableXBlockMixin(runtime, element) {
if (field.hasEditor()) { if (field.hasEditor()) {
field.removeEditor(); field.removeEditor();
} }
} });
// If WYSIWYG editor was used, // If WYSIWYG editor was used,
// prefer its data over values of "Vectors" and "Expected result" fields: // prefer its data over values of "Vectors" and "Expected result" fields:
if (!_.isEmpty(data)) { if (!_.isEmpty(data)) {
...@@ -125,12 +125,11 @@ function StudioEditableXBlockMixin(runtime, element) { ...@@ -125,12 +125,11 @@ function StudioEditableXBlockMixin(runtime, element) {
cancel: function() { cancel: function() {
// Remove TinyMCE instances to make sure jQuery does not try to access stale instances // Remove TinyMCE instances to make sure jQuery does not try to access stale instances
// when loading editor for another block: // when loading editor for another block:
for (var i in fields) { _.each(fields, function(field) {
var field = fields[i];
if (field.hasEditor()) { if (field.hasEditor()) {
field.removeEditor(); field.removeEditor();
} }
} });
runtime.notify('cancel', {}); runtime.notify('cancel', {});
} }
......
...@@ -593,7 +593,7 @@ function VectorDrawXBlock(runtime, element, init_args) { ...@@ -593,7 +593,7 @@ function VectorDrawXBlock(runtime, element, init_args) {
var correctness = $('.correctness', element), var correctness = $('.correctness', element),
correctClass = 'checkmark-correct fa fa-check', correctClass = 'checkmark-correct fa fa-check',
incorrectClass = 'checkmark-incorrect fa fa-times'; incorrectClass = 'checkmark-incorrect fa fa-times';
if (data.result.ok) { if (data.result.correct) {
correctness.removeClass(incorrectClass); correctness.removeClass(incorrectClass);
correctness.addClass(correctClass); correctness.addClass(correctClass);
} else { } else {
......
...@@ -530,7 +530,7 @@ class VectorDrawXBlock(StudioEditableXBlockMixin, XBlock): ...@@ -530,7 +530,7 @@ class VectorDrawXBlock(StudioEditableXBlockMixin, XBlock):
# Save result # Save result
self.result = result self.result = result
# Publish grade data # Publish grade data
score = 1 if result["ok"] else 0 score = 1 if result["correct"] else 0
self.runtime.publish(self, 'grade', dict(value=score, max_value=1)) self.runtime.publish(self, 'grade', dict(value=score, max_value=1))
return { return {
"result": result, "result": result,
......
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