diff --git a/cms/static/coffee/spec/models/course_spec.js b/cms/static/coffee/spec/models/course_spec.js
index b6dc658e5a..2bdb333f57 100644
--- a/cms/static/coffee/spec/models/course_spec.js
+++ b/cms/static/coffee/spec/models/course_spec.js
@@ -1,10 +1,20 @@
-define ["js/models/course"], (Course) ->
- describe "Course", ->
- describe "basic", ->
- beforeEach ->
- @model = new Course({
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+define(["js/models/course"], Course =>
+ describe("Course", () =>
+ describe("basic", function() {
+ beforeEach(function() {
+ return this.model = new Course({
name: "Greek Hero"
- })
+ });
+ });
- it "should take a name argument", ->
- expect(@model.get("name")).toEqual("Greek Hero")
+ return it("should take a name argument", function() {
+ return expect(this.model.get("name")).toEqual("Greek Hero");
+ });
+ })
+ )
+);
diff --git a/cms/static/coffee/spec/models/metadata_spec.js b/cms/static/coffee/spec/models/metadata_spec.js
index ba3c4a2b65..dd5bbea0f3 100644
--- a/cms/static/coffee/spec/models/metadata_spec.js
+++ b/cms/static/coffee/spec/models/metadata_spec.js
@@ -1,59 +1,74 @@
-define ["js/models/metadata"], (Metadata) ->
- describe "Metadata", ->
- it "knows when the value has not been modified", ->
- model = new Metadata(
- {'value': 'original', 'explicitly_set': false})
- expect(model.isModified()).toBeFalsy()
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+define(["js/models/metadata"], Metadata =>
+ describe("Metadata", function() {
+ it("knows when the value has not been modified", function() {
+ let model = new Metadata(
+ {'value': 'original', 'explicitly_set': false});
+ expect(model.isModified()).toBeFalsy();
model = new Metadata(
- {'value': 'original', 'explicitly_set': true})
- model.setValue('original')
- expect(model.isModified()).toBeFalsy()
+ {'value': 'original', 'explicitly_set': true});
+ model.setValue('original');
+ return expect(model.isModified()).toBeFalsy();
+ });
- it "knows when the value has been modified", ->
- model = new Metadata(
- {'value': 'original', 'explicitly_set': false})
- model.setValue('original')
- expect(model.isModified()).toBeTruthy()
+ it("knows when the value has been modified", function() {
+ let model = new Metadata(
+ {'value': 'original', 'explicitly_set': false});
+ model.setValue('original');
+ expect(model.isModified()).toBeTruthy();
model = new Metadata(
- {'value': 'original', 'explicitly_set': true})
- model.setValue('modified')
- expect(model.isModified()).toBeTruthy()
+ {'value': 'original', 'explicitly_set': true});
+ model.setValue('modified');
+ return expect(model.isModified()).toBeTruthy();
+ });
- it "tracks when values have been explicitly set", ->
- model = new Metadata(
- {'value': 'original', 'explicitly_set': false})
- expect(model.isExplicitlySet()).toBeFalsy()
- model.setValue('original')
- expect(model.isExplicitlySet()).toBeTruthy()
+ it("tracks when values have been explicitly set", function() {
+ const model = new Metadata(
+ {'value': 'original', 'explicitly_set': false});
+ expect(model.isExplicitlySet()).toBeFalsy();
+ model.setValue('original');
+ return expect(model.isExplicitlySet()).toBeTruthy();
+ });
- it "has both 'display value' and a 'value' methods", ->
- model = new Metadata(
- {'value': 'default', 'explicitly_set': false})
- expect(model.getValue()).toBeNull
- expect(model.getDisplayValue()).toBe('default')
- model.setValue('modified')
- expect(model.getValue()).toBe('modified')
- expect(model.getDisplayValue()).toBe('modified')
+ it("has both 'display value' and a 'value' methods", function() {
+ const model = new Metadata(
+ {'value': 'default', 'explicitly_set': false});
+ expect(model.getValue()).toBeNull;
+ expect(model.getDisplayValue()).toBe('default');
+ model.setValue('modified');
+ expect(model.getValue()).toBe('modified');
+ return expect(model.getDisplayValue()).toBe('modified');
+ });
- it "has a clear method for reverting to the default", ->
- model = new Metadata(
- {'value': 'original', 'default_value' : 'default', 'explicitly_set': true})
- model.clear()
- expect(model.getValue()).toBeNull
- expect(model.getDisplayValue()).toBe('default')
- expect(model.isExplicitlySet()).toBeFalsy()
+ it("has a clear method for reverting to the default", function() {
+ const model = new Metadata(
+ {'value': 'original', 'default_value' : 'default', 'explicitly_set': true});
+ model.clear();
+ expect(model.getValue()).toBeNull;
+ expect(model.getDisplayValue()).toBe('default');
+ return expect(model.isExplicitlySet()).toBeFalsy();
+ });
- it "has a getter for field name", ->
- model = new Metadata({'field_name': 'foo'})
- expect(model.getFieldName()).toBe('foo')
+ it("has a getter for field name", function() {
+ const model = new Metadata({'field_name': 'foo'});
+ return expect(model.getFieldName()).toBe('foo');
+ });
- it "has a getter for options", ->
- model = new Metadata({'options': ['foo', 'bar']})
- expect(model.getOptions()).toEqual(['foo', 'bar'])
+ it("has a getter for options", function() {
+ const model = new Metadata({'options': ['foo', 'bar']});
+ return expect(model.getOptions()).toEqual(['foo', 'bar']);
+ });
- it "has a getter for type", ->
- model = new Metadata({'type': 'Integer'})
- expect(model.getType()).toBe(Metadata.INTEGER_TYPE)
+ return it("has a getter for type", function() {
+ const model = new Metadata({'type': 'Integer'});
+ return expect(model.getType()).toBe(Metadata.INTEGER_TYPE);
+ });
+ })
+);
diff --git a/cms/static/coffee/spec/models/section_spec.js b/cms/static/coffee/spec/models/section_spec.js
index 8a954b50dc..011099773e 100644
--- a/cms/static/coffee/spec/models/section_spec.js
+++ b/cms/static/coffee/spec/models/section_spec.js
@@ -1,50 +1,67 @@
-define ["js/models/section", "edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers", "js/utils/module"], (Section, AjaxHelpers, ModuleUtils) ->
- describe "Section", ->
- describe "basic", ->
- beforeEach ->
- @model = new Section({
- id: 42
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+define(["js/models/section", "edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers", "js/utils/module"], (Section, AjaxHelpers, ModuleUtils) =>
+ describe("Section", function() {
+ describe("basic", function() {
+ beforeEach(function() {
+ return this.model = new Section({
+ id: 42,
name: "Life, the Universe, and Everything"
- })
+ });
+ });
- it "should take an id argument", ->
- expect(@model.get("id")).toEqual(42)
+ it("should take an id argument", function() {
+ return expect(this.model.get("id")).toEqual(42);
+ });
- it "should take a name argument", ->
- expect(@model.get("name")).toEqual("Life, the Universe, and Everything")
+ it("should take a name argument", function() {
+ return expect(this.model.get("name")).toEqual("Life, the Universe, and Everything");
+ });
- it "should have a URL set", ->
- expect(@model.url()).toEqual(ModuleUtils.getUpdateUrl(42))
+ it("should have a URL set", function() {
+ return expect(this.model.url()).toEqual(ModuleUtils.getUpdateUrl(42));
+ });
- it "should serialize to JSON correctly", ->
- expect(@model.toJSON()).toEqual({
+ return it("should serialize to JSON correctly", function() {
+ return expect(this.model.toJSON()).toEqual({
metadata:
{
display_name: "Life, the Universe, and Everything"
}
- })
+ });
+ });
+ });
- describe "XHR", ->
- beforeEach ->
- spyOn(Section.prototype, 'showNotification')
- spyOn(Section.prototype, 'hideNotification')
- @model = new Section({
- id: 42
+ return describe("XHR", function() {
+ beforeEach(function() {
+ spyOn(Section.prototype, 'showNotification');
+ spyOn(Section.prototype, 'hideNotification');
+ return this.model = new Section({
+ id: 42,
name: "Life, the Universe, and Everything"
- })
+ });
+ });
- it "show/hide a notification when it saves to the server", ->
- server = AjaxHelpers.server([200, {"Content-Type": "application/json"}, "{}"])
+ it("show/hide a notification when it saves to the server", function() {
+ const server = AjaxHelpers.server([200, {"Content-Type": "application/json"}, "{}"]);
- @model.save()
- expect(Section.prototype.showNotification).toHaveBeenCalled()
- server.respond()
- expect(Section.prototype.hideNotification).toHaveBeenCalled()
+ this.model.save();
+ expect(Section.prototype.showNotification).toHaveBeenCalled();
+ server.respond();
+ return expect(Section.prototype.hideNotification).toHaveBeenCalled();
+ });
- it "don't hide notification when saving fails", ->
- # this is handled by the global AJAX error handler
- server = AjaxHelpers.server([500, {"Content-Type": "application/json"}, "{}"])
+ return it("don't hide notification when saving fails", function() {
+ // this is handled by the global AJAX error handler
+ const server = AjaxHelpers.server([500, {"Content-Type": "application/json"}, "{}"]);
- @model.save()
- server.respond()
- expect(Section.prototype.hideNotification).not.toHaveBeenCalled()
+ this.model.save();
+ server.respond();
+ return expect(Section.prototype.hideNotification).not.toHaveBeenCalled();
+ });
+ });
+ })
+);
diff --git a/cms/static/coffee/spec/models/settings_course_grader_spec.js b/cms/static/coffee/spec/models/settings_course_grader_spec.js
index 23cf22d371..1d0ba32d92 100644
--- a/cms/static/coffee/spec/models/settings_course_grader_spec.js
+++ b/cms/static/coffee/spec/models/settings_course_grader_spec.js
@@ -1,39 +1,52 @@
-define ["js/models/settings/course_grader"], (CourseGrader) ->
- describe "CourseGraderModel", ->
- describe "parseWeight", ->
- it "converts a float to an integer", ->
- model = new CourseGrader({weight: 7.0001, min_count: 3.67, drop_count: 1.88}, {parse:true})
- expect(model.get('weight')).toBe(7)
- expect(model.get('min_count')).toBe(4)
- expect(model.get('drop_count')).toBe(2)
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+define(["js/models/settings/course_grader"], CourseGrader =>
+ describe("CourseGraderModel", () =>
+ describe("parseWeight", function() {
+ it("converts a float to an integer", function() {
+ const model = new CourseGrader({weight: 7.0001, min_count: 3.67, drop_count: 1.88}, {parse:true});
+ expect(model.get('weight')).toBe(7);
+ expect(model.get('min_count')).toBe(4);
+ return expect(model.get('drop_count')).toBe(2);
+ });
- it "converts float value of weight to an integer with rounding", ->
- model = new CourseGrader({weight: 28.999999999999996}, {parse:true})
- expect(model.get('weight')).toBe(29)
+ it("converts float value of weight to an integer with rounding", function() {
+ const model = new CourseGrader({weight: 28.999999999999996}, {parse:true});
+ return expect(model.get('weight')).toBe(29);
+ });
- it "converts a string to an integer", ->
- model = new CourseGrader({weight: '7.0001', min_count: '3.67', drop_count: '1.88'}, {parse:true})
- expect(model.get('weight')).toBe(7)
- expect(model.get('min_count')).toBe(4)
- expect(model.get('drop_count')).toBe(2)
+ it("converts a string to an integer", function() {
+ const model = new CourseGrader({weight: '7.0001', min_count: '3.67', drop_count: '1.88'}, {parse:true});
+ expect(model.get('weight')).toBe(7);
+ expect(model.get('min_count')).toBe(4);
+ return expect(model.get('drop_count')).toBe(2);
+ });
- it "does a no-op for integers", ->
- model = new CourseGrader({weight: 7, min_count: 3, drop_count: 1}, {parse:true})
- expect(model.get('weight')).toBe(7)
- expect(model.get('min_count')).toBe(3)
- expect(model.get('drop_count')).toBe(1)
+ it("does a no-op for integers", function() {
+ const model = new CourseGrader({weight: 7, min_count: 3, drop_count: 1}, {parse:true});
+ expect(model.get('weight')).toBe(7);
+ expect(model.get('min_count')).toBe(3);
+ return expect(model.get('drop_count')).toBe(1);
+ });
- it "gives validation error if min_count is less than 1 or drop_count is NaN", ->
- model = new CourseGrader()
- errors = model.validate({min_count: 0, drop_count: ''}, {validate:true})
- expect(errors.min_count).toBe('Please enter an integer greater than 0.')
- expect(errors.drop_count).toBe('Please enter non-negative integer.')
- # don't allow negative integers
- errors = model.validate({min_count: -12, drop_count: -1}, {validate:true})
- expect(errors.min_count).toBe('Please enter an integer greater than 0.')
- expect(errors.drop_count).toBe('Please enter non-negative integer.')
- # don't allow floats
- errors = model.validate({min_count: 12.2, drop_count: 1.5}, {validate:true})
- expect(errors.min_count).toBe('Please enter an integer greater than 0.')
- expect(errors.drop_count).toBe('Please enter non-negative integer.')
+ return it("gives validation error if min_count is less than 1 or drop_count is NaN", function() {
+ const model = new CourseGrader();
+ let errors = model.validate({min_count: 0, drop_count: ''}, {validate:true});
+ expect(errors.min_count).toBe('Please enter an integer greater than 0.');
+ expect(errors.drop_count).toBe('Please enter non-negative integer.');
+ // don't allow negative integers
+ errors = model.validate({min_count: -12, drop_count: -1}, {validate:true});
+ expect(errors.min_count).toBe('Please enter an integer greater than 0.');
+ expect(errors.drop_count).toBe('Please enter non-negative integer.');
+ // don't allow floats
+ errors = model.validate({min_count: 12.2, drop_count: 1.5}, {validate:true});
+ expect(errors.min_count).toBe('Please enter an integer greater than 0.');
+ return expect(errors.drop_count).toBe('Please enter non-negative integer.');
+ });
+ })
+ )
+);
diff --git a/cms/static/coffee/spec/models/settings_grading_spec.js b/cms/static/coffee/spec/models/settings_grading_spec.js
index 4092f4f161..6238024fef 100644
--- a/cms/static/coffee/spec/models/settings_grading_spec.js
+++ b/cms/static/coffee/spec/models/settings_grading_spec.js
@@ -1,36 +1,52 @@
-define ["underscore", "js/models/settings/course_grading_policy"], (_, CourseGradingPolicy) ->
- describe "CourseGradingPolicy", ->
- beforeEach ->
- @model = new CourseGradingPolicy()
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+define(["underscore", "js/models/settings/course_grading_policy"], (_, CourseGradingPolicy) =>
+ describe("CourseGradingPolicy", function() {
+ beforeEach(function() {
+ return this.model = new CourseGradingPolicy();
+ });
- describe "parse", ->
- it "sets a null grace period to 00:00", ->
- attrs = @model.parse(grace_period: null)
- expect(attrs.grace_period).toEqual(
+ describe("parse", () =>
+ it("sets a null grace period to 00:00", function() {
+ const attrs = this.model.parse({grace_period: null});
+ return expect(attrs.grace_period).toEqual({
hours: 0,
minutes: 0
- )
+ });
+ })
+ );
- describe "parseGracePeriod", ->
- it "parses a time in HH:MM format", ->
- time = @model.parseGracePeriod("07:19")
- expect(time).toEqual(
+ describe("parseGracePeriod", function() {
+ it("parses a time in HH:MM format", function() {
+ const time = this.model.parseGracePeriod("07:19");
+ return expect(time).toEqual({
hours: 7,
minutes: 19
- )
+ });
+ });
- it "returns null on an incorrectly formatted string", ->
- expect(@model.parseGracePeriod("asdf")).toBe(null)
- expect(@model.parseGracePeriod("7:19")).toBe(null)
- expect(@model.parseGracePeriod("1000:00")).toBe(null)
+ return it("returns null on an incorrectly formatted string", function() {
+ expect(this.model.parseGracePeriod("asdf")).toBe(null);
+ expect(this.model.parseGracePeriod("7:19")).toBe(null);
+ return expect(this.model.parseGracePeriod("1000:00")).toBe(null);
+ });
+ });
- describe "validate", ->
- it "enforces that the passing grade is <= the minimum grade to receive credit if credit is enabled", ->
- @model.set({minimum_grade_credit: 0.8, grace_period: '01:00', is_credit_course: true})
- @model.set('grade_cutoffs', [0.9], validate: true)
- expect(_.keys(@model.validationError)).toContain('minimum_grade_credit')
+ return describe("validate", function() {
+ it("enforces that the passing grade is <= the minimum grade to receive credit if credit is enabled", function() {
+ this.model.set({minimum_grade_credit: 0.8, grace_period: '01:00', is_credit_course: true});
+ this.model.set('grade_cutoffs', [0.9], {validate: true});
+ return expect(_.keys(this.model.validationError)).toContain('minimum_grade_credit');
+ });
- it "does not enforce the passing grade limit in non-credit courses", ->
- @model.set({minimum_grade_credit: 0.8, grace_period: '01:00', is_credit_course: false})
- @model.set({grade_cutoffs: [0.9]}, validate: true)
- expect(@model.validationError).toBe(null)
+ return it("does not enforce the passing grade limit in non-credit courses", function() {
+ this.model.set({minimum_grade_credit: 0.8, grace_period: '01:00', is_credit_course: false});
+ this.model.set({grade_cutoffs: [0.9]}, {validate: true});
+ return expect(this.model.validationError).toBe(null);
+ });
+ });
+ })
+);
diff --git a/cms/static/coffee/spec/models/textbook_spec.js b/cms/static/coffee/spec/models/textbook_spec.js
index dc10df8a47..75ac6f875a 100644
--- a/cms/static/coffee/spec/models/textbook_spec.js
+++ b/cms/static/coffee/spec/models/textbook_spec.js
@@ -1,78 +1,98 @@
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS203: Remove `|| {}` from converted for-own loops
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
-define ["backbone", "js/models/textbook", "js/collections/textbook", "js/models/chapter", "js/collections/chapter", "cms/js/main"],
-(Backbone, Textbook, TextbookSet, Chapter, ChapterSet, main) ->
+define(["backbone", "js/models/textbook", "js/collections/textbook", "js/models/chapter", "js/collections/chapter", "cms/js/main"],
+function(Backbone, Textbook, TextbookSet, Chapter, ChapterSet, main) {
- describe "Textbook model", ->
- beforeEach ->
- main()
- @model = new Textbook()
- CMS.URL.TEXTBOOKS = "/textbooks"
+ describe("Textbook model", function() {
+ beforeEach(function() {
+ main();
+ this.model = new Textbook();
+ return CMS.URL.TEXTBOOKS = "/textbooks";
+ });
- afterEach ->
- delete CMS.URL.TEXTBOOKS
+ afterEach(() => delete CMS.URL.TEXTBOOKS);
- describe "Basic", ->
- it "should have an empty name by default", ->
- expect(@model.get("name")).toEqual("")
+ describe("Basic", function() {
+ it("should have an empty name by default", function() {
+ return expect(this.model.get("name")).toEqual("");
+ });
- it "should not show chapters by default", ->
- expect(@model.get("showChapters")).toBeFalsy()
+ it("should not show chapters by default", function() {
+ return expect(this.model.get("showChapters")).toBeFalsy();
+ });
- it "should have a ChapterSet with one chapter by default", ->
- chapters = @model.get("chapters")
- expect(chapters).toBeInstanceOf(ChapterSet)
- expect(chapters.length).toEqual(1)
- expect(chapters.at(0).isEmpty()).toBeTruthy()
+ it("should have a ChapterSet with one chapter by default", function() {
+ const chapters = this.model.get("chapters");
+ expect(chapters).toBeInstanceOf(ChapterSet);
+ expect(chapters.length).toEqual(1);
+ return expect(chapters.at(0).isEmpty()).toBeTruthy();
+ });
- it "should be empty by default", ->
- expect(@model.isEmpty()).toBeTruthy()
+ it("should be empty by default", function() {
+ return expect(this.model.isEmpty()).toBeTruthy();
+ });
- it "should have a URL root", ->
- urlRoot = _.result(@model, 'urlRoot')
- expect(urlRoot).toBeTruthy()
+ it("should have a URL root", function() {
+ const urlRoot = _.result(this.model, 'urlRoot');
+ return expect(urlRoot).toBeTruthy();
+ });
- it "should be able to reset itself", ->
- @model.set("name", "foobar")
- @model.reset()
- expect(@model.get("name")).toEqual("")
+ it("should be able to reset itself", function() {
+ this.model.set("name", "foobar");
+ this.model.reset();
+ return expect(this.model.get("name")).toEqual("");
+ });
- it "should not be dirty by default", ->
- expect(@model.isDirty()).toBeFalsy()
+ it("should not be dirty by default", function() {
+ return expect(this.model.isDirty()).toBeFalsy();
+ });
- it "should be dirty after it's been changed", ->
- @model.set("name", "foobar")
- expect(@model.isDirty()).toBeTruthy()
+ it("should be dirty after it's been changed", function() {
+ this.model.set("name", "foobar");
+ return expect(this.model.isDirty()).toBeTruthy();
+ });
- it "should not be dirty after calling setOriginalAttributes", ->
- @model.set("name", "foobar")
- @model.setOriginalAttributes()
- expect(@model.isDirty()).toBeFalsy()
+ return it("should not be dirty after calling setOriginalAttributes", function() {
+ this.model.set("name", "foobar");
+ this.model.setOriginalAttributes();
+ return expect(this.model.isDirty()).toBeFalsy();
+ });
+ });
- describe "Input/Output", ->
- deepAttributes = (obj) ->
- if obj instanceof Backbone.Model
- deepAttributes(obj.attributes)
- else if obj instanceof Backbone.Collection
- obj.map(deepAttributes);
- else if _.isArray(obj)
- _.map(obj, deepAttributes);
- else if _.isObject(obj)
- attributes = {};
- for own prop, val of obj
- attributes[prop] = deepAttributes(val)
- attributes
- else
- obj
+ describe("Input/Output", function() {
+ var deepAttributes = function(obj) {
+ if (obj instanceof Backbone.Model) {
+ return deepAttributes(obj.attributes);
+ } else if (obj instanceof Backbone.Collection) {
+ return obj.map(deepAttributes);
+ } else if (_.isArray(obj)) {
+ return _.map(obj, deepAttributes);
+ } else if (_.isObject(obj)) {
+ const attributes = {};
+ for (let prop of Object.keys(obj || {})) {
+ const val = obj[prop];
+ attributes[prop] = deepAttributes(val);
+ }
+ return attributes;
+ } else {
+ return obj;
+ }
+ };
- it "should match server model to client model", ->
- serverModelSpec = {
+ return it("should match server model to client model", function() {
+ const serverModelSpec = {
"tab_title": "My Textbook",
"chapters": [
{"title": "Chapter 1", "url": "/ch1.pdf"},
{"title": "Chapter 2", "url": "/ch2.pdf"},
]
- }
- clientModelSpec = {
+ };
+ const clientModelSpec = {
"name": "My Textbook",
"showChapters": false,
"editing": false,
@@ -86,113 +106,142 @@ define ["backbone", "js/models/textbook", "js/collections/textbook", "js/models/
"order": 2
}
]
- }
+ };
- model = new Textbook(serverModelSpec, {parse: true})
- expect(deepAttributes(model)).toEqual(clientModelSpec)
- expect(model.toJSON()).toEqual(serverModelSpec)
+ const model = new Textbook(serverModelSpec, {parse: true});
+ expect(deepAttributes(model)).toEqual(clientModelSpec);
+ return expect(model.toJSON()).toEqual(serverModelSpec);
+ });
+ });
- describe "Validation", ->
- it "requires a name", ->
- model = new Textbook({name: ""})
- expect(model.isValid()).toBeFalsy()
+ return describe("Validation", function() {
+ it("requires a name", function() {
+ const model = new Textbook({name: ""});
+ return expect(model.isValid()).toBeFalsy();
+ });
- it "requires at least one chapter", ->
- model = new Textbook({name: "foo"})
- model.get("chapters").reset()
- expect(model.isValid()).toBeFalsy()
+ it("requires at least one chapter", function() {
+ const model = new Textbook({name: "foo"});
+ model.get("chapters").reset();
+ return expect(model.isValid()).toBeFalsy();
+ });
- it "requires a valid chapter", ->
- chapter = new Chapter()
- chapter.isValid = -> false
- model = new Textbook({name: "foo"})
- model.get("chapters").reset([chapter])
- expect(model.isValid()).toBeFalsy()
+ it("requires a valid chapter", function() {
+ const chapter = new Chapter();
+ chapter.isValid = () => false;
+ const model = new Textbook({name: "foo"});
+ model.get("chapters").reset([chapter]);
+ return expect(model.isValid()).toBeFalsy();
+ });
- it "requires all chapters to be valid", ->
- chapter1 = new Chapter()
- chapter1.isValid = -> true
- chapter2 = new Chapter()
- chapter2.isValid = -> false
- model = new Textbook({name: "foo"})
- model.get("chapters").reset([chapter1, chapter2])
- expect(model.isValid()).toBeFalsy()
+ it("requires all chapters to be valid", function() {
+ const chapter1 = new Chapter();
+ chapter1.isValid = () => true;
+ const chapter2 = new Chapter();
+ chapter2.isValid = () => false;
+ const model = new Textbook({name: "foo"});
+ model.get("chapters").reset([chapter1, chapter2]);
+ return expect(model.isValid()).toBeFalsy();
+ });
- it "can pass validation", ->
- chapter = new Chapter()
- chapter.isValid = -> true
- model = new Textbook({name: "foo"})
- model.get("chapters").reset([chapter])
- expect(model.isValid()).toBeTruthy()
+ return it("can pass validation", function() {
+ const chapter = new Chapter();
+ chapter.isValid = () => true;
+ const model = new Textbook({name: "foo"});
+ model.get("chapters").reset([chapter]);
+ return expect(model.isValid()).toBeTruthy();
+ });
+ });
+ });
- describe "Textbook collection", ->
- beforeEach ->
- CMS.URL.TEXTBOOKS = "/textbooks"
- @collection = new TextbookSet()
+ describe("Textbook collection", function() {
+ beforeEach(function() {
+ CMS.URL.TEXTBOOKS = "/textbooks";
+ return this.collection = new TextbookSet();
+ });
- afterEach ->
- delete CMS.URL.TEXTBOOKS
+ afterEach(() => delete CMS.URL.TEXTBOOKS);
- it "should have a url set", ->
- url = _.result(@collection, 'url')
- expect(url).toEqual("/textbooks")
+ return it("should have a url set", function() {
+ const url = _.result(this.collection, 'url');
+ return expect(url).toEqual("/textbooks");
+ });
+ });
- describe "Chapter model", ->
- beforeEach ->
- @model = new Chapter()
+ describe("Chapter model", function() {
+ beforeEach(function() {
+ return this.model = new Chapter();
+ });
- describe "Basic", ->
- it "should have a name by default", ->
- expect(@model.get("name")).toEqual("")
+ describe("Basic", function() {
+ it("should have a name by default", function() {
+ return expect(this.model.get("name")).toEqual("");
+ });
- it "should have an asset_path by default", ->
- expect(@model.get("asset_path")).toEqual("")
+ it("should have an asset_path by default", function() {
+ return expect(this.model.get("asset_path")).toEqual("");
+ });
- it "should have an order by default", ->
- expect(@model.get("order")).toEqual(1)
+ it("should have an order by default", function() {
+ return expect(this.model.get("order")).toEqual(1);
+ });
- it "should be empty by default", ->
- expect(@model.isEmpty()).toBeTruthy()
+ return it("should be empty by default", function() {
+ return expect(this.model.isEmpty()).toBeTruthy();
+ });
+ });
- describe "Validation", ->
- it "requires a name", ->
- model = new Chapter({name: "", asset_path: "a.pdf"})
- expect(model.isValid()).toBeFalsy()
+ return describe("Validation", function() {
+ it("requires a name", function() {
+ const model = new Chapter({name: "", asset_path: "a.pdf"});
+ return expect(model.isValid()).toBeFalsy();
+ });
- it "requires an asset_path", ->
- model = new Chapter({name: "a", asset_path: ""})
- expect(model.isValid()).toBeFalsy()
+ it("requires an asset_path", function() {
+ const model = new Chapter({name: "a", asset_path: ""});
+ return expect(model.isValid()).toBeFalsy();
+ });
- it "can pass validation", ->
- model = new Chapter({name: "a", asset_path: "a.pdf"})
- expect(model.isValid()).toBeTruthy()
+ return it("can pass validation", function() {
+ const model = new Chapter({name: "a", asset_path: "a.pdf"});
+ return expect(model.isValid()).toBeTruthy();
+ });
+ });
+ });
- describe "Chapter collection", ->
- beforeEach ->
- @collection = new ChapterSet()
+ return describe("Chapter collection", function() {
+ beforeEach(function() {
+ return this.collection = new ChapterSet();
+ });
- it "is empty by default", ->
- expect(@collection.isEmpty()).toBeTruthy()
+ it("is empty by default", function() {
+ return expect(this.collection.isEmpty()).toBeTruthy();
+ });
- it "is empty if all chapters are empty", ->
- @collection.add([{}, {}, {}])
- expect(@collection.isEmpty()).toBeTruthy()
+ it("is empty if all chapters are empty", function() {
+ this.collection.add([{}, {}, {}]);
+ return expect(this.collection.isEmpty()).toBeTruthy();
+ });
- it "is not empty if a chapter is not empty", ->
- @collection.add([{}, {name: "full"}, {}])
- expect(@collection.isEmpty()).toBeFalsy()
+ it("is not empty if a chapter is not empty", function() {
+ this.collection.add([{}, {name: "full"}, {}]);
+ return expect(this.collection.isEmpty()).toBeFalsy();
+ });
- it "should have a nextOrder function", ->
- expect(@collection.nextOrder()).toEqual(1)
- @collection.add([{}])
- expect(@collection.nextOrder()).toEqual(2)
- @collection.add([{}])
- expect(@collection.nextOrder()).toEqual(3)
- # verify that it doesn't just return an incrementing value each time
- expect(@collection.nextOrder()).toEqual(3)
- # try going back one
- @collection.remove(@collection.last())
- expect(@collection.nextOrder()).toEqual(2)
+ return it("should have a nextOrder function", function() {
+ expect(this.collection.nextOrder()).toEqual(1);
+ this.collection.add([{}]);
+ expect(this.collection.nextOrder()).toEqual(2);
+ this.collection.add([{}]);
+ expect(this.collection.nextOrder()).toEqual(3);
+ // verify that it doesn't just return an incrementing value each time
+ expect(this.collection.nextOrder()).toEqual(3);
+ // try going back one
+ this.collection.remove(this.collection.last());
+ return expect(this.collection.nextOrder()).toEqual(2);
+ });
+ });
+});
diff --git a/cms/static/coffee/spec/models/upload_spec.js b/cms/static/coffee/spec/models/upload_spec.js
index 17cd887b36..04900f7d7f 100644
--- a/cms/static/coffee/spec/models/upload_spec.js
+++ b/cms/static/coffee/spec/models/upload_spec.js
@@ -1,71 +1,93 @@
-define ["js/models/uploads"], (FileUpload) ->
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+define(["js/models/uploads"], FileUpload =>
- describe "FileUpload", ->
- beforeEach ->
- @model = new FileUpload()
+ describe("FileUpload", function() {
+ beforeEach(function() {
+ return this.model = new FileUpload();
+ });
- it "is unfinished by default", ->
- expect(@model.get("finished")).toBeFalsy()
+ it("is unfinished by default", function() {
+ return expect(this.model.get("finished")).toBeFalsy();
+ });
- it "is not uploading by default", ->
- expect(@model.get("uploading")).toBeFalsy()
+ it("is not uploading by default", function() {
+ return expect(this.model.get("uploading")).toBeFalsy();
+ });
- it "is valid by default", ->
- expect(@model.isValid()).toBeTruthy()
+ it("is valid by default", function() {
+ return expect(this.model.isValid()).toBeTruthy();
+ });
- it "is valid for text files by default", ->
- file = {"type": "text/plain", "name": "filename.txt"}
- @model.set("selectedFile", file);
- expect(@model.isValid()).toBeTruthy()
+ it("is valid for text files by default", function() {
+ const file = {"type": "text/plain", "name": "filename.txt"};
+ this.model.set("selectedFile", file);
+ return expect(this.model.isValid()).toBeTruthy();
+ });
- it "is valid for PNG files by default", ->
- file = {"type": "image/png", "name": "filename.png"}
- @model.set("selectedFile", file);
- expect(@model.isValid()).toBeTruthy()
+ it("is valid for PNG files by default", function() {
+ const file = {"type": "image/png", "name": "filename.png"};
+ this.model.set("selectedFile", file);
+ return expect(this.model.isValid()).toBeTruthy();
+ });
- it "can accept a file type when explicitly set", ->
- file = {"type": "image/png", "name": "filename.png"}
- @model.set("mimeTypes": ["image/png"])
- @model.set("selectedFile", file)
- expect(@model.isValid()).toBeTruthy()
+ it("can accept a file type when explicitly set", function() {
+ const file = {"type": "image/png", "name": "filename.png"};
+ this.model.set({"mimeTypes": ["image/png"]});
+ this.model.set("selectedFile", file);
+ return expect(this.model.isValid()).toBeTruthy();
+ });
- it "can accept a file format when explicitly set", ->
- file = {"type": "", "name": "filename.png"}
- @model.set("fileFormats": ["png"])
- @model.set("selectedFile", file)
- expect(@model.isValid()).toBeTruthy()
+ it("can accept a file format when explicitly set", function() {
+ const file = {"type": "", "name": "filename.png"};
+ this.model.set({"fileFormats": ["png"]});
+ this.model.set("selectedFile", file);
+ return expect(this.model.isValid()).toBeTruthy();
+ });
- it "can accept multiple file types", ->
- file = {"type": "image/gif", "name": "filename.gif"}
- @model.set("mimeTypes": ["image/png", "image/jpeg", "image/gif"])
- @model.set("selectedFile", file)
- expect(@model.isValid()).toBeTruthy()
+ it("can accept multiple file types", function() {
+ const file = {"type": "image/gif", "name": "filename.gif"};
+ this.model.set({"mimeTypes": ["image/png", "image/jpeg", "image/gif"]});
+ this.model.set("selectedFile", file);
+ return expect(this.model.isValid()).toBeTruthy();
+ });
- it "can accept multiple file formats", ->
- file = {"type": "image/gif", "name": "filename.gif"}
- @model.set("fileFormats": ["png", "jpeg", "gif"])
- @model.set("selectedFile", file)
- expect(@model.isValid()).toBeTruthy()
+ it("can accept multiple file formats", function() {
+ const file = {"type": "image/gif", "name": "filename.gif"};
+ this.model.set({"fileFormats": ["png", "jpeg", "gif"]});
+ this.model.set("selectedFile", file);
+ return expect(this.model.isValid()).toBeTruthy();
+ });
- describe "fileTypes", ->
- it "returns a list of the uploader's file types", ->
- @model.set('mimeTypes', ['image/png', 'application/json'])
- @model.set('fileFormats', ['gif', 'srt'])
- expect(@model.fileTypes()).toEqual(['PNG', 'JSON', 'GIF', 'SRT'])
+ describe("fileTypes", () =>
+ it("returns a list of the uploader's file types", function() {
+ this.model.set('mimeTypes', ['image/png', 'application/json']);
+ this.model.set('fileFormats', ['gif', 'srt']);
+ return expect(this.model.fileTypes()).toEqual(['PNG', 'JSON', 'GIF', 'SRT']);
+ })
+ );
- describe "formatValidTypes", ->
- it "returns a map of formatted file types and extensions", ->
- @model.set('mimeTypes', ['image/png', 'image/jpeg', 'application/json'])
- formatted = @model.formatValidTypes()
- expect(formatted).toEqual(
+ return describe("formatValidTypes", function() {
+ it("returns a map of formatted file types and extensions", function() {
+ this.model.set('mimeTypes', ['image/png', 'image/jpeg', 'application/json']);
+ const formatted = this.model.formatValidTypes();
+ return expect(formatted).toEqual({
fileTypes: 'PNG, JPEG or JSON',
fileExtensions: '.png, .jpeg or .json'
- )
+ });
+ });
- it "does not format with only one mime type", ->
- @model.set('mimeTypes', ['application/pdf'])
- formatted = @model.formatValidTypes()
- expect(formatted).toEqual(
+ return it("does not format with only one mime type", function() {
+ this.model.set('mimeTypes', ['application/pdf']);
+ const formatted = this.model.formatValidTypes();
+ return expect(formatted).toEqual({
fileTypes: 'PDF',
fileExtensions: '.pdf'
- )
+ });
+ });
+ });
+ })
+);
diff --git a/cms/static/coffee/spec/views/assets_spec.js b/cms/static/coffee/spec/views/assets_spec.js
index e94d166a52..44a2a9d758 100644
--- a/cms/static/coffee/spec/views/assets_spec.js
+++ b/cms/static/coffee/spec/views/assets_spec.js
@@ -1,221 +1,252 @@
-define ["jquery", "edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers", "squire"],
-($, AjaxHelpers, Squire) ->
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+define(["jquery", "edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers", "squire"],
+function($, AjaxHelpers, Squire) {
- assetLibraryTpl = readFixtures('asset-library.underscore')
- assetTpl = readFixtures('asset.underscore')
+ const assetLibraryTpl = readFixtures('asset-library.underscore');
+ const assetTpl = readFixtures('asset.underscore');
- describe "Asset view", ->
- beforeEach (done) ->
- setFixtures($("
+ console.log(two * 2);
+
- But in this there should be
-
- Great ideas require offsetting.
+But in this there should be
+
+Great ideas require offsetting.
- bad tests require drivel
-
+bad tests require drivel
+
- [code]
- Code should be nicely monospaced.
- [/code]
- """)
- expect(data).toXMLEqual("""
-
-
Not a header
-
A header
-
Multiple choice w/ parentheticals
-
-
- option (with parens)
- xd option (x)
- parentheses inside
- no space b4 close paren
-
-
-
Choice checks
-
-
- option1 [x]
- correct
- redundant
- distractor
- no space
-
-
-
Option with multiple correct ones
-
-
-
-
Option with embedded parens
-
-
-
-
What happens w/ empty correct options?
-
-
-
+[code]
+Code should be nicely monospaced.
+[/code]\
+`);
+ return expect(data).toXMLEqual(`\
+
+
Not a header
+
A header
+
Multiple choice w/ parentheticals
+
+
+ option (with parens)
+ xd option (x)
+ parentheses inside
+ no space b4 close paren
+
+
+
Choice checks
+
+
+ option1 [x]
+ correct
+ redundant
+ distractor
+ no space
+
+
+
Option with multiple correct ones
+
+
+
+
Option with embedded parens
+
+
+
+
What happens w/ empty correct options?
+
+
+
+
+
+
Explanation
+
see
+
+
+
[explanation]
+
orphaned start
+
No p tags in the below
+
+
But in this there should be
+
+
Great ideas require offsetting.
+
bad tests require drivel
+
+
+ Code should be nicely monospaced.
+
+
+`);
+ });
+
+ it('can separate responsetypes based on ---', function() {
+ const data = MarkdownEditingDescriptor.markdownToXml(`\
+Multiple choice problems allow learners to select only one option. Learners can see all the options along with the problem text.
+
+>>Which of the following countries has the largest population?<<
+( ) Brazil {{ timely feedback -- explain why an almost correct answer is wrong }}
+( ) Germany
+(x) Indonesia
+( ) Russia
+
+[explanation]
+According to September 2014 estimates:
+The population of Indonesia is approximately 250 million.
+The population of Brazil is approximately 200 million.
+The population of Russia is approximately 146 million.
+The population of Germany is approximately 81 million.
+[explanation]
+
+---
+
+Checkbox problems allow learners to select multiple options. Learners can see all the options along with the problem text.
+
+>>The following languages are in the Indo-European family:<<
+[x] Urdu
+[ ] Finnish
+[x] Marathi
+[x] French
+[ ] Hungarian
+
+Note: Make sure you select all of the correct options—there may be more than one!
+
+[explanation]
+Urdu, Marathi, and French are all Indo-European languages, while Finnish and Hungarian are in the Uralic family.
+[explanation]
+\
+`);
+ return expect(data).toXMLEqual(`\
+
+
+
Multiple choice problems allow learners to select only one option. Learners can see all the options along with the problem text.
+
+
+ Brazil timely feedback -- explain why an almost correct answer is wrong
+
+ Germany
+ Indonesia
+ Russia
+
+
+
+
Explanation
+
According to September 2014 estimates:
+
The population of Indonesia is approximately 250 million.
+
The population of Brazil is approximately 200 million.
+
The population of Russia is approximately 146 million.
+
The population of Germany is approximately 81 million.
+
+
+
+
+
+
Checkbox problems allow learners to select multiple options. Learners can see all the options along with the problem text.
+
+
+ Urdu
+ Finnish
+ Marathi
+ French
+ Hungarian
+
+
Note: Make sure you select all of the correct options—there may be more than one!
-
Explanation
-
see
+
Explanation
+
Urdu, Marathi, and French are all Indo-European languages, while Finnish and Hungarian are in the Uralic family.
-
[explanation]
-
orphaned start
-
No p tags in the below
-
-
But in this there should be
-
-
Great ideas require offsetting.
-
bad tests require drivel
-
-
- Code should be nicely monospaced.
-
-
- """)
+ it('can separate other things based on ---', function() {
+ const data = MarkdownEditingDescriptor.markdownToXml(`\
+Multiple choice problems allow learners to select only one option. Learners can see all the options along with the problem text.
- it 'can separate responsetypes based on ---', ->
- data = MarkdownEditingDescriptor.markdownToXml("""
- Multiple choice problems allow learners to select only one option. Learners can see all the options along with the problem text.
+---
- >>Which of the following countries has the largest population?<<
- ( ) Brazil {{ timely feedback -- explain why an almost correct answer is wrong }}
- ( ) Germany
- (x) Indonesia
- ( ) Russia
+>>Which of the following countries has the largest population?<<
+( ) Brazil {{ timely feedback -- explain why an almost correct answer is wrong }}
+( ) Germany
+(x) Indonesia
+( ) Russia
- [explanation]
- According to September 2014 estimates:
- The population of Indonesia is approximately 250 million.
- The population of Brazil is approximately 200 million.
- The population of Russia is approximately 146 million.
- The population of Germany is approximately 81 million.
- [explanation]
+[explanation]
+According to September 2014 estimates:
+The population of Indonesia is approximately 250 million.
+The population of Brazil is approximately 200 million.
+The population of Russia is approximately 146 million.
+The population of Germany is approximately 81 million.
+[explanation]\
+`);
+ return expect(data).toXMLEqual(`\
+
+
Multiple choice problems allow learners to select only one option. Learners can see all the options along with the problem text.
+
+
+
+
+ Brazil timely feedback -- explain why an almost correct answer is wrong
+
+ Germany
+ Indonesia
+ Russia
+
+
+
+
Explanation
+
According to September 2014 estimates:
+
The population of Indonesia is approximately 250 million.
+
The population of Brazil is approximately 200 million.
+
The population of Russia is approximately 146 million.
+
The population of Germany is approximately 81 million.
+
+
+
+\
+`);
+ });
+
+ it('can do separation if spaces are present around ---', function() {
+ const data = MarkdownEditingDescriptor.markdownToXml(`\
+>>The following languages are in the Indo-European family:||There are three correct choices.<<
+[x] Urdu
+[ ] Finnish
+[x] Marathi
+[x] French
+[ ] Hungarian
---
- Checkbox problems allow learners to select multiple options. Learners can see all the options along with the problem text.
+>>Which of the following countries has the largest population?||You have only choice.<<
+( ) Brazil {{ timely feedback -- explain why an almost correct answer is wrong }}
+( ) Germany
+(x) Indonesia
+( ) Russia\
+`);
+ return expect(data).toXMLEqual(`\
+
+
+
+ There are three correct choices.
+
+ Urdu
+ Finnish
+ Marathi
+ French
+ Hungarian
+
+
- >>The following languages are in the Indo-European family:<<
- [x] Urdu
- [ ] Finnish
- [x] Marathi
- [x] French
- [ ] Hungarian
+
+
+ You have only choice.
+
+ Brazil
+ timely feedback -- explain why an almost correct answer is wrong
+
+ Germany
+ Indonesia
+ Russia
+
+
+\
+`);
+ });
- Note: Make sure you select all of the correct options—there may be more than one!
+ it('can extract question description', function() {
+ const data = MarkdownEditingDescriptor.markdownToXml(`\
+>>The following languages are in the Indo-European family:||Choose wisely.<<
+[x] Urdu
+[ ] Finnish
+[x] Marathi
+[x] French
+[ ] Hungarian\
+`);
+ return expect(data).toXMLEqual(`\
+
+
+
+ Choose wisely.
+
+ Urdu
+ Finnish
+ Marathi
+ French
+ Hungarian
+
+
+\
+`);
+ });
- [explanation]
- Urdu, Marathi, and French are all Indo-European languages, while Finnish and Hungarian are in the Uralic family.
- [explanation]
+ it('can handle question and description spanned across multiple lines', function() {
+ const data = MarkdownEditingDescriptor.markdownToXml(`\
+>>The following languages
+are in the
+Indo-European family:
+||
+first second
+third
+<<
+[x] Urdu
+[ ] Finnish
+[x] Marathi\
+`);
+ return expect(data).toXMLEqual(`\
+
+
+
+ first second third
+
+ Urdu
+ Finnish
+ Marathi
+
+
+\
+`);
+ });
- """)
- expect(data).toXMLEqual("""
-
-
-
Multiple choice problems allow learners to select only one option. Learners can see all the options along with the problem text.
-
-
- Brazil timely feedback -- explain why an almost correct answer is wrong
-
- Germany
- Indonesia
- Russia
-
-
-
-
Explanation
-
According to September 2014 estimates:
-
The population of Indonesia is approximately 250 million.
-
The population of Brazil is approximately 200 million.
-
The population of Russia is approximately 146 million.
-
The population of Germany is approximately 81 million.
-
-
-
-
-
-
Checkbox problems allow learners to select multiple options. Learners can see all the options along with the problem text.
-
-
- Urdu
- Finnish
- Marathi
- French
- Hungarian
-
-
Note: Make sure you select all of the correct options—there may be more than one!
-
-
-
Explanation
-
Urdu, Marathi, and French are all Indo-European languages, while Finnish and Hungarian are in the Uralic family.
-
-
-
-
- """)
-
- it 'can separate other things based on ---', ->
- data = MarkdownEditingDescriptor.markdownToXml("""
- Multiple choice problems allow learners to select only one option. Learners can see all the options along with the problem text.
-
- ---
-
- >>Which of the following countries has the largest population?<<
- ( ) Brazil {{ timely feedback -- explain why an almost correct answer is wrong }}
- ( ) Germany
- (x) Indonesia
- ( ) Russia
-
- [explanation]
- According to September 2014 estimates:
- The population of Indonesia is approximately 250 million.
- The population of Brazil is approximately 200 million.
- The population of Russia is approximately 146 million.
- The population of Germany is approximately 81 million.
- [explanation]
- """)
- expect(data).toXMLEqual("""
-
-
Multiple choice problems allow learners to select only one option. Learners can see all the options along with the problem text.
-
-
-
-
- Brazil timely feedback -- explain why an almost correct answer is wrong
-
- Germany
- Indonesia
- Russia
-
-
-
-
Explanation
-
According to September 2014 estimates:
-
The population of Indonesia is approximately 250 million.
-
The population of Brazil is approximately 200 million.
-
The population of Russia is approximately 146 million.
-
The population of Germany is approximately 81 million.
-
-
-
-
- """)
-
- it 'can do separation if spaces are present around ---', ->
- data = MarkdownEditingDescriptor.markdownToXml("""
- >>The following languages are in the Indo-European family:||There are three correct choices.<<
- [x] Urdu
- [ ] Finnish
- [x] Marathi
- [x] French
- [ ] Hungarian
-
- ---
-
- >>Which of the following countries has the largest population?||You have only choice.<<
- ( ) Brazil {{ timely feedback -- explain why an almost correct answer is wrong }}
- ( ) Germany
- (x) Indonesia
- ( ) Russia
- """)
- expect(data).toXMLEqual("""
-
-
-
- There are three correct choices.
-
- Urdu
- Finnish
- Marathi
- French
- Hungarian
-
-
-
-
-
- You have only choice.
-
- Brazil
- timely feedback -- explain why an almost correct answer is wrong
-
- Germany
- Indonesia
- Russia
-
-
-
- """)
-
- it 'can extract question description', ->
- data = MarkdownEditingDescriptor.markdownToXml("""
- >>The following languages are in the Indo-European family:||Choose wisely.<<
- [x] Urdu
- [ ] Finnish
- [x] Marathi
- [x] French
- [ ] Hungarian
- """)
- expect(data).toXMLEqual("""
-
-
-
- Choose wisely.
-
- Urdu
- Finnish
- Marathi
- French
- Hungarian
-
-
-
- """)
-
- it 'can handle question and description spanned across multiple lines', ->
- data = MarkdownEditingDescriptor.markdownToXml("""
- >>The following languages
- are in the
- Indo-European family:
- ||
- first second
- third
- <<
- [x] Urdu
- [ ] Finnish
- [x] Marathi
- """)
- expect(data).toXMLEqual("""
-
-
-
- first second third
-
- Urdu
- Finnish
- Marathi
-
-
-
- """)
-
- it 'will not add empty description', ->
- data = MarkdownEditingDescriptor.markdownToXml("""
- >>The following languages are in the Indo-European family:||<<
- [x] Urdu
- [ ] Finnish
- """)
- expect(data).toXMLEqual("""
-
-
-
-
- Urdu
- Finnish
-
-
-
- """)
+ return it('will not add empty description', function() {
+ const data = MarkdownEditingDescriptor.markdownToXml(`\
+>>The following languages are in the Indo-European family:||<<
+[x] Urdu
+[ ] Finnish\
+`);
+ return expect(data).toXMLEqual(`\
+
+
+
+
+ Urdu
+ Finnish
+
+
+\
+`);
+ });
+ });
+});
diff --git a/common/lib/xmodule/xmodule/js/spec/problem/edit_spec_hint.js b/common/lib/xmodule/xmodule/js/spec/problem/edit_spec_hint.js
index 1a9b7aad97..ef21db04ec 100644
--- a/common/lib/xmodule/xmodule/js/spec/problem/edit_spec_hint.js
+++ b/common/lib/xmodule/xmodule/js/spec/problem/edit_spec_hint.js
@@ -1,996 +1,1036 @@
-# This file tests the parsing of extended-hints, double bracket sections {{ .. }}
-# for all sorts of markdown.
-describe 'Markdown to xml extended hint dropdown', ->
- it 'produces xml', ->
- data = MarkdownEditingDescriptor.markdownToXml("""
- Translation between Dropdown and ________ is straightforward.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+// This file tests the parsing of extended-hints, double bracket sections {{ .. }}
+// for all sorts of markdown.
+describe('Markdown to xml extended hint dropdown', function() {
+ it('produces xml', function() {
+ const data = MarkdownEditingDescriptor.markdownToXml(`\
+Translation between Dropdown and ________ is straightforward.
- [[
- (Multiple Choice) {{ Good Job::Yes, multiple choice is the right answer. }}
- Text Input {{ No, text input problems don't present options. }}
- Numerical Input {{ No, numerical input problems don't present options. }}
- ]]
+[[
+ (Multiple Choice) {{ Good Job::Yes, multiple choice is the right answer. }}
+ Text Input {{ No, text input problems don't present options. }}
+ Numerical Input {{ No, numerical input problems don't present options. }}
+]]
- Clowns have funny _________ to make people laugh.
+Clowns have funny _________ to make people laugh.
- [[
- dogs {{ NOPE::Not dogs, not cats, not toads }}
- (FACES) {{ With lots of makeup, doncha know?}}
+[[
+ dogs {{ NOPE::Not dogs, not cats, not toads }}
+ (FACES) {{ With lots of makeup, doncha know?}}
- money {{ Clowns don't have any money, of course }}
- donkeys {{don't be an ass.}}
- -no hint-
- ]]
-
- """)
- expect(data).toXMLEqual("""
-
-
Translation between Dropdown and ________ is straightforward.
-
-
-
-
-
-
-
-
Clowns have funny _________ to make people laugh.
-
-
-
-
-
-
-
-
-
-
- """)
-
- it 'produces xml with demand hint', ->
- data = MarkdownEditingDescriptor.markdownToXml("""
- Translation between Dropdown and ________ is straightforward.
-
- [[
- (Right) {{ Good Job::yes }}
- Wrong 1 {{no}}
- Wrong 2 {{ Label::no }}
- ]]
-
- || 0) zero ||
- || 1) one ||
- || 2) two ||
- """)
- expect(data).toXMLEqual("""
-
-
-
Translation between Dropdown and ________ is straightforward.
+ money {{ Clowns don't have any money, of course }}
+ donkeys {{don't be an ass.}}
+ -no hint-
+]]
+\
+`);
+ return expect(data).toXMLEqual(`\
+
+
Translation between Dropdown and ________ is straightforward.
+
-
-
-
-
-
-
-
- 0) zero
- 1) one
- 2) two
-
-
- """)
-
- it 'produces xml with single-line markdown syntax', ->
- data = MarkdownEditingDescriptor.markdownToXml("""
- A Question ________ is answered.
-
- [[(Right), Wrong 1, Wrong 2]]
- || 0) zero ||
- || 1) one ||
- """)
- expect(data).toXMLEqual("""
-
-
-
A Question ________ is answered.
-
-
-
-
- 0) zero
- 1) one
-
-
- """)
-
- it 'produces xml with fewer newlines', ->
- data = MarkdownEditingDescriptor.markdownToXml("""
- >>q1<<
- [[ (aa) {{ hint1 }}
- bb
- cc {{ hint2 }} ]]
- """)
- expect(data).toXMLEqual("""
-
-
-
+
+
+
+
+
+
Clowns have funny _________ to make people laugh.
+
-
-
-
-
-
-
-
-
- """)
-
- it 'produces xml even with lots of whitespace', ->
- data = MarkdownEditingDescriptor.markdownToXml("""
- >>q1<<
- [[
-
-
- aa {{ hint1 }}
-
- bb {{ hint2 }}
- (cc)
-
- ]]
- """)
- expect(data).toXMLEqual("""
-
-
-
-
-
-
-
-
-
-
-
-
- """)
-
-describe 'Markdown to xml extended hint checkbox', ->
- it 'produces xml', ->
- data = MarkdownEditingDescriptor.markdownToXml("""
- >>Select all the fruits from the list<<
-
- [x] Apple {{ selected: You're right that apple is a fruit. }, {unselected: Remember that apple is also a fruit.}}
- [ ] Mushroom {{U: You're right that mushrooms aren't fruit}, { selected: Mushroom is a fungus, not a fruit.}}
- [x] Grape {{ selected: You're right that grape is a fruit }, {unselected: Remember that grape is also a fruit.}}
- [ ] Mustang
- [ ] Camero {{S:I don't know what a Camero is but it isn't a fruit.},{U:What is a camero anyway?}}
-
-
- {{ ((A*B)) You're right that apple is a fruit, but there's one you're missing. Also, mushroom is not a fruit.}}
- {{ ((B*C)) You're right that grape is a fruit, but there's one you're missing. Also, mushroom is not a fruit. }}
-
-
- >>Select all the vegetables from the list<<
-
- [ ] Banana {{ selected: No, sorry, a banana is a fruit. }, {unselected: poor banana.}}
- [ ] Ice Cream
- [ ] Mushroom {{U: You're right that mushrooms aren't vegetables.}, { selected: Mushroom is a fungus, not a vegetable.}}
- [x] Brussel Sprout {{S: Brussel sprouts are vegetables.}, {u: Brussel sprout is the only vegetable in this list.}}
-
-
- {{ ((A*B)) Making a banana split? }}
- {{ ((B*D)) That will make a horrible dessert: a brussel sprout split? }}
- """)
- expect(data).toXMLEqual("""
-
-
-
-
- Apple
- You're right that apple is a fruit.
- Remember that apple is also a fruit.
-
- Mushroom
- Mushroom is a fungus, not a fruit.
- You're right that mushrooms aren't fruit
-
- Grape
- You're right that grape is a fruit
- Remember that grape is also a fruit.
-
- Mustang
- Camero
- I don't know what a Camero is but it isn't a fruit.
- What is a camero anyway?
-
- You're right that apple is a fruit, but there's one you're missing. Also, mushroom is not a fruit.
- You're right that grape is a fruit, but there's one you're missing. Also, mushroom is not a fruit.
-
-
-
-
-
-
- Banana
- No, sorry, a banana is a fruit.
- poor banana.
-
- Ice Cream
- Mushroom
- Mushroom is a fungus, not a vegetable.
- You're right that mushrooms aren't vegetables.
-
- Brussel Sprout
- Brussel sprouts are vegetables.
- Brussel sprout is the only vegetable in this list.
-
- Making a banana split?
- That will make a horrible dessert: a brussel sprout split?
-
-
-
- """)
-
- it 'produces xml also with demand hints', ->
- data = MarkdownEditingDescriptor.markdownToXml("""
- >>Select all the fruits from the list<<
-
- [x] Apple {{ selected: You're right that apple is a fruit. }, {unselected: Remember that apple is also a fruit.}}
- [ ] Mushroom {{U: You're right that mushrooms aren't fruit}, { selected: Mushroom is a fungus, not a fruit.}}
- [x] Grape {{ selected: You're right that grape is a fruit }, {unselected: Remember that grape is also a fruit.}}
- [ ] Mustang
- [ ] Camero {{S:I don't know what a Camero is but it isn't a fruit.},{U:What is a camero anyway?}}
-
- {{ ((A*B)) You're right that apple is a fruit, but there's one you're missing. Also, mushroom is not a fruit.}}
- {{ ((B*C)) You're right that grape is a fruit, but there's one you're missing. Also, mushroom is not a fruit.}}
-
- >>Select all the vegetables from the list<<
-
- [ ] Banana {{ selected: No, sorry, a banana is a fruit. }, {unselected: poor banana.}}
- [ ] Ice Cream
- [ ] Mushroom {{U: You're right that mushrooms aren't vegatbles}, { selected: Mushroom is a fungus, not a vegetable.}}
- [x] Brussel Sprout {{S: Brussel sprouts are vegetables.}, {u: Brussel sprout is the only vegetable in this list.}}
-
- {{ ((A*B)) Making a banana split? }}
- {{ ((B*D)) That will make a horrible dessert: a brussel sprout split? }}
-
- || Hint one.||
- || Hint two. ||
- || Hint three. ||
- """)
- expect(data).toXMLEqual("""
-
-
-
-
- Apple
- You're right that apple is a fruit.
- Remember that apple is also a fruit.
-
- Mushroom
- Mushroom is a fungus, not a fruit.
- You're right that mushrooms aren't fruit
-
- Grape
- You're right that grape is a fruit
- Remember that grape is also a fruit.
-
- Mustang
- Camero
- I don't know what a Camero is but it isn't a fruit.
- What is a camero anyway?
-
- You're right that apple is a fruit, but there's one you're missing. Also, mushroom is not a fruit.
- You're right that grape is a fruit, but there's one you're missing. Also, mushroom is not a fruit.
-
-
-
-
-
-
- Banana
- No, sorry, a banana is a fruit.
- poor banana.
-
- Ice Cream
- Mushroom
- Mushroom is a fungus, not a vegetable.
- You're right that mushrooms aren't vegatbles
-
- Brussel Sprout
- Brussel sprouts are vegetables.
- Brussel sprout is the only vegetable in this list.
-
- Making a banana split?
- That will make a horrible dessert: a brussel sprout split?
-
-
-
-
- Hint one.
- Hint two.
- Hint three.
-
-
- """)
-
-
-describe 'Markdown to xml extended hint multiple choice', ->
- it 'produces xml', ->
- data = MarkdownEditingDescriptor.markdownToXml("""
- >>Select the fruit from the list<<
-
- () Mushroom {{ Mushroom is a fungus, not a fruit.}}
- () Potato
- (x) Apple {{ OUTSTANDING::Apple is indeed a fruit.}}
-
- >>Select the vegetables from the list<<
-
- () Mushroom {{ Mushroom is a fungus, not a vegetable.}}
- (x) Potato {{ Potato is a root vegetable. }}
- () Apple {{ OOPS::Apple is a fruit.}}
- """)
- expect(data).toXMLEqual("""
-
-
-
-
- Mushroom
- Mushroom is a fungus, not a fruit.
-
- Potato
- Apple
- Apple is indeed a fruit.
-
-
-
-
-
-
-
- Mushroom
- Mushroom is a fungus, not a vegetable.
-
- Potato
- Potato is a root vegetable.
-
- Apple
- Apple is a fruit.
-
-
-
-
- """)
-
- it 'produces xml with demand hints', ->
- data = MarkdownEditingDescriptor.markdownToXml("""
- >>Select the fruit from the list<<
-
- () Mushroom {{ Mushroom is a fungus, not a fruit.}}
- () Potato
- (x) Apple {{ OUTSTANDING::Apple is indeed a fruit.}}
-
- || 0) spaces on previous line. ||
- || 1) roses are red. ||
-
- >>Select the vegetables from the list<<
-
- () Mushroom {{ Mushroom is a fungus, not a vegetable.}}
- (x) Potato {{ Potato is a root vegetable. }}
- () Apple {{ OOPS::Apple is a fruit.}}
-
- || 2) where are the lions? ||
-
- """)
- expect(data).toXMLEqual("""
-
-
-
-
- Mushroom
- Mushroom is a fungus, not a fruit.
-
- Potato
- Apple
- Apple is indeed a fruit.
-
-
-
-
-
-
-
- Mushroom
- Mushroom is a fungus, not a vegetable.
-
- Potato
- Potato is a root vegetable.
-
- Apple
- Apple is a fruit.
-
-
-
-
-
- 0) spaces on previous line.
- 1) roses are red.
- 2) where are the lions?
-
-
- """)
-
-
-describe 'Markdown to xml extended hint text input', ->
- it 'produces xml', ->
- data = MarkdownEditingDescriptor.markdownToXml(""">>In which country would you find the city of Paris?<<
- = France {{ BRAVO::Viva la France! }}
-
- """)
- expect(data).toXMLEqual("""
-
-
-
- Viva la France!
-
-
-
-
-
- """)
-
- it 'produces xml with or=', ->
- data = MarkdownEditingDescriptor.markdownToXml(""">>Where Paris?<<
- = France {{ BRAVO::hint1}}
- or= USA {{ meh::hint2 }}
-
- """)
- expect(data).toXMLEqual("""
-
-
-
- hint1
- hint2
-
-
-
-
-
-
- """)
-
- it 'produces xml with not=', ->
- data = MarkdownEditingDescriptor.markdownToXml(""">>Revenge is a dish best served<<
- = cold {{khaaaaaan!}}
- not= warm {{feedback2}}
-
- """)
- expect(data).toXMLEqual("""
-
-
-
- khaaaaaan!
- feedback2
-
-
-
-
-
- """)
-
- it 'produces xml with s=', ->
- data = MarkdownEditingDescriptor.markdownToXml(""">>q<<
- s= 2 {{feedback1}}
-
- """)
- expect(data).toXMLEqual("""
-
-
-
- feedback1
-
-
-
-
-
- """)
-
- it 'produces xml with = and or= and not=', ->
- data = MarkdownEditingDescriptor.markdownToXml(""">>q<<
- = aaa
- or= bbb {{feedback1}}
- not= no {{feedback2}}
- or= ccc
-
- """)
- expect(data).toXMLEqual("""
-
-
-
- feedback1
-
- feedback2
-
-
-
-
-
-
- """)
-
- it 'produces xml with s= and or=', ->
- data = MarkdownEditingDescriptor.markdownToXml(""">>q<<
- s= 2 {{feedback1}}
- or= bbb {{feedback2}}
- or= ccc
-
- """)
- expect(data).toXMLEqual("""
-
-
-
- feedback1
- feedback2
-
-
-
-
-
-
-
- """)
-
- it 'produces xml with each = making a new question', ->
- data = MarkdownEditingDescriptor.markdownToXml("""
- >>q<<
- = aaa
- or= bbb
- s= ccc
- """)
- expect(data).toXMLEqual("""
-
-
-
-
-
-
-
-
-
-
- """)
-
- it 'produces xml with each = making a new question amid blank lines and paragraphs', ->
- data = MarkdownEditingDescriptor.markdownToXml("""
- paragraph
- >>q<<
- = aaa
-
- or= bbb
- s= ccc
-
- paragraph 2
-
- """)
- expect(data).toXMLEqual("""
-
-
paragraph
-
-
-
-
-
-
-
-
-
paragraph 2
-
- """)
-
- it 'produces xml without a question when or= is just hung out there by itself', ->
- data = MarkdownEditingDescriptor.markdownToXml("""
- paragraph
- >>q<<
- or= aaa
- paragraph 2
-
- """)
- expect(data).toXMLEqual("""
-
-
paragraph
-
-
or= aaa
-
paragraph 2
-
- """)
-
- it 'produces xml with each = with feedback making a new question', ->
- data = MarkdownEditingDescriptor.markdownToXml("""
- >>q<<
- s= aaa
- or= bbb {{feedback1}}
- = ccc {{feedback2}}
-
- """)
- expect(data).toXMLEqual("""
-
-
-
-
- feedback1
-
-
-
-
- feedback2
-
-
-
- """)
-
- it 'produces xml with demand hints', ->
- data = MarkdownEditingDescriptor.markdownToXml(""">>Where Paris?<<
- = France {{ BRAVO::hint1 }}
-
- || There are actually two countries with cities named Paris. ||
- || Paris is the capital of one of those countries. ||
-
- """)
- expect(data).toXMLEqual("""
-
-
-
- hint1
-
-
-
-
- There are actually two countries with cities named Paris.
- Paris is the capital of one of those countries.
-
- """)
-
-
-describe 'Markdown to xml extended hint numeric input', ->
- it 'produces xml', ->
- data = MarkdownEditingDescriptor.markdownToXml("""
- >>Enter the numerical value of Pi:<<
- = 3.14159 +- .02 {{ Pie for everyone! }}
-
- >>Enter the approximate value of 502*9:<<
- = 4518 +- 15% {{PIE:: No pie for you!}}
-
- >>Enter the number of fingers on a human hand<<
- = 5
-
- """)
- expect(data).toXMLEqual("""
-
-
-
-
-
- Pie for everyone!
-
-
-
-
-
-
- No pie for you!
-
-
-
-
-
-
-
- """)
-
- # The output xml here shows some of the quirks of how historical markdown parsing does or does not put
- # in blank lines.
- it 'numeric input with hints and demand hints', ->
- data = MarkdownEditingDescriptor.markdownToXml("""
- >>text1<<
- = 1 {{ hint1 }}
- || hintA ||
- >>text2<<
- = 2 {{ hint2 }}
-
- || hintB ||
-
- """)
- expect(data).toXMLEqual("""
-
-
-
-
- hint1
-
-
-
-
- hint2
-
-
-
- hintA
- hintB
-
-
- """)
-
-
-describe 'Markdown to xml extended hint with multiline hints', ->
- it 'produces xml', ->
- data = MarkdownEditingDescriptor.markdownToXml("""
- >>Checkboxes<<
-
- [x] A {{
- selected: aaa },
- {unselected:bbb}}
- [ ] B {{U: c}, {
- selected: d.}}
-
- {{ ((A*B)) A*B hint}}
-
- >>What is 1 + 1?<<
- = 2 {{ part one, and
- part two
- }}
-
- >>hello?<<
- = hello {{
- hello
- hint
- }}
-
- >>multiple choice<<
- (x) AA{{hint1}}
- () BB {{
- hint2
- }}
- ( ) CC {{ hint3
- }}
-
- >>dropdown<<
- [[
- W1 {{
- no }}
- W2 {{
- nope}}
- (C1) {{ yes
- }}
- ]]
-
- || aaa ||
- ||bbb||
- || ccc ||
-
- """)
- expect(data).toXMLEqual("""
-
-
-
-
- A
- aaa
- bbb
-
- B
- d.
- c
-
- A*B hint
-
-
-
-
-
-
- part one, and part two
-
-
-
-
- hello hint
-
-
-
-
-
-
- AA
- hint1
-
- BB
- hint2
-
- CC
- hint3
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- aaa
- bbb
- ccc
-
-
- """)
-
-describe 'Markdown to xml extended hint with tricky syntax cases', ->
- # I'm entering this as utf-8 in this file.
- # I cannot find a way to set the encoding for .coffee files but it seems to work.
- it 'produces xml with unicode', ->
- data = MarkdownEditingDescriptor.markdownToXml("""
- >>á and Ø<<
-
- (x) Ø{{Ø}}
- () BB
-
- || Ø ||
-
- """)
- expect(data).toXMLEqual("""
-
-
-
-
- Ø
- Ø
-
- BB
-
-
-
-
- Ø
-
-
- """)
-
- it 'produces xml with quote-type characters', ->
- data = MarkdownEditingDescriptor.markdownToXml("""
- >>"quotes" aren't `fun`<<
- () "hello" {{ isn't }}
- (x) "isn't" {{ "hello" }}
-
- """)
- expect(data).toXMLEqual("""
-
-
-
-
- "hello"
- isn't
-
- "isn't"
- "hello"
-
-
-
-
- """)
-
- it 'produces xml with almost but not quite multiple choice syntax', ->
- data = MarkdownEditingDescriptor.markdownToXml("""
- >>q1<<
- this (x)
- () a {{ (hint) }}
- (x) b
- that (y)
- """)
- expect(data).toXMLEqual("""
-
-
-
-
this (x)
-
- a (hint)
-
- b
-
-
that (y)
-
-
-
-
- """)
-
- # An incomplete checkbox hint passes through to cue the author
- it 'produce xml with almost but not quite checkboxgroup syntax', ->
- data = MarkdownEditingDescriptor.markdownToXml("""
- >>q1<<
- this [x]
- [ ] a [square]
- [x] b {{ this hint passes through }}
- that []
- """)
- expect(data).toXMLEqual("""
-
+
+
+
+
+
+
+
+\
+`);
+ });
+
+ it('produces xml with demand hint', function() {
+ const data = MarkdownEditingDescriptor.markdownToXml(`\
+Translation between Dropdown and ________ is straightforward.
+
+[[
+ (Right) {{ Good Job::yes }}
+ Wrong 1 {{no}}
+ Wrong 2 {{ Label::no }}
+]]
+
+|| 0) zero ||
+|| 1) one ||
+|| 2) two ||\
+`);
+ return expect(data).toXMLEqual(`\
+
+
+
Translation between Dropdown and ________ is straightforward.
+
+
+
+
+
+
+
+
+ 0) zero
+ 1) one
+ 2) two
+
+\
+`);
+ });
+
+ it('produces xml with single-line markdown syntax', function() {
+ const data = MarkdownEditingDescriptor.markdownToXml(`\
+A Question ________ is answered.
+
+[[(Right), Wrong 1, Wrong 2]]
+|| 0) zero ||
+|| 1) one ||\
+`);
+ return expect(data).toXMLEqual(`\
+
+
+
A Question ________ is answered.
+
+
+
+
+ 0) zero
+ 1) one
+
+\
+`);
+ });
+
+ it('produces xml with fewer newlines', function() {
+ const data = MarkdownEditingDescriptor.markdownToXml(`\
+>>q1<<
+[[ (aa) {{ hint1 }}
+ bb
+ cc {{ hint2 }} ]]\
+`);
+ return expect(data).toXMLEqual(`\
+
+
+
+
+
+
+
+
+
+
+
+\
+`);
+ });
+
+ return it('produces xml even with lots of whitespace', function() {
+ const data = MarkdownEditingDescriptor.markdownToXml(`\
+>>q1<<
+[[
+
+
+ aa {{ hint1 }}
+
+ bb {{ hint2 }}
+ (cc)
+
+ ]]\
+`);
+ return expect(data).toXMLEqual(`\
+
+
+
+
+
+
+
+
+
+
+
+\
+`);
+ });
+});
+
+describe('Markdown to xml extended hint checkbox', function() {
+ it('produces xml', function() {
+ const data = MarkdownEditingDescriptor.markdownToXml(`\
+>>Select all the fruits from the list<<
+
+[x] Apple {{ selected: You're right that apple is a fruit. }, {unselected: Remember that apple is also a fruit.}}
+[ ] Mushroom {{U: You're right that mushrooms aren't fruit}, { selected: Mushroom is a fungus, not a fruit.}}
+[x] Grape {{ selected: You're right that grape is a fruit }, {unselected: Remember that grape is also a fruit.}}
+[ ] Mustang
+[ ] Camero {{S:I don't know what a Camero is but it isn't a fruit.},{U:What is a camero anyway?}}
+
+
+{{ ((A*B)) You're right that apple is a fruit, but there's one you're missing. Also, mushroom is not a fruit.}}
+{{ ((B*C)) You're right that grape is a fruit, but there's one you're missing. Also, mushroom is not a fruit. }}
+
+
+>>Select all the vegetables from the list<<
+
+[ ] Banana {{ selected: No, sorry, a banana is a fruit. }, {unselected: poor banana.}}
+[ ] Ice Cream
+[ ] Mushroom {{U: You're right that mushrooms aren't vegetables.}, { selected: Mushroom is a fungus, not a vegetable.}}
+[x] Brussel Sprout {{S: Brussel sprouts are vegetables.}, {u: Brussel sprout is the only vegetable in this list.}}
+
+
+{{ ((A*B)) Making a banana split? }}
+{{ ((B*D)) That will make a horrible dessert: a brussel sprout split? }}\
+`);
+ return expect(data).toXMLEqual(`\
+
+
-
-
this [x]
-
- a [square]
- b {{ this hint passes through }}
-
-
that []
+
+ Apple
+ You're right that apple is a fruit.
+ Remember that apple is also a fruit.
+
+ Mushroom
+ Mushroom is a fungus, not a fruit.
+ You're right that mushrooms aren't fruit
+
+ Grape
+ You're right that grape is a fruit
+ Remember that grape is also a fruit.
+
+ Mustang
+ Camero
+ I don't know what a Camero is but it isn't a fruit.
+ What is a camero anyway?
+
+ You're right that apple is a fruit, but there's one you're missing. Also, mushroom is not a fruit.
+ You're right that grape is a fruit, but there's one you're missing. Also, mushroom is not a fruit.
+
+
+
+
+ Banana
+ No, sorry, a banana is a fruit.
+ poor banana.
+
+ Ice Cream
+ Mushroom
+ Mushroom is a fungus, not a vegetable.
+ You're right that mushrooms aren't vegetables.
+
+ Brussel Sprout
+ Brussel sprouts are vegetables.
+ Brussel sprout is the only vegetable in this list.
+
+ Making a banana split?
+ That will make a horrible dessert: a brussel sprout split?
+
+
+\
+`);
+ });
-
- """)
+ return it('produces xml also with demand hints', function() {
+ const data = MarkdownEditingDescriptor.markdownToXml(`\
+>>Select all the fruits from the list<<
- # It's sort of a pain to edit DOS line endings without some editor or other "fixing" them
- # for you. Therefore, we construct DOS line endings on the fly just for the test.
- it 'produces xml with DOS \r\n line endings', ->
- markdown = """
- >>q22<<
+[x] Apple {{ selected: You're right that apple is a fruit. }, {unselected: Remember that apple is also a fruit.}}
+[ ] Mushroom {{U: You're right that mushrooms aren't fruit}, { selected: Mushroom is a fungus, not a fruit.}}
+[x] Grape {{ selected: You're right that grape is a fruit }, {unselected: Remember that grape is also a fruit.}}
+[ ] Mustang
+[ ] Camero {{S:I don't know what a Camero is but it isn't a fruit.},{U:What is a camero anyway?}}
- [[
- (x) {{ hintx
- these
- span
- }}
+{{ ((A*B)) You're right that apple is a fruit, but there's one you're missing. Also, mushroom is not a fruit.}}
+{{ ((B*C)) You're right that grape is a fruit, but there's one you're missing. Also, mushroom is not a fruit.}}
- yy {{ meh::hinty }}
- zzz {{ hintz }}
- ]]
- """
- markdown = markdown.replace(/\n/g, '\r\n') # make DOS line endings
- data = MarkdownEditingDescriptor.markdownToXml(markdown)
- expect(data).toXMLEqual("""
-
+>>Select all the vegetables from the list<<
+
+[ ] Banana {{ selected: No, sorry, a banana is a fruit. }, {unselected: poor banana.}}
+[ ] Ice Cream
+[ ] Mushroom {{U: You're right that mushrooms aren't vegatbles}, { selected: Mushroom is a fungus, not a vegetable.}}
+[x] Brussel Sprout {{S: Brussel sprouts are vegetables.}, {u: Brussel sprout is the only vegetable in this list.}}
+
+{{ ((A*B)) Making a banana split? }}
+{{ ((B*D)) That will make a horrible dessert: a brussel sprout split? }}
+
+|| Hint one.||
+|| Hint two. ||
+|| Hint three. ||\
+`);
+ return expect(data).toXMLEqual(`\
+
+
+
+
+ Apple
+ You're right that apple is a fruit.
+ Remember that apple is also a fruit.
+
+ Mushroom
+ Mushroom is a fungus, not a fruit.
+ You're right that mushrooms aren't fruit
+
+ Grape
+ You're right that grape is a fruit
+ Remember that grape is also a fruit.
+
+ Mustang
+ Camero
+ I don't know what a Camero is but it isn't a fruit.
+ What is a camero anyway?
+
+ You're right that apple is a fruit, but there's one you're missing. Also, mushroom is not a fruit.
+ You're right that grape is a fruit, but there's one you're missing. Also, mushroom is not a fruit.
+
+
+
+
+
+
+ Banana
+ No, sorry, a banana is a fruit.
+ poor banana.
+
+ Ice Cream
+ Mushroom
+ Mushroom is a fungus, not a vegetable.
+ You're right that mushrooms aren't vegatbles
+
+ Brussel Sprout
+ Brussel sprouts are vegetables.
+ Brussel sprout is the only vegetable in this list.
+
+ Making a banana split?
+ That will make a horrible dessert: a brussel sprout split?
+
+
+
+
+ Hint one.
+ Hint two.
+ Hint three.
+
+\
+`);
+ });
+});
+
+
+describe('Markdown to xml extended hint multiple choice', function() {
+ it('produces xml', function() {
+ const data = MarkdownEditingDescriptor.markdownToXml(`\
+>>Select the fruit from the list<<
+
+() Mushroom {{ Mushroom is a fungus, not a fruit.}}
+() Potato
+(x) Apple {{ OUTSTANDING::Apple is indeed a fruit.}}
+
+>>Select the vegetables from the list<<
+
+() Mushroom {{ Mushroom is a fungus, not a vegetable.}}
+(x) Potato {{ Potato is a root vegetable. }}
+() Apple {{ OOPS::Apple is a fruit.}}\
+`);
+ return expect(data).toXMLEqual(`\
+
+
+
+
+ Mushroom
+ Mushroom is a fungus, not a fruit.
+
+ Potato
+ Apple
+ Apple is indeed a fruit.
+
+
+
+
+
+
+
+ Mushroom
+ Mushroom is a fungus, not a vegetable.
+
+ Potato
+ Potato is a root vegetable.
+
+ Apple
+ Apple is a fruit.
+
+
+
+\
+`);
+ });
+
+ return it('produces xml with demand hints', function() {
+ const data = MarkdownEditingDescriptor.markdownToXml(`\
+>>Select the fruit from the list<<
+
+() Mushroom {{ Mushroom is a fungus, not a fruit.}}
+() Potato
+(x) Apple {{ OUTSTANDING::Apple is indeed a fruit.}}
+
+|| 0) spaces on previous line. ||
+|| 1) roses are red. ||
+
+>>Select the vegetables from the list<<
+
+() Mushroom {{ Mushroom is a fungus, not a vegetable.}}
+(x) Potato {{ Potato is a root vegetable. }}
+() Apple {{ OOPS::Apple is a fruit.}}
+
+|| 2) where are the lions? ||
+\
+`);
+ return expect(data).toXMLEqual(`\
+
+
+
+
+ Mushroom
+ Mushroom is a fungus, not a fruit.
+
+ Potato
+ Apple
+ Apple is indeed a fruit.
+
+
+
+
+
+
+
+ Mushroom
+ Mushroom is a fungus, not a vegetable.
+
+ Potato
+ Potato is a root vegetable.
+
+ Apple
+ Apple is a fruit.
+
+
+
+
+
+ 0) spaces on previous line.
+ 1) roses are red.
+ 2) where are the lions?
+
+\
+`);
+ });
+});
+
+
+describe('Markdown to xml extended hint text input', function() {
+ it('produces xml', function() {
+ const data = MarkdownEditingDescriptor.markdownToXml(`>>In which country would you find the city of Paris?<<
+= France {{ BRAVO::Viva la France! }}
+\
+`);
+ return expect(data).toXMLEqual(`\
+
+
+
+Viva la France!
+
+
+
+
+\
+`);
+ });
+
+ it('produces xml with or=', function() {
+ const data = MarkdownEditingDescriptor.markdownToXml(`>>Where Paris?<<
+= France {{ BRAVO::hint1}}
+or= USA {{ meh::hint2 }}
+\
+`);
+ return expect(data).toXMLEqual(`\
+
+
+
+hint1
+ hint2
+
+
+
+
+
+\
+`);
+ });
+
+ it('produces xml with not=', function() {
+ const data = MarkdownEditingDescriptor.markdownToXml(`>>Revenge is a dish best served<<
+= cold {{khaaaaaan!}}
+not= warm {{feedback2}}
+\
+`);
+ return expect(data).toXMLEqual(`\
+
+
+
+khaaaaaan!
+ feedback2
+
+
+
+
+\
+`);
+ });
+
+ it('produces xml with s=', function() {
+ const data = MarkdownEditingDescriptor.markdownToXml(`>>q<<
+s= 2 {{feedback1}}
+\
+`);
+ return expect(data).toXMLEqual(`\
+
+
+
+feedback1
+
+
+
+
+\
+`);
+ });
+
+ it('produces xml with = and or= and not=', function() {
+ const data = MarkdownEditingDescriptor.markdownToXml(`>>q<<
+= aaa
+or= bbb {{feedback1}}
+not= no {{feedback2}}
+or= ccc
+\
+`);
+ return expect(data).toXMLEqual(`\
+
+
+
+feedback1
+
+ feedback2
+
+
+
+
+
+\
+`);
+ });
+
+ it('produces xml with s= and or=', function() {
+ const data = MarkdownEditingDescriptor.markdownToXml(`>>q<<
+s= 2 {{feedback1}}
+or= bbb {{feedback2}}
+or= ccc
+\
+`);
+ return expect(data).toXMLEqual(`\
+
+
+
+feedback1
+ feedback2
+
+
+
+
+
+
+\
+`);
+ });
+
+ it('produces xml with each = making a new question', function() {
+ const data = MarkdownEditingDescriptor.markdownToXml(`\
+>>q<<
+= aaa
+or= bbb
+s= ccc\
+`);
+ return expect(data).toXMLEqual(`\
+
+
+
+
+
+
+
+
+
+\
+`);
+ });
+
+ it('produces xml with each = making a new question amid blank lines and paragraphs', function() {
+ const data = MarkdownEditingDescriptor.markdownToXml(`\
+paragraph
+>>q<<
+= aaa
+
+or= bbb
+s= ccc
+
+paragraph 2
+\
+`);
+ return expect(data).toXMLEqual(`\
+
+
paragraph
+
+
+
+
+
+
+
+
+
paragraph 2
+\
+`);
+ });
+
+ it('produces xml without a question when or= is just hung out there by itself', function() {
+ const data = MarkdownEditingDescriptor.markdownToXml(`\
+paragraph
+>>q<<
+or= aaa
+paragraph 2
+\
+`);
+ return expect(data).toXMLEqual(`\
+
+
paragraph
+
+
or= aaa
+
paragraph 2
+\
+`);
+ });
+
+ it('produces xml with each = with feedback making a new question', function() {
+ const data = MarkdownEditingDescriptor.markdownToXml(`\
+>>q<<
+s= aaa
+or= bbb {{feedback1}}
+= ccc {{feedback2}}
+\
+`);
+ return expect(data).toXMLEqual(`\
+
+
+
+
+ feedback1
+
+
+
+
+ feedback2
+
+
+\
+`);
+ });
+
+ return it('produces xml with demand hints', function() {
+ const data = MarkdownEditingDescriptor.markdownToXml(`>>Where Paris?<<
+= France {{ BRAVO::hint1 }}
+
+|| There are actually two countries with cities named Paris. ||
+|| Paris is the capital of one of those countries. ||
+\
+`);
+ return expect(data).toXMLEqual(`\
+
+
+
+hint1
+
+
+
+
+ There are actually two countries with cities named Paris.
+ Paris is the capital of one of those countries.
+
+`);
+ });
+});
+
+
+describe('Markdown to xml extended hint numeric input', function() {
+ it('produces xml', function() {
+ const data = MarkdownEditingDescriptor.markdownToXml(`\
+>>Enter the numerical value of Pi:<<
+= 3.14159 +- .02 {{ Pie for everyone! }}
+
+>>Enter the approximate value of 502*9:<<
+= 4518 +- 15% {{PIE:: No pie for you!}}
+
+>>Enter the number of fingers on a human hand<<
+= 5
+\
+`);
+ return expect(data).toXMLEqual(`\
+
+
+
+
+
+ Pie for everyone!
+
+
+
+
+
+
+ No pie for you!
+
+
+
+
+
+
+\
+`);
+ });
+
+ // The output xml here shows some of the quirks of how historical markdown parsing does or does not put
+ // in blank lines.
+ return it('numeric input with hints and demand hints', function() {
+ const data = MarkdownEditingDescriptor.markdownToXml(`\
+>>text1<<
+= 1 {{ hint1 }}
+|| hintA ||
+>>text2<<
+= 2 {{ hint2 }}
+
+|| hintB ||
+\
+`);
+ return expect(data).toXMLEqual(`\
+
+
+
+
+ hint1
+
+
+
+
+ hint2
+
+
+
+ hintA
+ hintB
+
+\
+`);
+ });
+});
+
+
+describe('Markdown to xml extended hint with multiline hints', () =>
+ it('produces xml', function() {
+ const data = MarkdownEditingDescriptor.markdownToXml(`\
+>>Checkboxes<<
+
+[x] A {{
+selected: aaa },
+{unselected:bbb}}
+[ ] B {{U: c}, {
+selected: d.}}
+
+{{ ((A*B)) A*B hint}}
+
+>>What is 1 + 1?<<
+= 2 {{ part one, and
+ part two
+ }}
+
+>>hello?<<
+= hello {{
+hello
+hint
+}}
+
+>>multiple choice<<
+(x) AA{{hint1}}
+() BB {{
+ hint2
+}}
+( ) CC {{ hint3
+}}
+
+>>dropdown<<
+[[
+ W1 {{
+ no }}
+ W2 {{
+ nope}}
+ (C1) {{ yes
+ }}
+]]
+
+|| aaa ||
+||bbb||
+|| ccc ||
+\
+`);
+ return expect(data).toXMLEqual(`\
+
+
+
+
+ A
+ aaa
+ bbb
+
+ B
+ d.
+ c
+
+ A*B hint
+
+
+
+
+
+
+ part one, and part two
+
+
+
+
+ hello hint
+
+
+
+
+
+
+ AA
+ hint1
+
+ BB
+ hint2
+
+ CC
+ hint3
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+ aaa
+ bbb
+ ccc
+
+\
+`);
+ })
+);
-
- """)
+describe('Markdown to xml extended hint with tricky syntax cases', function() {
+ // I'm entering this as utf-8 in this file.
+ // I cannot find a way to set the encoding for .coffee files but it seems to work.
+ it('produces xml with unicode', function() {
+ const data = MarkdownEditingDescriptor.markdownToXml(`\
+>>á and Ø<<
+
+(x) Ø{{Ø}}
+() BB
+
+|| Ø ||
+\
+`);
+ return expect(data).toXMLEqual(`\
+
+
+
+
+ Ø
+ Ø
+
+ BB
+
+
+
+
+ Ø
+
+\
+`);
+ });
+
+ it('produces xml with quote-type characters', function() {
+ const data = MarkdownEditingDescriptor.markdownToXml(`\
+>>"quotes" aren't \`fun\`<<
+() "hello" {{ isn't }}
+(x) "isn't" {{ "hello" }}
+\
+`);
+ return expect(data).toXMLEqual(`\
+
+
+
+
+ "hello"
+ isn't
+
+ "isn't"
+ "hello"
+
+
+
+\
+`);
+ });
+
+ it('produces xml with almost but not quite multiple choice syntax', function() {
+ const data = MarkdownEditingDescriptor.markdownToXml(`\
+>>q1<<
+this (x)
+() a {{ (hint) }}
+(x) b
+that (y)\
+`);
+ return expect(data).toXMLEqual(`\
+
+
+
+
this (x)
+
+ a (hint)
+
+ b
+
+
that (y)
+
+
+
+\
+`);
+ });
+
+ // An incomplete checkbox hint passes through to cue the author
+ it('produce xml with almost but not quite checkboxgroup syntax', function() {
+ const data = MarkdownEditingDescriptor.markdownToXml(`\
+>>q1<<
+this [x]
+[ ] a [square]
+[x] b {{ this hint passes through }}
+that []\
+`);
+ return expect(data).toXMLEqual(`\
+
+
+
+
this [x]
+
+ a [square]
+ b {{ this hint passes through }}
+
+
that []
+
+
+
+\
+`);
+ });
+
+ // It's sort of a pain to edit DOS line endings without some editor or other "fixing" them
+ // for you. Therefore, we construct DOS line endings on the fly just for the test.
+ return it('produces xml with DOS \r\n line endings', function() {
+ let markdown = `\
+>>q22<<
+
+[[
+ (x) {{ hintx
+ these
+ span
+ }}
+
+ yy {{ meh::hinty }}
+ zzz {{ hintz }}
+]]\
+`;
+ markdown = markdown.replace(/\n/g, '\r\n'); // make DOS line endings
+ const data = MarkdownEditingDescriptor.markdownToXml(markdown);
+ return expect(data).toXMLEqual(`\
+
+
+
+
+
+
+
+
+
+
+
+\
+`);
+ });
+});
diff --git a/common/lib/xmodule/xmodule/js/spec/tabs/edit.js b/common/lib/xmodule/xmodule/js/spec/tabs/edit.js
index ae73009bf3..79c6762c26 100644
--- a/common/lib/xmodule/xmodule/js/spec/tabs/edit.js
+++ b/common/lib/xmodule/xmodule/js/spec/tabs/edit.js
@@ -1,90 +1,111 @@
-describe "TabsEditingDescriptor", ->
- beforeEach ->
- @isInactiveClass = "is-inactive"
- @isCurrent = "current"
- loadFixtures 'tabs-edit.html'
- @descriptor = new TabsEditingDescriptor($('.xblock'))
- @html_id = 'test_id'
- @tab_0_switch = jasmine.createSpy('tab_0_switch');
- @tab_0_modelUpdate = jasmine.createSpy('tab_0_modelUpdate');
- @tab_1_switch = jasmine.createSpy('tab_1_switch');
- @tab_1_modelUpdate = jasmine.createSpy('tab_1_modelUpdate');
- TabsEditingDescriptor.Model.addModelUpdate(@html_id, 'Tab 0 Editor', @tab_0_modelUpdate)
- TabsEditingDescriptor.Model.addOnSwitch(@html_id, 'Tab 0 Editor', @tab_0_switch)
- TabsEditingDescriptor.Model.addModelUpdate(@html_id, 'Tab 1 Transcripts', @tab_1_modelUpdate)
- TabsEditingDescriptor.Model.addOnSwitch(@html_id, 'Tab 1 Transcripts', @tab_1_switch)
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+describe("TabsEditingDescriptor", function() {
+ beforeEach(function() {
+ this.isInactiveClass = "is-inactive";
+ this.isCurrent = "current";
+ loadFixtures('tabs-edit.html');
+ this.descriptor = new TabsEditingDescriptor($('.xblock'));
+ this.html_id = 'test_id';
+ this.tab_0_switch = jasmine.createSpy('tab_0_switch');
+ this.tab_0_modelUpdate = jasmine.createSpy('tab_0_modelUpdate');
+ this.tab_1_switch = jasmine.createSpy('tab_1_switch');
+ this.tab_1_modelUpdate = jasmine.createSpy('tab_1_modelUpdate');
+ TabsEditingDescriptor.Model.addModelUpdate(this.html_id, 'Tab 0 Editor', this.tab_0_modelUpdate);
+ TabsEditingDescriptor.Model.addOnSwitch(this.html_id, 'Tab 0 Editor', this.tab_0_switch);
+ TabsEditingDescriptor.Model.addModelUpdate(this.html_id, 'Tab 1 Transcripts', this.tab_1_modelUpdate);
+ TabsEditingDescriptor.Model.addOnSwitch(this.html_id, 'Tab 1 Transcripts', this.tab_1_switch);
- spyOn($.fn, 'hide').and.callThrough()
- spyOn($.fn, 'show').and.callThrough()
- spyOn(TabsEditingDescriptor.Model, 'initialize')
- spyOn(TabsEditingDescriptor.Model, 'updateValue')
+ spyOn($.fn, 'hide').and.callThrough();
+ spyOn($.fn, 'show').and.callThrough();
+ spyOn(TabsEditingDescriptor.Model, 'initialize');
+ return spyOn(TabsEditingDescriptor.Model, 'updateValue');
+ });
- afterEach ->
- TabsEditingDescriptor.Model.modules= {}
+ afterEach(() => TabsEditingDescriptor.Model.modules= {});
- describe "constructor", ->
- it "first tab should be visible", ->
- expect(@descriptor.$tabs.first()).toHaveClass(@isCurrent)
- expect(@descriptor.$content.first()).not.toHaveClass(@isInactiveClass)
+ describe("constructor", () =>
+ it("first tab should be visible", function() {
+ expect(this.descriptor.$tabs.first()).toHaveClass(this.isCurrent);
+ return expect(this.descriptor.$content.first()).not.toHaveClass(this.isInactiveClass);
+ })
+ );
- describe "onSwitchEditor", ->
- it "switching tabs changes styles", ->
- @descriptor.$tabs.eq(1).trigger("click")
- expect(@descriptor.$tabs.eq(0)).not.toHaveClass(@isCurrent)
- expect(@descriptor.$content.eq(0)).toHaveClass(@isInactiveClass)
- expect(@descriptor.$tabs.eq(1)).toHaveClass(@isCurrent)
- expect(@descriptor.$content.eq(1)).not.toHaveClass(@isInactiveClass)
- expect(@tab_1_switch).toHaveBeenCalled()
+ describe("onSwitchEditor", function() {
+ it("switching tabs changes styles", function() {
+ this.descriptor.$tabs.eq(1).trigger("click");
+ expect(this.descriptor.$tabs.eq(0)).not.toHaveClass(this.isCurrent);
+ expect(this.descriptor.$content.eq(0)).toHaveClass(this.isInactiveClass);
+ expect(this.descriptor.$tabs.eq(1)).toHaveClass(this.isCurrent);
+ expect(this.descriptor.$content.eq(1)).not.toHaveClass(this.isInactiveClass);
+ return expect(this.tab_1_switch).toHaveBeenCalled();
+ });
- it "if click on current tab, nothing should happen", ->
- spyOn($.fn, 'trigger').and.callThrough()
- currentTab = @descriptor.$tabs.filter('.' + @isCurrent)
- @descriptor.$tabs.eq(0).trigger("click")
- expect(@descriptor.$tabs.filter('.' + @isCurrent)).toEqual(currentTab)
- expect($.fn.trigger.calls.count()).toEqual(1)
+ it("if click on current tab, nothing should happen", function() {
+ spyOn($.fn, 'trigger').and.callThrough();
+ const currentTab = this.descriptor.$tabs.filter(`.${this.isCurrent}`);
+ this.descriptor.$tabs.eq(0).trigger("click");
+ expect(this.descriptor.$tabs.filter(`.${this.isCurrent}`)).toEqual(currentTab);
+ return expect($.fn.trigger.calls.count()).toEqual(1);
+ });
- it "onSwitch function call", ->
- @descriptor.$tabs.eq(1).trigger("click")
- expect(TabsEditingDescriptor.Model.updateValue).toHaveBeenCalled()
- expect(@tab_1_switch).toHaveBeenCalled()
+ return it("onSwitch function call", function() {
+ this.descriptor.$tabs.eq(1).trigger("click");
+ expect(TabsEditingDescriptor.Model.updateValue).toHaveBeenCalled();
+ return expect(this.tab_1_switch).toHaveBeenCalled();
+ });
+ });
- describe "save", ->
- it "function for current tab should be called", ->
- @descriptor.$tabs.eq(1).trigger("click")
- data = @descriptor.save().data
- expect(@tab_1_modelUpdate).toHaveBeenCalled()
+ return describe("save", function() {
+ it("function for current tab should be called", function() {
+ this.descriptor.$tabs.eq(1).trigger("click");
+ const { data } = this.descriptor.save();
+ return expect(this.tab_1_modelUpdate).toHaveBeenCalled();
+ });
- it "detach click event", ->
- spyOn($.fn, "off")
- @descriptor.save()
- expect($.fn.off).toHaveBeenCalledWith(
+ return it("detach click event", function() {
+ spyOn($.fn, "off");
+ this.descriptor.save();
+ return expect($.fn.off).toHaveBeenCalledWith(
'click',
'.editor-tabs .tab',
- @descriptor.onSwitchEditor
- )
+ this.descriptor.onSwitchEditor
+ );
+ });
+ });
+});
-describe "TabsEditingDescriptor special save cases", ->
- beforeEach ->
- @isInactiveClass = "is-inactive"
- @isCurrent = "current"
- loadFixtures 'tabs-edit.html'
- @descriptor = new window.TabsEditingDescriptor($('.xblock'))
- @html_id = 'test_id'
+describe("TabsEditingDescriptor special save cases", function() {
+ beforeEach(function() {
+ this.isInactiveClass = "is-inactive";
+ this.isCurrent = "current";
+ loadFixtures('tabs-edit.html');
+ this.descriptor = new window.TabsEditingDescriptor($('.xblock'));
+ return this.html_id = 'test_id';
+ });
- describe "save", ->
- it "case: no init", ->
- data = @descriptor.save().data
- expect(data).toEqual(null)
+ return describe("save", function() {
+ it("case: no init", function() {
+ const { data } = this.descriptor.save();
+ return expect(data).toEqual(null);
+ });
- it "case: no function in model update", ->
- TabsEditingDescriptor.Model.initialize(@html_id)
- data = @descriptor.save().data
- expect(data).toEqual(null)
+ it("case: no function in model update", function() {
+ TabsEditingDescriptor.Model.initialize(this.html_id);
+ const { data } = this.descriptor.save();
+ return expect(data).toEqual(null);
+ });
- it "case: no function in model update, but value presented", ->
- @tab_0_modelUpdate = jasmine.createSpy('tab_0_modelUpdate').and.returnValue(1)
- TabsEditingDescriptor.Model.addModelUpdate(@html_id, 'Tab 0 Editor', @tab_0_modelUpdate)
- @descriptor.$tabs.eq(1).trigger("click")
- expect(@tab_0_modelUpdate).toHaveBeenCalled()
- data = @descriptor.save().data
- expect(data).toEqual(1)
+ return it("case: no function in model update, but value presented", function() {
+ this.tab_0_modelUpdate = jasmine.createSpy('tab_0_modelUpdate').and.returnValue(1);
+ TabsEditingDescriptor.Model.addModelUpdate(this.html_id, 'Tab 0 Editor', this.tab_0_modelUpdate);
+ this.descriptor.$tabs.eq(1).trigger("click");
+ expect(this.tab_0_modelUpdate).toHaveBeenCalled();
+ const { data } = this.descriptor.save();
+ return expect(data).toEqual(1);
+ });
+ });
+});
diff --git a/common/static/coffee/spec/jquery.immediateDescendents_spec.js b/common/static/coffee/spec/jquery.immediateDescendents_spec.js
index d16bc29c20..6d99bc145e 100644
--- a/common/static/coffee/spec/jquery.immediateDescendents_spec.js
+++ b/common/static/coffee/spec/jquery.immediateDescendents_spec.js
@@ -1,26 +1,38 @@
-describe "$.immediateDescendents", ->
- beforeEach ->
- setFixtures """
-
-
-
-
-
-
-
-
- """
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+describe("$.immediateDescendents", function() {
+ beforeEach(function() {
+ setFixtures(`\
+
+
+
+
+
+
+
+
\
+`
+ );
- @descendents = $('#jasmine-fixtures').immediateDescendents(".xblock").get()
+ return this.descendents = $('#jasmine-fixtures').immediateDescendents(".xblock").get();
+ });
- it "finds non-immediate children", ->
- expect(@descendents).toContain($('#grandchild').get(0))
+ it("finds non-immediate children", function() {
+ return expect(this.descendents).toContain($('#grandchild').get(0));
+ });
- it "finds immediate children", ->
- expect(@descendents).toContain($('#child').get(0))
+ it("finds immediate children", function() {
+ return expect(this.descendents).toContain($('#child').get(0));
+ });
- it "skips nested descendents", ->
- expect(@descendents).not.toContain($('#nested').get(0))
+ it("skips nested descendents", function() {
+ return expect(this.descendents).not.toContain($('#nested').get(0));
+ });
- it "finds 2 children", ->
- expect(@descendents.length).toBe(2)
\ No newline at end of file
+ return it("finds 2 children", function() {
+ return expect(this.descendents.length).toBe(2);
+ });
+});
\ No newline at end of file
diff --git a/lms/static/coffee/spec/calculator_spec.js b/lms/static/coffee/spec/calculator_spec.js
index 91d69902e1..87159ae0ad 100644
--- a/lms/static/coffee/spec/calculator_spec.js
+++ b/lms/static/coffee/spec/calculator_spec.js
@@ -1,353 +1,435 @@
-describe 'Calculator', ->
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+describe('Calculator', function() {
- KEY =
- TAB : 9
- ENTER : 13
- ALT : 18
- ESC : 27
- SPACE : 32
- LEFT : 37
- UP : 38
- RIGHT : 39
+ const KEY = {
+ TAB : 9,
+ ENTER : 13,
+ ALT : 18,
+ ESC : 27,
+ SPACE : 32,
+ LEFT : 37,
+ UP : 38,
+ RIGHT : 39,
DOWN : 40
+ };
- beforeEach ->
- loadFixtures 'coffee/fixtures/calculator.html'
- @calculator = new Calculator
+ beforeEach(function() {
+ loadFixtures('coffee/fixtures/calculator.html');
+ return this.calculator = new Calculator;
+ });
- describe 'bind', ->
- it 'bind the calculator button', ->
- expect($('.calc')).toHandleWith 'click', @calculator.toggle
+ describe('bind', function() {
+ it('bind the calculator button', function() {
+ return expect($('.calc')).toHandleWith('click', this.calculator.toggle);
+ });
- it 'bind key up on calculator', ->
- expect($('#calculator_wrapper')).toHandle 'keyup', @calculator.handleKeyUpOnHint
+ it('bind key up on calculator', function() {
+ return expect($('#calculator_wrapper')).toHandle('keyup', this.calculator.handleKeyUpOnHint);
+ });
- it 'bind the help button', ->
- # This events is bind by $.click()
- expect($('#calculator_hint')).toHandle 'click'
+ it('bind the help button', () =>
+ // This events is bind by $.click()
+ expect($('#calculator_hint')).toHandle('click')
+ );
- it 'bind the calculator submit', ->
- expect($('form#calculator')).toHandleWith 'submit', @calculator.calculate
+ it('bind the calculator submit', function() {
+ return expect($('form#calculator')).toHandleWith('submit', this.calculator.calculate);
+ });
- xit 'prevent default behavior on form submit', ->
- jasmine.stubRequests()
- $('form#calculator').submit (e) ->
- expect(e.isDefaultPrevented()).toBeTruthy()
- e.preventDefault()
- $('form#calculator').submit()
+ return xit('prevent default behavior on form submit', function() {
+ jasmine.stubRequests();
+ $('form#calculator').submit(function(e) {
+ expect(e.isDefaultPrevented()).toBeTruthy();
+ return e.preventDefault();
+ });
+ return $('form#calculator').submit();
+ });
+ });
- describe 'toggle', ->
- it 'focuses the input when toggled', (done)->
+ describe('toggle', function() {
+ it('focuses the input when toggled', function(done){
- self = this
- focus = ()->
- deferred = $.Deferred()
+ const self = this;
+ const focus = function(){
+ const deferred = $.Deferred();
- # Since the focus is called asynchronously, we need to
- # wait until focus() is called.
- spyOn($.fn, 'focus').and.callFake (elementName) ->
- deferred.resolve()
+ // Since the focus is called asynchronously, we need to
+ // wait until focus() is called.
+ spyOn($.fn, 'focus').and.callFake(elementName => deferred.resolve());
- self.calculator.toggle(jQuery.Event("click"))
+ self.calculator.toggle(jQuery.Event("click"));
- deferred.promise()
+ return deferred.promise();
+ };
- focus().then(
- ->
- expect($('#calculator_wrapper #calculator_input').focus).toHaveBeenCalled()
- ).always(done)
+ return focus().then(
+ () => expect($('#calculator_wrapper #calculator_input').focus).toHaveBeenCalled()).always(done);
+ });
- it 'toggle the close button on the calculator button', ->
- @calculator.toggle(jQuery.Event("click"))
- expect($('.calc')).toHaveClass('closed')
+ return it('toggle the close button on the calculator button', function() {
+ this.calculator.toggle(jQuery.Event("click"));
+ expect($('.calc')).toHaveClass('closed');
- @calculator.toggle(jQuery.Event("click"))
- expect($('.calc')).not.toHaveClass('closed')
+ this.calculator.toggle(jQuery.Event("click"));
+ return expect($('.calc')).not.toHaveClass('closed');
+ });
+ });
- describe 'showHint', ->
- it 'show the help overlay', ->
- @calculator.showHint()
- expect($('.help')).toHaveClass('shown')
- expect($('.help')).toHaveAttr('aria-hidden', 'false')
+ describe('showHint', () =>
+ it('show the help overlay', function() {
+ this.calculator.showHint();
+ expect($('.help')).toHaveClass('shown');
+ return expect($('.help')).toHaveAttr('aria-hidden', 'false');
+ })
+ );
- describe 'hideHint', ->
- it 'show the help overlay', ->
- @calculator.hideHint()
- expect($('.help')).not.toHaveClass('shown')
- expect($('.help')).toHaveAttr('aria-hidden', 'true')
+ describe('hideHint', () =>
+ it('show the help overlay', function() {
+ this.calculator.hideHint();
+ expect($('.help')).not.toHaveClass('shown');
+ return expect($('.help')).toHaveAttr('aria-hidden', 'true');
+ })
+ );
- describe 'handleClickOnHintButton', ->
- it 'on click hint button hint popup becomes visible ', ->
- e = jQuery.Event('click');
+ describe('handleClickOnHintButton', () =>
+ it('on click hint button hint popup becomes visible ', function() {
+ const e = jQuery.Event('click');
$('#calculator_hint').trigger(e);
- expect($('.help')).toHaveClass 'shown'
+ return expect($('.help')).toHaveClass('shown');
+ })
+ );
- describe 'handleClickOnDocument', ->
- it 'on click out of the hint popup it becomes hidden', ->
- @calculator.showHint()
- e = jQuery.Event('click');
+ describe('handleClickOnDocument', () =>
+ it('on click out of the hint popup it becomes hidden', function() {
+ this.calculator.showHint();
+ const e = jQuery.Event('click');
$(document).trigger(e);
- expect($('.help')).not.toHaveClass 'shown'
+ return expect($('.help')).not.toHaveClass('shown');
+ })
+ );
- describe 'handleClickOnHintPopup', ->
- it 'on click of hint popup it remains visible', ->
- @calculator.showHint()
- e = jQuery.Event('click');
+ describe('handleClickOnHintPopup', () =>
+ it('on click of hint popup it remains visible', function() {
+ this.calculator.showHint();
+ const e = jQuery.Event('click');
$('#calculator_input_help').trigger(e);
- expect($('.help')).toHaveClass 'shown'
+ return expect($('.help')).toHaveClass('shown');
+ })
+ );
- describe 'selectHint', ->
- it 'select correct hint item', ->
- spyOn($.fn, 'focus')
- element = $('.hint-item').eq(1)
- @calculator.selectHint(element)
+ describe('selectHint', function() {
+ it('select correct hint item', function() {
+ spyOn($.fn, 'focus');
+ const element = $('.hint-item').eq(1);
+ this.calculator.selectHint(element);
- expect(element.focus).toHaveBeenCalled()
- expect(@calculator.activeHint).toEqual(element)
- expect(@calculator.hintPopup).toHaveAttr('data-calculator-hint', element.attr('id'))
+ expect(element.focus).toHaveBeenCalled();
+ expect(this.calculator.activeHint).toEqual(element);
+ return expect(this.calculator.hintPopup).toHaveAttr('data-calculator-hint', element.attr('id'));
+ });
- it 'select the first hint if argument element is not passed', ->
- @calculator.selectHint()
- expect(@calculator.activeHint.attr('id')).toEqual($('.hint-item').first().attr('id'))
+ it('select the first hint if argument element is not passed', function() {
+ this.calculator.selectHint();
+ return expect(this.calculator.activeHint.attr('id')).toEqual($('.hint-item').first().attr('id'));
+ });
- it 'select the first hint if argument element is empty', ->
- @calculator.selectHint([])
- expect(@calculator.activeHint.attr('id')).toBe($('.hint-item').first().attr('id'))
+ return it('select the first hint if argument element is empty', function() {
+ this.calculator.selectHint([]);
+ return expect(this.calculator.activeHint.attr('id')).toBe($('.hint-item').first().attr('id'));
+ });
+ });
- describe 'prevHint', ->
+ describe('prevHint', function() {
- it 'Prev hint item is selected', ->
- @calculator.activeHint = $('.hint-item').eq(1)
- @calculator.prevHint()
+ it('Prev hint item is selected', function() {
+ this.calculator.activeHint = $('.hint-item').eq(1);
+ this.calculator.prevHint();
- expect(@calculator.activeHint.attr('id')).toBe($('.hint-item').eq(0).attr('id'))
+ return expect(this.calculator.activeHint.attr('id')).toBe($('.hint-item').eq(0).attr('id'));
+ });
- it 'if this was the second item, select the first one', ->
- @calculator.activeHint = $('.hint-item').eq(1)
- @calculator.prevHint()
+ it('if this was the second item, select the first one', function() {
+ this.calculator.activeHint = $('.hint-item').eq(1);
+ this.calculator.prevHint();
- expect(@calculator.activeHint.attr('id')).toBe($('.hint-item').eq(0).attr('id'))
+ return expect(this.calculator.activeHint.attr('id')).toBe($('.hint-item').eq(0).attr('id'));
+ });
- it 'if this was the first item, select the last one', ->
- @calculator.activeHint = $('.hint-item').eq(0)
- @calculator.prevHint()
+ it('if this was the first item, select the last one', function() {
+ this.calculator.activeHint = $('.hint-item').eq(0);
+ this.calculator.prevHint();
- expect(@calculator.activeHint.attr('id')).toBe($('.hint-item').eq(2).attr('id'))
+ return expect(this.calculator.activeHint.attr('id')).toBe($('.hint-item').eq(2).attr('id'));
+ });
- it 'if this was the last item, select the second last', ->
- @calculator.activeHint = $('.hint-item').eq(2)
- @calculator.prevHint()
+ return it('if this was the last item, select the second last', function() {
+ this.calculator.activeHint = $('.hint-item').eq(2);
+ this.calculator.prevHint();
- expect(@calculator.activeHint.attr('id')).toBe($('.hint-item').eq(1).attr('id'))
+ return expect(this.calculator.activeHint.attr('id')).toBe($('.hint-item').eq(1).attr('id'));
+ });
+ });
- describe 'nextHint', ->
+ describe('nextHint', function() {
- it 'if this was the first item, select the second one', ->
- @calculator.activeHint = $('.hint-item').eq(0)
- @calculator.nextHint()
+ it('if this was the first item, select the second one', function() {
+ this.calculator.activeHint = $('.hint-item').eq(0);
+ this.calculator.nextHint();
- expect(@calculator.activeHint.attr('id')).toBe($('.hint-item').eq(1).attr('id'))
+ return expect(this.calculator.activeHint.attr('id')).toBe($('.hint-item').eq(1).attr('id'));
+ });
- it 'If this was the second item, select the last one', ->
- @calculator.activeHint = $('.hint-item').eq(1)
- @calculator.nextHint()
+ it('If this was the second item, select the last one', function() {
+ this.calculator.activeHint = $('.hint-item').eq(1);
+ this.calculator.nextHint();
- expect(@calculator.activeHint.attr('id')).toBe($('.hint-item').eq(2).attr('id'))
+ return expect(this.calculator.activeHint.attr('id')).toBe($('.hint-item').eq(2).attr('id'));
+ });
- it 'If this was the last item, select the first one', ->
- @calculator.activeHint = $('.hint-item').eq(2)
- @calculator.nextHint()
+ return it('If this was the last item, select the first one', function() {
+ this.calculator.activeHint = $('.hint-item').eq(2);
+ this.calculator.nextHint();
- expect(@calculator.activeHint.attr('id')).toBe($('.hint-item').eq(0).attr('id'))
+ return expect(this.calculator.activeHint.attr('id')).toBe($('.hint-item').eq(0).attr('id'));
+ });
+ });
- describe 'handleKeyDown', ->
- assertHintIsHidden = (calc, key) ->
- spyOn(calc, 'hideHint')
- calc.showHint()
- e = jQuery.Event('keydown', { keyCode: key });
- value = calc.handleKeyDown(e)
+ describe('handleKeyDown', function() {
+ const assertHintIsHidden = function(calc, key) {
+ spyOn(calc, 'hideHint');
+ calc.showHint();
+ const e = jQuery.Event('keydown', { keyCode: key });
+ const value = calc.handleKeyDown(e);
- expect(calc.hideHint).toHaveBeenCalled
- expect(value).toBeFalsy()
- expect(e.isDefaultPrevented()).toBeTruthy()
+ expect(calc.hideHint).toHaveBeenCalled;
+ expect(value).toBeFalsy();
+ return expect(e.isDefaultPrevented()).toBeTruthy();
+ };
- assertHintIsVisible = (calc, key) ->
- spyOn(calc, 'showHint')
- spyOn($.fn, 'focus')
- e = jQuery.Event('keydown', { keyCode: key });
- value = calc.handleKeyDown(e)
+ const assertHintIsVisible = function(calc, key) {
+ spyOn(calc, 'showHint');
+ spyOn($.fn, 'focus');
+ const e = jQuery.Event('keydown', { keyCode: key });
+ const value = calc.handleKeyDown(e);
- expect(calc.showHint).toHaveBeenCalled
- expect(value).toBeFalsy()
- expect(e.isDefaultPrevented()).toBeTruthy()
- expect(calc.activeHint.focus).toHaveBeenCalled()
+ expect(calc.showHint).toHaveBeenCalled;
+ expect(value).toBeFalsy();
+ expect(e.isDefaultPrevented()).toBeTruthy();
+ return expect(calc.activeHint.focus).toHaveBeenCalled();
+ };
- assertNothingHappens = (calc, key) ->
- spyOn(calc, 'showHint')
- e = jQuery.Event('keydown', { keyCode: key });
- value = calc.handleKeyDown(e)
+ const assertNothingHappens = function(calc, key) {
+ spyOn(calc, 'showHint');
+ const e = jQuery.Event('keydown', { keyCode: key });
+ const value = calc.handleKeyDown(e);
- expect(calc.showHint).not.toHaveBeenCalled
- expect(value).toBeTruthy()
- expect(e.isDefaultPrevented()).toBeFalsy()
+ expect(calc.showHint).not.toHaveBeenCalled;
+ expect(value).toBeTruthy();
+ return expect(e.isDefaultPrevented()).toBeFalsy();
+ };
- it 'hint popup becomes hidden on press ENTER', ->
- assertHintIsHidden(@calculator, KEY.ENTER)
+ it('hint popup becomes hidden on press ENTER', function() {
+ return assertHintIsHidden(this.calculator, KEY.ENTER);
+ });
- it 'hint popup becomes visible on press ENTER', ->
- assertHintIsVisible(@calculator, KEY.ENTER)
+ it('hint popup becomes visible on press ENTER', function() {
+ return assertHintIsVisible(this.calculator, KEY.ENTER);
+ });
- it 'hint popup becomes hidden on press SPACE', ->
- assertHintIsHidden(@calculator, KEY.SPACE)
+ it('hint popup becomes hidden on press SPACE', function() {
+ return assertHintIsHidden(this.calculator, KEY.SPACE);
+ });
- it 'hint popup becomes visible on press SPACE', ->
- assertHintIsVisible(@calculator, KEY.SPACE)
+ it('hint popup becomes visible on press SPACE', function() {
+ return assertHintIsVisible(this.calculator, KEY.SPACE);
+ });
- it 'Nothing happens on press ALT', ->
- assertNothingHappens(@calculator, KEY.ALT)
+ it('Nothing happens on press ALT', function() {
+ return assertNothingHappens(this.calculator, KEY.ALT);
+ });
- it 'Nothing happens on press any other button', ->
- assertNothingHappens(@calculator, KEY.DOWN)
+ return it('Nothing happens on press any other button', function() {
+ return assertNothingHappens(this.calculator, KEY.DOWN);
+ });
+ });
- describe 'handleKeyDownOnHint', ->
- it 'Navigation works in proper way', ->
- calc = @calculator
+ describe('handleKeyDownOnHint', () =>
+ it('Navigation works in proper way', function() {
+ const calc = this.calculator;
- eventToShowHint = jQuery.Event('keydown', { keyCode: KEY.ENTER } );
+ const eventToShowHint = jQuery.Event('keydown', { keyCode: KEY.ENTER } );
$('#calculator_hint').trigger(eventToShowHint);
- spyOn(calc, 'hideHint')
- spyOn(calc, 'prevHint')
- spyOn(calc, 'nextHint')
- spyOn($.fn, 'focus')
+ spyOn(calc, 'hideHint');
+ spyOn(calc, 'prevHint');
+ spyOn(calc, 'nextHint');
+ spyOn($.fn, 'focus');
- cases =
- left:
- event:
- keyCode: KEY.LEFT
+ const cases = {
+ left: {
+ event: {
+ keyCode: KEY.LEFT,
shiftKey: false
- returnedValue: false
- called:
+ },
+ returnedValue: false,
+ called: {
'prevHint': calc
+ },
isPropagationStopped: true
+ },
- leftWithShift:
- returnedValue: true
- event:
- keyCode: KEY.LEFT
+ leftWithShift: {
+ returnedValue: true,
+ event: {
+ keyCode: KEY.LEFT,
shiftKey: true
- not_called:
+ },
+ not_called: {
'prevHint': calc
+ }
+ },
- up:
- event:
- keyCode: KEY.UP
+ up: {
+ event: {
+ keyCode: KEY.UP,
shiftKey: false
- returnedValue: false
- called:
+ },
+ returnedValue: false,
+ called: {
'prevHint': calc
+ },
isPropagationStopped: true
+ },
- upWithShift:
- returnedValue: true
- event:
- keyCode: KEY.UP
+ upWithShift: {
+ returnedValue: true,
+ event: {
+ keyCode: KEY.UP,
shiftKey: true
- not_called:
+ },
+ not_called: {
'prevHint': calc
+ }
+ },
- right:
- event:
- keyCode: KEY.RIGHT
+ right: {
+ event: {
+ keyCode: KEY.RIGHT,
shiftKey: false
- returnedValue: false
- called:
+ },
+ returnedValue: false,
+ called: {
'nextHint': calc
+ },
isPropagationStopped: true
+ },
- rightWithShift:
- returnedValue: true
- event:
- keyCode: KEY.RIGHT
+ rightWithShift: {
+ returnedValue: true,
+ event: {
+ keyCode: KEY.RIGHT,
shiftKey: true
- not_called:
+ },
+ not_called: {
'nextHint': calc
+ }
+ },
- down:
- event:
- keyCode: KEY.DOWN
+ down: {
+ event: {
+ keyCode: KEY.DOWN,
shiftKey: false
- returnedValue: false
- called:
+ },
+ returnedValue: false,
+ called: {
'nextHint': calc
+ },
isPropagationStopped: true
+ },
- downWithShift:
- returnedValue: true
- event:
- keyCode: KEY.DOWN
+ downWithShift: {
+ returnedValue: true,
+ event: {
+ keyCode: KEY.DOWN,
shiftKey: true
- not_called:
+ },
+ not_called: {
'nextHint': calc
+ }
+ },
- esc:
- returnedValue: false
- event:
- keyCode: KEY.ESC
+ esc: {
+ returnedValue: false,
+ event: {
+ keyCode: KEY.ESC,
shiftKey: false
- called:
- 'hideHint': calc
+ },
+ called: {
+ 'hideHint': calc,
'focus': $.fn
+ },
isPropagationStopped: true
+ },
- alt:
- returnedValue: true
- event:
+ alt: {
+ returnedValue: true,
+ event: {
which: KEY.ALT
- not_called:
- 'hideHint': calc
- 'nextHint': calc
+ },
+ not_called: {
+ 'hideHint': calc,
+ 'nextHint': calc,
'prevHint': calc
+ }
+ }
+ };
- $.each(cases, (key, data) ->
- calc.hideHint.calls.reset()
- calc.prevHint.calls.reset()
- calc.nextHint.calls.reset()
- $.fn.focus.calls.reset()
+ return $.each(cases, function(key, data) {
+ calc.hideHint.calls.reset();
+ calc.prevHint.calls.reset();
+ calc.nextHint.calls.reset();
+ $.fn.focus.calls.reset();
- e = jQuery.Event('keydown', data.event or {});
- value = calc.handleKeyDownOnHint(e)
+ const e = jQuery.Event('keydown', data.event || {});
+ const value = calc.handleKeyDownOnHint(e);
- if data.called
- $.each(data.called, (method, obj) ->
- expect(obj[method]).toHaveBeenCalled()
- )
+ if (data.called) {
+ $.each(data.called, (method, obj) => expect(obj[method]).toHaveBeenCalled());
+ }
- if data.not_called
- $.each(data.not_called, (method, obj) ->
- expect(obj[method]).not.toHaveBeenCalled()
- )
+ if (data.not_called) {
+ $.each(data.not_called, (method, obj) => expect(obj[method]).not.toHaveBeenCalled());
+ }
- if data.isPropagationStopped
- expect(e.isPropagationStopped()).toBeTruthy()
- else
- expect(e.isPropagationStopped()).toBeFalsy()
+ if (data.isPropagationStopped) {
+ expect(e.isPropagationStopped()).toBeTruthy();
+ } else {
+ expect(e.isPropagationStopped()).toBeFalsy();
+ }
- expect(value).toBe(data.returnedValue)
- )
+ return expect(value).toBe(data.returnedValue);
+ });
+ })
+ );
- describe 'calculate', ->
- beforeEach ->
- $('#calculator_input').val '1+2'
- spyOn($, 'getWithPrefix').and.callFake (url, data, callback) ->
- callback({ result: 3 })
- @calculator.calculate()
+ return describe('calculate', function() {
+ beforeEach(function() {
+ $('#calculator_input').val('1+2');
+ spyOn($, 'getWithPrefix').and.callFake((url, data, callback) => callback({ result: 3 }));
+ return this.calculator.calculate();
+ });
- it 'send data to /calculate', ->
- expect($.getWithPrefix).toHaveBeenCalledWith '/calculate',
- equation: '1+2'
- , jasmine.any(Function)
+ it('send data to /calculate', () =>
+ expect($.getWithPrefix).toHaveBeenCalledWith('/calculate',
+ {equation: '1+2'}
+ , jasmine.any(Function))
+ );
- it 'update the calculator output', ->
- expect($('#calculator_output').val()).toEqual('3')
+ return it('update the calculator output', () => expect($('#calculator_output').val()).toEqual('3'));
+ });
+});
diff --git a/lms/static/coffee/spec/courseware_spec.js b/lms/static/coffee/spec/courseware_spec.js
index 129b4308a6..3be0cda49c 100644
--- a/lms/static/coffee/spec/courseware_spec.js
+++ b/lms/static/coffee/spec/courseware_spec.js
@@ -1,31 +1,40 @@
-describe 'Courseware', ->
- describe 'start', ->
- it 'binds the Logger', ->
- spyOn(Logger, 'bind')
- Courseware.start()
- expect(Logger.bind).toHaveBeenCalled()
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+describe('Courseware', function() {
+ describe('start', () =>
+ it('binds the Logger', function() {
+ spyOn(Logger, 'bind');
+ Courseware.start();
+ return expect(Logger.bind).toHaveBeenCalled();
+ })
+ );
- describe 'render', ->
- beforeEach ->
- jasmine.stubRequests()
- @courseware = new Courseware
- spyOn(window, 'Histogram')
- spyOn(window, 'Problem')
- spyOn(window, 'Video')
- spyOn(XBlock, 'initializeBlocks')
- setFixtures """
-