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);
});
},
}
};
......@@ -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.
......
/**
Interface for response (submission) view.
Interface for response (submission) view.
Args:
Args:
element (DOM element): The DOM element representing the XBlock.
server (OpenAssessment.Server): The interface to the XBlock server.
fileUploader (OpenAssessment.FileUploader): File uploader instance.
baseView (OpenAssessment.BaseView): Container view.
data (Object): The data object passed from XBlock backend.
Returns:
Returns:
OpenAssessment.ResponseView
**/
**/
OpenAssessment.ResponseView = function(element, server, fileUploader, baseView, data) {
this.element = element;
this.server = server;
......@@ -26,7 +26,6 @@ OpenAssessment.ResponseView = function(element, server, fileUploader, baseView,
this.fileUploaded = false;
};
OpenAssessment.ResponseView.prototype = {
// Milliseconds between checks for whether we should autosave.
......@@ -104,13 +103,13 @@ OpenAssessment.ResponseView.prototype = {
function(eventObject) {
eventObject.preventDefault();
// extract typed-in response and replace newline with br
var preview_text = sel.find('.submission__answer__part__text__value').val();
var preview_container = sel.find('#preview_content');
preview_container.html(preview_text.replace(/\r\n|\r|\n/g,"<br />"));
var previewText = sel.find('.submission__answer__part__text__value').val();
var previewContainer = sel.find('#preview_content');
previewContainer.html(previewText.replace(/\r\n|\r|\n/g,"<br />"));
// Render in mathjax
sel.find('#submission__preview__item').show();
MathJax.Hub.Queue(['Typeset', MathJax.Hub, preview_container[0]]);
MathJax.Hub.Queue(['Typeset', MathJax.Hub, previewContainer[0]]);
}
);
......@@ -256,8 +255,7 @@ OpenAssessment.ResponseView.prototype = {
if (enabled) {
window.onbeforeunload = function() {
// Keep this on one big line to avoid gettext bug: http://stackoverflow.com/a/24579117
/* jshint maxlen:300 */
return gettext("If you leave this page without saving or submitting your response, you'll lose any work you've done on the response.");
return gettext("If you leave this page without saving or submitting your response, you'll lose any work you've done on the response."); // jscs:ignore maximumLineLength
};
}
else {
......@@ -409,7 +407,7 @@ OpenAssessment.ResponseView.prototype = {
// check if there is a file selected but not uploaded yet
if (view.files !== null && !view.fileUploaded) {
var msg = gettext('Do you want to upload your file before submitting?');
if(confirm(msg)) {
if (confirm(msg)) {
fileDefer = view.fileUpload();
} else {
view.submitEnabled(true);
......@@ -477,8 +475,7 @@ OpenAssessment.ResponseView.prototype = {
**/
confirmSubmission: function() {
// Keep this on one big line to avoid gettext bug: http://stackoverflow.com/a/24579117
/* jshint maxlen:300 */
var msg = gettext("You're about to submit your response for this assignment. After you submit this response, you can't change it or submit a new response.");
var msg = gettext("You're about to submit your response for this assignment. After you submit this response, you can't change it or submit a new response."); // jscs:ignore maximumLineLength
// TODO -- UI for confirmation dialog instead of JS confirm
return $.Deferred(function(defer) {
if (confirm(msg)) { defer.resolve(); }
......@@ -536,7 +533,6 @@ OpenAssessment.ResponseView.prototype = {
$("#file__upload").toggleClass("is--disabled", this.files === null);
},
/**
Manages file uploads for submission attachments. Retrieves a one-time
upload URL from the server, and uses it to upload images to a designated
......
......@@ -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 = {
/**
......
/**
Encapsulate interactions with OpenAssessment XBlock handlers.
**/
Encapsulate interactions with OpenAssessment XBlock handlers.
**/
// Since the server is included by both LMS and Studio views,
// skip loading it the second time.
......@@ -118,14 +118,14 @@ if (typeof OpenAssessment.Server === "undefined" || !OpenAssessment.Server) {
/**
Load the Student Info section in Staff Info.
**/
studentInfo: function(student_username) {
studentInfo: function(studentUsername) {
var url = this.url('render_student_info');
return $.Deferred(function(defer) {
$.ajax({
url: url,
type: "POST",
dataType: "html",
data: {student_username: student_username}
data: {student_username: studentUsername}
}).done(function(data) {
defer.resolveWith(this, [data]);
}).fail(function() {
......@@ -223,7 +223,7 @@ if (typeof OpenAssessment.Server === "undefined" || !OpenAssessment.Server) {
'feedback_options': options
});
return $.Deferred(function(defer) {
$.ajax({ type: "POST", url: url, data: payload, contentType: jsonContentType }).done(
$.ajax({type: "POST", url: url, data: payload, contentType: jsonContentType}).done(
function(data) {
if (data.success) { defer.resolve(); }
else { defer.rejectWith(this, [data.msg]); }
......@@ -266,7 +266,7 @@ if (typeof OpenAssessment.Server === "undefined" || !OpenAssessment.Server) {
submission_uuid: uuid
});
return $.Deferred(function(defer) {
$.ajax({ type: "POST", url: url, data: payload, contentType: jsonContentType }).done(
$.ajax({type: "POST", url: url, data: payload, contentType: jsonContentType}).done(
function(data) {
if (data.success) {
defer.resolve();
......@@ -310,7 +310,7 @@ if (typeof OpenAssessment.Server === "undefined" || !OpenAssessment.Server) {
overall_feedback: overallFeedback
});
return $.Deferred(function(defer) {
$.ajax({ type: "POST", url: url, data: payload, contentType: jsonContentType }).done(
$.ajax({type: "POST", url: url, data: payload, contentType: jsonContentType}).done(
function(data) {
if (data.success) {
defer.resolve();
......@@ -351,7 +351,7 @@ if (typeof OpenAssessment.Server === "undefined" || !OpenAssessment.Server) {
options_selected: optionsSelected
});
return $.Deferred(function(defer) {
$.ajax({ type: "POST", url: url, data: payload, contentType: jsonContentType }).done(
$.ajax({type: "POST", url: url, data: payload, contentType: jsonContentType}).done(
function(data) {
if (data.success) {
defer.resolveWith(this, [data.corrections]);
......@@ -385,7 +385,7 @@ if (typeof OpenAssessment.Server === "undefined" || !OpenAssessment.Server) {
scheduleTraining: function() {
var url = this.url('schedule_training');
return $.Deferred(function(defer) {
$.ajax({ type: "POST", url: url, data: "\"\"", contentType: jsonContentType}).done(
$.ajax({type: "POST", url: url, data: "\"\"", contentType: jsonContentType}).done(
function(data) {
if (data.success) {
defer.resolveWith(this, [data.msg]);
......@@ -409,7 +409,7 @@ if (typeof OpenAssessment.Server === "undefined" || !OpenAssessment.Server) {
rescheduleUnfinishedTasks: function() {
var url = this.url('reschedule_unfinished_tasks');
return $.Deferred(function(defer) {
$.ajax({ type: "POST", url: url, data: "\"\"", contentType: jsonContentType}).done(
$.ajax({type: "POST", url: url, data: "\"\"", contentType: jsonContentType}).done(
function(data) {
if (data.success) {
defer.resolveWith(this, [data.msg]);
......@@ -563,14 +563,14 @@ if (typeof OpenAssessment.Server === "undefined" || !OpenAssessment.Server) {
submissionUUID: ID for submission to be cancelled from pool.
comments: reason to cancel the submission
         **/
cancelSubmission: function (submissionUUID, comments) {
cancelSubmission: function(submissionUUID, comments) {
var url = this.url('cancel_submission');
var payload = JSON.stringify({
submission_uuid: submissionUUID,
comments: comments
});
return $.Deferred(function (defer) {
$.ajax({ type: "POST", url: url, data: payload, contentType: jsonContentType }).done(
return $.Deferred(function(defer) {
$.ajax({type: "POST", url: url, data: payload, contentType: jsonContentType}).done(
function(data) {
if (data.success) {
defer.resolveWith(this, [data.msg]);
......
/**
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 = {
......
......@@ -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;
......
......@@ -35,7 +35,7 @@ OpenAssessment.ItemUtilities = {
var label = $(element).attr('data-label');
var name = $(element).val();
// We don't want the lack of a label to make it look like - 1 points.
if (label === ""){
if (label === "") {
label = gettext('Unnamed Option');
}
var singularString = label + " - " + points + " point";
......@@ -65,16 +65,16 @@ OpenAssessment.ItemUtilities = {
};
/**
The Prompt Class is used to construct and maintain references to prompts from within a prompts
container object. Constructs a new Prompt element.
The Prompt Class is used to construct and maintain references to prompts from within a prompts
container object. Constructs a new Prompt element.
Args:
Args:
element (OpenAssessment.Container): The container that the prompt is a member of.
notifier (OpenAssessment.Notifier): Used to send notifications of updates to prompts.
Returns:
Returns:
OpenAssessment.Prompt
**/
**/
OpenAssessment.Prompt = function(element, notifier) {
this.element = element;
this.notifier = notifier;
......@@ -90,7 +90,7 @@ OpenAssessment.Prompt.prototype = {
'description': 'Write a nice long essay about anything.'
}
**/
getFieldValues: function () {
getFieldValues: function() {
var fields = {
description: this.description()
};
......@@ -118,7 +118,7 @@ OpenAssessment.Prompt.prototype = {
Hook into the event handler for addition of a prompt.
*/
addHandler: function (){
addHandler: function() {
this.notifier.notificationFired(
"promptAdd",
{
......@@ -131,7 +131,7 @@ OpenAssessment.Prompt.prototype = {
Hook into the event handler for removal of a prompt.
*/
removeHandler: function (){
removeHandler: function() {
this.notifier.notificationFired(
"promptRemove",
{
......@@ -172,22 +172,22 @@ OpenAssessment.Prompt.prototype = {
};
/**
The RubricOption Class used to construct and maintain references to rubric options from within an options
container object. Constructs a new RubricOption element.
The RubricOption Class used to construct and maintain references to rubric options from within an options
container object. Constructs a new RubricOption element.
Args:
Args:
element (OpenAssessment.Container): The container that the option is a member of.
notifier (OpenAssessment.Notifier): Used to send notifications of updates to rubric options.
Returns:
Returns:
OpenAssessment.RubricOption
**/
**/
OpenAssessment.RubricOption = function(element, notifier) {
this.element = element;
this.notifier = notifier;
this.pointsField = new OpenAssessment.IntField(
$(".openassessment_criterion_option_points", this.element),
{ min: 0, max: 999 }
{min: 0, max: 999}
);
};
......@@ -211,7 +211,7 @@ OpenAssessment.RubricOption.prototype = {
'explanation': 'Essay was primarily composed of emojis.'
}
**/
getFieldValues: function () {
getFieldValues: function() {
var fields = {
label: this.label(),
points: this.points(),
......@@ -278,7 +278,7 @@ OpenAssessment.RubricOption.prototype = {
Hook into the event handler for addition of a criterion option.
*/
addHandler: function (){
addHandler: function() {
var criterionElement = $(this.element).closest(".openassessment_criterion");
var criterionName = $(criterionElement).data('criterion');
......@@ -310,7 +310,7 @@ OpenAssessment.RubricOption.prototype = {
Hook into the event handler for removal of a criterion option.
*/
removeHandler: function (){
removeHandler: function() {
var criterionName = $(this.element).data('criterion');
var optionName = $(this.element).data('option');
this.notifier.notificationFired(
......@@ -327,7 +327,7 @@ OpenAssessment.RubricOption.prototype = {
modified.
*/
updateHandler: function(){
updateHandler: function() {
var fields = this.getFieldValues();
var criterionName = $(this.element).data('criterion');
var optionName = $(this.element).data('option');
......@@ -377,14 +377,14 @@ OpenAssessment.RubricOption.prototype = {
};
/**
The RubricCriterion Class is used to construct and get information from a rubric element within
the DOM.
The RubricCriterion Class is used to construct and get information from a rubric element within
the DOM.
Args:
Args:
element (JQuery Object): The selection which describes the scope of the criterion.
notifier (OpenAssessment.Notifier): Used to send notifications of updates to rubric criteria.
Returns:
Returns:
OpenAssessment.RubricCriterion
**/
OpenAssessment.RubricCriterion = function(element, notifier) {
......@@ -404,7 +404,6 @@ OpenAssessment.RubricCriterion = function(element, notifier) {
);
};
OpenAssessment.RubricCriterion.prototype = {
/**
......@@ -436,7 +435,7 @@ OpenAssessment.RubricCriterion.prototype = {
]
}
**/
getFieldValues: function () {
getFieldValues: function() {
var fields = {
label: this.label(),
prompt: this.prompt(),
......@@ -507,7 +506,7 @@ OpenAssessment.RubricCriterion.prototype = {
Hook into the event handler for addition of a criterion.
*/
addHandler: function (){
addHandler: function() {
var criteria = $(".openassessment_criterion", this.element.parent());
// Create the unique name for this option.
var name = OpenAssessment.ItemUtilities.createUniqueName(criteria, "data-criterion");
......@@ -520,7 +519,7 @@ OpenAssessment.RubricCriterion.prototype = {
Hook into the event handler for removal of a criterion.
*/
removeHandler: function(){
removeHandler: function() {
var criterionName = $(this.element).data('criterion');
this.notifier.notificationFired("criterionRemove", {'criterionName': criterionName});
},
......@@ -529,7 +528,7 @@ OpenAssessment.RubricCriterion.prototype = {
Hook into the event handler when a rubric criterion is modified.
*/
updateHandler: function(){
updateHandler: function() {
var fields = this.getFieldValues();
var criterionName = fields.name;
var criterionLabel = fields.label;
......@@ -599,7 +598,6 @@ OpenAssessment.RubricCriterion.prototype = {
}
};
/**
The TrainingExample class is used to construct and retrieve information from its element within the DOM
......@@ -610,7 +608,7 @@ OpenAssessment.RubricCriterion.prototype = {
OpenAssessment.TrainingExample
**/
OpenAssessment.TrainingExample = function(element){
OpenAssessment.TrainingExample = function(element) {
this.element = element;
this.criteria = $(".openassessment_training_example_criterion_option", this.element);
this.answer = $('.openassessment_training_example_essay_part textarea', this.element);
......@@ -620,12 +618,12 @@ OpenAssessment.TrainingExample.prototype = {
/**
Returns the values currently stored in the fields associated with this training example.
**/
getFieldValues: function () {
getFieldValues: function() {
// Iterates through all of the options selected by the training example, and adds them
// to a list.
var optionsSelected = this.criteria.map(
function () {
function() {
return {
criterion: $(this).data('criterion'),
option: $(this).prop('value')
......@@ -643,8 +641,8 @@ OpenAssessment.TrainingExample.prototype = {
addHandler: function() {
// Goes through and instantiates the option description in the training example for each option.
$(".openassessment_training_example_criterion_option", this.element) .each( function () {
$('option', this).each(function(){
$(".openassessment_training_example_criterion_option", this.element) .each(function() {
$('option', this).each(function() {
OpenAssessment.ItemUtilities.refreshOptionString($(this));
});
});
......
......@@ -10,7 +10,7 @@
Returns:
OpenAssessment.StudioView
**/
**/
OpenAssessment.StudioView = function(runtime, element, server, data) {
this.element = element;
......@@ -78,7 +78,7 @@ 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 () {
fixModalHeight: function() {
// Add the full height class to every element from the XBlock
// to the modal window in Studio.
$(this.element)
......@@ -127,7 +127,7 @@ 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: 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,7 +162,7 @@ OpenAssessment.StudioView.prototype = {
view.updateEditorContext();
}
}
).fail(function (errMsg) {
).fail(function(errMsg) {
view.showError(errMsg);
});
}
......@@ -176,7 +176,7 @@ OpenAssessment.StudioView.prototype = {
onConfirm (function): A function that accepts no arguments,
executed if the user confirms the update.
**/
confirmPostReleaseUpdate: function (onConfirm) {
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(); }
......@@ -185,7 +185,7 @@ OpenAssessment.StudioView.prototype = {
/**
Save the updated problem definition to the server.
**/
updateEditorContext: function () {
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: function() {
// Notify the client-side runtime so it will close the editing modal
this.saveTabState();
this.runtime.notify('cancel', {});
......@@ -230,7 +230,7 @@ OpenAssessment.StudioView.prototype = {
Args:
errorMsg (string): The error message to display.
**/
showError: function (errorMsg) {
showError: function(errorMsg) {
this.runtime.notify('error', {msg: errorMsg});
},
......@@ -271,10 +271,9 @@ OpenAssessment.StudioView.prototype = {
this.settingsView.clearValidationErrors();
this.rubricView.clearValidationErrors();
this.promptsView.clearValidationErrors();
},
}
};
/* XBlock entry point for Studio view */
/* jshint unused:false */
function OpenAssessmentEditor(runtime, element, data) {
......
/**
Interface for editing peer assessment settings.
Interface for editing peer assessment settings.
Args:
Args:
element (DOM element): The DOM element representing this view.
Returns:
Returns:
OpenAssessment.EditPeerAssessmentView
**/
**/
OpenAssessment.EditPeerAssessmentView = function(element) {
this.element = element;
this.name = "peer-assessment";
this.mustGradeField = new OpenAssessment.IntField(
$("#peer_assessment_must_grade", this.element),
{ min: 0, max: 99 }
{min: 0, max: 99}
);
this.mustBeGradedByField = new OpenAssessment.IntField(
$("#peer_assessment_graded_by", this.element),
{ min: 0, max: 99 }
{min: 0, max: 99}
);
// Configure the toggle checkbox to enable/disable this assessment
......@@ -192,7 +192,7 @@ OpenAssessment.EditPeerAssessmentView.prototype = {
if (this.mustGradeField.validationErrors().length > 0) {
errors.push("Peer assessment must grade is invalid");
}
if(this.mustBeGradedByField.validationErrors().length > 0) {
if (this.mustBeGradedByField.validationErrors().length > 0) {
errors.push("Peer assessment must be graded by is invalid");
}
return errors;
......@@ -209,17 +209,16 @@ OpenAssessment.EditPeerAssessmentView.prototype = {
},
};
/**
Interface for editing self assessment settings.
Interface for editing self assessment settings.
Args:
Args:
element (DOM element): The DOM element representing this view.
Returns:
Returns:
OpenAssessment.EditSelfAssessmentView
**/
**/
OpenAssessment.EditSelfAssessmentView = function(element) {
this.element = element;
this.name = "self-assessment";
......@@ -373,15 +372,15 @@ OpenAssessment.EditSelfAssessmentView.prototype = {
};
/**
Interface for editing self assessment settings.
Interface for editing self assessment settings.
Args:
Args:
element (DOM element): The DOM element representing this view.
Returns:
Returns:
OpenAssessment.EditStudentTrainingView
**/
**/
OpenAssessment.EditStudentTrainingView = function(element) {
this.element = element;
this.name = "student-training";
......@@ -527,15 +526,15 @@ OpenAssessment.EditStudentTrainingView.prototype = {
};
/**
Interface for editing example-based assessment settings.
Interface for editing example-based assessment settings.
Args:
Args:
element (DOM element): The DOM element representing this view.
Returns:
Returns:
OpenAssessment.EditExampleBasedAssessmentView
**/
**/
OpenAssessment.EditExampleBasedAssessmentView = function(element) {
this.element = element;
this.name = "example-based-assessment";
......@@ -620,5 +619,5 @@ OpenAssessment.EditExampleBasedAssessmentView.prototype = {
validate: function() { return true; },
validationErrors: function() { return []; },
clearValidationErrors: function() {},
clearValidationErrors: function() {}
};
/**
Utilities for reading / writing fields.
**/
Utilities for reading / writing fields.
**/
OpenAssessment.Fields = {
stringField: function(sel, value) {
if (value !== undefined) { sel.val(value); }
......@@ -10,21 +10,20 @@ OpenAssessment.Fields = {
booleanField: function(sel, value) {
if (value !== undefined) { sel.prop("checked", value); }
return sel.prop("checked");
},
}
};
/**
Integer input.
Integer input.
Args:
Args:
inputSel (JQuery selector or DOM element): The input field.
Keyword args:
Keyword args:
min (int): The minimum value allowed in the input.
max (int): The maximum value allowed in the input.
**/
**/
OpenAssessment.IntField = function(inputSel, restrictions) {
this.max = restrictions.max;
this.min = restrictions.min;
......@@ -100,24 +99,23 @@ OpenAssessment.IntField.prototype = {
validationErrors: function() {
var hasError = this.input.hasClass("openassessment_highlighted_field");
return hasError ? ["Int field is invalid"] : [];
},
}
};
/**
Show and hide elements based on a checkbox.
Show and hide elements based on a checkbox.
Args:
Args:
checkboxSel (JQuery selector): The checkbox used to toggle whether sections
are shown or hidden.
shownSel (JQuery selector): The section to show when the checkbox is checked.
hiddenSel (JQuery selector): The section to show when the checkbox is unchecked.
notifier (OpenAssessment.Notifier): Receives notifications when the checkbox state changes.
Sends the following notifications:
Sends the following notifications:
* toggleOn
* toggleOff
**/
**/
OpenAssessment.ToggleControl = function(checkboxSel, shownSel, hiddenSel, notifier) {
this.checkbox = checkboxSel;
this.shownSection = shownSel;
......@@ -164,16 +162,15 @@ OpenAssessment.ToggleControl.prototype = {
}
};
/**
Date and time input fields.
Date and time input fields.
Args:
Args:
element (DOM element): The parent element of the control inputs.
datePicker (string): The CSS selector for the date input field.
timePicker (string): The CSS selector for the time input field.
**/
**/
OpenAssessment.DatetimeControl = function(element, datePicker, timePicker) {
this.element = element;
this.datePicker = datePicker;
......@@ -190,7 +187,7 @@ OpenAssessment.DatetimeControl.prototype = {
**/
install: function() {
var dateString = $(this.datePicker, this.element).val();
$(this.datePicker, this.element).datepicker({ showButtonPanel: true })
$(this.datePicker, this.element).datepicker({showButtonPanel: true})
.datepicker("option", "dateFormat", "yy-mm-dd")
.datepicker("setDate", dateString);
$(this.timePicker, this.element).timepicker({
......@@ -247,7 +244,7 @@ OpenAssessment.DatetimeControl.prototype = {
//time validation
var matches = timeString.match(/^\d{2}:\d{2}$/g);
var isTimeValid = (matches !== null);
if(!isTimeValid) {
if (!isTimeValid) {
$(this.timePicker, this.element).addClass("openassessment_highlighted_field");
}
......@@ -279,10 +276,9 @@ OpenAssessment.DatetimeControl.prototype = {
if (timeHasError) { errors.push("Time is invalid"); }
return errors;
},
}
};
/**
Show and hide elements based on select options.
......
/**
Dynamically update student training examples based on
changes to the prompts or the rubric.
**/
Dynamically update student training examples based on
changes to the prompts or the rubric.
**/
OpenAssessment.StudentTrainingListener = function() {
this.element = $('#oa_student_training_editor');
this.alert = new OpenAssessment.ValidationAlert();
......@@ -93,10 +93,9 @@ OpenAssessment.StudentTrainingListener.prototype = {
});
if (criterionAdded) {
/* jshint maxlen:300 */
this.displayAlertMsg(
gettext("Criterion Added"),
gettext("You have added a criterion. You will need to select an option for the criterion in the Learner Training step. To do this, click the Settings tab.")
gettext("You have added a criterion. You will need to select an option for the criterion in the Learner Training step. To do this, click the Settings tab.") // jscs:ignore maximumLineLength
);
}
},
......@@ -141,10 +140,9 @@ OpenAssessment.StudentTrainingListener.prototype = {
});
if (invalidated) {
/* jshint maxlen:300 */
this.displayAlertMsg(
gettext("Option Deleted"),
gettext("You have deleted an option. That option has been removed from its criterion in the sample responses in the Learner Training step. You might have to select a new option for the criterion.")
gettext("You have deleted an option. That option has been removed from its criterion in the sample responses in the Learner Training step. You might have to select a new option for the criterion.") // jscs:ignore maximumLineLength
);
}
},
......@@ -177,10 +175,9 @@ OpenAssessment.StudentTrainingListener.prototype = {
});
if (changed) {
/* jshint maxlen:300 */
this.displayAlertMsg(
gettext("Option Deleted"),
gettext("You have deleted all the options for this criterion. The criterion has been removed from the sample responses in the Learner Training step.")
gettext("You have deleted all the options for this criterion. The criterion has been removed from the sample responses in the Learner Training step.") // jscs:ignore maximumLineLength
);
}
},
......@@ -205,10 +202,9 @@ OpenAssessment.StudentTrainingListener.prototype = {
);
if (changed) {
/* jshint maxlen:300 */
this.displayAlertMsg(
gettext("Criterion Deleted"),
gettext("You have deleted a criterion. The criterion has been removed from the example responses in the Learner Training step.")
gettext("You have deleted a criterion. The criterion has been removed from the example responses in the Learner Training step.") // jscs:ignore maximumLineLength
);
}
},
......@@ -365,12 +361,11 @@ OpenAssessment.StudentTrainingListener.prototype = {
}
};
/**
Show a warning when a user disables an assessment,
since any data in the disabled section won't be persisted
on save.
**/
Show a warning when a user disables an assessment,
since any data in the disabled section won't be persisted
on save.
**/
OpenAssessment.AssessmentToggleListener = function() {
this.alert = new OpenAssessment.ValidationAlert();
};
......
/**
Editing interface for the prompts.
Editing interface for the prompts.
Args:
Args:
element (DOM element): The DOM element representing this view.
Returns:
Returns:
OpenAssessment.EditPromptsView
**/
**/
OpenAssessment.EditPromptsView = function(element, notifier) {
this.element = element;
this.editorElement = $(this.element).closest("#openassessment-editor");
......@@ -27,7 +27,6 @@ OpenAssessment.EditPromptsView = function(element, notifier) {
this.promptsContainer.addEventListeners();
};
OpenAssessment.EditPromptsView.prototype = {
/**
......
/**
Interface for editing rubric definitions.
Interface for editing rubric definitions.
Args:
Args:
element (DOM element): The DOM element representing the rubric.
notifier (OpenAssessment.Notifier): Used to notify other views about updates to the rubric.
This view fires the following notification events:
This view fires the following notification events:
* optionAdd: An option was added to the rubric.
* optionRemove: An option was removed from the rubric.
* optionUpdated: An option's label and/or points were updated in the rubric.
* criterionRemove: A criterion was removed from the rubric.
* criterionUpdated: A criterion's label was updated in the rubric.
**/
**/
OpenAssessment.EditRubricView = function(element, notifier) {
this.element = element;
this.criterionAddButton = $('#openassessment_rubric_add_criterion', this.element);
......@@ -63,12 +63,12 @@ OpenAssessment.EditRubricView.prototype = {
var criteria = this.criteriaContainer.getItemValues();
// Add order_num fields for criteria and options
for (var criterion_idx = 0; criterion_idx < criteria.length; criterion_idx++) {
var criterion = criteria[criterion_idx];
criterion.order_num = criterion_idx;
for (var option_idx = 0; option_idx < criterion.options.length; option_idx++) {
var option = criterion.options[option_idx];
option.order_num = option_idx;
for (var criterionIndex = 0; criterionIndex < criteria.length; criterionIndex++) {
var criterion = criteria[criterionIndex];
criterion.order_num = criterionIndex;
for (var optionIndex = 0; optionIndex < criterion.options.length; optionIndex++) {
var option = criterion.options[optionIndex];
option.order_num = optionIndex;
}
}
......@@ -222,7 +222,7 @@ OpenAssessment.EditRubricView.prototype = {
if (!isValid) {
this.criterionAddButton
.addClass("openassessment_highlighted_field")
.click( function() {
.click(function() {
$(this).removeClass("openassessment_highlighted_field");
}
);
......
......@@ -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