Commit 0d4a06ac by Tim Krones

Address upstream review comments.

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