Commit 0880502f by David Ormsbee Committed by Calen Pennington

CoffeeScript tests migration: Decaffeinate files

This is running decaffeinate, with no additional cleanup.
parent 5c64da2f
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");
});
})
)
);
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 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 getter for field name", ->
model = new Metadata({'field_name': 'foo'})
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 type", ->
model = new Metadata({'type': 'Integer'})
expect(model.getType()).toBe(Metadata.INTEGER_TYPE)
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", 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", function() {
const model = new Metadata({'field_name': 'foo'});
return expect(model.getFieldName()).toBe('foo');
});
it("has a getter for options", function() {
const model = new Metadata({'options': ['foo', 'bar']});
return expect(model.getOptions()).toEqual(['foo', 'bar']);
});
return it("has a getter for type", function() {
const model = new Metadata({'type': 'Integer'});
return expect(model.getType()).toBe(Metadata.INTEGER_TYPE);
});
})
);
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();
});
});
})
);
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.');
});
})
)
);
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);
});
});
})
);
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'
)
});
});
});
})
);
class MinimaxProblemDisplay extends XProblemDisplay
constructor: (@state, @submission, @evaluation, @container, @submissionField, @parameters={}) ->
super(@state, @submission, @evaluation, @container, @submissionField, @parameters)
render: () ->
createSubmission: () ->
@newSubmission = {}
if @submission?
for id, value of @submission
@newSubmission[id] = value
getCurrentSubmission: () ->
return @newSubmission
root = exports ? this
root.TestProblemDisplay = TestProblemDisplay
/*
* decaffeinate suggestions:
* DS001: Remove Babel/TypeScript constructor workaround
* DS102: Remove unnecessary code created because of implicit returns
* DS205: Consider reworking code to avoid use of IIFEs
* DS207: Consider shorter variations of null checks
* DS208: Avoid top-level this
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
class MinimaxProblemDisplay extends XProblemDisplay {
constructor(state, submission, evaluation, container, submissionField, parameters) {
{
// Hack: trick Babel/TypeScript into allowing this before super.
if (false) { super(); }
let thisFn = (() => { this; }).toString();
let thisName = thisFn.slice(thisFn.indexOf('{') + 1, thisFn.indexOf(';')).trim();
eval(`${thisName} = this;`);
}
this.state = state;
this.submission = submission;
this.evaluation = evaluation;
this.container = container;
this.submissionField = submissionField;
if (parameters == null) { parameters = {}; }
this.parameters = parameters;
super(this.state, this.submission, this.evaluation, this.container, this.submissionField, this.parameters);
}
render() {}
createSubmission() {
this.newSubmission = {};
if (this.submission != null) {
return (() => {
const result = [];
for (let id in this.submission) {
const value = this.submission[id];
result.push(this.newSubmission[id] = value);
}
return result;
})();
}
}
getCurrentSubmission() {
return this.newSubmission;
}
}
const root = typeof exports !== 'undefined' && exports !== null ? exports : this;
root.TestProblemDisplay = TestProblemDisplay;
class TestProblemGenerator extends XProblemGenerator
/*
* decaffeinate suggestions:
* DS001: Remove Babel/TypeScript constructor workaround
* DS207: Consider shorter variations of null checks
* DS208: Avoid top-level this
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
class TestProblemGenerator extends XProblemGenerator {
constructor: (seed, @parameters = {}) ->
constructor(seed, parameters) {
super(seed, @parameters)
{
// Hack: trick Babel/TypeScript into allowing this before super.
if (false) { super(); }
let thisFn = (() => { this; }).toString();
let thisName = thisFn.slice(thisFn.indexOf('{') + 1, thisFn.indexOf(';')).trim();
eval(`${thisName} = this;`);
}
if (parameters == null) { parameters = {}; }
this.parameters = parameters;
super(seed, this.parameters);
}
generate: () ->
generate() {
@problemState.value = @parameters.value
this.problemState.value = this.parameters.value;
return @problemState
return this.problemState;
}
}
root = exports ? this
root.generatorClass = TestProblemGenerator
const root = typeof exports !== 'undefined' && exports !== null ? exports : this;
root.generatorClass = TestProblemGenerator;
class TestProblemGrader extends XProblemGrader
constructor: (@submission, @problemState, @parameters={}) ->
super(@submission, @problemState, @parameters)
solve: () ->
@solution = {0: @problemState.value}
grade: () ->
if not @solution?
@solve()
allCorrect = true
for id, value of @solution
valueCorrect = if @submission? then (value == @submission[id]) else false
@evaluation[id] = valueCorrect
if not valueCorrect
allCorrect = false
return allCorrect
root = exports ? this
root.graderClass = TestProblemGrader
/*
* decaffeinate suggestions:
* DS001: Remove Babel/TypeScript constructor workaround
* DS102: Remove unnecessary code created because of implicit returns
* DS207: Consider shorter variations of null checks
* DS208: Avoid top-level this
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
class TestProblemGrader extends XProblemGrader {
constructor(submission, problemState, parameters) {
{
// Hack: trick Babel/TypeScript into allowing this before super.
if (false) { super(); }
let thisFn = (() => { this; }).toString();
let thisName = thisFn.slice(thisFn.indexOf('{') + 1, thisFn.indexOf(';')).trim();
eval(`${thisName} = this;`);
}
this.submission = submission;
this.problemState = problemState;
if (parameters == null) { parameters = {}; }
this.parameters = parameters;
super(this.submission, this.problemState, this.parameters);
}
solve() {
return this.solution = {0: this.problemState.value};
}
grade() {
if ((this.solution == null)) {
this.solve();
}
let allCorrect = true;
for (let id in this.solution) {
const value = this.solution[id];
const valueCorrect = (this.submission != null) ? (value === this.submission[id]) : false;
this.evaluation[id] = valueCorrect;
if (!valueCorrect) {
allCorrect = false;
}
}
return allCorrect;
}
}
const root = typeof exports !== 'undefined' && exports !== null ? exports : this;
root.graderClass = TestProblemGrader;
class XProblemGenerator
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* DS207: Consider shorter variations of null checks
* DS208: Avoid top-level this
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
class XProblemGenerator {
constructor: (seed, @parameters={}) ->
constructor(seed, parameters) {
@random = new MersenneTwister(seed)
if (parameters == null) { parameters = {}; }
this.parameters = parameters;
this.random = new MersenneTwister(seed);
@problemState = {}
this.problemState = {};
}
generate: () ->
generate() {
console.error("Abstract method called: XProblemGenerator.generate")
return console.error("Abstract method called: XProblemGenerator.generate");
}
}
class XProblemDisplay
class XProblemDisplay {
constructor: (@state, @submission, @evaluation, @container, @submissionField, @parameters={}) ->
constructor(state, submission, evaluation, container, submissionField, parameters) {
this.state = state;
this.submission = submission;
this.evaluation = evaluation;
this.container = container;
this.submissionField = submissionField;
if (parameters == null) { parameters = {}; }
this.parameters = parameters;
}
render: () ->
render() {
console.error("Abstract method called: XProblemDisplay.render")
return console.error("Abstract method called: XProblemDisplay.render");
}
updateSubmission: () ->
updateSubmission() {
@submissionField.val(JSON.stringify(@getCurrentSubmission()))
return this.submissionField.val(JSON.stringify(this.getCurrentSubmission()));
}
getCurrentSubmission: () ->
console.error("Abstract method called: XProblemDisplay.getCurrentSubmission")
getCurrentSubmission() {
return console.error("Abstract method called: XProblemDisplay.getCurrentSubmission");
}
}
class XProblemGrader
class XProblemGrader {
constructor: (@submission, @problemState, @parameters={}) ->
constructor(submission, problemState, parameters) {
@solution = null
@evaluation = {}
this.submission = submission;
this.problemState = problemState;
if (parameters == null) { parameters = {}; }
this.parameters = parameters;
this.solution = null;
this.evaluation = {};
}
solve: () ->
solve() {
console.error("Abstract method called: XProblemGrader.solve")
return console.error("Abstract method called: XProblemGrader.solve");
}
grade: () ->
grade() {
console.error("Abstract method called: XProblemGrader.grade")
return console.error("Abstract method called: XProblemGrader.grade");
}
}
root = exports ? this
const root = typeof exports !== 'undefined' && exports !== null ? exports : this;
root.XProblemGenerator = XProblemGenerator
root.XProblemDisplay = XProblemDisplay
root.XProblemGrader = XProblemGrader
root.XProblemGenerator = XProblemGenerator;
root.XProblemDisplay = XProblemDisplay;
root.XProblemGrader = XProblemGrader;
describe 'Annotatable', ->
beforeEach ->
loadFixtures 'annotatable.html'
describe 'constructor', ->
el = $('.xblock-student_view.xmodule_AnnotatableModule')
beforeEach ->
@annotatable = new Annotatable(el)
it 'works', ->
expect(1).toBe(1)
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
describe('Annotatable', function() {
beforeEach(() => loadFixtures('annotatable.html'));
return describe('constructor', function() {
const el = $('.xblock-student_view.xmodule_AnnotatableModule');
beforeEach(function() {
return this.annotatable = new Annotatable(el);
});
return it('works', () => expect(1).toBe(1));
});
});
describe 'HTMLEditingDescriptor', ->
beforeEach ->
window.baseUrl = "/static/deadbeef"
afterEach ->
delete window.baseUrl
describe 'Visual HTML Editor', ->
beforeEach ->
loadFixtures 'html-edit-visual.html'
@descriptor = new HTMLEditingDescriptor($('.test-component'))
it 'Returns data from Visual Editor if text has changed', ->
visualEditorStub =
getContent: () -> 'from visual editor'
spyOn(@descriptor, 'getVisualEditor').and.callFake () ->
visualEditorStub
data = @descriptor.save().data
expect(data).toEqual('from visual editor')
it 'Returns data from Raw Editor if text has not changed', ->
visualEditorStub =
getContent: () -> '<p>original visual text</p>'
spyOn(@descriptor, 'getVisualEditor').and.callFake () ->
visualEditorStub
data = @descriptor.save().data
expect(data).toEqual('raw text')
it 'Performs link rewriting for static assets when saving', ->
visualEditorStub =
getContent: () -> 'from visual editor with /c4x/foo/bar/asset/image.jpg'
spyOn(@descriptor, 'getVisualEditor').and.callFake () ->
visualEditorStub
data = @descriptor.save().data
expect(data).toEqual('from visual editor with /static/image.jpg')
it 'When showing visual editor links are rewritten to c4x format', ->
visualEditorStub =
content: 'text /static/image.jpg'
startContent: 'text /static/image.jpg'
focus: ->
setContent: (x) -> @content = x
getContent: -> @content
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
describe('HTMLEditingDescriptor', function() {
beforeEach(() => window.baseUrl = "/static/deadbeef");
afterEach(() => delete window.baseUrl);
describe('Visual HTML Editor', function() {
beforeEach(function() {
loadFixtures('html-edit-visual.html');
return this.descriptor = new HTMLEditingDescriptor($('.test-component'));
});
it('Returns data from Visual Editor if text has changed', function() {
const visualEditorStub =
{getContent() { return 'from visual editor'; }};
spyOn(this.descriptor, 'getVisualEditor').and.callFake(() => visualEditorStub);
const { data } = this.descriptor.save();
return expect(data).toEqual('from visual editor');
});
it('Returns data from Raw Editor if text has not changed', function() {
const visualEditorStub =
{getContent() { return '<p>original visual text</p>'; }};
spyOn(this.descriptor, 'getVisualEditor').and.callFake(() => visualEditorStub);
const { data } = this.descriptor.save();
return expect(data).toEqual('raw text');
});
it('Performs link rewriting for static assets when saving', function() {
const visualEditorStub =
{getContent() { return 'from visual editor with /c4x/foo/bar/asset/image.jpg'; }};
spyOn(this.descriptor, 'getVisualEditor').and.callFake(() => visualEditorStub);
const { data } = this.descriptor.save();
return expect(data).toEqual('from visual editor with /static/image.jpg');
});
it('When showing visual editor links are rewritten to c4x format', function() {
const visualEditorStub = {
content: 'text /static/image.jpg',
startContent: 'text /static/image.jpg',
focus() {},
setContent(x) { return this.content = x; },
getContent() { return this.content; }
};
@descriptor.initInstanceCallback(visualEditorStub)
expect(visualEditorStub.getContent()).toEqual('text /c4x/foo/bar/asset/image.jpg')
it 'Enables spellcheck', ->
expect($('.html-editor iframe')[0].contentDocument.body.spellcheck).toBe(true)
describe 'Raw HTML Editor', ->
beforeEach ->
loadFixtures 'html-editor-raw.html'
@descriptor = new HTMLEditingDescriptor($('.test-component'))
it 'Returns data from raw editor', ->
data = @descriptor.save().data
expect(data).toEqual('raw text')
this.descriptor.initInstanceCallback(visualEditorStub);
return expect(visualEditorStub.getContent()).toEqual('text /c4x/foo/bar/asset/image.jpg');
});
return it('Enables spellcheck', () => expect($('.html-editor iframe')[0].contentDocument.body.spellcheck).toBe(true));
});
return describe('Raw HTML Editor', function() {
beforeEach(function() {
loadFixtures('html-editor-raw.html');
return this.descriptor = new HTMLEditingDescriptor($('.test-component'));
});
return it('Returns data from raw editor', function() {
const { data } = this.descriptor.save();
return expect(data).toEqual('raw text');
});
});
});
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);
});
});
});
describe "$.immediateDescendents", ->
beforeEach ->
setFixtures """
<div>
<div class='xblock' id='child'>
<div class='xblock' id='nested'/>
</div>
<div>
<div class='xblock' id='grandchild'/>
</div>
</div>
"""
/*
* 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(`\
<div>
<div class='xblock' id='child'>
<div class='xblock' id='nested'/>
</div>
<div>
<div class='xblock' id='grandchild'/>
</div>
</div>\
`
);
@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
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 """
<div class="course-content">
<div id="video_1" class="video" data-streams="1.0:abc1234"></div>
<div id="video_2" class="video" data-streams="1.0:def5678"></div>
<div id="problem_3" class="problems-wrapper" data-problem-id="3" data-url="/example/url/">
<div id="histogram_3" class="histogram" data-histogram="[[0, 1]]" style="height: 20px; display: block;">
</div>
</div>
"""
@courseware.render()
return describe('render', function() {
beforeEach(function() {
jasmine.stubRequests();
this.courseware = new Courseware;
spyOn(window, 'Histogram');
spyOn(window, 'Problem');
spyOn(window, 'Video');
spyOn(XBlock, 'initializeBlocks');
setFixtures(`\
<div class="course-content">
<div id="video_1" class="video" data-streams="1.0:abc1234"></div>
<div id="video_2" class="video" data-streams="1.0:def5678"></div>
<div id="problem_3" class="problems-wrapper" data-problem-id="3" data-url="/example/url/">
<div id="histogram_3" class="histogram" data-histogram="[[0, 1]]" style="height: 20px; display: block;">
</div>
</div>\
`
);
return this.courseware.render();
});
it 'ensure that the XModules have been loaded', ->
expect(XBlock.initializeBlocks).toHaveBeenCalled()
it('ensure that the XModules have been loaded', () => expect(XBlock.initializeBlocks).toHaveBeenCalled());
it 'detect the histrogram element and convert it', ->
expect(window.Histogram).toHaveBeenCalledWith('3', [[0, 1]])
return it('detect the histrogram element and convert it', () => expect(window.Histogram).toHaveBeenCalledWith('3', [[0, 1]]));
});
});
describe 'FeedbackForm', ->
beforeEach ->
loadFixtures 'coffee/fixtures/feedback_form.html'
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
describe('FeedbackForm', function() {
beforeEach(() => loadFixtures('coffee/fixtures/feedback_form.html'));
describe 'constructor', ->
beforeEach ->
new FeedbackForm
spyOn($, 'postWithPrefix').and.callFake (url, data, callback, format) ->
callback()
return describe('constructor', function() {
beforeEach(function() {
new FeedbackForm;
return spyOn($, 'postWithPrefix').and.callFake((url, data, callback, format) => callback());
});
it 'post data to /send_feedback on click', ->
$('#feedback_subject').val 'Awesome!'
$('#feedback_message').val 'This site is really good.'
$('#feedback_button').click()
it('post data to /send_feedback on click', function() {
$('#feedback_subject').val('Awesome!');
$('#feedback_message').val('This site is really good.');
$('#feedback_button').click();
expect($.postWithPrefix).toHaveBeenCalledWith '/send_feedback', {
subject: 'Awesome!'
message: 'This site is really good.'
return expect($.postWithPrefix).toHaveBeenCalledWith('/send_feedback', {
subject: 'Awesome!',
message: 'This site is really good.',
url: window.location.href
}, jasmine.any(Function), 'json'
}, jasmine.any(Function), 'json');
});
it 'replace the form with a thank you message', ->
$('#feedback_button').click()
return it('replace the form with a thank you message', function() {
$('#feedback_button').click();
expect($('#feedback_div').html()).toEqual 'Feedback submitted. Thank you'
return expect($('#feedback_div').html()).toEqual('Feedback submitted. Thank you');
});
});
});
jasmine.stubbedMetadata =
slowerSpeedYoutubeId:
id: 'slowerSpeedYoutubeId'
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
jasmine.stubbedMetadata = {
slowerSpeedYoutubeId: {
id: 'slowerSpeedYoutubeId',
duration: 300
normalSpeedYoutubeId:
id: 'normalSpeedYoutubeId'
},
normalSpeedYoutubeId: {
id: 'normalSpeedYoutubeId',
duration: 200
bogus:
},
bogus: {
duration: 100
}
};
jasmine.stubbedCaption =
start: [0, 10000, 20000, 30000]
jasmine.stubbedCaption = {
start: [0, 10000, 20000, 30000],
text: ['Caption at 0', 'Caption at 10000', 'Caption at 20000', 'Caption at 30000']
};
jasmine.stubRequests = ->
spyOn($, 'ajax').and.callFake (settings) ->
if match = settings.url.match /youtube\.com\/.+\/videos\/(.+)\?v=2&alt=jsonc/
settings.success data: jasmine.stubbedMetadata[match[1]]
else if match = settings.url.match /static\/subs\/(.+)\.srt\.sjson/
settings.success jasmine.stubbedCaption
else if settings.url.match /modx\/.+\/problem_get$/
settings.success html: readFixtures('problem_content.html')
else if settings.url == '/calculate' ||
jasmine.stubRequests = () =>
spyOn($, 'ajax').and.callFake(function(settings) {
let match;
if (match = settings.url.match(/youtube\.com\/.+\/videos\/(.+)\?v=2&alt=jsonc/)) {
return settings.success({data: jasmine.stubbedMetadata[match[1]]});
} else if (match = settings.url.match(/static\/subs\/(.+)\.srt\.sjson/)) {
return settings.success(jasmine.stubbedCaption);
} else if (settings.url.match(/modx\/.+\/problem_get$/)) {
return settings.success({html: readFixtures('problem_content.html')});
} else if ((settings.url === '/calculate') ||
settings.url.match(/modx\/.+\/goto_position$/) ||
settings.url.match(/event$/) ||
settings.url.match(/modx\/.+\/problem_(check|reset|show|save)$/)
# do nothing
else
throw "External request attempted for #{settings.url}, which is not defined."
settings.url.match(/modx\/.+\/problem_(check|reset|show|save)$/)) {
// do nothing
} else {
throw `External request attempted for ${settings.url}, which is not defined.`;
}
})
;
jasmine.stubYoutubePlayer = ->
YT.Player = -> jasmine.createSpyObj 'YT.Player', ['cueVideoById', 'getVideoEmbedCode',
jasmine.stubYoutubePlayer = () =>
YT.Player = () => jasmine.createSpyObj('YT.Player', ['cueVideoById', 'getVideoEmbedCode',
'getCurrentTime', 'getPlayerState', 'getVolume', 'setVolume', 'loadVideoById',
'playVideo', 'pauseVideo', 'seekTo']
'playVideo', 'pauseVideo', 'seekTo'])
;
jasmine.stubVideoPlayer = (context, enableParts, createPlayer=true) ->
enableParts = [enableParts] unless $.isArray(enableParts)
jasmine.stubVideoPlayer = function(context, enableParts, createPlayer) {
let currentPartName;
if (createPlayer == null) { createPlayer = true; }
if (!$.isArray(enableParts)) { enableParts = [enableParts]; }
suite = context.suite
currentPartName = suite.description while suite = suite.parentSuite
enableParts.push currentPartName
let { suite } = context;
while ((suite = suite.parentSuite)) { currentPartName = suite.description; }
enableParts.push(currentPartName);
for part in ['VideoCaption', 'VideoSpeedControl', 'VideoVolumeControl', 'VideoProgressSlider']
unless $.inArray(part, enableParts) >= 0
spyOn window, part
for (let part of ['VideoCaption', 'VideoSpeedControl', 'VideoVolumeControl', 'VideoProgressSlider']) {
if (!($.inArray(part, enableParts) >= 0)) {
spyOn(window, part);
}
}
loadFixtures 'video.html'
jasmine.stubRequests()
YT.Player = undefined
context.video = new Video 'example', '.75:slowerSpeedYoutubeId,1.0:normalSpeedYoutubeId'
jasmine.stubYoutubePlayer()
if createPlayer
return new VideoPlayer(video: context.video)
loadFixtures('video.html');
jasmine.stubRequests();
YT.Player = undefined;
context.video = new Video('example', '.75:slowerSpeedYoutubeId,1.0:normalSpeedYoutubeId');
jasmine.stubYoutubePlayer();
if (createPlayer) {
return new VideoPlayer({video: context.video});
}
};
# Stub Youtube API
window.YT =
PlayerState:
UNSTARTED: -1
ENDED: 0
PLAYING: 1
PAUSED: 2
BUFFERING: 3
// Stub Youtube API
window.YT = {
PlayerState: {
UNSTARTED: -1,
ENDED: 0,
PLAYING: 1,
PAUSED: 2,
BUFFERING: 3,
CUED: 5
}
};
# Stub jQuery.cookie
$.cookie = jasmine.createSpy('jQuery.cookie').and.returnValue '1.0'
// Stub jQuery.cookie
$.cookie = jasmine.createSpy('jQuery.cookie').and.returnValue('1.0');
# Stub jQuery.qtip
$.fn.qtip = jasmine.createSpy 'jQuery.qtip'
// Stub jQuery.qtip
$.fn.qtip = jasmine.createSpy('jQuery.qtip');
# Stub jQuery.scrollTo
$.fn.scrollTo = jasmine.createSpy 'jQuery.scrollTo'
// Stub jQuery.scrollTo
$.fn.scrollTo = jasmine.createSpy('jQuery.scrollTo');
describe 'Histogram', ->
beforeEach ->
spyOn $, 'plot'
describe 'constructor', ->
it 'instantiate the data arrays', ->
histogram = new Histogram 1, []
expect(histogram.xTicks).toEqual []
expect(histogram.yTicks).toEqual []
expect(histogram.data).toEqual []
describe 'calculate', ->
beforeEach ->
@histogram = new Histogram(1, [[null, 1], [1, 1], [2, 2], [3, 3]])
it 'store the correct value for data', ->
expect(@histogram.data).toEqual [[1, Math.log(2)], [2, Math.log(3)], [3, Math.log(4)]]
it 'store the correct value for x ticks', ->
expect(@histogram.xTicks).toEqual [[1, '1'], [2, '2'], [3, '3']]
it 'store the correct value for y ticks', ->
expect(@histogram.yTicks).toEqual
describe 'render', ->
it 'call flot with correct option', ->
new Histogram(1, [[1, 1], [2, 2], [3, 3]])
firstArg = $.plot.calls.mostRecent().args[0]
secondArg = $.plot.calls.mostRecent().args[1]
thirdArg = $.plot.calls.mostRecent().args[2]
expect(firstArg.selector).toEqual($("#histogram_1").selector)
expect(secondArg).toEqual([
data: [[1, Math.log(2)], [2, Math.log(3)], [3, Math.log(4)]]
bars:
show: true
align: 'center'
lineWidth: 0
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
describe('Histogram', function() {
beforeEach(() => spyOn($, 'plot'));
describe('constructor', () =>
it('instantiate the data arrays', function() {
const histogram = new Histogram(1, []);
expect(histogram.xTicks).toEqual([]);
expect(histogram.yTicks).toEqual([]);
return expect(histogram.data).toEqual([]);
})
);
describe('calculate', function() {
beforeEach(function() {
return this.histogram = new Histogram(1, [[null, 1], [1, 1], [2, 2], [3, 3]]);
});
it('store the correct value for data', function() {
return expect(this.histogram.data).toEqual([[1, Math.log(2)], [2, Math.log(3)], [3, Math.log(4)]]);
});
it('store the correct value for x ticks', function() {
return expect(this.histogram.xTicks).toEqual([[1, '1'], [2, '2'], [3, '3']]);
});
return it('store the correct value for y ticks', function() {
return expect(this.histogram.yTicks).toEqual;
});
});
return describe('render', () =>
it('call flot with correct option', function() {
new Histogram(1, [[1, 1], [2, 2], [3, 3]]);
const firstArg = $.plot.calls.mostRecent().args[0];
const secondArg = $.plot.calls.mostRecent().args[1];
const thirdArg = $.plot.calls.mostRecent().args[2];
expect(firstArg.selector).toEqual($("#histogram_1").selector);
expect(secondArg).toEqual([{
data: [[1, Math.log(2)], [2, Math.log(3)], [3, Math.log(4)]],
bars: {
show: true,
align: 'center',
lineWidth: 0,
fill: 1.0
},
color: "#b72121"
])
expect(thirdArg).toEqual(
xaxis:
min: -1
max: 4
ticks: [[1, '1'], [2, '2'], [3, '3']]
}
]);
return expect(thirdArg).toEqual({
xaxis: {
min: -1,
max: 4,
ticks: [[1, '1'], [2, '2'], [3, '3']],
tickLength: 0
yaxis:
min: 0.0
max: Math.log(4) * 1.1
ticks: [[Math.log(2), '1'], [Math.log(3), '2'], [Math.log(4), '3']]
},
yaxis: {
min: 0.0,
max: Math.log(4) * 1.1,
ticks: [[Math.log(2), '1'], [Math.log(3), '2'], [Math.log(4), '3']],
labelWidth: 50
)
}
});
})
);
});
describe 'Tab', ->
beforeEach ->
loadFixtures 'coffee/fixtures/tab.html'
@items = $.parseJSON readFixtures('coffee/fixtures/items.json')
describe 'constructor', ->
beforeEach ->
spyOn($.fn, 'tabs')
@tab = new Tab 1, @items
it 'set the element', ->
expect(@tab.el).toEqual $('#tab_1')
it 'build the tabs', ->
links = $('.navigation li>a').map(-> $(this).attr('href')).get()
expect(links).toEqual ['#tab-1-0', '#tab-1-1', '#tab-1-2']
it 'build the container', ->
containers = $('section').map(-> $(this).attr('id')).get()
expect(containers).toEqual ['tab-1-0', 'tab-1-1', 'tab-1-2']
it 'bind the tabs', ->
expect($.fn.tabs).toHaveBeenCalledWith show: @tab.onShow
# As of jQuery 1.9, the onShow callback is deprecated
# http://jqueryui.com/upgrade-guide/1.9/#deprecated-show-event-renamed-to-activate
# The code below tests that onShow does what is expected,
# but note that onShow will NOT be called when the user
# clicks on the tab if we're using jQuery version >= 1.9
describe 'onShow', ->
beforeEach ->
@tab = new Tab 1, @items
@tab.onShow($('#tab-1-0'), {'index': 1})
it 'replace content in the container', ->
@tab.onShow($('#tab-1-1'), {'index': 1})
expect($('#tab-1-0').html()).toEqual ''
expect($('#tab-1-1').html()).toEqual 'Video 2'
expect($('#tab-1-2').html()).toEqual ''
it 'trigger contentChanged event on the element', ->
spyOnEvent @tab.el, 'contentChanged'
@tab.onShow($('#tab-1-1'), {'index': 1})
expect('contentChanged').toHaveBeenTriggeredOn @tab.el
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
describe('Tab', function() {
beforeEach(function() {
loadFixtures('coffee/fixtures/tab.html');
return this.items = $.parseJSON(readFixtures('coffee/fixtures/items.json'));
});
describe('constructor', function() {
beforeEach(function() {
spyOn($.fn, 'tabs');
return this.tab = new Tab(1, this.items);
});
it('set the element', function() {
return expect(this.tab.el).toEqual($('#tab_1'));
});
it('build the tabs', function() {
const links = $('.navigation li>a').map(function() { return $(this).attr('href'); }).get();
return expect(links).toEqual(['#tab-1-0', '#tab-1-1', '#tab-1-2']);
});
it('build the container', function() {
const containers = $('section').map(function() { return $(this).attr('id'); }).get();
return expect(containers).toEqual(['tab-1-0', 'tab-1-1', 'tab-1-2']);
});
return it('bind the tabs', function() {
return expect($.fn.tabs).toHaveBeenCalledWith({show: this.tab.onShow});
});
});
// As of jQuery 1.9, the onShow callback is deprecated
// http://jqueryui.com/upgrade-guide/1.9/#deprecated-show-event-renamed-to-activate
// The code below tests that onShow does what is expected,
// but note that onShow will NOT be called when the user
// clicks on the tab if we're using jQuery version >= 1.9
return describe('onShow', function() {
beforeEach(function() {
this.tab = new Tab(1, this.items);
return this.tab.onShow($('#tab-1-0'), {'index': 1});
});
it('replace content in the container', function() {
this.tab.onShow($('#tab-1-1'), {'index': 1});
expect($('#tab-1-0').html()).toEqual('');
expect($('#tab-1-1').html()).toEqual('Video 2');
return expect($('#tab-1-2').html()).toEqual('');
});
return it('trigger contentChanged event on the element', function() {
spyOnEvent(this.tab.el, 'contentChanged');
this.tab.onShow($('#tab-1-1'), {'index': 1});
return expect('contentChanged').toHaveBeenTriggeredOn(this.tab.el);
});
});
});
describe "RequireJS namespacing", ->
beforeEach ->
# Jasmine does not provide a way to use the typeof operator. We need
# to create our own custom matchers so that a TypeError is not thrown.
jasmine.addMatchers
requirejsTobeUndefined: ->
{
compare: ->
{
pass: typeof requirejs is "undefined"
}
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
describe("RequireJS namespacing", function() {
beforeEach(() =>
// Jasmine does not provide a way to use the typeof operator. We need
// to create our own custom matchers so that a TypeError is not thrown.
jasmine.addMatchers({
requirejsTobeUndefined() {
return {
compare() {
return {
pass: typeof requirejs === "undefined"
};
}
requireTobeUndefined: ->
{
compare: ->
{
pass: typeof require is "undefined"
}
};
},
requireTobeUndefined() {
return {
compare() {
return {
pass: typeof require === "undefined"
};
}
defineTobeUndefined: ->
{
compare: ->
{
pass: typeof define is "undefined"
}
};
},
defineTobeUndefined() {
return {
compare() {
return {
pass: typeof define === "undefined"
};
}
it "check that the RequireJS object is present in the global namespace", ->
expect(RequireJS).toEqual jasmine.any(Object)
expect(window.RequireJS).toEqual jasmine.any(Object)
it "check that requirejs(), require(), and define() are not in the global namespace", ->
# The custom matchers that we defined in the beforeEach() function do
# not operate on an object. We pass a dummy empty object {} not to
# confuse Jasmine.
expect({}).requirejsTobeUndefined()
expect({}).requireTobeUndefined()
expect({}).defineTobeUndefined()
expect(window.requirejs).not.toBeDefined()
expect(window.require).not.toBeDefined()
expect(window.define).not.toBeDefined()
describe "RequireJS module creation", ->
inDefineCallback = undefined
inRequireCallback = undefined
it "check that we can use RequireJS to define() and require() a module", (done) ->
d1 = $.Deferred()
d2 = $.Deferred()
# Because Require JS works asynchronously when defining and requiring
# modules, we need to use the special Jasmine functions runs(), and
# waitsFor() to set up this test.
func = () ->
# Initialize the variable that we will test for. They will be set
# to true in the appropriate callback functions called by Require
# JS. If their values do not change, this will mean that something
# is not working as is intended.
inDefineCallback = false
inRequireCallback = false
# Define our test module.
RequireJS.define "test_module", [], ->
inDefineCallback = true
d1.resolve()
# This module returns an object. It can be accessed via the
# Require JS require() function.
module_status: "OK"
# Require our defined test module.
RequireJS.require ["test_module"], (test_module) ->
inRequireCallback = true
# If our test module was defined properly, then we should
# be able to get the object it returned, and query some
# property.
expect(test_module.module_status).toBe "OK"
d2.resolve()
func()
# We will wait before checking if our module was defined and that we were able to require() the module.
$.when(d1, d2).done(->
# The final test behavior
expect(inDefineCallback).toBeTruthy()
expect(inRequireCallback).toBeTruthy()
).always(done)
};
}}));
it("check that the RequireJS object is present in the global namespace", function() {
expect(RequireJS).toEqual(jasmine.any(Object));
return expect(window.RequireJS).toEqual(jasmine.any(Object));
});
return it("check that requirejs(), require(), and define() are not in the global namespace", function() {
// The custom matchers that we defined in the beforeEach() function do
// not operate on an object. We pass a dummy empty object {} not to
// confuse Jasmine.
expect({}).requirejsTobeUndefined();
expect({}).requireTobeUndefined();
expect({}).defineTobeUndefined();
expect(window.requirejs).not.toBeDefined();
expect(window.require).not.toBeDefined();
return expect(window.define).not.toBeDefined();
});
});
describe("RequireJS module creation", function() {
let inDefineCallback = undefined;
let inRequireCallback = undefined;
return it("check that we can use RequireJS to define() and require() a module", function(done) {
const d1 = $.Deferred();
const d2 = $.Deferred();
// Because Require JS works asynchronously when defining and requiring
// modules, we need to use the special Jasmine functions runs(), and
// waitsFor() to set up this test.
const func = function() {
// Initialize the variable that we will test for. They will be set
// to true in the appropriate callback functions called by Require
// JS. If their values do not change, this will mean that something
// is not working as is intended.
inDefineCallback = false;
inRequireCallback = false;
// Define our test module.
RequireJS.define("test_module", [], function() {
inDefineCallback = true;
d1.resolve();
// This module returns an object. It can be accessed via the
// Require JS require() function.
return {module_status: "OK"};
});
// Require our defined test module.
return RequireJS.require(["test_module"], function(test_module) {
inRequireCallback = true;
// If our test module was defined properly, then we should
// be able to get the object it returned, and query some
// property.
expect(test_module.module_status).toBe("OK");
return d2.resolve();
});
};
func();
// We will wait before checking if our module was defined and that we were able to require() the module.
return $.when(d1, d2).done(function() {
// The final test behavior
expect(inDefineCallback).toBeTruthy();
return expect(inRequireCallback).toBeTruthy();
}).always(done);
});
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment