Update vendors.

This commit is contained in:
John-David Dalton
2016-02-01 09:41:53 -08:00
parent 5522e4641d
commit a43e4f10ef
12 changed files with 772 additions and 570 deletions

View File

@@ -29,6 +29,9 @@
QUnit.config.hidepassed = true; QUnit.config.hidepassed = true;
QUnit.config.excused = { QUnit.config.excused = {
'Arrays': { 'Arrays': {
'difference': [
'can perform an OO-style difference'
],
'drop': [ 'drop': [
'is an alias for rest' 'is an alias for rest'
], ],
@@ -99,11 +102,15 @@
'is an alias for first' 'is an alias for first'
], ],
'uniq': [ 'uniq': [
'can find the unique values of an array using a custom iterator', 'uses the result of `iterator` for uniqueness comparisons (unsorted case)',
'can find the unique values of an array using a custom iterator without specifying whether array is sorted', '`sorted` argument defaults to false when omitted',
'string iterator works with sorted array', 'when `iterator` is a string, uses that key for comparisons (unsorted case)',
'can use pluck like iterator', 'uses the result of `iterator` for uniqueness comparisons (sorted case)',
'when `iterator` is a string, uses that key for comparisons (sorted case)',
'can use falsey pluck like iterator' 'can use falsey pluck like iterator'
],
'union': [
'can perform an OO-style union'
] ]
}, },
'Chaining': { 'Chaining': {

View File

@@ -1,4 +1,4 @@
Copyright (c) 2010-2015 Jeremy Ashkenas, DocumentCloud Copyright (c) 2010-2016 Jeremy Ashkenas, DocumentCloud
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation

View File

@@ -1,6 +1,6 @@
// Backbone.js 1.2.3 // Backbone.js 1.2.3
// (c) 2010-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors // (c) 2010-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
// Backbone may be freely distributed under the MIT license. // Backbone may be freely distributed under the MIT license.
// For all details and documentation: // For all details and documentation:
// http://backbonejs.org // http://backbonejs.org
@@ -146,7 +146,7 @@
events = eventsApi(iteratee, events, names[i], name[names[i]], opts); events = eventsApi(iteratee, events, names[i], name[names[i]], opts);
} }
} else if (name && eventSplitter.test(name)) { } else if (name && eventSplitter.test(name)) {
// Handle space separated event names by delegating them individually. // Handle space-separated event names by delegating them individually.
for (names = name.split(eventSplitter); i < names.length; i++) { for (names = name.split(eventSplitter); i < names.length; i++) {
events = iteratee(events, names[i], callback, opts); events = iteratee(events, names[i], callback, opts);
} }
@@ -348,7 +348,7 @@
}; };
// Handles triggering the appropriate event callbacks. // Handles triggering the appropriate event callbacks.
var triggerApi = function(objEvents, name, cb, args) { var triggerApi = function(objEvents, name, callback, args) {
if (objEvents) { if (objEvents) {
var events = objEvents[name]; var events = objEvents[name];
var allEvents = objEvents.all; var allEvents = objEvents.all;
@@ -810,7 +810,10 @@
var singular = !_.isArray(models); var singular = !_.isArray(models);
models = singular ? [models] : models.slice(); models = singular ? [models] : models.slice();
var removed = this._removeModels(models, options); var removed = this._removeModels(models, options);
if (!options.silent && removed.length) this.trigger('update', this, options); if (!options.silent && removed.length) {
options.changes = {added: [], merged: [], removed: removed};
this.trigger('update', this, options);
}
return singular ? removed[0] : removed; return singular ? removed[0] : removed;
}, },
@@ -835,6 +838,7 @@
var set = []; var set = [];
var toAdd = []; var toAdd = [];
var toMerge = [];
var toRemove = []; var toRemove = [];
var modelMap = {}; var modelMap = {};
@@ -860,6 +864,7 @@
var attrs = this._isModel(model) ? model.attributes : model; var attrs = this._isModel(model) ? model.attributes : model;
if (options.parse) attrs = existing.parse(attrs, options); if (options.parse) attrs = existing.parse(attrs, options);
existing.set(attrs, options); existing.set(attrs, options);
toMerge.push(existing);
if (sortable && !sort) sort = existing.hasChanged(sortAttr); if (sortable && !sort) sort = existing.hasChanged(sortAttr);
} }
if (!modelMap[existing.cid]) { if (!modelMap[existing.cid]) {
@@ -893,8 +898,8 @@
var orderChanged = false; var orderChanged = false;
var replace = !sortable && add && remove; var replace = !sortable && add && remove;
if (set.length && replace) { if (set.length && replace) {
orderChanged = this.length !== set.length || _.some(this.models, function(model, index) { orderChanged = this.length !== set.length || _.some(this.models, function(m, index) {
return model !== set[index]; return m !== set[index];
}); });
this.models.length = 0; this.models.length = 0;
splice(this.models, set, 0); splice(this.models, set, 0);
@@ -908,7 +913,7 @@
// Silently sort the collection if appropriate. // Silently sort the collection if appropriate.
if (sort) this.sort({silent: true}); if (sort) this.sort({silent: true});
// Unless silenced, it's time to fire all appropriate add/sort events. // Unless silenced, it's time to fire all appropriate add/sort/update events.
if (!options.silent) { if (!options.silent) {
for (i = 0; i < toAdd.length; i++) { for (i = 0; i < toAdd.length; i++) {
if (at != null) options.index = at + i; if (at != null) options.index = at + i;
@@ -916,7 +921,14 @@
model.trigger('add', model, this, options); model.trigger('add', model, this, options);
} }
if (sort || orderChanged) this.trigger('sort', this, options); if (sort || orderChanged) this.trigger('sort', this, options);
if (toAdd.length || toRemove.length) this.trigger('update', this, options); if (toAdd.length || toRemove.length || toMerge.length) {
options.changes = {
added: toAdd,
removed: toRemove,
merged: toMerge
};
this.trigger('update', this, options);
}
} }
// Return the added (or merged) model (or models). // Return the added (or merged) model (or models).
@@ -973,6 +985,11 @@
return this._byId[obj] || this._byId[id] || this._byId[obj.cid]; return this._byId[obj] || this._byId[id] || this._byId[obj.cid];
}, },
// Returns `true` if the model is in the collection.
has: function(obj) {
return this.get(obj) != null;
},
// Get the model at the given index. // Get the model at the given index.
at: function(index) { at: function(index) {
if (index < 0) index += this.length; if (index < 0) index += this.length;
@@ -1045,9 +1062,9 @@
if (!wait) this.add(model, options); if (!wait) this.add(model, options);
var collection = this; var collection = this;
var success = options.success; var success = options.success;
options.success = function(model, resp, callbackOpts) { options.success = function(m, resp, callbackOpts) {
if (wait) collection.add(model, callbackOpts); if (wait) collection.add(m, callbackOpts);
if (success) success.call(callbackOpts.context, model, resp, callbackOpts); if (success) success.call(callbackOpts.context, m, resp, callbackOpts);
}; };
model.save(null, options); model.save(null, options);
return model; return model;
@@ -1587,8 +1604,8 @@
// Does the pathname match the root? // Does the pathname match the root?
matchRoot: function() { matchRoot: function() {
var path = this.decodeFragment(this.location.pathname); var path = this.decodeFragment(this.location.pathname);
var root = path.slice(0, this.root.length - 1) + '/'; var rootPath = path.slice(0, this.root.length - 1) + '/';
return root === this.root; return rootPath === this.root;
}, },
// Unicode characters in `location.pathname` are percent encoded so they're // Unicode characters in `location.pathname` are percent encoded so they're
@@ -1660,8 +1677,8 @@
// If we've started off with a route from a `pushState`-enabled // If we've started off with a route from a `pushState`-enabled
// browser, but we're currently in a browser that doesn't support it... // browser, but we're currently in a browser that doesn't support it...
if (!this._hasPushState && !this.atRoot()) { if (!this._hasPushState && !this.atRoot()) {
var root = this.root.slice(0, -1) || '/'; var rootPath = this.root.slice(0, -1) || '/';
this.location.replace(root + '#' + this.getPath()); this.location.replace(rootPath + '#' + this.getPath());
// Return immediately as browser will do redirect to new url // Return immediately as browser will do redirect to new url
return true; return true;
@@ -1785,11 +1802,11 @@
fragment = this.getFragment(fragment || ''); fragment = this.getFragment(fragment || '');
// Don't include a trailing slash on the root. // Don't include a trailing slash on the root.
var root = this.root; var rootPath = this.root;
if (fragment === '' || fragment.charAt(0) === '?') { if (fragment === '' || fragment.charAt(0) === '?') {
root = root.slice(0, -1) || '/'; rootPath = rootPath.slice(0, -1) || '/';
} }
var url = root + fragment; var url = rootPath + fragment;
// Strip the hash and decode for matching. // Strip the hash and decode for matching.
fragment = this.decodeFragment(fragment.replace(pathStripper, '')); fragment = this.decodeFragment(fragment.replace(pathStripper, ''));

File diff suppressed because it is too large Load Diff

View File

@@ -273,8 +273,8 @@
QUnit.test('#2030 - set with failed validate, followed by another set triggers change', function(assert) { QUnit.test('#2030 - set with failed validate, followed by another set triggers change', function(assert) {
var attr = 0, main = 0, error = 0; var attr = 0, main = 0, error = 0;
var Model = Backbone.Model.extend({ var Model = Backbone.Model.extend({
validate: function(attr) { validate: function(attrs) {
if (attr.x > 1) { if (attrs.x > 1) {
error++; error++;
return 'this is an error'; return 'this is an error';
} }
@@ -379,15 +379,15 @@
var Collection = Backbone.Collection.extend({ var Collection = Backbone.Collection.extend({
model: Model model: Model
}); });
var collection = new Collection([{id: 'c5'}, {id: 'c6'}, {id: 'c7'}]); var col = new Collection([{id: 'c5'}, {id: 'c6'}, {id: 'c7'}]);
assert.equal(collection.get('c6').cid.charAt(0), 'm'); assert.equal(col.get('c6').cid.charAt(0), 'm');
collection.set([{id: 'c6', value: 'test'}], { col.set([{id: 'c6', value: 'test'}], {
merge: true, merge: true,
add: true, add: true,
remove: false remove: false
}); });
assert.ok(collection.get('c6').has('value')); assert.ok(col.get('c6').has('value'));
}); });
QUnit.test('set an empty string', function(assert) { QUnit.test('set an empty string', function(assert) {
@@ -480,8 +480,8 @@
assert.expect(2); assert.expect(2);
var value; var value;
var model = new Backbone.Model({name: 'Rob'}); var model = new Backbone.Model({name: 'Rob'});
model.on('change', function(model, options) { model.on('change', function(m, options) {
value = options.prefix + model.get('name'); value = options.prefix + m.get('name');
}); });
model.set({name: 'Bob'}, {prefix: 'Mr. '}); model.set({name: 'Bob'}, {prefix: 'Mr. '});
assert.equal(value, 'Mr. Bob'); assert.equal(value, 'Mr. Bob');
@@ -517,10 +517,10 @@
model.validate = function(attrs) { model.validate = function(attrs) {
if (attrs.admin) return "Can't change admin status."; if (attrs.admin) return "Can't change admin status.";
}; };
model.sync = function(method, model, options) { model.sync = function(method, m, options) {
options.success.call(this, {admin: true}); options.success.call(this, {admin: true});
}; };
model.on('invalid', function(model, error) { model.on('invalid', function(m, error) {
lastError = error; lastError = error;
}); });
model.save(null); model.save(null);
@@ -542,7 +542,7 @@
model.on('error', function() { model.on('error', function() {
assert.ok(true); assert.ok(true);
}); });
model.sync = function(method, model, options) { model.sync = function(method, m, options) {
options.error(); options.error();
}; };
model.save({data: 2, id: 1}); model.save({data: 2, id: 1});
@@ -560,8 +560,8 @@
assert.equal(this, obj); assert.equal(this, obj);
} }
}; };
model.sync = function(method, model, options) { model.sync = function(method, m, opts) {
options.success.call(options.context); opts.success.call(opts.context);
}; };
model.save({data: 2, id: 1}, options); model.save({data: 2, id: 1}, options);
model.fetch(options); model.fetch(options);
@@ -578,8 +578,8 @@
assert.equal(this, obj); assert.equal(this, obj);
} }
}; };
model.sync = function(method, model, options) { model.sync = function(method, m, opts) {
options.error.call(options.context); opts.error.call(opts.context);
}; };
model.save({data: 2, id: 1}, options); model.save({data: 2, id: 1}, options);
model.fetch(options); model.fetch(options);
@@ -593,7 +593,7 @@
model.parse = function() { model.parse = function() {
assert.ok(false); assert.ok(false);
}; };
model.sync = function(method, model, options) { model.sync = function(method, m, options) {
options.success({i: ++i}); options.success({i: ++i});
}; };
model.fetch({parse: false}); model.fetch({parse: false});
@@ -627,7 +627,7 @@
QUnit.test('save in positional style', function(assert) { QUnit.test('save in positional style', function(assert) {
assert.expect(1); assert.expect(1);
var model = new Backbone.Model(); var model = new Backbone.Model();
model.sync = function(method, model, options) { model.sync = function(method, m, options) {
options.success(); options.success();
}; };
model.save('title', 'Twelfth Night'); model.save('title', 'Twelfth Night');
@@ -637,13 +637,13 @@
QUnit.test('save with non-object success response', function(assert) { QUnit.test('save with non-object success response', function(assert) {
assert.expect(2); assert.expect(2);
var model = new Backbone.Model(); var model = new Backbone.Model();
model.sync = function(method, model, options) { model.sync = function(method, m, options) {
options.success('', options); options.success('', options);
options.success(null, options); options.success(null, options);
}; };
model.save({testing: 'empty'}, { model.save({testing: 'empty'}, {
success: function(model) { success: function(m) {
assert.deepEqual(model.attributes, {testing: 'empty'}); assert.deepEqual(m.attributes, {testing: 'empty'});
} }
}); });
}); });
@@ -660,16 +660,16 @@
QUnit.test('save will pass extra options to success callback', function(assert) { QUnit.test('save will pass extra options to success callback', function(assert) {
assert.expect(1); assert.expect(1);
var SpecialSyncModel = Backbone.Model.extend({ var SpecialSyncModel = Backbone.Model.extend({
sync: function(method, model, options) { sync: function(method, m, options) {
_.extend(options, {specialSync: true}); _.extend(options, {specialSync: true});
return Backbone.Model.prototype.sync.call(this, method, model, options); return Backbone.Model.prototype.sync.call(this, method, m, options);
}, },
urlRoot: '/test' urlRoot: '/test'
}); });
var model = new SpecialSyncModel(); var model = new SpecialSyncModel();
var onSuccess = function(model, response, options) { var onSuccess = function(m, response, options) {
assert.ok(options.specialSync, 'Options were passed correctly to callback'); assert.ok(options.specialSync, 'Options were passed correctly to callback');
}; };
@@ -687,16 +687,16 @@
QUnit.test('fetch will pass extra options to success callback', function(assert) { QUnit.test('fetch will pass extra options to success callback', function(assert) {
assert.expect(1); assert.expect(1);
var SpecialSyncModel = Backbone.Model.extend({ var SpecialSyncModel = Backbone.Model.extend({
sync: function(method, model, options) { sync: function(method, m, options) {
_.extend(options, {specialSync: true}); _.extend(options, {specialSync: true});
return Backbone.Model.prototype.sync.call(this, method, model, options); return Backbone.Model.prototype.sync.call(this, method, m, options);
}, },
urlRoot: '/test' urlRoot: '/test'
}); });
var model = new SpecialSyncModel(); var model = new SpecialSyncModel();
var onSuccess = function(model, response, options) { var onSuccess = function(m, response, options) {
assert.ok(options.specialSync, 'Options were passed correctly to callback'); assert.ok(options.specialSync, 'Options were passed correctly to callback');
}; };
@@ -717,16 +717,16 @@
QUnit.test('destroy will pass extra options to success callback', function(assert) { QUnit.test('destroy will pass extra options to success callback', function(assert) {
assert.expect(1); assert.expect(1);
var SpecialSyncModel = Backbone.Model.extend({ var SpecialSyncModel = Backbone.Model.extend({
sync: function(method, model, options) { sync: function(method, m, options) {
_.extend(options, {specialSync: true}); _.extend(options, {specialSync: true});
return Backbone.Model.prototype.sync.call(this, method, model, options); return Backbone.Model.prototype.sync.call(this, method, m, options);
}, },
urlRoot: '/test' urlRoot: '/test'
}); });
var model = new SpecialSyncModel({id: 'id'}); var model = new SpecialSyncModel({id: 'id'});
var onSuccess = function(model, response, options) { var onSuccess = function(m, response, options) {
assert.ok(options.specialSync, 'Options were passed correctly to callback'); assert.ok(options.specialSync, 'Options were passed correctly to callback');
}; };
@@ -748,7 +748,7 @@
model.validate = function(attrs) { model.validate = function(attrs) {
if (attrs.admin !== this.get('admin')) return "Can't change admin status."; if (attrs.admin !== this.get('admin')) return "Can't change admin status.";
}; };
model.on('invalid', function(model, error) { model.on('invalid', function(m, error) {
lastError = error; lastError = error;
}); });
var result = model.set({a: 100}); var result = model.set({a: 100});
@@ -793,7 +793,7 @@
model.validate = function(attrs) { model.validate = function(attrs) {
if (attrs.admin) return "Can't change admin status."; if (attrs.admin) return "Can't change admin status.";
}; };
model.on('invalid', function(model, error) { model.on('invalid', function(m, error) {
boundError = true; boundError = true;
}); });
var result = model.set({a: 100}, {validate: true}); var result = model.set({a: 100}, {validate: true});
@@ -848,14 +848,14 @@
QUnit.test("Nested change events don't clobber previous attributes", function(assert) { QUnit.test("Nested change events don't clobber previous attributes", function(assert) {
assert.expect(4); assert.expect(4);
new Backbone.Model() new Backbone.Model()
.on('change:state', function(model, newState) { .on('change:state', function(m, newState) {
assert.equal(model.previous('state'), undefined); assert.equal(m.previous('state'), undefined);
assert.equal(newState, 'hello'); assert.equal(newState, 'hello');
// Fire a nested change event. // Fire a nested change event.
model.set({other: 'whatever'}); m.set({other: 'whatever'});
}) })
.on('change:state', function(model, newState) { .on('change:state', function(m, newState) {
assert.equal(model.previous('state'), undefined); assert.equal(m.previous('state'), undefined);
assert.equal(newState, 'hello'); assert.equal(newState, 'hello');
}) })
.set({state: 'hello'}); .set({state: 'hello'});
@@ -1021,7 +1021,7 @@
QUnit.test('#1030 - `save` with `wait` results in correct attributes if success is called during sync', function(assert) { QUnit.test('#1030 - `save` with `wait` results in correct attributes if success is called during sync', function(assert) {
assert.expect(2); assert.expect(2);
var model = new Backbone.Model({x: 1, y: 2}); var model = new Backbone.Model({x: 1, y: 2});
model.sync = function(method, model, options) { model.sync = function(method, m, options) {
options.success(); options.success();
}; };
model.on('change:x', function() { assert.ok(true); }); model.on('change:x', function() { assert.ok(true); });
@@ -1038,7 +1038,7 @@
QUnit.test('save turns on parse flag', function(assert) { QUnit.test('save turns on parse flag', function(assert) {
var Model = Backbone.Model.extend({ var Model = Backbone.Model.extend({
sync: function(method, model, options) { assert.ok(options.parse); } sync: function(method, m, options) { assert.ok(options.parse); }
}); });
new Model().save(); new Model().save();
}); });
@@ -1142,7 +1142,7 @@
model.set({y: 1}, {silent: true}); model.set({y: 1}, {silent: true});
model.set({y: 2}); model.set({y: 2});
}); });
model.on('change:y', function(model, val) { model.on('change:y', function(m, val) {
assert.equal(val, 2); assert.equal(val, 2);
}); });
model.set({x: true}); model.set({x: true});
@@ -1152,7 +1152,7 @@
assert.expect(1); assert.expect(1);
var changes = []; var changes = [];
var model = new Backbone.Model(); var model = new Backbone.Model();
model.on('change:b', function(model, val) { changes.push(val); }); model.on('change:b', function(m, val) { changes.push(val); });
model.on('change', function() { model.on('change', function() {
model.set({b: 1}); model.set({b: 1});
}); });
@@ -1202,11 +1202,11 @@
assert.expect(3); assert.expect(3);
var model = new Backbone.Model(); var model = new Backbone.Model();
var opts = { var opts = {
success: function( model, resp, options ) { success: function( m, resp, options ) {
assert.ok(options); assert.ok(options);
} }
}; };
model.sync = function(method, model, options) { model.sync = function(method, m, options) {
options.success(); options.success();
}; };
model.save({id: 1}, opts); model.save({id: 1}, opts);
@@ -1217,7 +1217,7 @@
QUnit.test("#1412 - Trigger 'sync' event.", function(assert) { QUnit.test("#1412 - Trigger 'sync' event.", function(assert) {
assert.expect(3); assert.expect(3);
var model = new Backbone.Model({id: 1}); var model = new Backbone.Model({id: 1});
model.sync = function(method, model, options) { options.success(); }; model.sync = function(method, m, options) { options.success(); };
model.on('sync', function(){ assert.ok(true); }); model.on('sync', function(){ assert.ok(true); });
model.fetch(); model.fetch();
model.save(); model.save();
@@ -1248,7 +1248,7 @@
assert.expect(1); assert.expect(1);
var Model = Backbone.Model.extend({ var Model = Backbone.Model.extend({
url: '/test/', url: '/test/',
sync: function(method, model, options){ options.success(); }, sync: function(method, m, options){ options.success(); },
validate: function(){ return 'invalid'; } validate: function(){ return 'invalid'; }
}); });
var model = new Model({id: 1}); var model = new Model({id: 1});
@@ -1271,7 +1271,7 @@
var done = assert.async(); var done = assert.async();
assert.expect(0); assert.expect(0);
var Model = Backbone.Model.extend({ var Model = Backbone.Model.extend({
sync: function(method, model, options) { sync: function(method, m, options) {
setTimeout(function(){ setTimeout(function(){
options.success(); options.success();
done(); done();
@@ -1301,7 +1301,7 @@
model.set({b: 2}, {silent: true}); model.set({b: 2}, {silent: true});
model.unset('c', {silent: true}); model.unset('c', {silent: true});
}); });
model.on('change:a change:b change:c', function(model, val) { changes.push(val); }); model.on('change:a change:b change:c', function(m, val) { changes.push(val); });
model.set({a: 'a', b: 1, c: 'item'}); model.set({a: 'a', b: 1, c: 'item'});
assert.deepEqual(changes, ['a', 1, 'item']); assert.deepEqual(changes, ['a', 1, 'item']);
assert.deepEqual(model.attributes, {a: 'c', b: 2}); assert.deepEqual(model.attributes, {a: 'c', b: 2});
@@ -1319,7 +1319,7 @@
assert.expect(2); assert.expect(2);
var changes = []; var changes = [];
var model = new Backbone.Model(); var model = new Backbone.Model();
model.on('change:a change:b change:c', function(model, val) { changes.push(val); }); model.on('change:a change:b change:c', function(m, val) { changes.push(val); });
model.on('change', function() { model.on('change', function() {
model.set({a: 'c'}, {silent: true}); model.set({a: 'c'}, {silent: true});
}); });

View File

@@ -5,7 +5,7 @@
var lastRoute = null; var lastRoute = null;
var lastArgs = []; var lastArgs = [];
var onRoute = function(router, route, args) { var onRoute = function(routerParam, route, args) {
lastRoute = route; lastRoute = route;
lastArgs = args; lastArgs = args;
}; };
@@ -354,7 +354,7 @@
QUnit.test('No events are triggered if #execute returns false.', function(assert) { QUnit.test('No events are triggered if #execute returns false.', function(assert) {
assert.expect(1); assert.expect(1);
var Router = Backbone.Router.extend({ var MyRouter = Backbone.Router.extend({
routes: { routes: {
foo: function() { foo: function() {
@@ -369,9 +369,9 @@
}); });
var router = new Router; var myRouter = new MyRouter;
router.on('route route:foo', function() { myRouter.on('route route:foo', function() {
assert.ok(false); assert.ok(false);
}); });
@@ -639,14 +639,14 @@
QUnit.test('#1746 - Router allows empty route.', function(assert) { QUnit.test('#1746 - Router allows empty route.', function(assert) {
assert.expect(1); assert.expect(1);
var Router = Backbone.Router.extend({ var MyRouter = Backbone.Router.extend({
routes: {'': 'empty'}, routes: {'': 'empty'},
empty: function(){}, empty: function(){},
route: function(route){ route: function(route){
assert.strictEqual(route, ''); assert.strictEqual(route, '');
} }
}); });
new Router; new MyRouter;
}); });
QUnit.test('#1794 - Trailing space in fragments.', function(assert) { QUnit.test('#1794 - Trailing space in fragments.', function(assert) {
@@ -698,8 +698,8 @@
} }
}); });
var router = new RouterExtended(); var myRouter = new RouterExtended();
assert.deepEqual({home: 'root', index: 'index.html', show: 'show', search: 'search'}, router.routes); assert.deepEqual({home: 'root', index: 'index.html', show: 'show', search: 'search'}, myRouter.routes);
}); });
QUnit.test('#2538 - hashChange to pushState only if both requested.', function(assert) { QUnit.test('#2538 - hashChange to pushState only if both requested.', function(assert) {
@@ -731,12 +731,12 @@
} }
}); });
var Router = Backbone.Router.extend({ var MyRouter = Backbone.Router.extend({
routes: { routes: {
hash: function() { assert.ok(false); } hash: function() { assert.ok(false); }
} }
}); });
var router = new Router; var myRouter = new MyRouter;
location.replace('http://example.com/'); location.replace('http://example.com/');
Backbone.history.start({ Backbone.history.start({
@@ -807,12 +807,12 @@
} }
}); });
var Router = Backbone.Router.extend({ var MyRouter = Backbone.Router.extend({
routes: { routes: {
path: function() { assert.ok(true); } path: function() { assert.ok(true); }
} }
}); });
var router = new Router; var myRouter = new MyRouter;
location.replace('http://example.com/'); location.replace('http://example.com/');
Backbone.history.start({pushState: true, hashChange: false}); Backbone.history.start({pushState: true, hashChange: false});
@@ -821,14 +821,14 @@
QUnit.test('Do not decode the search params.', function(assert) { QUnit.test('Do not decode the search params.', function(assert) {
assert.expect(1); assert.expect(1);
var Router = Backbone.Router.extend({ var MyRouter = Backbone.Router.extend({
routes: { routes: {
path: function(params){ path: function(params){
assert.strictEqual(params, 'x=y%3Fz'); assert.strictEqual(params, 'x=y%3Fz');
} }
} }
}); });
var router = new Router; var myRouter = new MyRouter;
Backbone.history.navigate('path?x=y%3Fz', true); Backbone.history.navigate('path?x=y%3Fz', true);
}); });
@@ -837,14 +837,14 @@
Backbone.history.stop(); Backbone.history.stop();
Backbone.history = _.extend(new Backbone.History, {location: location}); Backbone.history = _.extend(new Backbone.History, {location: location});
Backbone.history.start({pushState: true}); Backbone.history.start({pushState: true});
var Router = Backbone.Router.extend({ var MyRouter = Backbone.Router.extend({
routes: { routes: {
path: function(params) { path: function(params) {
assert.strictEqual(params, 'x=y'); assert.strictEqual(params, 'x=y');
} }
} }
}); });
var router = new Router; var myRouter = new MyRouter;
location.replace('http://example.com/path?x=y#hash'); location.replace('http://example.com/path?x=y#hash');
Backbone.history.checkUrl(); Backbone.history.checkUrl();
}); });
@@ -854,14 +854,14 @@
Backbone.history.stop(); Backbone.history.stop();
Backbone.history = _.extend(new Backbone.History, {location: location}); Backbone.history = _.extend(new Backbone.History, {location: location});
Backbone.history.start({pushState: true}); Backbone.history.start({pushState: true});
var Router = Backbone.Router.extend({ var MyRouter = Backbone.Router.extend({
routes: { routes: {
path: function(params) { path: function(params) {
assert.strictEqual(params, 'x=y'); assert.strictEqual(params, 'x=y');
} }
} }
}); });
var router = new Router; var myRouter = new MyRouter;
Backbone.history.navigate('path?x=y#hash', true); Backbone.history.navigate('path?x=y#hash', true);
}); });
@@ -870,14 +870,14 @@
location.replace('http://example.com/myyjä'); location.replace('http://example.com/myyjä');
Backbone.history.stop(); Backbone.history.stop();
Backbone.history = _.extend(new Backbone.History, {location: location}); Backbone.history = _.extend(new Backbone.History, {location: location});
var Router = Backbone.Router.extend({ var MyRouter = Backbone.Router.extend({
routes: { routes: {
myyjä: function() { myyjä: function() {
assert.ok(true); assert.ok(true);
} }
} }
}); });
new Router; new MyRouter;
Backbone.history.start({pushState: true}); Backbone.history.start({pushState: true});
}); });
@@ -887,14 +887,14 @@
location.pathname = '/myyj%C3%A4/foo%20%25%3F%2f%40%25%20bar'; location.pathname = '/myyj%C3%A4/foo%20%25%3F%2f%40%25%20bar';
Backbone.history.stop(); Backbone.history.stop();
Backbone.history = _.extend(new Backbone.History, {location: location}); Backbone.history = _.extend(new Backbone.History, {location: location});
var Router = Backbone.Router.extend({ var MyRouter = Backbone.Router.extend({
routes: { routes: {
'myyjä/:query': function(query) { 'myyjä/:query': function(query) {
assert.strictEqual(query, 'foo %?/@% bar'); assert.strictEqual(query, 'foo %?/@% bar');
} }
} }
}); });
new Router; new MyRouter;
Backbone.history.start({pushState: true}); Backbone.history.start({pushState: true});
}); });
@@ -903,14 +903,14 @@
location.replace('http://example.com/stuff%0Anonsense?param=foo%0Abar'); location.replace('http://example.com/stuff%0Anonsense?param=foo%0Abar');
Backbone.history.stop(); Backbone.history.stop();
Backbone.history = _.extend(new Backbone.History, {location: location}); Backbone.history = _.extend(new Backbone.History, {location: location});
var Router = Backbone.Router.extend({ var MyRouter = Backbone.Router.extend({
routes: { routes: {
'stuff\nnonsense': function() { 'stuff\nnonsense': function() {
assert.ok(true); assert.ok(true);
} }
} }
}); });
new Router; new MyRouter;
Backbone.history.start({pushState: true}); Backbone.history.start({pushState: true});
}); });
@@ -919,7 +919,7 @@
location.replace('http://example.com#foo/123/bar?x=y'); location.replace('http://example.com#foo/123/bar?x=y');
Backbone.history.stop(); Backbone.history.stop();
Backbone.history = _.extend(new Backbone.History, {location: location}); Backbone.history = _.extend(new Backbone.History, {location: location});
var Router = Backbone.Router.extend({ var MyRouter = Backbone.Router.extend({
routes: {'foo/:id/bar': 'foo'}, routes: {'foo/:id/bar': 'foo'},
foo: function(){}, foo: function(){},
execute: function(callback, args, name) { execute: function(callback, args, name) {
@@ -928,7 +928,7 @@
assert.strictEqual(name, 'foo'); assert.strictEqual(name, 'foo');
} }
}); });
var router = new Router; var myRouter = new MyRouter;
Backbone.history.start(); Backbone.history.start();
}); });
@@ -967,8 +967,8 @@
Backbone.history.stop(); Backbone.history.stop();
location.replace('http://example.com#login?a=value&backUrl=https%3A%2F%2Fwww.msn.com%2Fidp%2Fidpdemo%3Fspid%3Dspdemo%26target%3Db'); location.replace('http://example.com#login?a=value&backUrl=https%3A%2F%2Fwww.msn.com%2Fidp%2Fidpdemo%3Fspid%3Dspdemo%26target%3Db');
Backbone.history = _.extend(new Backbone.History, {location: location}); Backbone.history = _.extend(new Backbone.History, {location: location});
var router = new Backbone.Router; var myRouter = new Backbone.Router;
router.route('login', function(params) { myRouter.route('login', function(params) {
assert.strictEqual(params, 'a=value&backUrl=https%3A%2F%2Fwww.msn.com%2Fidp%2Fidpdemo%3Fspid%3Dspdemo%26target%3Db'); assert.strictEqual(params, 'a=value&backUrl=https%3A%2F%2Fwww.msn.com%2Fidp%2Fidpdemo%3Fspid%3Dspdemo%26target%3Db');
}); });
Backbone.history.start(); Backbone.history.start();
@@ -996,14 +996,14 @@
location.replace('http://example.com/foo'); location.replace('http://example.com/foo');
Backbone.history.stop(); Backbone.history.stop();
Backbone.history = _.extend(new Backbone.History, {location: location}); Backbone.history = _.extend(new Backbone.History, {location: location});
var Router = Backbone.Router.extend({ var MyRouter = Backbone.Router.extend({
routes: { routes: {
foo: function(){ foo: function(){
assert.ok(false, 'should not match unless root matches'); assert.ok(false, 'should not match unless root matches');
} }
} }
}); });
var router = new Router; var myRouter = new MyRouter;
Backbone.history.start({root: 'root', pushState: true}); Backbone.history.start({root: 'root', pushState: true});
}); });
@@ -1012,14 +1012,14 @@
location.replace('http://example.com/xxxx/foo'); location.replace('http://example.com/xxxx/foo');
Backbone.history.stop(); Backbone.history.stop();
Backbone.history = _.extend(new Backbone.History, {location: location}); Backbone.history = _.extend(new Backbone.History, {location: location});
var Router = Backbone.Router.extend({ var MyRouter = Backbone.Router.extend({
routes: { routes: {
foo: function(){ foo: function(){
assert.ok(false, 'should not match unless root matches'); assert.ok(false, 'should not match unless root matches');
} }
} }
}); });
var router = new Router; var myRouter = new MyRouter;
Backbone.history.start({root: 'root', pushState: true}); Backbone.history.start({root: 'root', pushState: true});
}); });
@@ -1028,10 +1028,10 @@
location.replace('http://example.com/x+y.z/foo'); location.replace('http://example.com/x+y.z/foo');
Backbone.history.stop(); Backbone.history.stop();
Backbone.history = _.extend(new Backbone.History, {location: location}); Backbone.history = _.extend(new Backbone.History, {location: location});
var Router = Backbone.Router.extend({ var MyRouter = Backbone.Router.extend({
routes: {foo: function(){ assert.ok(true); }} routes: {foo: function(){ assert.ok(true); }}
}); });
var router = new Router; var myRouter = new MyRouter;
Backbone.history.start({root: 'x+y.z', pushState: true}); Backbone.history.start({root: 'x+y.z', pushState: true});
}); });
@@ -1040,10 +1040,10 @@
location.replace('http://example.com/®ooτ/foo'); location.replace('http://example.com/®ooτ/foo');
Backbone.history.stop(); Backbone.history.stop();
Backbone.history = _.extend(new Backbone.History, {location: location}); Backbone.history = _.extend(new Backbone.History, {location: location});
var Router = Backbone.Router.extend({ var MyRouter = Backbone.Router.extend({
routes: {foo: function(){ assert.ok(true); }} routes: {foo: function(){ assert.ok(true); }}
}); });
var router = new Router; var myRouter = new MyRouter;
Backbone.history.start({root: '®ooτ', pushState: true}); Backbone.history.start({root: '®ooτ', pushState: true});
}); });
@@ -1052,10 +1052,10 @@
location.replace('http://example.com/®ooτ'); location.replace('http://example.com/®ooτ');
Backbone.history.stop(); Backbone.history.stop();
Backbone.history = _.extend(new Backbone.History, {location: location}); Backbone.history = _.extend(new Backbone.History, {location: location});
var Router = Backbone.Router.extend({ var MyRouter = Backbone.Router.extend({
routes: {'': function(){ assert.ok(true); }} routes: {'': function(){ assert.ok(true); }}
}); });
var router = new Router; var myRouter = new MyRouter;
Backbone.history.start({root: '®ooτ', pushState: true}); Backbone.history.start({root: '®ooτ', pushState: true});
}); });

View File

@@ -228,7 +228,7 @@
assert.expect(2); assert.expect(2);
var model = new Backbone.Model; var model = new Backbone.Model;
model.url = '/test'; model.url = '/test';
model.on('error', function(model, xhr, options) { model.on('error', function(m, xhr, options) {
assert.strictEqual(options.textStatus, 'textStatus'); assert.strictEqual(options.textStatus, 'textStatus');
assert.strictEqual(options.errorThrown, 'errorThrown'); assert.strictEqual(options.errorThrown, 'errorThrown');
}); });

View File

@@ -27,9 +27,9 @@
QUnit.test('$', function(assert) { QUnit.test('$', function(assert) {
assert.expect(2); assert.expect(2);
var view = new Backbone.View; var myView = new Backbone.View;
view.setElement('<p><a><b>test</b></a></p>'); myView.setElement('<p><a><b>test</b></a></p>');
var result = view.$('a b'); var result = myView.$('a b');
assert.strictEqual(result[0].innerHTML, 'test'); assert.strictEqual(result[0].innerHTML, 'test');
assert.ok(result.length === +result.length); assert.ok(result.length === +result.length);
@@ -37,12 +37,12 @@
QUnit.test('$el', function(assert) { QUnit.test('$el', function(assert) {
assert.expect(3); assert.expect(3);
var view = new Backbone.View; var myView = new Backbone.View;
view.setElement('<p><a><b>test</b></a></p>'); myView.setElement('<p><a><b>test</b></a></p>');
assert.strictEqual(view.el.nodeType, 1); assert.strictEqual(myView.el.nodeType, 1);
assert.ok(view.$el instanceof Backbone.$); assert.ok(myView.$el instanceof Backbone.$);
assert.strictEqual(view.$el[0], view.el); assert.strictEqual(myView.$el[0], myView.el);
}); });
QUnit.test('initialize', function(assert) { QUnit.test('initialize', function(assert) {
@@ -58,53 +58,53 @@
QUnit.test('render', function(assert) { QUnit.test('render', function(assert) {
assert.expect(1); assert.expect(1);
var view = new Backbone.View; var myView = new Backbone.View;
assert.equal(view.render(), view, '#render returns the view instance'); assert.equal(myView.render(), myView, '#render returns the view instance');
}); });
QUnit.test('delegateEvents', function(assert) { QUnit.test('delegateEvents', function(assert) {
assert.expect(6); assert.expect(6);
var counter1 = 0, counter2 = 0; var counter1 = 0, counter2 = 0;
var view = new Backbone.View({el: '#testElement'}); var myView = new Backbone.View({el: '#testElement'});
view.increment = function(){ counter1++; }; myView.increment = function(){ counter1++; };
view.$el.on('click', function(){ counter2++; }); myView.$el.on('click', function(){ counter2++; });
var events = {'click h1': 'increment'}; var events = {'click h1': 'increment'};
view.delegateEvents(events); myView.delegateEvents(events);
view.$('h1').trigger('click'); myView.$('h1').trigger('click');
assert.equal(counter1, 1); assert.equal(counter1, 1);
assert.equal(counter2, 1); assert.equal(counter2, 1);
view.$('h1').trigger('click'); myView.$('h1').trigger('click');
assert.equal(counter1, 2); assert.equal(counter1, 2);
assert.equal(counter2, 2); assert.equal(counter2, 2);
view.delegateEvents(events); myView.delegateEvents(events);
view.$('h1').trigger('click'); myView.$('h1').trigger('click');
assert.equal(counter1, 3); assert.equal(counter1, 3);
assert.equal(counter2, 3); assert.equal(counter2, 3);
}); });
QUnit.test('delegate', function(assert) { QUnit.test('delegate', function(assert) {
assert.expect(3); assert.expect(3);
var view = new Backbone.View({el: '#testElement'}); var myView = new Backbone.View({el: '#testElement'});
view.delegate('click', 'h1', function() { myView.delegate('click', 'h1', function() {
assert.ok(true); assert.ok(true);
}); });
view.delegate('click', function() { myView.delegate('click', function() {
assert.ok(true); assert.ok(true);
}); });
view.$('h1').trigger('click'); myView.$('h1').trigger('click');
assert.equal(view.delegate(), view, '#delegate returns the view instance'); assert.equal(myView.delegate(), myView, '#delegate returns the view instance');
}); });
QUnit.test('delegateEvents allows functions for callbacks', function(assert) { QUnit.test('delegateEvents allows functions for callbacks', function(assert) {
assert.expect(3); assert.expect(3);
var view = new Backbone.View({el: '<p></p>'}); var myView = new Backbone.View({el: '<p></p>'});
view.counter = 0; myView.counter = 0;
var events = { var events = {
click: function() { click: function() {
@@ -112,97 +112,97 @@
} }
}; };
view.delegateEvents(events); myView.delegateEvents(events);
view.$el.trigger('click'); myView.$el.trigger('click');
assert.equal(view.counter, 1); assert.equal(myView.counter, 1);
view.$el.trigger('click'); myView.$el.trigger('click');
assert.equal(view.counter, 2); assert.equal(myView.counter, 2);
view.delegateEvents(events); myView.delegateEvents(events);
view.$el.trigger('click'); myView.$el.trigger('click');
assert.equal(view.counter, 3); assert.equal(myView.counter, 3);
}); });
QUnit.test('delegateEvents ignore undefined methods', function(assert) { QUnit.test('delegateEvents ignore undefined methods', function(assert) {
assert.expect(0); assert.expect(0);
var view = new Backbone.View({el: '<p></p>'}); var myView = new Backbone.View({el: '<p></p>'});
view.delegateEvents({'click': 'undefinedMethod'}); myView.delegateEvents({'click': 'undefinedMethod'});
view.$el.trigger('click'); myView.$el.trigger('click');
}); });
QUnit.test('undelegateEvents', function(assert) { QUnit.test('undelegateEvents', function(assert) {
assert.expect(7); assert.expect(7);
var counter1 = 0, counter2 = 0; var counter1 = 0, counter2 = 0;
var view = new Backbone.View({el: '#testElement'}); var myView = new Backbone.View({el: '#testElement'});
view.increment = function(){ counter1++; }; myView.increment = function(){ counter1++; };
view.$el.on('click', function(){ counter2++; }); myView.$el.on('click', function(){ counter2++; });
var events = {'click h1': 'increment'}; var events = {'click h1': 'increment'};
view.delegateEvents(events); myView.delegateEvents(events);
view.$('h1').trigger('click'); myView.$('h1').trigger('click');
assert.equal(counter1, 1); assert.equal(counter1, 1);
assert.equal(counter2, 1); assert.equal(counter2, 1);
view.undelegateEvents(); myView.undelegateEvents();
view.$('h1').trigger('click'); myView.$('h1').trigger('click');
assert.equal(counter1, 1); assert.equal(counter1, 1);
assert.equal(counter2, 2); assert.equal(counter2, 2);
view.delegateEvents(events); myView.delegateEvents(events);
view.$('h1').trigger('click'); myView.$('h1').trigger('click');
assert.equal(counter1, 2); assert.equal(counter1, 2);
assert.equal(counter2, 3); assert.equal(counter2, 3);
assert.equal(view.undelegateEvents(), view, '#undelegateEvents returns the view instance'); assert.equal(myView.undelegateEvents(), myView, '#undelegateEvents returns the view instance');
}); });
QUnit.test('undelegate', function(assert) { QUnit.test('undelegate', function(assert) {
assert.expect(1); assert.expect(1);
view = new Backbone.View({el: '#testElement'}); var myView = new Backbone.View({el: '#testElement'});
view.delegate('click', function() { assert.ok(false); }); myView.delegate('click', function() { assert.ok(false); });
view.delegate('click', 'h1', function() { assert.ok(false); }); myView.delegate('click', 'h1', function() { assert.ok(false); });
view.undelegate('click'); myView.undelegate('click');
view.$('h1').trigger('click'); myView.$('h1').trigger('click');
view.$el.trigger('click'); myView.$el.trigger('click');
assert.equal(view.undelegate(), view, '#undelegate returns the view instance'); assert.equal(myView.undelegate(), myView, '#undelegate returns the view instance');
}); });
QUnit.test('undelegate with passed handler', function(assert) { QUnit.test('undelegate with passed handler', function(assert) {
assert.expect(1); assert.expect(1);
view = new Backbone.View({el: '#testElement'}); var myView = new Backbone.View({el: '#testElement'});
var listener = function() { assert.ok(false); }; var listener = function() { assert.ok(false); };
view.delegate('click', listener); myView.delegate('click', listener);
view.delegate('click', function() { assert.ok(true); }); myView.delegate('click', function() { assert.ok(true); });
view.undelegate('click', listener); myView.undelegate('click', listener);
view.$el.trigger('click'); myView.$el.trigger('click');
}); });
QUnit.test('undelegate with selector', function(assert) { QUnit.test('undelegate with selector', function(assert) {
assert.expect(2); assert.expect(2);
view = new Backbone.View({el: '#testElement'}); var myView = new Backbone.View({el: '#testElement'});
view.delegate('click', function() { assert.ok(true); }); myView.delegate('click', function() { assert.ok(true); });
view.delegate('click', 'h1', function() { assert.ok(false); }); myView.delegate('click', 'h1', function() { assert.ok(false); });
view.undelegate('click', 'h1'); myView.undelegate('click', 'h1');
view.$('h1').trigger('click'); myView.$('h1').trigger('click');
view.$el.trigger('click'); myView.$el.trigger('click');
}); });
QUnit.test('undelegate with handler and selector', function(assert) { QUnit.test('undelegate with handler and selector', function(assert) {
assert.expect(2); assert.expect(2);
view = new Backbone.View({el: '#testElement'}); var myView = new Backbone.View({el: '#testElement'});
view.delegate('click', function() { assert.ok(true); }); myView.delegate('click', function() { assert.ok(true); });
var handler = function(){ assert.ok(false); }; var handler = function(){ assert.ok(false); };
view.delegate('click', 'h1', handler); myView.delegate('click', 'h1', handler);
view.undelegate('click', 'h1', handler); myView.undelegate('click', 'h1', handler);
view.$('h1').trigger('click'); myView.$('h1').trigger('click');
view.$el.trigger('click'); myView.$el.trigger('click');
}); });
QUnit.test('tagName can be provided as a string', function(assert) { QUnit.test('tagName can be provided as a string', function(assert) {
@@ -302,11 +302,11 @@
} }
}); });
var view = new View; var myView = new View;
assert.strictEqual(view.el.className, 'backboneClass'); assert.strictEqual(myView.el.className, 'backboneClass');
assert.strictEqual(view.el.id, 'backboneId'); assert.strictEqual(myView.el.id, 'backboneId');
assert.strictEqual(view.$el.attr('class'), 'backboneClass'); assert.strictEqual(myView.$el.attr('class'), 'backboneClass');
assert.strictEqual(view.$el.attr('id'), 'backboneId'); assert.strictEqual(myView.$el.attr('id'), 'backboneId');
}); });
QUnit.test('multiple views per element', function(assert) { QUnit.test('multiple views per element', function(assert) {
@@ -345,7 +345,7 @@
} }
}); });
var view = new View; var myView = new View;
$('body').trigger('fake$event').trigger('fake$event'); $('body').trigger('fake$event').trigger('fake$event');
$('body').off('fake$event'); $('body').off('fake$event');
@@ -356,11 +356,11 @@
assert.expect(2); assert.expect(2);
var $el = $('body'); var $el = $('body');
var view = new Backbone.View({el: $el}); var myView = new Backbone.View({el: $el});
assert.ok(view.$el === $el); assert.ok(myView.$el === $el);
view.setElement($el = $($el)); myView.setElement($el = $($el));
assert.ok(view.$el === $el); assert.ok(myView.$el === $el);
}); });
QUnit.test('#986 - Undelegate before changing element.', function(assert) { QUnit.test('#986 - Undelegate before changing element.', function(assert) {
@@ -371,13 +371,13 @@
var View = Backbone.View.extend({ var View = Backbone.View.extend({
events: { events: {
click: function(e) { click: function(e) {
assert.ok(view.el === e.target); assert.ok(myView.el === e.target);
} }
} }
}); });
var view = new View({el: button1}); var myView = new View({el: button1});
view.setElement(button2); myView.setElement(button2);
button1.trigger('click'); button1.trigger('click');
button2.trigger('click'); button2.trigger('click');
@@ -405,14 +405,14 @@
} }
}); });
var view = new View({ var myView = new View({
model: new Backbone.Model, model: new Backbone.Model,
collection: new Backbone.Collection collection: new Backbone.Collection
}); });
view.stopListening(); myView.stopListening();
view.model.trigger('x'); myView.model.trigger('x');
view.collection.trigger('x'); myView.collection.trigger('x');
}); });
QUnit.test('Provide function for el.', function(assert) { QUnit.test('Provide function for el.', function(assert) {
@@ -423,9 +423,9 @@
} }
}); });
var view = new View; var myView = new View;
assert.ok(view.$el.is('p')); assert.ok(myView.$el.is('p'));
assert.ok(view.$el.has('a')); assert.ok(myView.$el.has('a'));
}); });
QUnit.test('events passed in options', function(assert) { QUnit.test('events passed in options', function(assert) {
@@ -439,52 +439,52 @@
} }
}); });
var view = new View({ var myView = new View({
events: { events: {
'click h1': 'increment' 'click h1': 'increment'
} }
}); });
view.$('h1').trigger('click').trigger('click'); myView.$('h1').trigger('click').trigger('click');
assert.equal(counter, 2); assert.equal(counter, 2);
}); });
QUnit.test('remove', function(assert) { QUnit.test('remove', function(assert) {
assert.expect(2); assert.expect(2);
var view = new Backbone.View; var myView = new Backbone.View;
document.body.appendChild(view.el); document.body.appendChild(view.el);
view.delegate('click', function() { assert.ok(false); }); myView.delegate('click', function() { assert.ok(false); });
view.listenTo(view, 'all x', function() { assert.ok(false); }); myView.listenTo(myView, 'all x', function() { assert.ok(false); });
assert.equal(view.remove(), view, '#remove returns the view instance'); assert.equal(myView.remove(), myView, '#remove returns the view instance');
view.$el.trigger('click'); myView.$el.trigger('click');
view.trigger('x'); myView.trigger('x');
// In IE8 and below, parentNode still exists but is not document.body. // In IE8 and below, parentNode still exists but is not document.body.
assert.notEqual(view.el.parentNode, document.body); assert.notEqual(myView.el.parentNode, document.body);
}); });
QUnit.test('setElement', function(assert) { QUnit.test('setElement', function(assert) {
assert.expect(3); assert.expect(3);
var view = new Backbone.View({ var myView = new Backbone.View({
events: { events: {
click: function() { assert.ok(false); } click: function() { assert.ok(false); }
} }
}); });
view.events = { myView.events = {
click: function() { assert.ok(true); } click: function() { assert.ok(true); }
}; };
var oldEl = view.el; var oldEl = myView.el;
var $oldEl = view.$el; var $oldEl = myView.$el;
view.setElement(document.createElement('div')); myView.setElement(document.createElement('div'));
$oldEl.click(); $oldEl.click();
view.$el.click(); myView.$el.click();
assert.notEqual(oldEl, view.el); assert.notEqual(oldEl, myView.el);
assert.notEqual($oldEl, view.$el); assert.notEqual($oldEl, myView.$el);
}); });
})(); })();

View File

@@ -1,4 +1,4 @@
Copyright (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Copyright (c) 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative
Reporters & Editors Reporters & Editors
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person

View File

@@ -143,33 +143,23 @@
QUnit.test('uniq', function(assert) { QUnit.test('uniq', function(assert) {
var list = [1, 2, 1, 3, 1, 4]; var list = [1, 2, 1, 3, 1, 4];
assert.deepEqual(_.uniq(list), [1, 2, 3, 4], 'can find the unique values of an unsorted array'); assert.deepEqual(_.uniq(list), [1, 2, 3, 4], 'can find the unique values of an unsorted array');
list = [1, 1, 1, 2, 2, 3]; list = [1, 1, 1, 2, 2, 3];
assert.deepEqual(_.uniq(list, true), [1, 2, 3], 'can find the unique values of a sorted array faster'); assert.deepEqual(_.uniq(list, true), [1, 2, 3], 'can find the unique values of a sorted array faster');
list = [{name: 'moe'}, {name: 'curly'}, {name: 'larry'}, {name: 'curly'}]; list = [{name: 'Moe'}, {name: 'Curly'}, {name: 'Larry'}, {name: 'Curly'}];
var iterator = function(value) { return value.name; }; var expected = [{name: 'Moe'}, {name: 'Curly'}, {name: 'Larry'}];
assert.deepEqual(_.map(_.uniq(list, false, iterator), iterator), ['moe', 'curly', 'larry'], 'can find the unique values of an array using a custom iterator'); var iterator = function(stooge) { return stooge.name; };
assert.deepEqual(_.uniq(list, false, iterator), expected, 'uses the result of `iterator` for uniqueness comparisons (unsorted case)');
assert.deepEqual(_.uniq(list, iterator), expected, '`sorted` argument defaults to false when omitted');
assert.deepEqual(_.uniq(list, 'name'), expected, 'when `iterator` is a string, uses that key for comparisons (unsorted case)');
assert.deepEqual(_.map(_.uniq(list, iterator), iterator), ['moe', 'curly', 'larry'], 'can find the unique values of an array using a custom iterator without specifying whether array is sorted'); list = [{score: 8}, {score: 10}, {score: 10}];
expected = [{score: 8}, {score: 10}];
iterator = function(value) { return value + 1; }; iterator = function(item) { return item.score; };
list = [1, 2, 2, 3, 4, 4]; assert.deepEqual(_.uniq(list, true, iterator), expected, 'uses the result of `iterator` for uniqueness comparisons (sorted case)');
assert.deepEqual(_.uniq(list, true, iterator), [1, 2, 3, 4], 'iterator works with sorted array'); assert.deepEqual(_.uniq(list, true, 'score'), expected, 'when `iterator` is a string, uses that key for comparisons (sorted case)');
var kittens = [
{kitten: 'Celery', cuteness: 8},
{kitten: 'Juniper', cuteness: 10},
{kitten: 'Spottis', cuteness: 10}
];
var expected = [
{kitten: 'Celery', cuteness: 8},
{kitten: 'Juniper', cuteness: 10}
];
assert.deepEqual(_.uniq(kittens, true, 'cuteness'), expected, 'string iterator works with sorted array');
assert.deepEqual(_.uniq([{0: 1}, {0: 1}, {0: 1}, {0: 2}], 0), [{0: 1}, {0: 2}], 'can use falsey pluck like iterator');
var result = (function(){ return _.uniq(arguments); }(1, 2, 1, 3, 1, 4)); var result = (function(){ return _.uniq(arguments); }(1, 2, 1, 3, 1, 4));
assert.deepEqual(result, [1, 2, 3, 4], 'works on an arguments object'); assert.deepEqual(result, [1, 2, 3, 4], 'works on an arguments object');
@@ -177,19 +167,17 @@
var a = {}, b = {}, c = {}; var a = {}, b = {}, c = {};
assert.deepEqual(_.uniq([a, b, a, b, c]), [a, b, c], 'works on values that can be tested for equivalency but not ordered'); assert.deepEqual(_.uniq([a, b, a, b, c]), [a, b, c], 'works on values that can be tested for equivalency but not ordered');
assert.deepEqual(_.uniq(null), []); assert.deepEqual(_.uniq(null), [], 'returns an empty array when `array` is not iterable');
var context = {}; var context = {};
list = [3]; list = [3];
_.uniq(list, function(value, index, array) { _.uniq(list, function(value, index, array) {
assert.strictEqual(this, context); assert.strictEqual(this, context, 'executes its iterator in the given context');
assert.strictEqual(value, 3); assert.strictEqual(value, 3, 'passes its iterator the value');
assert.strictEqual(index, 0); assert.strictEqual(index, 0, 'passes its iterator the index');
assert.strictEqual(array, list); assert.strictEqual(array, list, 'passes its iterator the entire array');
}, context); }, context);
assert.deepEqual(_.uniq([{a: 1, b: 1}, {a: 1, b: 2}, {a: 1, b: 3}, {a: 2, b: 1}], 'a'), [{a: 1, b: 1}, {a: 2, b: 1}], 'can use pluck like iterator');
assert.deepEqual(_.uniq([{0: 1, b: 1}, {0: 1, b: 2}, {0: 1, b: 3}, {0: 2, b: 1}], 0), [{0: 1, b: 1}, {0: 2, b: 1}], 'can use falsey pluck like iterator');
}); });
QUnit.test('unique', function(assert) { QUnit.test('unique', function(assert) {
@@ -198,44 +186,54 @@
QUnit.test('intersection', function(assert) { QUnit.test('intersection', function(assert) {
var stooges = ['moe', 'curly', 'larry'], leaders = ['moe', 'groucho']; var stooges = ['moe', 'curly', 'larry'], leaders = ['moe', 'groucho'];
assert.deepEqual(_.intersection(stooges, leaders), ['moe'], 'can take the set intersection of two arrays'); assert.deepEqual(_.intersection(stooges, leaders), ['moe'], 'can find the set intersection of two arrays');
assert.deepEqual(_(stooges).intersection(leaders), ['moe'], 'can perform an OO-style intersection'); assert.deepEqual(_(stooges).intersection(leaders), ['moe'], 'can perform an OO-style intersection');
var result = (function(){ return _.intersection(arguments, leaders); }('moe', 'curly', 'larry')); var result = (function(){ return _.intersection(arguments, leaders); }('moe', 'curly', 'larry'));
assert.deepEqual(result, ['moe'], 'works on an arguments object'); assert.deepEqual(result, ['moe'], 'works on an arguments object');
var theSixStooges = ['moe', 'moe', 'curly', 'curly', 'larry', 'larry']; var theSixStooges = ['moe', 'moe', 'curly', 'curly', 'larry', 'larry'];
assert.deepEqual(_.intersection(theSixStooges, leaders), ['moe'], 'returns a duplicate-free array'); assert.deepEqual(_.intersection(theSixStooges, leaders), ['moe'], 'returns a duplicate-free array');
result = _.intersection([2, 4, 3, 1], [1, 2, 3]); result = _.intersection([2, 4, 3, 1], [1, 2, 3]);
assert.deepEqual(result, [2, 3, 1], 'preserves order of first array'); assert.deepEqual(result, [2, 3, 1], 'preserves the order of the first array');
result = _.intersection(null, [1, 2, 3]); result = _.intersection(null, [1, 2, 3]);
assert.equal(Object.prototype.toString.call(result), '[object Array]', 'returns an empty array when passed null as first argument'); assert.deepEqual(result, [], 'returns an empty array when passed null as the first argument');
assert.equal(result.length, 0, 'returns an empty array when passed null as first argument');
result = _.intersection([1, 2, 3], null); result = _.intersection([1, 2, 3], null);
assert.equal(Object.prototype.toString.call(result), '[object Array]', 'returns an empty array when passed null as argument beyond the first'); assert.deepEqual(result, [], 'returns an empty array when passed null as an argument beyond the first');
assert.equal(result.length, 0, 'returns an empty array when passed null as argument beyond the first');
}); });
QUnit.test('union', function(assert) { QUnit.test('union', function(assert) {
var result = _.union([1, 2, 3], [2, 30, 1], [1, 40]); var result = _.union([1, 2, 3], [2, 30, 1], [1, 40]);
assert.deepEqual(result, [1, 2, 3, 30, 40], 'takes the union of a list of arrays'); assert.deepEqual(result, [1, 2, 3, 30, 40], 'can find the union of a list of arrays');
result = _([1, 2, 3]).union([2, 30, 1], [1, 40]);
assert.deepEqual(result, [1, 2, 3, 30, 40], 'can perform an OO-style union');
result = _.union([1, 2, 3], [2, 30, 1], [1, 40, [1]]); result = _.union([1, 2, 3], [2, 30, 1], [1, 40, [1]]);
assert.deepEqual(result, [1, 2, 3, 30, 40, [1]], 'takes the union of a list of nested arrays'); assert.deepEqual(result, [1, 2, 3, 30, 40, [1]], 'can find the union of a list of nested arrays');
var args = null; result = _.union([10, 20], [1, 30, 10], [0, 40]);
(function(){ args = arguments; }(1, 2, 3)); assert.deepEqual(result, [10, 20, 1, 30, 0, 40], 'orders values by their first encounter');
result = _.union(args, [2, 30, 1], [1, 40]);
assert.deepEqual(result, [1, 2, 3, 30, 40], 'takes the union of a list of arrays');
result = _.union([1, 2, 3], 4); result = (function(){ return _.union(arguments, [2, 30, 1], [1, 40]); }(1, 2, 3));
assert.deepEqual(result, [1, 2, 3], 'restrict the union to arrays only'); assert.deepEqual(result, [1, 2, 3, 30, 40], 'works on an arguments object');
assert.deepEqual(_.union([1, 2, 3], 4), [1, 2, 3], 'restricts the union to arrays only');
}); });
QUnit.test('difference', function(assert) { QUnit.test('difference', function(assert) {
var result = _.difference([1, 2, 3], [2, 30, 40]); var result = _.difference([1, 2, 3], [2, 30, 40]);
assert.deepEqual(result, [1, 3], 'takes the difference of two arrays'); assert.deepEqual(result, [1, 3], 'can find the difference of two arrays');
result = _([1, 2, 3]).difference([2, 30, 40]);
assert.deepEqual(result, [1, 3], 'can perform an OO-style difference');
result = _.difference([1, 2, 3, 4], [2, 30, 40], [1, 11, 111]); result = _.difference([1, 2, 3, 4], [2, 30, 40], [1, 11, 111]);
assert.deepEqual(result, [3, 4], 'takes the difference of three arrays'); assert.deepEqual(result, [3, 4], 'can find the difference of three arrays');
result = _.difference([8, 9, 3, 1], [3, 8]);
assert.deepEqual(result, [9, 1], 'preserves the order of the first array');
result = (function(){ return _.difference(arguments, [2, 30, 40]); }(1, 2, 3));
assert.deepEqual(result, [1, 3], 'works on an arguments object');
result = _.difference([1, 2, 3], 1); result = _.difference([1, 2, 3], 1);
assert.deepEqual(result, [1, 2, 3], 'restrict the difference to arrays only'); assert.deepEqual(result, [1, 2, 3], 'restrict the difference to arrays only');

View File

@@ -728,6 +728,11 @@
assert.ok(_.isFinite(0), '0 is finite'); assert.ok(_.isFinite(0), '0 is finite');
assert.ok(_.isFinite(123), 'Ints are finite'); assert.ok(_.isFinite(123), 'Ints are finite');
assert.ok(_.isFinite(-12.44), 'Floats are finite'); assert.ok(_.isFinite(-12.44), 'Floats are finite');
if (typeof Symbol === 'function') {
assert.ok(!_.isFinite(Symbol()), 'symbols are not numbers');
assert.ok(!_.isFinite(Symbol('description')), 'described symbols are not numbers');
assert.ok(!_.isFinite(Object(Symbol())), 'boxed symbols are not numbers');
}
}); });
QUnit.test('isNaN', function(assert) { QUnit.test('isNaN', function(assert) {

View File

@@ -1,6 +1,6 @@
// Underscore.js 1.8.3 // Underscore.js 1.8.3
// http://underscorejs.org // http://underscorejs.org
// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors // (c) 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
// Underscore may be freely distributed under the MIT license. // Underscore may be freely distributed under the MIT license.
(function() { (function() {
@@ -93,7 +93,7 @@
return _.property(value); return _.property(value);
}; };
// An external wrapper for the internal callback generator // An external wrapper for the internal callback generator.
_.iteratee = function(value, context) { _.iteratee = function(value, context) {
return cb(value, context, Infinity); return cb(value, context, Infinity);
}; };
@@ -504,7 +504,7 @@
for (var i = 0, length = getLength(input); i < length; i++) { for (var i = 0, length = getLength(input); i < length; i++) {
var value = input[i]; var value = input[i];
if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) { if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) {
// Flatten current level of array or arguments object // Flatten current level of array or arguments object.
if (shallow) { if (shallow) {
var j = 0, len = value.length; var j = 0, len = value.length;
while (j < len) output[idx++] = value[j++]; while (j < len) output[idx++] = value[j++];
@@ -592,7 +592,7 @@
}); });
// Complement of _.zip. Unzip accepts an array of arrays and groups // Complement of _.zip. Unzip accepts an array of arrays and groups
// each array's elements on shared indices // each array's elements on shared indices.
_.unzip = function(array) { _.unzip = function(array) {
var length = array && _.max(array, getLength).length || 0; var length = array && _.max(array, getLength).length || 0;
var result = Array(length); var result = Array(length);
@@ -622,7 +622,7 @@
return result; return result;
}; };
// Generator function to create the findIndex and findLastIndex functions // Generator function to create the findIndex and findLastIndex functions.
var createPredicateIndexFinder = function(dir) { var createPredicateIndexFinder = function(dir) {
return function(array, predicate, context) { return function(array, predicate, context) {
predicate = cb(predicate, context); predicate = cb(predicate, context);
@@ -635,7 +635,7 @@
}; };
}; };
// Returns the first index on an array-like that passes a predicate test // Returns the first index on an array-like that passes a predicate test.
_.findIndex = createPredicateIndexFinder(1); _.findIndex = createPredicateIndexFinder(1);
_.findLastIndex = createPredicateIndexFinder(-1); _.findLastIndex = createPredicateIndexFinder(-1);
@@ -652,7 +652,7 @@
return low; return low;
}; };
// Generator function to create the indexOf and lastIndexOf functions // Generator function to create the indexOf and lastIndexOf functions.
var createIndexFinder = function(dir, predicateFind, sortedIndex) { var createIndexFinder = function(dir, predicateFind, sortedIndex) {
return function(array, item, idx) { return function(array, item, idx) {
var i = 0, length = getLength(array); var i = 0, length = getLength(array);
@@ -707,7 +707,7 @@
}; };
// Split an **array** into several arrays containing **count** or less elements // Split an **array** into several arrays containing **count** or less elements
// of initial array // of initial array.
_.chunk = function(array, count) { _.chunk = function(array, count) {
if (count == null || count < 1) return []; if (count == null || count < 1) return [];
@@ -723,7 +723,7 @@
// ------------------ // ------------------
// Determines whether to execute a function as a constructor // Determines whether to execute a function as a constructor
// or a normal function with the provided arguments // or a normal function with the provided arguments.
var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) { var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) {
if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args); if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
var self = baseCreate(sourceFunc.prototype); var self = baseCreate(sourceFunc.prototype);
@@ -959,7 +959,7 @@
}; };
// Retrieve the names of an object's own properties. // Retrieve the names of an object's own properties.
// Delegates to **ECMAScript 5**'s native `Object.keys` // Delegates to **ECMAScript 5**'s native `Object.keys`.
_.keys = function(obj) { _.keys = function(obj) {
if (!_.isObject(obj)) return []; if (!_.isObject(obj)) return [];
if (nativeKeys) return nativeKeys(obj); if (nativeKeys) return nativeKeys(obj);
@@ -991,8 +991,8 @@
return values; return values;
}; };
// Returns the results of applying the iteratee to each element of the object // Returns the results of applying the iteratee to each element of the object.
// In contrast to _.map it returns an object // In contrast to _.map it returns an object.
_.mapObject = function(obj, iteratee, context) { _.mapObject = function(obj, iteratee, context) {
iteratee = cb(iteratee, context); iteratee = cb(iteratee, context);
var keys = _.keys(obj), var keys = _.keys(obj),
@@ -1027,7 +1027,7 @@
}; };
// Return a sorted list of the function names available on the object. // Return a sorted list of the function names available on the object.
// Aliased as `methods` // Aliased as `methods`.
_.functions = _.methods = function(obj) { _.functions = _.methods = function(obj) {
var names = []; var names = [];
for (var key in obj) { for (var key in obj) {
@@ -1058,11 +1058,11 @@
// Extend a given object with all the properties in passed-in object(s). // Extend a given object with all the properties in passed-in object(s).
_.extend = createAssigner(_.allKeys); _.extend = createAssigner(_.allKeys);
// Assigns a given object with all the own properties in the passed-in object(s) // Assigns a given object with all the own properties in the passed-in object(s).
// (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
_.extendOwn = _.assign = createAssigner(_.keys); _.extendOwn = _.assign = createAssigner(_.keys);
// Returns the first key on an object that passes a predicate test // Returns the first key on an object that passes a predicate test.
_.findKey = function(obj, predicate, context) { _.findKey = function(obj, predicate, context) {
predicate = cb(predicate, context); predicate = cb(predicate, context);
var keys = _.keys(obj), key; var keys = _.keys(obj), key;
@@ -1185,7 +1185,7 @@
return '' + a === '' + b; return '' + a === '' + b;
case '[object Number]': case '[object Number]':
// `NaN`s are equivalent, but non-reflexive. // `NaN`s are equivalent, but non-reflexive.
// Object(NaN) is equivalent to NaN // Object(NaN) is equivalent to NaN.
if (+a !== +a) return +b !== +b; if (+a !== +a) return +b !== +b;
// An `egal` comparison is performed for other numeric values. // An `egal` comparison is performed for other numeric values.
return +a === 0 ? 1 / +a === 1 / b : +a === +b; return +a === 0 ? 1 / +a === 1 / b : +a === +b;
@@ -1311,7 +1311,7 @@
// Is a given object a finite number? // Is a given object a finite number?
_.isFinite = function(obj) { _.isFinite = function(obj) {
return isFinite(obj) && !isNaN(parseFloat(obj)); return !_.isSymbol(obj) && isFinite(obj) && !isNaN(parseFloat(obj));
}; };
// Is the given value `NaN`? // Is the given value `NaN`?
@@ -1420,7 +1420,7 @@
var escaper = function(match) { var escaper = function(match) {
return map[match]; return map[match];
}; };
// Regexes for identifying a key that needs to be escaped // Regexes for identifying a key that needs to be escaped.
var source = '(?:' + _.keys(map).join('|') + ')'; var source = '(?:' + _.keys(map).join('|') + ')';
var testRegexp = RegExp(source); var testRegexp = RegExp(source);
var replaceRegexp = RegExp(source, 'g'); var replaceRegexp = RegExp(source, 'g');