Commit aba4abd5 by Andy Armstrong

Miscellaneous small improvements

* Bump version numbers
* Introduce JSCS style validation
* Address style failures
parent 582a4a4f
{
"preset": "google",
// edX specific rules
"validateIndentation": 4,
"maximumLineLength": 120,
"disallowMultipleVarDecl": false,
"requireCamelCaseOrUpperCaseIdentifiers": {"ignoreProperties": true},
// Temporary overrides until we clean up further...
"validateQuoteMarks": null, // We should standardize on single quotes
"disallowKeywordsOnNewLine": [] // Other repos disallow lines starting with "else"
}
......@@ -14,7 +14,6 @@
"forin" : true, // Requires all for in loops to filter object's items.
"freeze" : true, // Prohibits overwriting prototypes of native objects such as Array, Date and so on.
"immed" : true, // Prohibits the use of immediate function invocations without wrapping them in parentheses.
// "indent" : 4, // Enforces specific tab width for your code. Has no effect when "white" option is not used.
"latedef" : "nofunc", // Prohibits the use of a variable before it was defined. Setting this option to "nofunc" will allow function declarations to be ignored.
"newcap" : true, // Requires you to capitalize names of constructor functions.
"noarg" : true, // Prohibits the use of arguments.caller and arguments.callee.
......@@ -27,11 +26,6 @@
"unused" : true, // Warns when you define and never use your variables.
"strict" : false, // Requires all functions to run in ECMAScript 5's strict mode.
"trailing" : true, // Makes it an error to leave a trailing whitespace in your code.
"maxlen" : 120, // Lets you set the maximum length of a line.
//"maxparams" : 4, // Lets you set the max number of formal parameters allowed per function.
//"maxdepth" : 4, // Lets you control how nested do you want your blocks to be.
//"maxstatements" : 4, // Lets you set the max number of statements allowed per function.
//"maxcomplexity" : 4, // Lets you control cyclomatic complexity throughout your code.
// == Relaxing Options ================================================
......
......@@ -21,7 +21,6 @@ install-python:
./scripts/install-python.sh
install-js:
npm config set loglevel warn
npm install
install-nltk-data:
......@@ -43,6 +42,7 @@ install-test:
pip install -q -r requirements/test.txt
install-sys-requirements: install-system install-node
npm config set loglevel warn
install-dev:
gem install sass
......@@ -52,9 +52,12 @@ install: install-wheels install-python install-js install-nltk-data install-test
quality:
jshint openassessment/xblock/static/js/src -c .jshintrc --verbose
./node_modules/jscs/bin/jscs openassessment/xblock/static/js/src --verbose
test: quality
./scripts/test.sh
test: quality test-python test-js
test-python:
./scripts/test-python.sh
render-templates:
./scripts/render-templates.sh
......@@ -65,6 +68,8 @@ test-js: render-templates
test-js-debug: render-templates
./scripts/js-debugger.sh
test-sandbox: test-acceptance test-a11y
test-acceptance:
./scripts/test-acceptance.sh tests
......
......@@ -2,7 +2,7 @@
Tests for the Openassessment Container Object.
**/
describe("OpenAssessment.Container", function () {
describe("OpenAssessment.Container", function() {
var counter = 0;
var StubContainerItem = function(element) {
......@@ -38,7 +38,7 @@ describe("OpenAssessment.Container", function () {
);
};
beforeEach(function () {
beforeEach(function() {
// Reset the counter before each test
counter = 0;
......
......@@ -174,7 +174,7 @@ describe("OpenAssessment edit assessment views", function() {
});
it("enables and disables", function() { testEnableAndDisable(view); });
it("loads a description", function () {
it("loads a description", function() {
// This assumes a particular structure of the DOM,
// which is set by the HTML fixture.
expect(view.description()).toEqual({
......@@ -192,7 +192,7 @@ describe("OpenAssessment edit assessment views", function() {
});
});
it("modifies a description", function () {
it("modifies a description", function() {
view.exampleContainer.add();
expect(view.description()).toEqual({
examples: [
......
......@@ -429,7 +429,7 @@ describe("OpenAssessment.StudentTrainingListenerWithTrainingExamples", function(
});
it("adds a criterion and an option, then adds a training example", function (){
it("adds a criterion and an option, then adds a training example", function(){
// Initial state, set by the fixture
assertExampleLabels(
listener.examplesOptionsLabels(),
......
......@@ -208,7 +208,7 @@ describe("OpenAssessment.EditRubricView", function() {
});
});
it("validates option points", function () {
it("validates option points", function() {
// Test that a particular value is marked as valid/invalid
var testValidateOptionPoints = function(value, isValid) {
var option = view.getOptionItem(0, 0);
......
......@@ -27,7 +27,6 @@ OpenAssessment.BaseView = function(runtime, element, server, data) {
this.staffAreaView = new OpenAssessment.StaffAreaView(this.element, this.server, this);
};
OpenAssessment.BaseView.prototype = {
/**
......@@ -39,7 +38,7 @@ OpenAssessment.BaseView.prototype = {
*/
scrollToTop: function() {
if ($.scrollTo instanceof Function) {
$(window).scrollTo($("#openassessment__steps", this.element), 800, {offset:-50});
$(window).scrollTo($("#openassessment__steps", this.element), 800, {offset: -50});
}
},
......@@ -49,8 +48,8 @@ OpenAssessment.BaseView.prototype = {
Args:
parentSel (JQuery selector): CSS selector for the container element.
**/
setUpCollapseExpand: function (parentSel) {
parentSel.on('click', '.ui-toggle-visibility__control', function (eventData) {
setUpCollapseExpand: function(parentSel) {
parentSel.on('click', '.ui-toggle-visibility__control', function(eventData) {
var sel = $(eventData.target).closest('.ui-toggle-visibility');
sel.toggleClass('is--collapsed');
}
......
......@@ -15,7 +15,6 @@ OpenAssessment.GradeView = function(element, server, baseView) {
this.baseView = baseView;
};
OpenAssessment.GradeView.prototype = {
/**
Load the grade view.
......
......@@ -15,7 +15,6 @@ OpenAssessment.LeaderboardView = function(element, server, baseView) {
this.baseView = baseView;
};
OpenAssessment.LeaderboardView.prototype = {
/**
Load the leaderboard view.
......@@ -32,5 +31,5 @@ OpenAssessment.LeaderboardView.prototype = {
).fail(function(errMsg) {
baseView.showLoadError('leaderboard', errMsg);
});
},
}
};
......@@ -31,5 +31,5 @@ OpenAssessment.MessageView.prototype = {
).fail(function(errMsg) {
baseView.showLoadError('message', errMsg);
});
}
}
};
......@@ -16,7 +16,6 @@ OpenAssessment.PeerView = function(element, server, baseView) {
this.rubric = null;
};
OpenAssessment.PeerView.prototype = {
/**
......@@ -184,7 +183,7 @@ OpenAssessment.PeerView.prototype = {
Common peer assessment request building, used for all types of peer assessments.
Args:
successFunction (function): The function called if the request is
successfunction(function): The function called if the request is
successful. This varies based on the type of request to submit
a peer assessment.
......
......@@ -11,7 +11,6 @@ OpenAssessment.Rubric = function(element) {
this.element = element;
};
OpenAssessment.Rubric.prototype = {
/**
Get or set per-criterion feedback.
......
......@@ -16,7 +16,6 @@ OpenAssessment.SelfView = function(element, server, baseView) {
this.rubric = null;
};
OpenAssessment.SelfView.prototype = {
/**
......
......@@ -52,15 +52,15 @@
loadStudentInfo: function() {
var view = this;
var sel = $('#openassessment__staff-tools', this.element);
var student_username = sel.find('#openassessment__student_username').val();
this.server.studentInfo(student_username).done(
var studentUsername = sel.find('#openassessment__student_username').val();
this.server.studentInfo(studentUsername).done(
function(html) {
// Load the HTML and install event handlers
$('#openassessment__student-info', view.element).replaceWith(html);
// Install key handler for new staff grade Save button.
var selCancelSub = $('#openassessment__staff-info__cancel__submission', view.element);
selCancelSub.on('click', '#submit_cancel_submission', function (eventObject) {
selCancelSub.on('click', '#submit_cancel_submission', function(eventObject) {
eventObject.preventDefault();
view.cancelSubmission($(this).data('submission-uuid'));
}
......
......@@ -16,7 +16,6 @@ OpenAssessment.StudentTrainingView = function(element, server, baseView) {
this.rubric = null;
};
OpenAssessment.StudentTrainingView.prototype = {
/**
......
/**
JavaScript shared between all open assessment modules.
WARNING: Don't add anything to this file until you're
absolutely sure there isn't a way to encapsulate it in
an object!
**/
JavaScript shared between all open assessment modules.
WARNING: Don't add anything to this file until you're
absolutely sure there isn't a way to encapsulate it in
an object!
**/
/* Namespace for open assessment */
/* jshint ignore:start */
......@@ -14,25 +13,22 @@ if (typeof OpenAssessment == "undefined" || !OpenAssessment) {
}
/* jshint ignore:end */
// Stub gettext if the runtime doesn't provide it
if (typeof window.gettext === 'undefined') {
window.gettext = function(text) { return text; };
}
// If ngettext isn't found (workbench, testing, etc.), return the simplistic english version
if (typeof window.ngetgext === 'undefined') {
window.ngettext = function (singular_text, plural_text, n) {
window.ngettext = function(singularText, pluralText, n) {
if (n > 1) {
return plural_text;
return pluralText;
} else {
return singular_text;
return singularText;
}
};
}
// Stub event logging if the runtime doesn't provide it
if (typeof window.Logger === 'undefined') {
window.Logger = {
......@@ -40,7 +36,6 @@ if (typeof window.Logger === 'undefined') {
};
}
// Stub MathJax is the runtime doesn't provide it
if (typeof window.MathJax === 'undefined') {
window.MathJax = {
......@@ -49,4 +44,4 @@ if (typeof window.MathJax === 'undefined') {
Queue: function() {}
}
};
}
\ No newline at end of file
}
......@@ -92,7 +92,7 @@ OpenAssessment.Container.prototype = {
// Find items already in the container and install click
// handlers for the delete buttons.
$("." + this.removeButtonClass, this.containerElement).click(
function (eventData) {
function(eventData) {
var item = container.createContainerItem(eventData.target);
container.remove(item);
}
......@@ -137,7 +137,7 @@ OpenAssessment.Container.prototype = {
// Install a click handler for the delete button
if (this.addRemoveEnabled) {
containerItem.find('.' + this.removeButtonClass)
.click(function (eventData) {
.click(function(eventData) {
var containerItem = container.createContainerItem(eventData.target);
container.remove(containerItem);
});
......@@ -176,7 +176,7 @@ OpenAssessment.Container.prototype = {
array: The values representing each container item.
**/
getItemValues: function () {
getItemValues: function() {
var values = [];
var container = this;
......
......@@ -3,14 +3,14 @@
The constructor initializes the DOM for editing.
Args:
runtime (Runtime): an XBlock runtime instance.
element (DOM element): The DOM element representing this XBlock.
server (OpenAssessment.Server): The interface to the XBlock server.
data (Object literal): The data object passed from XBlock backend.
runtime (Runtime): an XBlock runtime instance.
element (DOM element): The DOM element representing this XBlock.
server (OpenAssessment.Server): The interface to the XBlock server.
data (Object literal): The data object passed from XBlock backend.
Returns:
OpenAssessment.StudioView
**/
OpenAssessment.StudioView
**/
OpenAssessment.StudioView = function(runtime, element, server, data) {
this.element = element;
......@@ -63,7 +63,7 @@ OpenAssessment.StudioView = function(runtime, element, server, data) {
// Initialize the rubric tab view
this.rubricView = new OpenAssessment.EditRubricView(
$("#oa_rubric_editor_wrapper", this.element).get(0),
new OpenAssessment.Notifier([
new OpenAssessment.Notifier([
studentTrainingListener
])
);
......@@ -76,9 +76,9 @@ OpenAssessment.StudioView = function(runtime, element, server, data) {
OpenAssessment.StudioView.prototype = {
/**
Adjusts the modal's height, position and padding to be larger for OA editing only (Does not impact other modals)
**/
fixModalHeight: function () {
Adjusts the modal's height, position and padding to be larger for OA editing only (Does not impact other modals)
**/
fixModalHeight: function() {
// Add the full height class to every element from the XBlock
// to the modal window in Studio.
$(this.element)
......@@ -93,14 +93,14 @@ OpenAssessment.StudioView.prototype = {
},
/**
Initializes the tabs that seperate the sections of the editor.
Initializes the tabs that seperate the sections of the editor.
Because this function relies on the OpenAssessment Name space, the tab that it first
active will be the one that the USER was presented with, regardless of which editor they
were using. I.E. If I leave Editor A in the settings state, and enter editor B, editor B
will automatically open with the settings state.
Because this function relies on the OpenAssessment Name space, the tab that it first
active will be the one that the USER was presented with, regardless of which editor they
were using. I.E. If I leave Editor A in the settings state, and enter editor B, editor B
will automatically open with the settings state.
**/
**/
initializeTabs: function() {
// If this is the first editor that the user has opened, default to the prompt view.
if (typeof(OpenAssessment.lastOpenEditingTab) === "undefined") {
......@@ -124,10 +124,10 @@ OpenAssessment.StudioView.prototype = {
},
/**
Save the problem's XML definition to the server.
If the problem has been released, make the user confirm the save.
**/
save: function () {
Save the problem's XML definition to the server.
If the problem has been released, make the user confirm the save.
**/
save: function() {
var view = this;
this.saveTabState();
......@@ -154,7 +154,7 @@ OpenAssessment.StudioView.prototype = {
// Check whether the problem has been released; if not,
// warn the user and allow them to cancel.
this.server.checkReleased().done(
function (isReleased) {
function(isReleased) {
if (isReleased) {
view.confirmPostReleaseUpdate($.proxy(view.updateEditorContext, view));
}
......@@ -162,30 +162,30 @@ OpenAssessment.StudioView.prototype = {
view.updateEditorContext();
}
}
).fail(function (errMsg) {
).fail(function(errMsg) {
view.showError(errMsg);
});
}
},
/**
Make the user confirm that he/she wants to update a problem
that has already been released.
Args:
onConfirm (function): A function that accepts no arguments,
executed if the user confirms the update.
**/
confirmPostReleaseUpdate: function (onConfirm) {
Make the user confirm that he/she wants to update a problem
that has already been released.
Args:
onConfirm (function): A function that accepts no arguments,
executed if the user confirms the update.
**/
confirmPostReleaseUpdate: function(onConfirm) {
var msg = gettext("This problem has already been released. Any changes will apply only to future assessments.");
// TODO: classier confirm dialog
if (confirm(msg)) { onConfirm(); }
},
/**
Save the updated problem definition to the server.
**/
updateEditorContext: function () {
Save the updated problem definition to the server.
**/
updateEditorContext: function() {
// Notify the client-side runtime that we are starting
// to save so it can show the "Saving..." notification
this.runtime.notify('save', {state: 'start'});
......@@ -209,16 +209,16 @@ OpenAssessment.StudioView.prototype = {
// Notify the client-side runtime that we finished saving
// so it can hide the "Saving..." notification.
// Then reload the view.
function () { view.runtime.notify('save', {state: 'end'}); }
function() { view.runtime.notify('save', {state: 'end'}); }
).fail(
function (msg) { view.showError(msg); }
function(msg) { view.showError(msg); }
);
},
/**
Cancel editing.
**/
cancel: function () {
Cancel editing.
**/
cancel: function() {
// Notify the client-side runtime so it will close the editing modal
this.saveTabState();
this.runtime.notify('cancel', {});
......@@ -228,19 +228,19 @@ OpenAssessment.StudioView.prototype = {
Display an error message to the user.
Args:
errorMsg (string): The error message to display.
errorMsg (string): The error message to display.
**/
showError: function (errorMsg) {
showError: function(errorMsg) {
this.runtime.notify('error', {msg: errorMsg});
},
/**
Mark validation errors.
Mark validation errors.
Returns:
Boolean indicating whether the view is valid.
Returns:
Boolean indicating whether the view is valid.
**/
**/
validate: function() {
var settingsValid = this.settingsView.validate();
var rubricValid = this.rubricView.validate();
......@@ -248,14 +248,14 @@ OpenAssessment.StudioView.prototype = {
return settingsValid && rubricValid && promptsValid;
},
/**
Return a list of validation errors visible in the UI.
Mainly useful for testing.
/**
Return a list of validation errors visible in the UI.
Mainly useful for testing.
Returns:
list of string
Returns:
list of string
**/
**/
validationErrors: function() {
return this.settingsView.validationErrors().concat(
this.rubricView.validationErrors().concat(
......@@ -265,23 +265,22 @@ OpenAssessment.StudioView.prototype = {
},
/**
Clear all validation errors from the UI.
**/
Clear all validation errors from the UI.
**/
clearValidationErrors: function() {
this.settingsView.clearValidationErrors();
this.rubricView.clearValidationErrors();
this.promptsView.clearValidationErrors();
},
}
};
/* XBlock entry point for Studio view */
/* jshint unused:false */
function OpenAssessmentEditor(runtime, element, data) {
/**
Initialize the editing interface on page load.
**/
Initialize the editing interface on page load.
**/
var server = new OpenAssessment.Server(runtime, element);
new OpenAssessment.StudioView(runtime, element, server, data);
}
......@@ -44,4 +44,4 @@ OpenAssessment.Notifier.prototype = {
}
}
}
};
\ No newline at end of file
};
/**
Editing interface for the prompts.
Editing interface for the prompts.
Args:
element (DOM element): The DOM element representing this view.
Args:
element (DOM element): The DOM element representing this view.
Returns:
OpenAssessment.EditPromptsView
Returns:
OpenAssessment.EditPromptsView
**/
**/
OpenAssessment.EditPromptsView = function(element, notifier) {
this.element = element;
this.editorElement = $(this.element).closest("#openassessment-editor");
......@@ -27,36 +27,35 @@ OpenAssessment.EditPromptsView = function(element, notifier) {
this.promptsContainer.addEventListeners();
};
OpenAssessment.EditPromptsView.prototype = {
/**
Construct a list of prompts definitions from the editor UI.
Returns:
list of prompt objects
Example usage:
>>> editPromptsView.promptsDefinition();
[
{
uuid: "cfvgbh657",
description: "Description",
order_num: 0,
},
...
]
**/
Construct a list of prompts definitions from the editor UI.
Returns:
list of prompt objects
Example usage:
>>> editPromptsView.promptsDefinition();
[
{
uuid: "cfvgbh657",
description: "Description",
order_num: 0,
},
...
]
**/
promptsDefinition: function() {
var prompts = this.promptsContainer.getItemValues();
return prompts;
},
/**
Add a new prompt.
Uses a client-side template to create the new prompt.
**/
Add a new prompt.
Uses a client-side template to create the new prompt.
**/
addPrompt: function() {
if (this.addRemoveEnabled) {
this.promptsContainer.add();
......@@ -64,11 +63,11 @@ OpenAssessment.EditPromptsView.prototype = {
},
/**
Remove a prompt.
Remove a prompt.
Args:
item (OpenAssessment.RubricCriterion): The criterion item to remove.
**/
Args:
item (OpenAssessment.RubricCriterion): The criterion item to remove.
**/
removePrompt: function(item) {
if (this.addRemoveEnabled) {
this.promptsContainer.remove(item);
......@@ -76,56 +75,56 @@ OpenAssessment.EditPromptsView.prototype = {
},
/**
Retrieve all prompts.
Retrieve all prompts.
Returns:
Array of OpenAssessment.Prompt objects.
Returns:
Array of OpenAssessment.Prompt objects.
**/
**/
getAllPrompts: function() {
return this.promptsContainer.getAllItems();
},
/**
Retrieve a prompt item from the prompts.
Retrieve a prompt item from the prompts.
Args:
index (int): The index of the prompt, starting from 0.
Args:
index (int): The index of the prompt, starting from 0.
Returns:
OpenAssessment.Prompt or null
Returns:
OpenAssessment.Prompt or null
**/
**/
getPromptItem: function(index) {
return this.promptsContainer.getItem(index);
},
/**
Mark validation errors.
Mark validation errors.
Returns:
Boolean indicating whether the view is valid.
Returns:
Boolean indicating whether the view is valid.
**/
**/
validate: function() {
return true;
},
/**
Return a list of validation errors visible in the UI.
Mainly useful for testing.
/**
Return a list of validation errors visible in the UI.
Mainly useful for testing.
Returns:
list of string
Returns:
list of string
**/
**/
validationErrors: function() {
var errors = [];
return errors;
},
/**
Clear all validation errors from the UI.
**/
Clear all validation errors from the UI.
**/
clearValidationErrors: function() {}
};
\ No newline at end of file
};
......@@ -38,7 +38,7 @@ OpenAssessment.EditSettingsView = function(element, assessmentViews, data) {
this.leaderboardIntField = new OpenAssessment.IntField(
$("#openassessment_leaderboard_editor", this.element),
{ min: 0, max: 100 }
{min: 0, max: 100}
);
this.fileTypeWhiteListInputField = new OpenAssessment.InputControl(
......@@ -67,13 +67,12 @@ OpenAssessment.EditSettingsView = function(element, assessmentViews, data) {
this.initializeSortableAssessments();
};
OpenAssessment.EditSettingsView.prototype = {
/**
Installs click listeners which initialize drag and drop functionality for assessment modules.
**/
initializeSortableAssessments: function () {
initializeSortableAssessments: function() {
var view = this;
// Initialize Drag and Drop of Assessment Modules
$('#openassessment_assessment_module_settings_editors', view.element).sortable({
......@@ -255,7 +254,7 @@ OpenAssessment.EditSettingsView.prototype = {
// Find all assessment modules within our element in the DOM,
// and append their definitions to the description
$('.openassessment_assessment_module_settings_editor', this.assessmentsElement).each(
function () {
function() {
var asmntView = view.assessmentViews[$(this).attr('id')];
if (asmntView.isEnabled()) {
var description = asmntView.description();
......@@ -280,7 +279,7 @@ OpenAssessment.EditSettingsView.prototype = {
var editorAssessments = [];
var view = this;
$('.openassessment_assessment_module_settings_editor', this.assessmentsElement).each(
function () {
function() {
var asmntView = view.assessmentViews[$(this).attr('id')];
editorAssessments.push(asmntView.name);
}
......
......@@ -48,7 +48,7 @@ OpenAssessment.ValidationAlert.prototype = {
'border-top-left-radius': '3px'
};
$('.oa_editor_content_wrapper', this.editorElement).each( function () {
$('.oa_editor_content_wrapper', this.editorElement).each(function() {
$(this).css(styles);
});
......@@ -61,12 +61,12 @@ OpenAssessment.ValidationAlert.prototype = {
Returns:
OpenAssessment.ValidationAlert
*/
show : function() {
show: function() {
var view = this;
if (this.isVisible()){
if (this.isVisible()) {
$(this.element).animate(
{'background-color': view.ALERT_YELLOW}, 300, 'swing', function () {
{'background-color': view.ALERT_YELLOW}, 300, 'swing', function() {
$(this).animate({'background-color': view.DARK_GREY}, 700, 'swing');
}
);
......@@ -84,7 +84,7 @@ OpenAssessment.ValidationAlert.prototype = {
'border-top-left-radius': '0px'
};
$('.oa_editor_content_wrapper', this.editorElement).each(function () {
$('.oa_editor_content_wrapper', this.editorElement).each(function() {
$(this).css(styles);
});
......
......@@ -16,7 +16,8 @@
"phantomjs": "^1.9.11",
"sinon": "^1.10.3",
"uglify-js": "2.3.6",
"jshint": "2.8.0"
"jshint": "2.8.0",
"jscs": "2.6.0"
},
"scripts": {
"test": "./node_modules/karma/bin/karma start --reporters spec,coverage"
......
......@@ -6,7 +6,7 @@
git+https://github.com/edx/XBlock.git@xblock-0.4.1#egg=XBlock==0.4.1
# edx-submissions
git+https://github.com/edx/edx-submissions.git@0.1.2#egg=edx-submissions==0.1.2
git+https://github.com/edx/edx-submissions.git@0.1.3#egg=edx-submissions==0.1.3
# Third Party Requirements
boto>=2.32.1,<3.0.0
......
-r base.txt
-r test-acceptance.txt
coverage==3.7.1
coverage==4.0.2
django-nose==1.4.1
mock==1.0.1
moto==0.2.22
pep8==1.5.7
moto==0.3.1
pep8==1.6.2
pylint<1.0
git+https://github.com/edx/django-pyfs.git@1.0.3#egg=django-pyfs==1.0.3
......
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