Commit 8b47e543 by Braden MacDonald

PEP8 Test and fixes, add three pylint checks as well

parent 8e19102d
...@@ -9,6 +9,6 @@ install: ...@@ -9,6 +9,6 @@ install:
- "pip install -r $VIRTUAL_ENV/src/xblock-sdk/requirements.txt" - "pip install -r $VIRTUAL_ENV/src/xblock-sdk/requirements.txt"
- "pip install -r $VIRTUAL_ENV/src/xblock-sdk/test-requirements.txt" - "pip install -r $VIRTUAL_ENV/src/xblock-sdk/test-requirements.txt"
- "pip install -r requirements.txt" - "pip install -r requirements.txt"
script: python run_tests.py --with-coverage --cover-package=mentoring script: python run_tests.py --with-coverage --cover-package=mentoring && pep8 mentoring --max-line-length=120 && pylint mentoring --disable=all --enable=function-redefined,undefined-variable,unused-variable
notifications: notifications:
email: false email: false
...@@ -83,7 +83,7 @@ class AnswerBlock(XBlock, StepMixin): ...@@ -83,7 +83,7 @@ class AnswerBlock(XBlock, StepMixin):
scope=Scope.user_state, scope=Scope.user_state,
default="" default=""
) )
# Shared student input - share answers among all Answer blocks in the course with the same name # Shared student input - share answers among all Answer blocks in the course with the same name
student_input_shared = Dict( student_input_shared = Dict(
scope=Scope.preferences, scope=Scope.preferences,
) )
......
...@@ -31,6 +31,7 @@ from xblock.fragment import Fragment ...@@ -31,6 +31,7 @@ from xblock.fragment import Fragment
# Classes ########################################################### # Classes ###########################################################
class HTMLBlock(XBlock): class HTMLBlock(XBlock):
""" """
Render content as HTML Render content as HTML
......
...@@ -23,14 +23,12 @@ ...@@ -23,14 +23,12 @@
# Imports ########################################################### # Imports ###########################################################
from .common import BlockWithContent from .common import BlockWithContent
from xblock.fields import Scope, String from xblock.fields import Scope, String
# Classes ########################################################### # Classes ###########################################################
class MentoringMessageBlock(BlockWithContent): class MentoringMessageBlock(BlockWithContent):
""" """
A message which can be conditionally displayed at the mentoring block level, A message which can be conditionally displayed at the mentoring block level,
......
...@@ -71,8 +71,9 @@ class MRQBlock(QuestionnaireAbstractBlock): ...@@ -71,8 +71,9 @@ class MRQBlock(QuestionnaireAbstractBlock):
} }
# Only include tips/results in returned response if we want to display them # Only include tips/results in returned response if we want to display them
if not self.hide_results: if not self.hide_results:
loader = ResourceLoader(__name__)
choice_result['completed'] = choice_completed choice_result['completed'] = choice_completed
choice_result['tips'] = ResourceLoader(__name__).render_template('templates/html/tip_choice_group.html', { choice_result['tips'] = loader.render_template('templates/html/tip_choice_group.html', {
'self': self, 'self': self,
'tips_html': choice_tips_html, 'tips_html': choice_tips_html,
'completed': choice_completed, 'completed': choice_completed,
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
# "AGPLv3". If not, see <http://www.gnu.org/licenses/>. # "AGPLv3". If not, see <http://www.gnu.org/licenses/>.
# #
class StepParentMixin(object): class StepParentMixin(object):
""" """
An XBlock mixin for a parent block containing Step children An XBlock mixin for a parent block containing Step children
...@@ -26,7 +27,7 @@ class StepParentMixin(object): ...@@ -26,7 +27,7 @@ class StepParentMixin(object):
@property @property
def steps(self): def steps(self):
""" """
Generator returning the usage_id for all of this XBlock's Generator returning the usage_id for all of this XBlock's
children that are "Steps" children that are "Steps"
""" """
step_ids = [] step_ids = []
......
...@@ -28,6 +28,7 @@ from xblock.fields import Scope, String ...@@ -28,6 +28,7 @@ from xblock.fields import Scope, String
# Functions ######################################################### # Functions #########################################################
def commas_to_set(commas_str): def commas_to_set(commas_str):
""" """
Converts a comma-separated string to a set Converts a comma-separated string to a set
......
...@@ -24,8 +24,10 @@ ...@@ -24,8 +24,10 @@
# Imports ########################################################### # Imports ###########################################################
import logging import logging
import unicodecsv
from itertools import groupby from itertools import groupby
from StringIO import StringIO
from webob import Response from webob import Response
from xblock.core import XBlock from xblock.core import XBlock
from xblock.fields import String, Scope from xblock.fields import String, Scope
...@@ -33,13 +35,13 @@ from xblock.fragment import Fragment ...@@ -33,13 +35,13 @@ from xblock.fragment import Fragment
from xblockutils.resources import ResourceLoader from xblockutils.resources import ResourceLoader
# Globals ########################################################### # Globals ###########################################################
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
# Utils ########################################################### # Utils ###########################################################
def list2csv(row): def list2csv(row):
""" """
Convert a list to a CSV string (single row) Convert a list to a CSV string (single row)
...@@ -84,16 +86,18 @@ class MentoringDataExportBlock(XBlock): ...@@ -84,16 +86,18 @@ class MentoringDataExportBlock(XBlock):
return response return response
def get_csv(self): def get_csv(self):
course_id = self.xmodule_runtime.course_id # course_id = self.xmodule_runtime.course_id
answers = Answer.objects.filter(course_id=course_id).order_by('student_id', 'name') # TODO: Fix this method - not working yet with rewrite away from LightChildren.
raise NotImplementedError
answers = [] # Answer.objects.filter(course_id=course_id).order_by('student_id', 'name')
answers_names = answers.values_list('name', flat=True).distinct().order_by('name') answers_names = answers.values_list('name', flat=True).distinct().order_by('name')
# Header line # Header line
yield list2csv([u'student_id'] + list(answers_names)) yield list2csv([u'student_id'] + list(answers_names))
if answers_names: if answers_names:
for k, student_answers in groupby(answers, lambda x: x.student_id): for _, student_answers in groupby(answers, lambda x: x.student_id):
row = [] row = []
next_answer_idx = 0 next_answer_idx = 0
for answer in student_answers: for answer in student_answers:
......
...@@ -86,8 +86,11 @@ class MentoringBlock(XBlock, StepParentMixin): ...@@ -86,8 +86,11 @@ class MentoringBlock(XBlock, StepParentMixin):
) )
url_name = String( url_name = String(
help="Name of the current step, used for URL building", help="Name of the current step, used for URL building",
default='mentoring-default', # TODO in future: set this to xblock.fields.UNIQUE_ID and remove self.url_name_with_default default='mentoring-default',
scope=Scope.content scope=Scope.content
# TODO in future: set this field's default to xblock.fields.UNIQUE_ID
# and remove self.url_name_with_default. Waiting until UNIQUE_ID support
# is available in edx-platform's pinned version of xblock. (See XBlock PR 249)
) )
enforce_dependency = Boolean( enforce_dependency = Boolean(
help="Should the next step be the current block to complete?", help="Should the next step be the current block to complete?",
...@@ -175,7 +178,6 @@ class MentoringBlock(XBlock, StepParentMixin): ...@@ -175,7 +178,6 @@ class MentoringBlock(XBlock, StepParentMixin):
# Migrate stored data if necessary # Migrate stored data if necessary
self.migrate_fields() self.migrate_fields()
fragment = Fragment() fragment = Fragment()
title = u"" title = u""
header = u"" header = u""
...@@ -258,7 +260,7 @@ class MentoringBlock(XBlock, StepParentMixin): ...@@ -258,7 +260,7 @@ class MentoringBlock(XBlock, StepParentMixin):
Returns True if the student needs to complete another step before being able to complete Returns True if the student needs to complete another step before being able to complete
the current one, and False otherwise the current one, and False otherwise
""" """
return self.enforce_dependency and (not self.completed) and (self.next_step != self.url_name_with_default) # TODO: Fix return self.enforce_dependency and (not self.completed) and (self.next_step != self.url_name_with_default)
@property @property
def next_step_url(self): def next_step_url(self):
......
...@@ -2,6 +2,7 @@ from .base_test import MentoringBaseTest ...@@ -2,6 +2,7 @@ from .base_test import MentoringBaseTest
CORRECT, INCORRECT, PARTIAL = "correct", "incorrect", "partially-correct" CORRECT, INCORRECT, PARTIAL = "correct", "incorrect", "partially-correct"
class MentoringAssessmentTest(MentoringBaseTest): class MentoringAssessmentTest(MentoringBaseTest):
def _selenium_bug_workaround_scroll_to(self, mentoring, question): def _selenium_bug_workaround_scroll_to(self, mentoring, question):
"""Workaround for selenium bug: """Workaround for selenium bug:
...@@ -20,7 +21,6 @@ class MentoringAssessmentTest(MentoringBaseTest): ...@@ -20,7 +21,6 @@ class MentoringAssessmentTest(MentoringBaseTest):
hopefully, this gives us enough room for the full step with the hopefully, this gives us enough room for the full step with the
control buttons to fit. control buttons to fit.
""" """
self.browser.execute_script("$('header.banner').remove();") # Hide the Workbench header which can obscure other elements we need
controls = mentoring.find_element_by_css_selector("div.submit") controls = mentoring.find_element_by_css_selector("div.submit")
title = question.find_element_by_css_selector("h3.question-title") title = question.find_element_by_css_selector("h3.question-title")
controls.click() controls.click()
...@@ -41,10 +41,6 @@ class MentoringAssessmentTest(MentoringBaseTest): ...@@ -41,10 +41,6 @@ class MentoringAssessmentTest(MentoringBaseTest):
self.assertIn("A Simple Assessment", mentoring.text) self.assertIn("A Simple Assessment", mentoring.text)
self.assertIn("This paragraph is shared between all questions.", mentoring.text) self.assertIn("This paragraph is shared between all questions.", mentoring.text)
def assert_disabled(self, elem):
self.assertTrue(elem.is_displayed())
self.assertFalse(elem.is_enabled())
class _GetChoices(object): class _GetChoices(object):
def __init__(self, question, selector=".choices"): def __init__(self, question, selector=".choices"):
self._mcq = question.find_element_by_css_selector(selector) self._mcq = question.find_element_by_css_selector(selector)
...@@ -60,7 +56,6 @@ class MentoringAssessmentTest(MentoringBaseTest): ...@@ -60,7 +56,6 @@ class MentoringAssessmentTest(MentoringBaseTest):
for choice in self._mcq.find_elements_by_css_selector(".choice")} for choice in self._mcq.find_elements_by_css_selector(".choice")}
def select(self, text): def select(self, text):
state = {}
for choice in self._mcq.find_elements_by_css_selector(".choice"): for choice in self._mcq.find_elements_by_css_selector(".choice"):
if choice.text == text: if choice.text == text:
choice.find_element_by_css_selector("input").click() choice.find_element_by_css_selector("input").click()
...@@ -75,7 +70,6 @@ class MentoringAssessmentTest(MentoringBaseTest): ...@@ -75,7 +70,6 @@ class MentoringAssessmentTest(MentoringBaseTest):
for name, count in states.items(): for name, count in states.items():
self.assertEqual(len(mentoring.find_elements_by_css_selector(".checkmark-{}".format(name))), count) self.assertEqual(len(mentoring.find_elements_by_css_selector(".checkmark-{}".format(name))), count)
def go_to_workbench_main_page(self): def go_to_workbench_main_page(self):
self.browser.get(self.live_server_url) self.browser.get(self.live_server_url)
...@@ -302,24 +296,27 @@ class MentoringAssessmentTest(MentoringBaseTest): ...@@ -302,24 +296,27 @@ class MentoringAssessmentTest(MentoringBaseTest):
self.multiple_choice_question(4, mentoring, controls, ("Its beauty",), PARTIAL, last=True) self.multiple_choice_question(4, mentoring, controls, ("Its beauty",), PARTIAL, last=True)
expected_results = { expected_results = {
"correct": 2, "partial": 1, "incorrect": 1, "percentage": 63, "correct": 2, "partial": 1, "incorrect": 1, "percentage": 63,
"num_attempts": 1, "max_attempts": 2} "num_attempts": 1, "max_attempts": 2
}
self.peek_at_review(mentoring, controls, expected_results) self.peek_at_review(mentoring, controls, expected_results)
self.assert_clickable(controls.try_again) self.assert_clickable(controls.try_again)
controls.try_again.click() controls.try_again.click()
self.freeform_answer(1, mentoring, controls, 'This is a different answer', CORRECT, self.freeform_answer(
saved_value='This is the answer') 1, mentoring, controls, 'This is a different answer', CORRECT, saved_value='This is the answer'
)
self.single_choice_question(2, mentoring, controls, 'Yes', CORRECT) self.single_choice_question(2, mentoring, controls, 'Yes', CORRECT)
self.rating_question(3, mentoring, controls, "1 - Not good at all", INCORRECT) self.rating_question(3, mentoring, controls, "1 - Not good at all", INCORRECT)
user_selection = ("Its elegance", "Its beauty", "Its gracefulness") user_selection = ("Its elegance", "Its beauty", "Its gracefulness")
self.multiple_choice_question(4, mentoring, controls, user_selection, CORRECT, last=True) self.multiple_choice_question(4, mentoring, controls, user_selection, CORRECT, last=True)
expected_results = { expected_results = {
"correct": 3, "partial": 0, "incorrect": 1, "percentage": 75, "correct": 3, "partial": 0, "incorrect": 1, "percentage": 75,
"num_attempts": 2, "max_attempts": 2} "num_attempts": 2, "max_attempts": 2
}
self.peek_at_review(mentoring, controls, expected_results) self.peek_at_review(mentoring, controls, expected_results)
self.assert_disabled(controls.try_again) self.assert_disabled(controls.try_again)
...@@ -332,7 +329,8 @@ class MentoringAssessmentTest(MentoringBaseTest): ...@@ -332,7 +329,8 @@ class MentoringAssessmentTest(MentoringBaseTest):
expected_results = { expected_results = {
"correct": 0, "partial": 0, "incorrect": 1, "percentage": 0, "correct": 0, "partial": 0, "incorrect": 1, "percentage": 0,
"num_attempts": 1, "max_attempts": 2} "num_attempts": 1, "max_attempts": 2
}
self.peek_at_review(mentoring, controls, expected_results) self.peek_at_review(mentoring, controls, expected_results)
......
...@@ -16,16 +16,16 @@ class TestFieldMigration(unittest.TestCase): ...@@ -16,16 +16,16 @@ class TestFieldMigration(unittest.TestCase):
""" """
# Instantiate a mentoring block with the old format # Instantiate a mentoring block with the old format
student_results = [ student_results = [
[ u'goal', [u'goal',
{ u'completed': True, {u'completed': True,
u'score': 1, u'score': 1,
u'student_input': u'test', u'student_input': u'test',
u'weight': 1}], u'weight': 1}],
[ u'mcq_1_1', [u'mcq_1_1',
{ u'completed': False, {u'completed': False,
u'score': 0, u'score': 0,
u'submission': u'maybenot', u'submission': u'maybenot',
u'weight': 1}], u'weight': 1}],
] ]
mentoring = MentoringBlock(MagicMock(), DictFieldData({'student_results': student_results}), Mock()) mentoring = MentoringBlock(MagicMock(), DictFieldData({'student_results': student_results}), Mock())
self.assertEqual(copy.deepcopy(student_results), mentoring.student_results) self.assertEqual(copy.deepcopy(student_results), mentoring.student_results)
......
[REPORTS]
reports=no
include-ids=yes
[FORMAT]
max-line-length=120
[MESSAGES CONTROL]
disable=invalid-name
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