mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-01-29 06:27:49 +00:00
Update vendors, rebuild minified files, update docs/license.
Former-commit-id: 689793b6e5c4bbae917e726dc646902c697ce3a7
This commit is contained in:
127
vendor/backbone/backbone.js
vendored
127
vendor/backbone/backbone.js
vendored
@@ -1,4 +1,4 @@
|
||||
// Backbone.js 0.9.2
|
||||
// Backbone.js 0.9.9-pre
|
||||
|
||||
// (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc.
|
||||
// Backbone may be freely distributed under the MIT license.
|
||||
@@ -34,7 +34,7 @@
|
||||
}
|
||||
|
||||
// Current version of the library. Keep in sync with `package.json`.
|
||||
Backbone.VERSION = '0.9.2';
|
||||
Backbone.VERSION = '0.9.9-pre';
|
||||
|
||||
// Require Underscore, if we're on the server, and it's not already present.
|
||||
var _ = root._;
|
||||
@@ -67,6 +67,9 @@
|
||||
// Regular expression used to split event strings
|
||||
var eventSplitter = /\s+/;
|
||||
|
||||
// Internal flag used to set event callbacks `once`.
|
||||
var once = false;
|
||||
|
||||
// A module that can be mixed in to *any object* in order to provide it with
|
||||
// custom events. You may bind with `on` or remove with `off` callback functions
|
||||
// to an event; `trigger`-ing an event fires all callbacks in succession.
|
||||
@@ -81,6 +84,13 @@
|
||||
// Bind one or more space separated events, `events`, to a `callback`
|
||||
// function. Passing `"all"` will bind the callback to all events fired.
|
||||
on: function(events, callback, context) {
|
||||
if (_.isObject(events)) {
|
||||
for (var key in events) {
|
||||
this.on(key, events[key], callback);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
var calls, event, list;
|
||||
if (!callback) return this;
|
||||
|
||||
@@ -89,16 +99,32 @@
|
||||
|
||||
while (event = events.shift()) {
|
||||
list = calls[event] || (calls[event] = []);
|
||||
list.push(callback, context);
|
||||
list.push(callback, context, once ? {} : null);
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
// Bind events to only be triggered a single time. After the first time
|
||||
// the callback is invoked, it will be removed.
|
||||
once: function(events, callback, context) {
|
||||
once = true;
|
||||
this.on(events, callback, context);
|
||||
once = false;
|
||||
return this;
|
||||
},
|
||||
|
||||
// Remove one or many callbacks. If `context` is null, removes all callbacks
|
||||
// with that function. If `callback` is null, removes all callbacks for the
|
||||
// event. If `events` is null, removes all bound callbacks for all events.
|
||||
off: function(events, callback, context) {
|
||||
if (_.isObject(events)) {
|
||||
for (var key in events) {
|
||||
this.off(key, events[key], callback);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
var event, calls, list, i;
|
||||
|
||||
// No events, or removing *all* events.
|
||||
@@ -117,9 +143,9 @@
|
||||
continue;
|
||||
}
|
||||
|
||||
for (i = list.length - 2; i >= 0; i -= 2) {
|
||||
for (i = list.length - 3; i >= 0; i -= 3) {
|
||||
if (!(callback && list[i] !== callback || context && list[i + 1] !== context)) {
|
||||
list.splice(i, 2);
|
||||
list.splice(i, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -132,7 +158,7 @@
|
||||
// (unless you're listening on `"all"`, which will cause your callback to
|
||||
// receive the true name of the event as the first argument).
|
||||
trigger: function(events) {
|
||||
var event, calls, list, i, length, args, all, rest;
|
||||
var event, calls, list, i, length, args, all, rest, callback, context, onced;
|
||||
if (!(calls = this._callbacks)) return this;
|
||||
|
||||
rest = [];
|
||||
@@ -153,15 +179,18 @@
|
||||
|
||||
// Execute event callbacks.
|
||||
if (list) {
|
||||
for (i = 0, length = list.length; i < length; i += 2) {
|
||||
list[i].apply(list[i + 1] || this, rest);
|
||||
for (i = 0, length = list.length; i < length; i += 3) {
|
||||
callback = list[i], context = list[i + 1], onced = list[i + 2];
|
||||
if (onced) calls[event].splice(i, 3);
|
||||
if (!onced || !onced.dead) callback.apply(context || this, rest);
|
||||
if (onced) onced.dead = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Execute "all" callbacks.
|
||||
if (all) {
|
||||
args = [event].concat(rest);
|
||||
for (i = 0, length = all.length; i < length; i += 2) {
|
||||
for (i = 0, length = all.length; i < length; i += 3) {
|
||||
all[i].apply(all[i + 1] || this, args);
|
||||
}
|
||||
}
|
||||
@@ -176,6 +205,10 @@
|
||||
Events.bind = Events.on;
|
||||
Events.unbind = Events.off;
|
||||
|
||||
// Allow the `Backbone` object to serve as a global event bus, for folks who
|
||||
// want global "pubsub" in a convenient place.
|
||||
_.extend(Backbone, Events);
|
||||
|
||||
// Backbone.Model
|
||||
// --------------
|
||||
|
||||
@@ -390,7 +423,9 @@
|
||||
};
|
||||
|
||||
// Finish configuring and sending the Ajax request.
|
||||
var xhr = this.sync(this.isNew() ? 'create' : 'update', this, options);
|
||||
var method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update');
|
||||
if (method == 'patch') options.attrs = attrs;
|
||||
var xhr = this.sync(method, this, options);
|
||||
|
||||
// When using `wait`, reset attributes to original values unless
|
||||
// `success` has been called already.
|
||||
@@ -565,7 +600,7 @@
|
||||
// returning `true` if all is well. If a specific `error` callback has
|
||||
// been passed, call that instead of firing the general `"error"` event.
|
||||
_validate: function(attrs, options) {
|
||||
if (options && options.silent || !this.validate) return true;
|
||||
if (!this.validate) return true;
|
||||
attrs = _.extend({}, this.attributes, attrs);
|
||||
var error = this.validate(attrs, options);
|
||||
if (!error) return true;
|
||||
@@ -588,10 +623,7 @@
|
||||
if (options.comparator !== void 0) this.comparator = options.comparator;
|
||||
this._reset();
|
||||
this.initialize.apply(this, arguments);
|
||||
if (models) {
|
||||
if (options.parse) models = this.parse(models);
|
||||
this.reset(models, {silent: true, parse: options.parse});
|
||||
}
|
||||
if (models) this.reset(models, _.extend({silent: true}, options));
|
||||
};
|
||||
|
||||
// Define the Collection's inheritable methods.
|
||||
@@ -679,7 +711,7 @@
|
||||
options || (options = {});
|
||||
models = _.isArray(models) ? models.slice() : [models];
|
||||
for (i = 0, l = models.length; i < l; i++) {
|
||||
model = this.getByCid(models[i]) || this.get(models[i]);
|
||||
model = this.get(models[i]);
|
||||
if (!model) continue;
|
||||
delete this._byId[model.id];
|
||||
delete this._byCid[model.cid];
|
||||
@@ -729,14 +761,9 @@
|
||||
},
|
||||
|
||||
// Get a model from the set by id.
|
||||
get: function(id) {
|
||||
if (id == null) return void 0;
|
||||
return this._byId[id.id != null ? id.id : id];
|
||||
},
|
||||
|
||||
// Get a model from the set by client id.
|
||||
getByCid: function(cid) {
|
||||
return cid && this._byCid[cid.cid || cid];
|
||||
get: function(obj) {
|
||||
if (obj == null) return void 0;
|
||||
return this._byId[obj.id != null ? obj.id : obj] || this._byCid[obj.cid || obj];
|
||||
},
|
||||
|
||||
// Get the model at the given index.
|
||||
@@ -769,7 +796,7 @@
|
||||
this.models.sort(_.bind(this.comparator, this));
|
||||
}
|
||||
|
||||
if (!options || !options.silent) this.trigger('reset', this, options);
|
||||
if (!options || !options.silent) this.trigger('sort', this, options);
|
||||
return this;
|
||||
},
|
||||
|
||||
@@ -778,16 +805,46 @@
|
||||
return _.invoke(this.models, 'get', attr);
|
||||
},
|
||||
|
||||
// Smartly update a collection with a change set of models, adding,
|
||||
// removing, and merging as necessary.
|
||||
update: function(models, options) {
|
||||
var model, i, l, id, cid, existing;
|
||||
var add = [], remove = [];
|
||||
options = _.extend({add: true, merge: true, remove: false}, options);
|
||||
|
||||
// Determine which models to add and merge, and which to remove.
|
||||
for (i = 0, l = models.length; i < l; i++) {
|
||||
model = models[i];
|
||||
existing = this.get(model);
|
||||
if (options.add || options.merge && existing) add.push(model);
|
||||
}
|
||||
if (options.remove) {
|
||||
var changeset = new Collection(models);
|
||||
for (i = 0, l = this.models.length; i < l; i++) {
|
||||
model = this.models[i];
|
||||
if (!changeset.get(model)) remove.push(model);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove models (if applicable) before we add and merge the rest.
|
||||
if (remove.length) this.remove(remove, options);
|
||||
if (add.length) this.add(add, options);
|
||||
return this;
|
||||
},
|
||||
|
||||
// When you have more items than you want to add or remove individually,
|
||||
// you can reset the entire set with a new list of models, without firing
|
||||
// any `add` or `remove` events. Fires `reset` when finished.
|
||||
reset: function(models, options) {
|
||||
options || (options = {});
|
||||
if (options.parse) models = this.parse(models);
|
||||
for (var i = 0, l = this.models.length; i < l; i++) {
|
||||
this._removeReference(this.models[i]);
|
||||
}
|
||||
options.previousModels = this.models;
|
||||
this._reset();
|
||||
if (models) this.add(models, _.extend({silent: true}, options));
|
||||
if (!options || !options.silent) this.trigger('reset', this, options);
|
||||
if (!options.silent) this.trigger('reset', this, options);
|
||||
return this;
|
||||
},
|
||||
|
||||
@@ -800,7 +857,8 @@
|
||||
var collection = this;
|
||||
var success = options.success;
|
||||
options.success = function(resp, status, xhr) {
|
||||
collection[options.add ? 'add' : 'reset'](collection.parse(resp, xhr), options);
|
||||
var method = options.update ? 'update' : 'reset';
|
||||
collection[method](collection.parse(resp, xhr), options);
|
||||
if (success) success(collection, resp, options);
|
||||
};
|
||||
return this.sync('read', this, options);
|
||||
@@ -859,7 +917,7 @@
|
||||
options || (options = {});
|
||||
options.collection = this;
|
||||
var model = new this.model(attrs, options);
|
||||
if (!model._validate(model.attributes, options)) return false;
|
||||
if (!model._validate(attrs, options)) return false;
|
||||
return model;
|
||||
},
|
||||
|
||||
@@ -932,7 +990,7 @@
|
||||
var optionalParam = /\((.*?)\)/g;
|
||||
var namedParam = /:\w+/g;
|
||||
var splatParam = /\*\w+/g;
|
||||
var escapeRegExp = /[-{}[\]+?.,\\^$|#\s]/g;
|
||||
var escapeRegExp = /[\-{}\[\]+?.,\\\^$|#\s]/g;
|
||||
|
||||
// Set up all inheritable **Backbone.Router** properties and methods.
|
||||
_.extend(Router.prototype, Events, {
|
||||
@@ -1051,7 +1109,7 @@
|
||||
fragment = this.getHash();
|
||||
}
|
||||
}
|
||||
return decodeURIComponent(fragment.replace(routeStripper, ''));
|
||||
return fragment.replace(routeStripper, '');
|
||||
},
|
||||
|
||||
// Start the hash change handling, returning `true` if the current URL matches
|
||||
@@ -1364,6 +1422,7 @@
|
||||
var methodMap = {
|
||||
'create': 'POST',
|
||||
'update': 'PUT',
|
||||
'patch': 'PATCH',
|
||||
'delete': 'DELETE',
|
||||
'read': 'GET'
|
||||
};
|
||||
@@ -1401,9 +1460,9 @@
|
||||
}
|
||||
|
||||
// Ensure that we have the appropriate request data.
|
||||
if (!options.data && model && (method === 'create' || method === 'update')) {
|
||||
if (options.data == null && model && (method === 'create' || method === 'update')) {
|
||||
params.contentType = 'application/json';
|
||||
params.data = JSON.stringify(model.toJSON(options));
|
||||
params.data = JSON.stringify(options.attrs || model.toJSON(options));
|
||||
}
|
||||
|
||||
// For older servers, emulate JSON by encoding the request into an HTML-form.
|
||||
@@ -1442,7 +1501,9 @@
|
||||
};
|
||||
|
||||
// Make the request, allowing the user to override any Ajax options.
|
||||
return Backbone.ajax(_.extend(params, options));
|
||||
var xhr = Backbone.ajax(_.extend(params, options));
|
||||
model.trigger('request', model, xhr, options);
|
||||
return xhr;
|
||||
};
|
||||
|
||||
// Set the default implementation of `Backbone.ajax` to proxy through to `$`.
|
||||
|
||||
136
vendor/backbone/test/collection.js
vendored
136
vendor/backbone/test/collection.js
vendored
@@ -18,17 +18,21 @@ $(document).ready(function() {
|
||||
|
||||
}));
|
||||
|
||||
test("new and sort", 7, function() {
|
||||
test("new and sort", 9, function() {
|
||||
var counter = 0;
|
||||
col.on('sort', function(){ counter++; });
|
||||
equal(col.first(), a, "a should be first");
|
||||
equal(col.last(), d, "d should be last");
|
||||
col.comparator = function(a, b) {
|
||||
return a.id > b.id ? -1 : 1;
|
||||
};
|
||||
col.sort();
|
||||
equal(counter, 1);
|
||||
equal(col.first(), a, "a should be first");
|
||||
equal(col.last(), d, "d should be last");
|
||||
col.comparator = function(model) { return model.id; };
|
||||
col.sort();
|
||||
equal(counter, 2);
|
||||
equal(col.first(), d, "d should be first");
|
||||
equal(col.last(), a, "a should be last");
|
||||
equal(col.length, 4);
|
||||
@@ -58,10 +62,10 @@ $(document).ready(function() {
|
||||
strictEqual(collection.last().get('a'), 4);
|
||||
});
|
||||
|
||||
test("get, getByCid", 3, function() {
|
||||
test("get", 3, function() {
|
||||
equal(col.get(0), d);
|
||||
equal(col.get(2), b);
|
||||
equal(col.getByCid(col.first().cid), col.first());
|
||||
equal(col.get(col.first().cid), col.first());
|
||||
});
|
||||
|
||||
test("get with non-default ids", 2, function() {
|
||||
@@ -304,13 +308,13 @@ $(document).ready(function() {
|
||||
var colE = new Backbone.Collection([e]);
|
||||
var colF = new Backbone.Collection([f]);
|
||||
ok(e != f);
|
||||
ok(colE.length == 1);
|
||||
ok(colF.length == 1);
|
||||
ok(colE.length === 1);
|
||||
ok(colF.length === 1);
|
||||
colE.remove(e);
|
||||
equal(passed, false);
|
||||
ok(colE.length == 0);
|
||||
ok(colE.length === 0);
|
||||
colF.remove(e);
|
||||
ok(colF.length == 0);
|
||||
ok(colF.length === 0);
|
||||
equal(passed, true);
|
||||
});
|
||||
|
||||
@@ -338,13 +342,13 @@ $(document).ready(function() {
|
||||
});
|
||||
equal(colE, e.collection);
|
||||
colF.remove(e);
|
||||
ok(colF.length == 0);
|
||||
ok(colE.length == 1);
|
||||
ok(colF.length === 0);
|
||||
ok(colE.length === 1);
|
||||
equal(counter, 1);
|
||||
equal(colE, e.collection);
|
||||
colE.remove(e);
|
||||
equal(null, e.collection);
|
||||
ok(colE.length == 0);
|
||||
ok(colE.length === 0);
|
||||
equal(counter, 2);
|
||||
});
|
||||
|
||||
@@ -354,8 +358,8 @@ $(document).ready(function() {
|
||||
var colE = new Backbone.Collection([e]);
|
||||
var colF = new Backbone.Collection([e]);
|
||||
e.destroy();
|
||||
ok(colE.length == 0);
|
||||
ok(colF.length == 0);
|
||||
ok(colE.length === 0);
|
||||
ok(colF.length === 0);
|
||||
equal(undefined, e.collection);
|
||||
});
|
||||
|
||||
@@ -365,8 +369,8 @@ $(document).ready(function() {
|
||||
var colE = new Backbone.Collection([e]);
|
||||
var colF = new Backbone.Collection([e]);
|
||||
e.destroy();
|
||||
ok(colE.length == 0);
|
||||
ok(colF.length == 0);
|
||||
ok(colE.length === 0);
|
||||
ok(colF.length === 0);
|
||||
equal(undefined, e.collection);
|
||||
});
|
||||
|
||||
@@ -542,7 +546,7 @@ $(document).ready(function() {
|
||||
equal(col.length, 0);
|
||||
});
|
||||
|
||||
test("#861, adding models to a collection which do not pass validation", 2, function() {
|
||||
test("#861, adding models to a collection which do not pass validation", function() {
|
||||
var Model = Backbone.Model.extend({
|
||||
validate: function(attrs) {
|
||||
if (attrs.id == 3) return "id can't be 3";
|
||||
@@ -567,9 +571,9 @@ $(document).ready(function() {
|
||||
validate: function(attrs){ if (!attrs.valid) return 'invalid'; }
|
||||
});
|
||||
var model = new collection.model({id: 1, valid: true});
|
||||
collection.add([model, {id: 2}]);;
|
||||
collection.add([model, {id: 2}]);
|
||||
model.trigger('test');
|
||||
ok(collection.getByCid(model.cid));
|
||||
ok(collection.get(model.cid));
|
||||
ok(collection.get(1));
|
||||
ok(!collection.get(2));
|
||||
equal(collection.length, 1);
|
||||
@@ -726,4 +730,102 @@ $(document).ready(function() {
|
||||
c.add({id: 4});
|
||||
});
|
||||
|
||||
test("#1407 parse option on constructor parses collection and models", 2, function() {
|
||||
var model = {
|
||||
namespace : [{id: 1}, {id:2}]
|
||||
};
|
||||
var Collection = Backbone.Collection.extend({
|
||||
model: Backbone.Model.extend({
|
||||
parse: function(model) {
|
||||
model.name = 'test';
|
||||
return model;
|
||||
}
|
||||
}),
|
||||
parse: function(model) {
|
||||
return model.namespace;
|
||||
}
|
||||
});
|
||||
var c = new Collection(model, {parse:true});
|
||||
|
||||
equal(c.length, 2);
|
||||
equal(c.at(0).get('name'), 'test');
|
||||
});
|
||||
|
||||
test("#1407 parse option on reset parses collection and models", 2, function() {
|
||||
var model = {
|
||||
namespace : [{id: 1}, {id:2}]
|
||||
};
|
||||
var Collection = Backbone.Collection.extend({
|
||||
model: Backbone.Model.extend({
|
||||
parse: function(model) {
|
||||
model.name = 'test';
|
||||
return model;
|
||||
}
|
||||
}),
|
||||
parse: function(model) {
|
||||
return model.namespace;
|
||||
}
|
||||
});
|
||||
var c = new Collection();
|
||||
c.reset(model, {parse:true});
|
||||
|
||||
equal(c.length, 2);
|
||||
equal(c.at(0).get('name'), 'test');
|
||||
});
|
||||
|
||||
|
||||
test("Reset includes previous models in triggered event.", 1, function() {
|
||||
var model = new Backbone.Model();
|
||||
var collection = new Backbone.Collection([model])
|
||||
.on('reset', function(collection, options) {
|
||||
deepEqual(options.previousModels, [model]);
|
||||
});
|
||||
collection.reset([]);
|
||||
});
|
||||
|
||||
test("update", function() {
|
||||
var m1 = new Backbone.Model();
|
||||
var m2 = new Backbone.Model({id: 2});
|
||||
var m3 = new Backbone.Model();
|
||||
var c = new Backbone.Collection([m1, m2]);
|
||||
|
||||
// Test add/change/remove events
|
||||
c.on('add', function(model) {
|
||||
strictEqual(model, m3);
|
||||
});
|
||||
c.on('change', function(model) {
|
||||
strictEqual(model, m2);
|
||||
});
|
||||
c.on('remove', function(model) {
|
||||
strictEqual(model, m1);
|
||||
});
|
||||
|
||||
// remove: false doesn't remove any models
|
||||
c.update([], {remove: false});
|
||||
strictEqual(c.length, 2);
|
||||
|
||||
// add: false doesn't add any models
|
||||
c.update([m1, m2, m3], {add: false});
|
||||
strictEqual(c.length, 2);
|
||||
|
||||
// merge: false doesn't change any models
|
||||
c.update([m1, {id: 2, a: 1}], {merge: false, remove: true});
|
||||
strictEqual(m2.get('a'), void 0);
|
||||
|
||||
// add: false, remove: false only merges existing models
|
||||
c.update([m1, {id: 2, a: 0}, m3, {id: 4}], {add: false, remove: false});
|
||||
strictEqual(c.length, 2);
|
||||
strictEqual(m2.get('a'), 0);
|
||||
|
||||
// default options add/remove/merge as appropriate
|
||||
c.update([{id: 2, a: 1}, m3]);
|
||||
strictEqual(c.length, 3);
|
||||
strictEqual(m2.get('a'), 1);
|
||||
|
||||
// Test removing models not passing an argument
|
||||
c.off('remove');
|
||||
c.update([], {remove: true});
|
||||
strictEqual(c.length, 0);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
120
vendor/backbone/test/events.js
vendored
120
vendor/backbone/test/events.js
vendored
@@ -17,7 +17,7 @@ $(document).ready(function() {
|
||||
|
||||
test("binding and triggering multiple events", 4, function() {
|
||||
var obj = { counter: 0 };
|
||||
_.extend(obj,Backbone.Events);
|
||||
_.extend(obj, Backbone.Events);
|
||||
|
||||
obj.on('a b c', function() { obj.counter += 1; });
|
||||
|
||||
@@ -35,6 +35,38 @@ $(document).ready(function() {
|
||||
equal(obj.counter, 5);
|
||||
});
|
||||
|
||||
test("binding and triggering with event maps", function() {
|
||||
var obj = { counter: 0 };
|
||||
_.extend(obj, Backbone.Events);
|
||||
|
||||
var increment = function() {
|
||||
this.counter += 1;
|
||||
};
|
||||
|
||||
obj.on({
|
||||
a: increment,
|
||||
b: increment,
|
||||
c: increment
|
||||
}, obj);
|
||||
|
||||
obj.trigger('a');
|
||||
equal(obj.counter, 1);
|
||||
|
||||
obj.trigger('a b');
|
||||
equal(obj.counter, 3);
|
||||
|
||||
obj.trigger('c');
|
||||
equal(obj.counter, 4);
|
||||
|
||||
obj.off({
|
||||
a: increment,
|
||||
c: increment
|
||||
}, obj);
|
||||
obj.trigger('a b c');
|
||||
equal(obj.counter, 5);
|
||||
});
|
||||
|
||||
|
||||
test("trigger all for each event", 3, function() {
|
||||
var a, b, obj = { counter: 0 };
|
||||
_.extend(obj, Backbone.Events);
|
||||
@@ -192,4 +224,90 @@ $(document).ready(function() {
|
||||
obj.trigger('event');
|
||||
});
|
||||
|
||||
test("once", 2, function() {
|
||||
// Same as the previous test, but we use once rather than having to explicitly unbind
|
||||
var obj = { counterA: 0, counterB: 0 };
|
||||
_.extend(obj,Backbone.Events);
|
||||
var incrA = function(){ obj.counterA += 1; obj.trigger('event'); };
|
||||
var incrB = function(){ obj.counterB += 1 };
|
||||
obj.once('event', incrA);
|
||||
obj.once('event', incrB);
|
||||
obj.trigger('event');
|
||||
obj.trigger('event');
|
||||
obj.trigger('event');
|
||||
equal(obj.counterA, 1, 'counterA should have only been incremented once.');
|
||||
equal(obj.counterB, 1, 'counterB should have only been incremented once.');
|
||||
});
|
||||
|
||||
test("once variant one", 3, function() {
|
||||
var f = function(){ ok(true); };
|
||||
|
||||
var a = _.extend({}, Backbone.Events).once('event', f);
|
||||
var b = _.extend({}, Backbone.Events).on('event', f);
|
||||
|
||||
a.trigger('event');
|
||||
|
||||
b.trigger('event');
|
||||
b.trigger('event');
|
||||
});
|
||||
|
||||
test("once variant two", 3, function() {
|
||||
var f = function(){ ok(true); };
|
||||
var obj = _.extend({}, Backbone.Events);
|
||||
|
||||
obj
|
||||
.once('event', f)
|
||||
.on('event', f)
|
||||
.trigger('event')
|
||||
.trigger('event');
|
||||
});
|
||||
|
||||
test("once with off", 0, function() {
|
||||
var f = function(){ ok(true); };
|
||||
var obj = _.extend({}, Backbone.Events);
|
||||
|
||||
obj.once('event', f);
|
||||
obj.off('event', f);
|
||||
obj.trigger('event');
|
||||
});
|
||||
|
||||
test("once with event maps", function() {
|
||||
var obj = { counter: 0 };
|
||||
_.extend(obj, Backbone.Events);
|
||||
|
||||
var increment = function() {
|
||||
this.counter += 1;
|
||||
};
|
||||
|
||||
obj.once({
|
||||
a: increment,
|
||||
b: increment,
|
||||
c: increment
|
||||
}, obj);
|
||||
|
||||
obj.trigger('a');
|
||||
equal(obj.counter, 1);
|
||||
|
||||
obj.trigger('a b');
|
||||
equal(obj.counter, 2);
|
||||
|
||||
obj.trigger('c');
|
||||
equal(obj.counter, 3);
|
||||
|
||||
obj.trigger('a b c');
|
||||
equal(obj.counter, 3);
|
||||
});
|
||||
|
||||
test("Backbone object inherits Events", function() {
|
||||
ok(Backbone.on === Backbone.Events.on);
|
||||
});
|
||||
|
||||
asyncTest("once with asynchronous events", 1, function() {
|
||||
var func = _.debounce(function() { ok(true); start(); }, 50);
|
||||
var obj = _.extend({}, Backbone.Events).once('async', func);
|
||||
|
||||
obj.trigger('async');
|
||||
obj.trigger('async');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
26
vendor/backbone/test/model.js
vendored
26
vendor/backbone/test/model.js
vendored
@@ -270,7 +270,7 @@ $(document).ready(function() {
|
||||
};
|
||||
}
|
||||
});
|
||||
var model = new Defaulted({two: null});
|
||||
model = new Defaulted({two: null});
|
||||
equal(model.get('one'), 3);
|
||||
equal(model.get('two'), null);
|
||||
});
|
||||
@@ -351,7 +351,7 @@ $(document).ready(function() {
|
||||
equal(lastError, "Can't change admin status.");
|
||||
});
|
||||
|
||||
test("isValid", 5, function() {
|
||||
test("isValid", function() {
|
||||
var model = new Backbone.Model({valid: true});
|
||||
model.validate = function(attrs) {
|
||||
if (!attrs.valid) return "invalid";
|
||||
@@ -359,8 +359,7 @@ $(document).ready(function() {
|
||||
equal(model.isValid(), true);
|
||||
equal(model.set({valid: false}), false);
|
||||
equal(model.isValid(), true);
|
||||
ok(model.set('valid', false, {silent: true}));
|
||||
equal(model.isValid(), false);
|
||||
ok(!model.set('valid', false, {silent: true}));
|
||||
});
|
||||
|
||||
test("save", 2, function() {
|
||||
@@ -369,6 +368,19 @@ $(document).ready(function() {
|
||||
ok(_.isEqual(this.syncArgs.model, doc));
|
||||
});
|
||||
|
||||
test("save with PATCH", function() {
|
||||
doc.clear().set({id: 1, a: 1, b: 2, c: 3, d: 4});
|
||||
doc.save();
|
||||
equal(this.syncArgs.method, 'update');
|
||||
equal(this.syncArgs.options.attrs, undefined);
|
||||
|
||||
doc.save({b: 2, d: 4}, {patch: true});
|
||||
equal(this.syncArgs.method, 'patch');
|
||||
equal(_.size(this.syncArgs.options.attrs), 2);
|
||||
equal(this.syncArgs.options.attrs.d, 4);
|
||||
equal(this.syncArgs.options.attrs.a, undefined);
|
||||
});
|
||||
|
||||
test("save in positional style", 1, function() {
|
||||
var model = new Backbone.Model();
|
||||
model.sync = function(method, model, options) {
|
||||
@@ -402,7 +414,7 @@ $(document).ready(function() {
|
||||
ok(true, "non-persisted model should not call sync");
|
||||
});
|
||||
|
||||
test("validate", 7, function() {
|
||||
test("validate", function() {
|
||||
var lastError;
|
||||
var model = new Backbone.Model();
|
||||
model.validate = function(attrs) {
|
||||
@@ -415,8 +427,6 @@ $(document).ready(function() {
|
||||
equal(result, model);
|
||||
equal(model.get('a'), 100);
|
||||
equal(lastError, undefined);
|
||||
result = model.set({admin: true}, {silent: true});
|
||||
equal(model.get('admin'), true);
|
||||
result = model.set({a: 200, admin: false});
|
||||
equal(lastError, "Can't change admin status.");
|
||||
equal(result, false);
|
||||
@@ -639,7 +649,7 @@ $(document).ready(function() {
|
||||
equal(model.get('x'), 3);
|
||||
});
|
||||
|
||||
test("save with wait validates attributes", 1, function() {
|
||||
test("save with wait validates attributes", function() {
|
||||
var model = new Backbone.Model();
|
||||
model.url = '/test';
|
||||
model.validate = function() { ok(true); };
|
||||
|
||||
14
vendor/backbone/test/router.js
vendored
14
vendor/backbone/test/router.js
vendored
@@ -107,7 +107,7 @@ $(document).ready(function() {
|
||||
},
|
||||
|
||||
optionalItem: function(arg){
|
||||
this.arg = arg !== undefined ? arg : null;
|
||||
this.arg = arg !== void 0 ? arg : null;
|
||||
},
|
||||
|
||||
splat : function(args) {
|
||||
@@ -139,7 +139,7 @@ $(document).ready(function() {
|
||||
location.replace('http://example.com#search/news');
|
||||
Backbone.history.checkUrl();
|
||||
equal(router.query, 'news');
|
||||
equal(router.page, undefined);
|
||||
equal(router.page, void 0);
|
||||
equal(lastRoute, 'search');
|
||||
equal(lastArgs[0], 'news');
|
||||
});
|
||||
@@ -265,12 +265,12 @@ $(document).ready(function() {
|
||||
if (!Backbone.history.iframe) ok(true);
|
||||
});
|
||||
|
||||
test("route callback gets passed decoded values", 3, function() {
|
||||
test("#967 - Route callback gets passed encoded values.", 3, function() {
|
||||
var route = 'has%2Fslash/complex-has%23hash/has%20space';
|
||||
Backbone.history.navigate(route, {trigger: true});
|
||||
equal(router.first, 'has/slash');
|
||||
equal(router.part, 'has#hash');
|
||||
equal(router.rest, 'has space');
|
||||
strictEqual(router.first, 'has%2Fslash');
|
||||
strictEqual(router.part, 'has%23hash');
|
||||
strictEqual(router.rest, 'has%20space');
|
||||
});
|
||||
|
||||
test("correctly handles URLs with % (#868)", 3, function() {
|
||||
@@ -279,7 +279,7 @@ $(document).ready(function() {
|
||||
location.replace('http://example.com#search/fat');
|
||||
Backbone.history.checkUrl();
|
||||
equal(router.query, 'fat');
|
||||
equal(router.page, undefined);
|
||||
equal(router.page, void 0);
|
||||
equal(lastRoute, 'search');
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user