mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-01-29 06:27:49 +00:00
Update vendors.
This commit is contained in:
2
vendor/backbone/LICENSE
vendored
2
vendor/backbone/LICENSE
vendored
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2010-2014 Jeremy Ashkenas, DocumentCloud
|
||||
Copyright (c) 2010-2015 Jeremy Ashkenas, DocumentCloud
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
|
||||
938
vendor/backbone/backbone.js
vendored
938
vendor/backbone/backbone.js
vendored
File diff suppressed because it is too large
Load Diff
344
vendor/backbone/test/collection.js
vendored
344
vendor/backbone/test/collection.js
vendored
@@ -16,23 +16,20 @@
|
||||
|
||||
});
|
||||
|
||||
test("new and sort", 9, function() {
|
||||
test("new and sort", 6, 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");
|
||||
deepEqual(col.pluck('label'), ['a', 'b', 'c', 'd']);
|
||||
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");
|
||||
deepEqual(col.pluck('label'), ['a', 'b', 'c', 'd']);
|
||||
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");
|
||||
deepEqual(col.pluck('label'), ['d', 'c', 'b', 'a']);
|
||||
equal(col.length, 4);
|
||||
});
|
||||
|
||||
@@ -60,6 +57,20 @@
|
||||
strictEqual(collection.last().get('a'), 4);
|
||||
});
|
||||
|
||||
test("clone preserves model and comparator", 3, function() {
|
||||
var Model = Backbone.Model.extend();
|
||||
var comparator = function(model){ return model.id; };
|
||||
|
||||
var collection = new Backbone.Collection([{id: 1}], {
|
||||
model: Model,
|
||||
comparator: comparator
|
||||
}).clone();
|
||||
collection.add({id: 2});
|
||||
ok(collection.at(0) instanceof Model);
|
||||
ok(collection.at(1) instanceof Model);
|
||||
strictEqual(collection.comparator, comparator);
|
||||
});
|
||||
|
||||
test("get", 6, function() {
|
||||
equal(col.get(0), d);
|
||||
equal(col.get(d.clone()), d);
|
||||
@@ -70,10 +81,9 @@
|
||||
});
|
||||
|
||||
test("get with non-default ids", 5, function() {
|
||||
var col = new Backbone.Collection();
|
||||
var MongoModel = Backbone.Model.extend({idAttribute: '_id'});
|
||||
var model = new MongoModel({_id: 100});
|
||||
col.add(model);
|
||||
var col = new Backbone.Collection([model], {model: MongoModel});
|
||||
equal(col.get(100), model);
|
||||
equal(col.get(model.cid), model);
|
||||
equal(col.get(model), model);
|
||||
@@ -88,7 +98,7 @@
|
||||
test('get with "undefined" id', function() {
|
||||
var collection = new Backbone.Collection([{id: 1}, {id: 'undefined'}]);
|
||||
equal(collection.get(1).id, 1);
|
||||
}),
|
||||
});
|
||||
|
||||
test("update index when id changes", 4, function() {
|
||||
var col = new Backbone.Collection();
|
||||
@@ -104,8 +114,9 @@
|
||||
equal(col.get(101).get('name'), 'dalmatians');
|
||||
});
|
||||
|
||||
test("at", 1, function() {
|
||||
test("at", 2, function() {
|
||||
equal(col.at(2), c);
|
||||
equal(col.at(-2), c);
|
||||
});
|
||||
|
||||
test("pluck", 1, function() {
|
||||
@@ -287,9 +298,10 @@
|
||||
deepEqual(col.pluck('id'), [1, 2, 3]);
|
||||
});
|
||||
|
||||
test("remove", 5, function() {
|
||||
test("remove", 7, function() {
|
||||
var removed = null;
|
||||
var otherRemoved = null;
|
||||
var result = null;
|
||||
col.on('remove', function(model, col, options) {
|
||||
removed = model.get('label');
|
||||
equal(options.index, 3);
|
||||
@@ -297,8 +309,12 @@
|
||||
otherCol.on('remove', function(model, col, options) {
|
||||
otherRemoved = true;
|
||||
});
|
||||
col.remove(d);
|
||||
result = col.remove(d);
|
||||
equal(removed, 'd');
|
||||
strictEqual(result, d);
|
||||
//if we try to remove d again, it's not going to actually get removed
|
||||
result = col.remove(d);
|
||||
strictEqual(result, undefined);
|
||||
equal(col.length, 3);
|
||||
equal(col.first(), a);
|
||||
equal(otherRemoved, null);
|
||||
@@ -464,6 +480,21 @@
|
||||
collection.fetch();
|
||||
});
|
||||
|
||||
test("#3283 - fetch with an error response calls error with context", 1, function () {
|
||||
var collection = new Backbone.Collection();
|
||||
var obj = {};
|
||||
var options = {
|
||||
context: obj,
|
||||
error: function() {
|
||||
equal(this, obj);
|
||||
}
|
||||
};
|
||||
collection.sync = function (method, model, options) {
|
||||
options.error.call(options.context);
|
||||
};
|
||||
collection.fetch(options);
|
||||
});
|
||||
|
||||
test("ensure fetch only parses once", 1, function() {
|
||||
var collection = new Backbone.Collection;
|
||||
var counter = 0;
|
||||
@@ -504,6 +535,30 @@
|
||||
equal(col.create({"foo":"bar"}, {validate:true}), false);
|
||||
});
|
||||
|
||||
test("create will pass extra options to success callback", 1, function () {
|
||||
var Model = Backbone.Model.extend({
|
||||
sync: function (method, model, options) {
|
||||
_.extend(options, {specialSync: true});
|
||||
return Backbone.Model.prototype.sync.call(this, method, model, options);
|
||||
}
|
||||
});
|
||||
|
||||
var Collection = Backbone.Collection.extend({
|
||||
model: Model,
|
||||
url: '/test'
|
||||
});
|
||||
|
||||
var collection = new Collection;
|
||||
|
||||
var success = function (model, response, options) {
|
||||
ok(options.specialSync, "Options were passed correctly to callback");
|
||||
};
|
||||
|
||||
collection.create({}, {success: success});
|
||||
this.ajaxSettings.success();
|
||||
|
||||
});
|
||||
|
||||
test("a failing create returns model with errors", function() {
|
||||
var ValidatingModel = Backbone.Model.extend({
|
||||
validate: function(attrs) {
|
||||
@@ -634,6 +689,16 @@
|
||||
});
|
||||
});
|
||||
|
||||
test("reset does not alter options by reference", 2, function() {
|
||||
var col = new Backbone.Collection([{id:1}]);
|
||||
var origOpts = {};
|
||||
col.on("reset", function(col, opts){
|
||||
equal(origOpts.previousModels, undefined);
|
||||
equal(opts.previousModels[0].id, 1);
|
||||
});
|
||||
col.reset([], origOpts);
|
||||
});
|
||||
|
||||
test("trigger custom events on models", 1, function() {
|
||||
var fired = null;
|
||||
a.on("custom", function() { fired = true; });
|
||||
@@ -672,22 +737,22 @@
|
||||
equal(col.length, 0);
|
||||
});
|
||||
|
||||
test("#861, adding models to a collection which do not pass validation, with validate:true", function() {
|
||||
var Model = Backbone.Model.extend({
|
||||
validate: function(attrs) {
|
||||
if (attrs.id == 3) return "id can't be 3";
|
||||
}
|
||||
});
|
||||
test("#861, adding models to a collection which do not pass validation, with validate:true", 2, function() {
|
||||
var Model = Backbone.Model.extend({
|
||||
validate: function(attrs) {
|
||||
if (attrs.id == 3) return "id can't be 3";
|
||||
}
|
||||
});
|
||||
|
||||
var Collection = Backbone.Collection.extend({
|
||||
model: Model
|
||||
});
|
||||
var Collection = Backbone.Collection.extend({
|
||||
model: Model
|
||||
});
|
||||
|
||||
var collection = new Collection;
|
||||
collection.on("error", function() { ok(true); });
|
||||
var collection = new Collection;
|
||||
collection.on("invalid", function() { ok(true); });
|
||||
|
||||
collection.add([{id: 1}, {id: 2}, {id: 3}, {id: 4}, {id: 5}, {id: 6}], {validate:true});
|
||||
deepEqual(collection.pluck('id'), [1, 2, 4, 5, 6]);
|
||||
collection.add([{id: 1}, {id: 2}, {id: 3}, {id: 4}, {id: 5}, {id: 6}], {validate:true});
|
||||
deepEqual(collection.pluck("id"), [1, 2, 4, 5, 6]);
|
||||
});
|
||||
|
||||
test("Invalid models are discarded with validate:true.", 5, function() {
|
||||
@@ -756,12 +821,13 @@
|
||||
var m = new Backbone.Model({x:1});
|
||||
var col = new Backbone.Collection();
|
||||
var opts = {
|
||||
success: function(collection, resp, options){
|
||||
ok(options);
|
||||
opts: true,
|
||||
success: function(collection, resp, options) {
|
||||
ok(options.opts);
|
||||
}
|
||||
};
|
||||
col.sync = m.sync = function( method, collection, options ){
|
||||
options.success(collection, [], options);
|
||||
options.success({});
|
||||
};
|
||||
col.fetch(opts);
|
||||
col.create(m, opts);
|
||||
@@ -791,6 +857,24 @@
|
||||
collection.off();
|
||||
});
|
||||
|
||||
test("#3283 - fetch, create calls success with context", 2, function() {
|
||||
var collection = new Backbone.Collection;
|
||||
collection.url = '/test';
|
||||
Backbone.ajax = function(settings) {
|
||||
settings.success.call(settings.context);
|
||||
};
|
||||
var obj = {};
|
||||
var options = {
|
||||
context: obj,
|
||||
success: function() {
|
||||
equal(this, obj);
|
||||
}
|
||||
};
|
||||
|
||||
collection.fetch(options);
|
||||
collection.create({id: 1}, options);
|
||||
});
|
||||
|
||||
test("#1447 - create with wait adds model.", 1, function() {
|
||||
var collection = new Backbone.Collection;
|
||||
var model = new Backbone.Model;
|
||||
@@ -1085,9 +1169,7 @@
|
||||
test("#1894 - Push should not trigger a sort", 0, function() {
|
||||
var Collection = Backbone.Collection.extend({
|
||||
comparator: 'id',
|
||||
sort: function() {
|
||||
ok(false);
|
||||
}
|
||||
sort: function() { ok(false); }
|
||||
});
|
||||
new Collection().push({id: 1});
|
||||
});
|
||||
@@ -1111,7 +1193,7 @@
|
||||
test("#1894 - `sort` can optionally be turned off", 0, function() {
|
||||
var Collection = Backbone.Collection.extend({
|
||||
comparator: 'id',
|
||||
sort: function() { ok(true); }
|
||||
sort: function() { ok(false); }
|
||||
});
|
||||
new Collection().add({id: 1}, {sort: false});
|
||||
});
|
||||
@@ -1146,6 +1228,25 @@
|
||||
Backbone.ajax = ajax;
|
||||
});
|
||||
|
||||
test("fetch will pass extra options to success callback", 1, function () {
|
||||
var SpecialSyncCollection = Backbone.Collection.extend({
|
||||
url: '/test',
|
||||
sync: function (method, collection, options) {
|
||||
_.extend(options, { specialSync: true });
|
||||
return Backbone.Collection.prototype.sync.call(this, method, collection, options);
|
||||
}
|
||||
});
|
||||
|
||||
var collection = new SpecialSyncCollection();
|
||||
|
||||
var onSuccess = function (collection, resp, options) {
|
||||
ok(options.specialSync, "Options were passed correctly to callback");
|
||||
};
|
||||
|
||||
collection.fetch({ success: onSuccess });
|
||||
this.ajaxSettings.success();
|
||||
});
|
||||
|
||||
test("`add` only `sort`s when necessary", 2, function () {
|
||||
var collection = new (Backbone.Collection.extend({
|
||||
comparator: 'a'
|
||||
@@ -1175,15 +1276,15 @@
|
||||
});
|
||||
|
||||
test("Attach options to collection.", 2, function() {
|
||||
var model = new Backbone.Model;
|
||||
var Model = Backbone.Model;
|
||||
var comparator = function(){};
|
||||
|
||||
var collection = new Backbone.Collection([], {
|
||||
model: model,
|
||||
model: Model,
|
||||
comparator: comparator
|
||||
});
|
||||
|
||||
ok(collection.model === model);
|
||||
ok(collection.model === Model);
|
||||
ok(collection.comparator === comparator);
|
||||
});
|
||||
|
||||
@@ -1309,7 +1410,7 @@
|
||||
equal(this._byId[model.id], void 0);
|
||||
equal(this._byId[model.cid], void 0);
|
||||
equal(model.collection, void 0);
|
||||
equal(model._events.all, void 0);
|
||||
equal(model._events, void 0);
|
||||
}
|
||||
|
||||
});
|
||||
@@ -1335,4 +1436,173 @@
|
||||
equal(c.models.length, 1);
|
||||
});
|
||||
|
||||
test('#3020: #set with {add: false} should not throw.', 2, function() {
|
||||
var collection = new Backbone.Collection;
|
||||
collection.set([{id: 1}], {add: false});
|
||||
strictEqual(collection.length, 0);
|
||||
strictEqual(collection.models.length, 0);
|
||||
});
|
||||
|
||||
test("create with wait, model instance, #3028", 1, function() {
|
||||
var collection = new Backbone.Collection();
|
||||
var model = new Backbone.Model({id: 1});
|
||||
model.sync = function(){
|
||||
equal(this.collection, collection);
|
||||
};
|
||||
collection.create(model, {wait: true});
|
||||
});
|
||||
|
||||
test("modelId", function() {
|
||||
var Stooge = Backbone.Model.extend();
|
||||
var StoogeCollection = Backbone.Collection.extend({model: Stooge});
|
||||
|
||||
// Default to using `Collection::model::idAttribute`.
|
||||
equal(StoogeCollection.prototype.modelId({id: 1}), 1);
|
||||
Stooge.prototype.idAttribute = '_id';
|
||||
equal(StoogeCollection.prototype.modelId({_id: 1}), 1);
|
||||
});
|
||||
|
||||
test('Polymorphic models work with "simple" constructors', function () {
|
||||
var A = Backbone.Model.extend();
|
||||
var B = Backbone.Model.extend();
|
||||
var C = Backbone.Collection.extend({
|
||||
model: function (attrs) {
|
||||
return attrs.type === 'a' ? new A(attrs) : new B(attrs);
|
||||
}
|
||||
});
|
||||
var collection = new C([{id: 1, type: 'a'}, {id: 2, type: 'b'}]);
|
||||
equal(collection.length, 2);
|
||||
ok(collection.at(0) instanceof A);
|
||||
equal(collection.at(0).id, 1);
|
||||
ok(collection.at(1) instanceof B);
|
||||
equal(collection.at(1).id, 2);
|
||||
});
|
||||
|
||||
test('Polymorphic models work with "advanced" constructors', function () {
|
||||
var A = Backbone.Model.extend({idAttribute: '_id'});
|
||||
var B = Backbone.Model.extend({idAttribute: '_id'});
|
||||
var C = Backbone.Collection.extend({
|
||||
model: Backbone.Model.extend({
|
||||
constructor: function (attrs) {
|
||||
return attrs.type === 'a' ? new A(attrs) : new B(attrs);
|
||||
},
|
||||
|
||||
idAttribute: '_id'
|
||||
})
|
||||
});
|
||||
var collection = new C([{_id: 1, type: 'a'}, {_id: 2, type: 'b'}]);
|
||||
equal(collection.length, 2);
|
||||
ok(collection.at(0) instanceof A);
|
||||
equal(collection.at(0), collection.get(1));
|
||||
ok(collection.at(1) instanceof B);
|
||||
equal(collection.at(1), collection.get(2));
|
||||
|
||||
C = Backbone.Collection.extend({
|
||||
model: function (attrs) {
|
||||
return attrs.type === 'a' ? new A(attrs) : new B(attrs);
|
||||
},
|
||||
|
||||
modelId: function (attrs) {
|
||||
return attrs.type + '-' + attrs.id;
|
||||
}
|
||||
});
|
||||
collection = new C([{id: 1, type: 'a'}, {id: 1, type: 'b'}]);
|
||||
equal(collection.length, 2);
|
||||
ok(collection.at(0) instanceof A);
|
||||
equal(collection.at(0), collection.get('a-1'));
|
||||
ok(collection.at(1) instanceof B);
|
||||
equal(collection.at(1), collection.get('b-1'));
|
||||
});
|
||||
|
||||
test("#3039: adding at index fires with correct at", 3, function() {
|
||||
var col = new Backbone.Collection([{at: 0}, {at: 4}]);
|
||||
col.on('add', function(model, col, options) {
|
||||
equal(model.get('at'), options.index);
|
||||
});
|
||||
col.add([{at: 1}, {at: 2}, {at: 3}], {at: 1});
|
||||
});
|
||||
|
||||
test("#3039: index is not sent when at is not specified", 2, function() {
|
||||
var col = new Backbone.Collection([{at: 0}]);
|
||||
col.on('add', function(model, col, options) {
|
||||
equal(undefined, options.index);
|
||||
});
|
||||
col.add([{at: 1}, {at: 2}]);
|
||||
});
|
||||
|
||||
test('#3199 - Order changing should trigger a sort', 1, function() {
|
||||
var one = new Backbone.Model({id: 1});
|
||||
var two = new Backbone.Model({id: 2});
|
||||
var three = new Backbone.Model({id: 3});
|
||||
var collection = new Backbone.Collection([one, two, three]);
|
||||
collection.on('sort', function() {
|
||||
ok(true);
|
||||
});
|
||||
collection.set([{id: 3}, {id: 2}, {id: 1}]);
|
||||
});
|
||||
|
||||
test('#3199 - Adding a model should trigger a sort', 1, function() {
|
||||
var one = new Backbone.Model({id: 1});
|
||||
var two = new Backbone.Model({id: 2});
|
||||
var three = new Backbone.Model({id: 3});
|
||||
var collection = new Backbone.Collection([one, two, three]);
|
||||
collection.on('sort', function() {
|
||||
ok(true);
|
||||
});
|
||||
collection.set([{id: 3}, {id: 2}, {id: 1}, {id: 0}]);
|
||||
})
|
||||
|
||||
test('#3199 - Order not changing should not trigger a sort', 0, function() {
|
||||
var one = new Backbone.Model({id: 1});
|
||||
var two = new Backbone.Model({id: 2});
|
||||
var three = new Backbone.Model({id: 3});
|
||||
var collection = new Backbone.Collection([one, two, three]);
|
||||
collection.on('sort', function() {
|
||||
ok(false);
|
||||
});
|
||||
collection.set([{id: 1}, {id: 2}, {id: 3}]);
|
||||
});
|
||||
|
||||
test("add supports negative indexes", 1, function() {
|
||||
var collection = new Backbone.Collection([{id: 1}]);
|
||||
collection.add([{id: 2}, {id: 3}], {at: -1});
|
||||
collection.add([{id: 2.5}], {at: -2});
|
||||
equal(collection.pluck('id').join(','), "1,2,2.5,3");
|
||||
});
|
||||
|
||||
test("#set accepts options.at as a string", 1, function() {
|
||||
var collection = new Backbone.Collection([{id: 1}, {id: 2}]);
|
||||
collection.add([{id: 3}], {at: '1'});
|
||||
deepEqual(collection.pluck('id'), [1, 3, 2]);
|
||||
});
|
||||
test("adding multiple models triggers `set` event once", 1, function() {
|
||||
var collection = new Backbone.Collection;
|
||||
collection.on('update', function() { ok(true); });
|
||||
collection.add([{id: 1}, {id: 2}, {id: 3}]);
|
||||
});
|
||||
|
||||
test("removing models triggers `set` event once", 1, function() {
|
||||
var collection = new Backbone.Collection([{id: 1}, {id: 2}, {id: 3}]);
|
||||
collection.on('update', function() { ok(true); });
|
||||
collection.remove([{id: 1}, {id: 2}]);
|
||||
});
|
||||
|
||||
test("remove does not trigger `set` when nothing removed", 0, function() {
|
||||
var collection = new Backbone.Collection([{id: 1}, {id: 2}]);
|
||||
collection.on('update', function() { ok(false); });
|
||||
collection.remove([{id: 3}]);
|
||||
});
|
||||
|
||||
test("set triggers `set` event once", 1, function() {
|
||||
var collection = new Backbone.Collection([{id: 1}, {id: 2}]);
|
||||
collection.on('update', function() { ok(true); });
|
||||
collection.set([{id: 1}, {id: 3}]);
|
||||
});
|
||||
|
||||
test("set does not trigger `set` event when nothing added nor removed", 0, function() {
|
||||
var collection = new Backbone.Collection([{id: 1}, {id: 2}]);
|
||||
collection.on('update', function() { ok(false); });
|
||||
collection.set([{id: 1}, {id: 2}]);
|
||||
});
|
||||
|
||||
})();
|
||||
|
||||
143
vendor/backbone/test/events.js
vendored
143
vendor/backbone/test/events.js
vendored
@@ -106,6 +106,19 @@
|
||||
b.trigger('event2');
|
||||
});
|
||||
|
||||
test("listenToOnce", 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.listenToOnce(obj, 'event', incrA);
|
||||
obj.listenToOnce(obj, 'event', incrB);
|
||||
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("listenToOnce and stopListening", 1, function() {
|
||||
var a = _.extend({}, Backbone.Events);
|
||||
var b = _.extend({}, Backbone.Events);
|
||||
@@ -152,18 +165,72 @@
|
||||
e.trigger("foo");
|
||||
});
|
||||
|
||||
test("stopListening cleans up references", 4, function() {
|
||||
test("stopListening cleans up references", 12, function() {
|
||||
var a = _.extend({}, Backbone.Events);
|
||||
var b = _.extend({}, Backbone.Events);
|
||||
var fn = function() {};
|
||||
a.listenTo(b, 'all', fn).stopListening();
|
||||
b.on('event', fn);
|
||||
a.listenTo(b, 'event', fn).stopListening();
|
||||
equal(_.size(a._listeningTo), 0);
|
||||
a.listenTo(b, 'all', fn).stopListening(b);
|
||||
equal(_.size(b._events.event), 1);
|
||||
equal(_.size(b._listeners), 0);
|
||||
a.listenTo(b, 'event', fn).stopListening(b);
|
||||
equal(_.size(a._listeningTo), 0);
|
||||
a.listenTo(b, 'all', fn).stopListening(null, 'all');
|
||||
equal(_.size(b._events.event), 1);
|
||||
equal(_.size(b._listeners), 0);
|
||||
a.listenTo(b, 'event', fn).stopListening(b, 'event');
|
||||
equal(_.size(a._listeningTo), 0);
|
||||
a.listenTo(b, 'all', fn).stopListening(null, null, fn);
|
||||
equal(_.size(b._events.event), 1);
|
||||
equal(_.size(b._listeners), 0);
|
||||
a.listenTo(b, 'event', fn).stopListening(b, 'event', fn);
|
||||
equal(_.size(a._listeningTo), 0);
|
||||
equal(_.size(b._events.event), 1);
|
||||
equal(_.size(b._listeners), 0);
|
||||
});
|
||||
|
||||
test("stopListening cleans up references from listenToOnce", 12, function() {
|
||||
var a = _.extend({}, Backbone.Events);
|
||||
var b = _.extend({}, Backbone.Events);
|
||||
var fn = function() {};
|
||||
b.on('event', fn);
|
||||
a.listenToOnce(b, 'event', fn).stopListening();
|
||||
equal(_.size(a._listeningTo), 0);
|
||||
equal(_.size(b._events.event), 1);
|
||||
equal(_.size(b._listeners), 0);
|
||||
a.listenToOnce(b, 'event', fn).stopListening(b);
|
||||
equal(_.size(a._listeningTo), 0);
|
||||
equal(_.size(b._events.event), 1);
|
||||
equal(_.size(b._listeners), 0);
|
||||
a.listenToOnce(b, 'event', fn).stopListening(b, 'event');
|
||||
equal(_.size(a._listeningTo), 0);
|
||||
equal(_.size(b._events.event), 1);
|
||||
equal(_.size(b._listeners), 0);
|
||||
a.listenToOnce(b, 'event', fn).stopListening(b, 'event', fn);
|
||||
equal(_.size(a._listeningTo), 0);
|
||||
equal(_.size(b._events.event), 1);
|
||||
equal(_.size(b._listeners), 0);
|
||||
});
|
||||
|
||||
test("listenTo and off cleaning up references", 8, function() {
|
||||
var a = _.extend({}, Backbone.Events);
|
||||
var b = _.extend({}, Backbone.Events);
|
||||
var fn = function() {};
|
||||
a.listenTo(b, 'event', fn);
|
||||
b.off();
|
||||
equal(_.size(a._listeningTo), 0);
|
||||
equal(_.size(b._listeners), 0);
|
||||
a.listenTo(b, 'event', fn);
|
||||
b.off('event');
|
||||
equal(_.size(a._listeningTo), 0);
|
||||
equal(_.size(b._listeners), 0);
|
||||
a.listenTo(b, 'event', fn);
|
||||
b.off(null, fn);
|
||||
equal(_.size(a._listeningTo), 0);
|
||||
equal(_.size(b._listeners), 0);
|
||||
a.listenTo(b, 'event', fn);
|
||||
b.off(null, null, a);
|
||||
equal(_.size(a._listeningTo), 0);
|
||||
equal(_.size(b._listeners), 0);
|
||||
});
|
||||
|
||||
test("listenTo and stopListening cleaning up references", 2, function() {
|
||||
@@ -174,7 +241,36 @@
|
||||
a.listenTo(b, 'other', function(){ ok(false); });
|
||||
a.stopListening(b, 'other');
|
||||
a.stopListening(b, 'all');
|
||||
equal(_.keys(a._listeningTo).length, 0);
|
||||
equal(_.size(a._listeningTo), 0);
|
||||
});
|
||||
|
||||
test("listenToOnce without context cleans up references after the event has fired", 2, function() {
|
||||
var a = _.extend({}, Backbone.Events);
|
||||
var b = _.extend({}, Backbone.Events);
|
||||
a.listenToOnce(b, 'all', function(){ ok(true); });
|
||||
b.trigger('anything');
|
||||
equal(_.size(a._listeningTo), 0);
|
||||
});
|
||||
|
||||
test("listenToOnce with event maps cleans up references", 2, function() {
|
||||
var a = _.extend({}, Backbone.Events);
|
||||
var b = _.extend({}, Backbone.Events);
|
||||
a.listenToOnce(b, {
|
||||
one: function() { ok(true); },
|
||||
two: function() { ok(false); }
|
||||
});
|
||||
b.trigger('one');
|
||||
equal(_.size(a._listeningTo), 1);
|
||||
});
|
||||
|
||||
test("listenToOnce with event maps binds the correct `this`", 1, function() {
|
||||
var a = _.extend({}, Backbone.Events);
|
||||
var b = _.extend({}, Backbone.Events);
|
||||
a.listenToOnce(b, {
|
||||
one: function() { ok(this === a); },
|
||||
two: function() { ok(false); }
|
||||
});
|
||||
b.trigger('one');
|
||||
});
|
||||
|
||||
test("listenTo with empty callback doesn't throw an error", 1, function(){
|
||||
@@ -277,15 +373,14 @@
|
||||
test("callback list is not altered during trigger", 2, function () {
|
||||
var counter = 0, obj = _.extend({}, Backbone.Events);
|
||||
var incr = function(){ counter++; };
|
||||
obj.on('event', function(){ obj.on('event', incr).on('all', incr); })
|
||||
.trigger('event');
|
||||
equal(counter, 0, 'bind does not alter callback list');
|
||||
obj.off()
|
||||
.on('event', function(){ obj.off('event', incr).off('all', incr); })
|
||||
.on('event', incr)
|
||||
.on('all', incr)
|
||||
.trigger('event');
|
||||
equal(counter, 2, 'unbind does not alter callback list');
|
||||
var incrOn = function(){ obj.on('event all', incr); };
|
||||
var incrOff = function(){ obj.off('event all', incr); };
|
||||
|
||||
obj.on('event all', incrOn).trigger('event');
|
||||
equal(counter, 0, 'on does not alter callback list');
|
||||
|
||||
obj.off().on('event', incrOff).on('event all', incr).trigger('event');
|
||||
equal(counter, 2, 'off does not alter callback list');
|
||||
});
|
||||
|
||||
test("#1282 - 'all' callback list is retrieved after each event.", 1, function() {
|
||||
@@ -305,7 +400,7 @@
|
||||
|
||||
test("if callback is truthy but not a function, `on` should throw an error just like jQuery", 1, function() {
|
||||
var view = _.extend({}, Backbone.Events).on('test', 'noop');
|
||||
raises(function() {
|
||||
throws(function() {
|
||||
view.trigger('test');
|
||||
});
|
||||
});
|
||||
@@ -457,6 +552,11 @@
|
||||
_.extend({}, Backbone.Events).once('event').trigger('event');
|
||||
});
|
||||
|
||||
test("listenToOnce without a callback is a noop", 0, function() {
|
||||
var obj = _.extend({}, Backbone.Events);
|
||||
obj.listenToOnce(obj, 'event').trigger('event');
|
||||
});
|
||||
|
||||
test("event functions are chainable", function() {
|
||||
var obj = _.extend({}, Backbone.Events);
|
||||
var obj2 = _.extend({}, Backbone.Events);
|
||||
@@ -474,4 +574,15 @@
|
||||
equal(obj, obj.stopListening());
|
||||
});
|
||||
|
||||
test("#3448 - listenToOnce with space-separated events", 2, function() {
|
||||
var one = _.extend({}, Backbone.Events);
|
||||
var two = _.extend({}, Backbone.Events);
|
||||
var count = 1;
|
||||
one.listenToOnce(two, 'x y', function(n) { ok(n === count++); });
|
||||
two.trigger('x', 1);
|
||||
two.trigger('x', 1);
|
||||
two.trigger('y', 2);
|
||||
two.trigger('y', 2);
|
||||
});
|
||||
|
||||
})();
|
||||
|
||||
173
vendor/backbone/test/model.js
vendored
173
vendor/backbone/test/model.js
vendored
@@ -83,7 +83,7 @@
|
||||
doc.collection.url = '/collection/';
|
||||
equal(doc.url(), '/collection/1-the-tempest');
|
||||
doc.collection = null;
|
||||
raises(function() { doc.url(); });
|
||||
throws(function() { doc.url(); });
|
||||
doc.collection = collection;
|
||||
});
|
||||
|
||||
@@ -120,6 +120,11 @@
|
||||
deepEqual(model.omit('foo', 'bar'), {'baz': 'c'});
|
||||
});
|
||||
|
||||
test("chain", function() {
|
||||
var model = new Backbone.Model({ a: 0, b: 1, c: 2 });
|
||||
deepEqual(model.chain().pick("a", "b", "c").values().compact().value(), [1, 2]);
|
||||
});
|
||||
|
||||
test("clone", 10, function() {
|
||||
var a = new Backbone.Model({ 'foo': 1, 'bar': 2, 'baz': 3});
|
||||
var b = a.clone();
|
||||
@@ -199,6 +204,32 @@
|
||||
strictEqual(model.has('undefined'), false);
|
||||
});
|
||||
|
||||
test("matches", 4, function() {
|
||||
var model = new Backbone.Model();
|
||||
|
||||
strictEqual(model.matches({'name': 'Jonas', 'cool': true}), false);
|
||||
|
||||
model.set({name: 'Jonas', 'cool': true});
|
||||
|
||||
strictEqual(model.matches({'name': 'Jonas'}), true);
|
||||
strictEqual(model.matches({'name': 'Jonas', 'cool': true}), true);
|
||||
strictEqual(model.matches({'name': 'Jonas', 'cool': false}), false);
|
||||
});
|
||||
|
||||
test("matches with predicate", function() {
|
||||
var model = new Backbone.Model({a: 0});
|
||||
|
||||
strictEqual(model.matches(function(attr) {
|
||||
return attr.a > 1 && attr.b != null;
|
||||
}), false);
|
||||
|
||||
model.set({a: 3, b: true});
|
||||
|
||||
strictEqual(model.matches(function(attr) {
|
||||
return attr.a > 1 && attr.b != null;
|
||||
}), true);
|
||||
})
|
||||
|
||||
test("set and unset", 8, function() {
|
||||
var a = new Backbone.Model({id: 'id', foo: 1, bar: 2, baz: 3});
|
||||
var changeCount = 0;
|
||||
@@ -312,6 +343,31 @@
|
||||
equal(model.isNew(), true);
|
||||
});
|
||||
|
||||
test("setting an alternative cid prefix", 4, function() {
|
||||
var Model = Backbone.Model.extend({
|
||||
cidPrefix: 'm'
|
||||
});
|
||||
var model = new Model();
|
||||
|
||||
equal(model.cid.charAt(0), 'm');
|
||||
|
||||
model = new Backbone.Model();
|
||||
equal(model.cid.charAt(0), 'c');
|
||||
|
||||
var Collection = Backbone.Collection.extend({
|
||||
model: Model
|
||||
});
|
||||
var collection = new Collection([{id: 'c5'}, {id: 'c6'}, {id: 'c7'}]);
|
||||
|
||||
equal(collection.get('c6').cid.charAt(0), 'm');
|
||||
collection.set([{id: 'c6', value: 'test'}], {
|
||||
merge: true,
|
||||
add: true,
|
||||
remove: false
|
||||
});
|
||||
ok(collection.get('c6').has('value'));
|
||||
});
|
||||
|
||||
test("set an empty string", 1, function() {
|
||||
var model = new Backbone.Model({name : "Model"});
|
||||
model.set({name : ''});
|
||||
@@ -460,6 +516,40 @@
|
||||
model.destroy();
|
||||
});
|
||||
|
||||
test("#3283 - save, fetch, destroy calls success with context", 3, function () {
|
||||
var model = new Backbone.Model();
|
||||
var obj = {};
|
||||
var options = {
|
||||
context: obj,
|
||||
success: function() {
|
||||
equal(this, obj);
|
||||
}
|
||||
};
|
||||
model.sync = function (method, model, options) {
|
||||
options.success.call(options.context);
|
||||
};
|
||||
model.save({data: 2, id: 1}, options);
|
||||
model.fetch(options);
|
||||
model.destroy(options);
|
||||
});
|
||||
|
||||
test("#3283 - save, fetch, destroy calls error with context", 3, function () {
|
||||
var model = new Backbone.Model();
|
||||
var obj = {};
|
||||
var options = {
|
||||
context: obj,
|
||||
error: function() {
|
||||
equal(this, obj);
|
||||
}
|
||||
};
|
||||
model.sync = function (method, model, options) {
|
||||
options.error.call(options.context);
|
||||
};
|
||||
model.save({data: 2, id: 1}, options);
|
||||
model.fetch(options);
|
||||
model.destroy(options);
|
||||
});
|
||||
|
||||
test("save with PATCH", function() {
|
||||
doc.clear().set({id: 1, a: 1, b: 2, c: 3, d: 4});
|
||||
doc.save();
|
||||
@@ -474,6 +564,14 @@
|
||||
equal(this.ajaxSettings.data, "{\"b\":2,\"d\":4}");
|
||||
});
|
||||
|
||||
test("save with PATCH and different attrs", function() {
|
||||
doc.clear().save({b: 2, d: 4}, {patch: true, attrs: {B: 1, D: 3}});
|
||||
equal(this.syncArgs.options.attrs.D, 3);
|
||||
equal(this.syncArgs.options.attrs.d, undefined);
|
||||
equal(this.ajaxSettings.data, "{\"B\":1,\"D\":3}");
|
||||
deepEqual(doc.attributes, {b: 2, d: 4});
|
||||
});
|
||||
|
||||
test("save in positional style", 1, function() {
|
||||
var model = new Backbone.Model();
|
||||
model.sync = function(method, model, options) {
|
||||
@@ -496,12 +594,59 @@
|
||||
});
|
||||
});
|
||||
|
||||
test("save with wait and supplied id", function() {
|
||||
var Model = Backbone.Model.extend({
|
||||
urlRoot: '/collection'
|
||||
});
|
||||
var model = new Model();
|
||||
model.save({id: 42}, {wait: true});
|
||||
equal(this.ajaxSettings.url, '/collection/42');
|
||||
});
|
||||
|
||||
test("save will pass extra options to success callback", 1, function () {
|
||||
var SpecialSyncModel = Backbone.Model.extend({
|
||||
sync: function (method, model, options) {
|
||||
_.extend(options, { specialSync: true });
|
||||
return Backbone.Model.prototype.sync.call(this, method, model, options);
|
||||
},
|
||||
urlRoot: '/test'
|
||||
});
|
||||
|
||||
var model = new SpecialSyncModel();
|
||||
|
||||
var onSuccess = function (model, response, options) {
|
||||
ok(options.specialSync, "Options were passed correctly to callback");
|
||||
};
|
||||
|
||||
model.save(null, { success: onSuccess });
|
||||
this.ajaxSettings.success();
|
||||
});
|
||||
|
||||
test("fetch", 2, function() {
|
||||
doc.fetch();
|
||||
equal(this.syncArgs.method, 'read');
|
||||
ok(_.isEqual(this.syncArgs.model, doc));
|
||||
});
|
||||
|
||||
test("fetch will pass extra options to success callback", 1, function () {
|
||||
var SpecialSyncModel = Backbone.Model.extend({
|
||||
sync: function (method, model, options) {
|
||||
_.extend(options, { specialSync: true });
|
||||
return Backbone.Model.prototype.sync.call(this, method, model, options);
|
||||
},
|
||||
urlRoot: '/test'
|
||||
});
|
||||
|
||||
var model = new SpecialSyncModel();
|
||||
|
||||
var onSuccess = function (model, response, options) {
|
||||
ok(options.specialSync, "Options were passed correctly to callback");
|
||||
};
|
||||
|
||||
model.fetch({ success: onSuccess });
|
||||
this.ajaxSettings.success();
|
||||
});
|
||||
|
||||
test("destroy", 3, function() {
|
||||
doc.destroy();
|
||||
equal(this.syncArgs.method, 'delete');
|
||||
@@ -511,6 +656,25 @@
|
||||
equal(newModel.destroy(), false);
|
||||
});
|
||||
|
||||
test("destroy will pass extra options to success callback", 1, function () {
|
||||
var SpecialSyncModel = Backbone.Model.extend({
|
||||
sync: function (method, model, options) {
|
||||
_.extend(options, { specialSync: true });
|
||||
return Backbone.Model.prototype.sync.call(this, method, model, options);
|
||||
},
|
||||
urlRoot: '/test'
|
||||
});
|
||||
|
||||
var model = new SpecialSyncModel({ id: 'id' });
|
||||
|
||||
var onSuccess = function (model, response, options) {
|
||||
ok(options.specialSync, "Options were passed correctly to callback");
|
||||
};
|
||||
|
||||
model.destroy({ success: onSuccess });
|
||||
this.ajaxSettings.success();
|
||||
});
|
||||
|
||||
test("non-persisted destroy", 1, function() {
|
||||
var a = new Backbone.Model({ 'foo': 1, 'bar': 2, 'baz': 3});
|
||||
a.sync = function() { throw "should not be called"; };
|
||||
@@ -967,11 +1131,14 @@
|
||||
model.destroy();
|
||||
});
|
||||
|
||||
test("#1365 - Destroy: New models execute success callback.", 2, function() {
|
||||
asyncTest("#1365 - Destroy: New models execute success callback.", 2, function() {
|
||||
new Backbone.Model()
|
||||
.on('sync', function() { ok(false); })
|
||||
.on('destroy', function(){ ok(true); })
|
||||
.destroy({ success: function(){ ok(true); }});
|
||||
.destroy({ success: function(){
|
||||
ok(true);
|
||||
start();
|
||||
}});
|
||||
});
|
||||
|
||||
test("#1433 - Save: An invalid model cannot be persisted.", 1, function() {
|
||||
|
||||
212
vendor/backbone/test/router.js
vendored
212
vendor/backbone/test/router.js
vendored
@@ -331,6 +331,36 @@
|
||||
Backbone.history.checkUrl();
|
||||
});
|
||||
|
||||
test("No events are triggered if #execute returns false.", 1, function() {
|
||||
var Router = Backbone.Router.extend({
|
||||
|
||||
routes: {
|
||||
foo: function() {
|
||||
ok(true);
|
||||
}
|
||||
},
|
||||
|
||||
execute: function(callback, args) {
|
||||
callback.apply(this, args);
|
||||
return false;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
var router = new Router;
|
||||
|
||||
router.on('route route:foo', function() {
|
||||
ok(false);
|
||||
});
|
||||
|
||||
Backbone.history.on('route', function() {
|
||||
ok(false);
|
||||
});
|
||||
|
||||
location.replace('http://example.com#foo');
|
||||
Backbone.history.checkUrl();
|
||||
});
|
||||
|
||||
test("#933, #908 - leading slash", 2, function() {
|
||||
location.replace('http://example.com/root/foo');
|
||||
|
||||
@@ -345,14 +375,6 @@
|
||||
strictEqual(Backbone.history.getFragment(), 'foo');
|
||||
});
|
||||
|
||||
test("#1003 - History is started before navigate is called", 1, function() {
|
||||
Backbone.history.stop();
|
||||
Backbone.history.navigate = function(){ ok(Backbone.History.started); };
|
||||
Backbone.history.start();
|
||||
// If this is not an old IE navigate will not be called.
|
||||
if (!Backbone.history.iframe) ok(true);
|
||||
});
|
||||
|
||||
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});
|
||||
@@ -375,7 +397,7 @@
|
||||
Backbone.history.navigate('charñ', {trigger: true});
|
||||
equal(router.charType, 'UTF');
|
||||
Backbone.history.navigate('char%C3%B1', {trigger: true});
|
||||
equal(router.charType, 'escaped');
|
||||
equal(router.charType, 'UTF');
|
||||
});
|
||||
|
||||
test("#1185 - Use pathname when hashChange is not wanted.", 1, function() {
|
||||
@@ -543,7 +565,7 @@
|
||||
Backbone.history.stop();
|
||||
location.replace('http://example.com/root/x/y?a=b');
|
||||
location.replace = function(url) {
|
||||
strictEqual(url, '/root/#x/y?a=b');
|
||||
strictEqual(url, '/root#x/y?a=b');
|
||||
};
|
||||
Backbone.history = _.extend(new Backbone.History, {
|
||||
location: location,
|
||||
@@ -711,6 +733,21 @@
|
||||
Backbone.history.navigate('');
|
||||
});
|
||||
|
||||
test('#2656 - No trailing slash on root.', 1, function() {
|
||||
Backbone.history.stop();
|
||||
Backbone.history = _.extend(new Backbone.History, {
|
||||
location: location,
|
||||
history: {
|
||||
pushState: function(state, title, url){
|
||||
strictEqual(url, '/root?x=1');
|
||||
}
|
||||
}
|
||||
});
|
||||
location.replace('http://example.com/root/path');
|
||||
Backbone.history.start({pushState: true, hashChange: false, root: 'root'});
|
||||
Backbone.history.navigate('?x=1');
|
||||
});
|
||||
|
||||
test('#2765 - Fragment matching sans query/hash.', 2, function() {
|
||||
Backbone.history.stop();
|
||||
Backbone.history = _.extend(new Backbone.History, {
|
||||
@@ -738,12 +775,12 @@
|
||||
var Router = Backbone.Router.extend({
|
||||
routes: {
|
||||
path: function(params){
|
||||
strictEqual(params, 'x=y%20z');
|
||||
strictEqual(params, 'x=y%3Fz');
|
||||
}
|
||||
}
|
||||
});
|
||||
var router = new Router;
|
||||
Backbone.history.navigate('path?x=y%20z', true);
|
||||
Backbone.history.navigate('path?x=y%3Fz', true);
|
||||
});
|
||||
|
||||
test('Navigate to a hash url.', function() {
|
||||
@@ -792,6 +829,22 @@
|
||||
Backbone.history.start({pushState: true});
|
||||
});
|
||||
|
||||
test('unicode pathname with % in a parameter', 1, function() {
|
||||
location.replace('http://example.com/myyjä/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 = _.extend(new Backbone.History, {location: location});
|
||||
var Router = Backbone.Router.extend({
|
||||
routes: {
|
||||
'myyjä/:query': function(query) {
|
||||
strictEqual(query, 'foo %?/@% bar');
|
||||
}
|
||||
}
|
||||
});
|
||||
new Router;
|
||||
Backbone.history.start({pushState: true});
|
||||
});
|
||||
|
||||
test('newline in route', 1, function() {
|
||||
location.replace('http://example.com/stuff%0Anonsense?param=foo%0Abar');
|
||||
Backbone.history.stop();
|
||||
@@ -807,4 +860,139 @@
|
||||
Backbone.history.start({pushState: true});
|
||||
});
|
||||
|
||||
test('Router#execute receives callback, args, name.', 3, function() {
|
||||
location.replace('http://example.com#foo/123/bar?x=y');
|
||||
Backbone.history.stop();
|
||||
Backbone.history = _.extend(new Backbone.History, {location: location});
|
||||
var Router = Backbone.Router.extend({
|
||||
routes: {'foo/:id/bar': 'foo'},
|
||||
foo: function(){},
|
||||
execute: function(callback, args, name) {
|
||||
strictEqual(callback, this.foo);
|
||||
deepEqual(args, ['123', 'x=y']);
|
||||
strictEqual(name, 'foo');
|
||||
}
|
||||
});
|
||||
var router = new Router;
|
||||
Backbone.history.start();
|
||||
});
|
||||
|
||||
test("pushState to hashChange with only search params.", 1, function() {
|
||||
Backbone.history.stop();
|
||||
location.replace('http://example.com?a=b');
|
||||
location.replace = function(url) {
|
||||
strictEqual(url, '/#?a=b');
|
||||
};
|
||||
Backbone.history = _.extend(new Backbone.History, {
|
||||
location: location,
|
||||
history: null
|
||||
});
|
||||
Backbone.history.start({pushState: true});
|
||||
});
|
||||
|
||||
test("#3123 - History#navigate decodes before comparison.", 1, function() {
|
||||
Backbone.history.stop();
|
||||
location.replace('http://example.com/shop/search?keyword=short%20dress');
|
||||
Backbone.history = _.extend(new Backbone.History, {
|
||||
location: location,
|
||||
history: {
|
||||
pushState: function(){ ok(false); },
|
||||
replaceState: function(){ ok(false); }
|
||||
}
|
||||
});
|
||||
Backbone.history.start({pushState: true});
|
||||
Backbone.history.navigate('shop/search?keyword=short%20dress', true);
|
||||
strictEqual(Backbone.history.fragment, 'shop/search?keyword=short dress');
|
||||
});
|
||||
|
||||
test('#3175 - Urls in the params', 1, function() {
|
||||
Backbone.history.stop();
|
||||
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});
|
||||
var router = new Backbone.Router;
|
||||
router.route('login', function(params) {
|
||||
strictEqual(params, 'a=value&backUrl=https%3A%2F%2Fwww.msn.com%2Fidp%2Fidpdemo%3Fspid%3Dspdemo%26target%3Db');
|
||||
});
|
||||
Backbone.history.start();
|
||||
});
|
||||
|
||||
test('#3358 - pushState to hashChange transition with search params', 1, function() {
|
||||
Backbone.history.stop();
|
||||
location.replace('/root?foo=bar');
|
||||
location.replace = function(url) {
|
||||
strictEqual(url, '/root#?foo=bar');
|
||||
};
|
||||
Backbone.history = _.extend(new Backbone.History, {
|
||||
location: location,
|
||||
history: {
|
||||
pushState: undefined,
|
||||
replaceState: undefined
|
||||
}
|
||||
});
|
||||
Backbone.history.start({root: '/root', pushState: true});
|
||||
});
|
||||
|
||||
test("Paths that don't match the root should not match no root", 0, function() {
|
||||
location.replace('http://example.com/foo');
|
||||
Backbone.history.stop();
|
||||
Backbone.history = _.extend(new Backbone.History, {location: location});
|
||||
var Router = Backbone.Router.extend({
|
||||
routes: {
|
||||
foo: function(){
|
||||
ok(false, 'should not match unless root matches');
|
||||
}
|
||||
}
|
||||
});
|
||||
var router = new Router;
|
||||
Backbone.history.start({root: 'root', pushState: true});
|
||||
});
|
||||
|
||||
test("Paths that don't match the root should not match roots of the same length", 0, function() {
|
||||
location.replace('http://example.com/xxxx/foo');
|
||||
Backbone.history.stop();
|
||||
Backbone.history = _.extend(new Backbone.History, {location: location});
|
||||
var Router = Backbone.Router.extend({
|
||||
routes: {
|
||||
foo: function(){
|
||||
ok(false, 'should not match unless root matches');
|
||||
}
|
||||
}
|
||||
});
|
||||
var router = new Router;
|
||||
Backbone.history.start({root: 'root', pushState: true});
|
||||
});
|
||||
|
||||
test("roots with regex characters", 1, function() {
|
||||
location.replace('http://example.com/x+y.z/foo');
|
||||
Backbone.history.stop();
|
||||
Backbone.history = _.extend(new Backbone.History, {location: location});
|
||||
var Router = Backbone.Router.extend({
|
||||
routes: {foo: function(){ ok(true); }}
|
||||
});
|
||||
var router = new Router;
|
||||
Backbone.history.start({root: 'x+y.z', pushState: true});
|
||||
});
|
||||
|
||||
test("roots with unicode characters", 1, function() {
|
||||
location.replace('http://example.com/®ooτ/foo');
|
||||
Backbone.history.stop();
|
||||
Backbone.history = _.extend(new Backbone.History, {location: location});
|
||||
var Router = Backbone.Router.extend({
|
||||
routes: {foo: function(){ ok(true); }}
|
||||
});
|
||||
var router = new Router;
|
||||
Backbone.history.start({root: '®ooτ', pushState: true});
|
||||
});
|
||||
|
||||
test("roots without slash", 1, function() {
|
||||
location.replace('http://example.com/®ooτ');
|
||||
Backbone.history.stop();
|
||||
Backbone.history = _.extend(new Backbone.History, {location: location});
|
||||
var Router = Backbone.Router.extend({
|
||||
routes: {'': function(){ ok(true); }}
|
||||
});
|
||||
var router = new Router;
|
||||
Backbone.history.start({root: '®ooτ', pushState: true});
|
||||
});
|
||||
|
||||
})();
|
||||
|
||||
6
vendor/backbone/test/setup/dom-setup.js
vendored
Normal file
6
vendor/backbone/test/setup/dom-setup.js
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
$('body').append(
|
||||
'<div id="qunit"></div>' +
|
||||
'<div id="qunit-fixture">' +
|
||||
'<div id="testElement"><h1>Test</h1></div>' +
|
||||
'</div>'
|
||||
);
|
||||
13
vendor/backbone/test/sync.js
vendored
13
vendor/backbone/test/sync.js
vendored
@@ -131,7 +131,7 @@
|
||||
|
||||
test("urlError", 2, function() {
|
||||
var model = new Backbone.Model();
|
||||
raises(function() {
|
||||
throws(function() {
|
||||
model.fetch();
|
||||
});
|
||||
model.fetch({url: '/one/two'});
|
||||
@@ -207,4 +207,15 @@
|
||||
strictEqual(this.ajaxSettings.beforeSend(xhr), false);
|
||||
});
|
||||
|
||||
test('#2928 - Pass along `textStatus` and `errorThrown`.', 2, function() {
|
||||
var model = new Backbone.Model;
|
||||
model.url = '/test';
|
||||
model.on('error', function(model, xhr, options) {
|
||||
strictEqual(options.textStatus, 'textStatus');
|
||||
strictEqual(options.errorThrown, 'errorThrown');
|
||||
});
|
||||
model.fetch();
|
||||
this.ajaxSettings.error({}, 'textStatus', 'errorThrown');
|
||||
});
|
||||
|
||||
})();
|
||||
|
||||
128
vendor/backbone/test/view.js
vendored
128
vendor/backbone/test/view.js
vendored
@@ -20,10 +20,22 @@
|
||||
equal(view.el.other, void 0);
|
||||
});
|
||||
|
||||
test("jQuery", 1, function() {
|
||||
test("$", 2, function() {
|
||||
var view = new Backbone.View;
|
||||
view.setElement('<p><a><b>test</b></a></p>');
|
||||
strictEqual(view.$('a b').html(), 'test');
|
||||
var result = view.$('a b');
|
||||
|
||||
strictEqual(result[0].innerHTML, 'test');
|
||||
ok(result.length === +result.length);
|
||||
});
|
||||
|
||||
test("$el", 3, function() {
|
||||
var view = new Backbone.View;
|
||||
view.setElement('<p><a><b>test</b></a></p>');
|
||||
strictEqual(view.el.nodeType, 1);
|
||||
|
||||
ok(view.$el instanceof Backbone.$);
|
||||
strictEqual(view.$el[0], view.el);
|
||||
});
|
||||
|
||||
test("initialize", 1, function() {
|
||||
@@ -60,6 +72,17 @@
|
||||
equal(counter2, 3);
|
||||
});
|
||||
|
||||
test("delegate", 2, function() {
|
||||
var view = new Backbone.View({el: '#testElement'});
|
||||
view.delegate('click', 'h1', function() {
|
||||
ok(true);
|
||||
});
|
||||
view.delegate('click', function() {
|
||||
ok(true);
|
||||
});
|
||||
view.$('h1').trigger('click');
|
||||
});
|
||||
|
||||
test("delegateEvents allows functions for callbacks", 3, function() {
|
||||
var view = new Backbone.View({el: '<p></p>'});
|
||||
view.counter = 0;
|
||||
@@ -114,6 +137,63 @@
|
||||
equal(counter2, 3);
|
||||
});
|
||||
|
||||
test("undelegate", 0, function() {
|
||||
view = new Backbone.View({el: '#testElement'});
|
||||
view.delegate('click', function() { ok(false); });
|
||||
view.delegate('click', 'h1', function() { ok(false); });
|
||||
|
||||
view.undelegate('click');
|
||||
|
||||
view.$('h1').trigger('click');
|
||||
view.$el.trigger('click');
|
||||
});
|
||||
|
||||
test("undelegate with passed handler", 1, function() {
|
||||
view = new Backbone.View({el: '#testElement'});
|
||||
var listener = function() { ok(false); };
|
||||
view.delegate('click', listener);
|
||||
view.delegate('click', function() { ok(true); });
|
||||
view.undelegate('click', listener);
|
||||
view.$el.trigger('click');
|
||||
});
|
||||
|
||||
test("undelegate with selector", 2, function() {
|
||||
view = new Backbone.View({el: '#testElement'});
|
||||
view.delegate('click', function() { ok(true); });
|
||||
view.delegate('click', 'h1', function() { ok(false); });
|
||||
view.undelegate('click', 'h1');
|
||||
view.$('h1').trigger('click');
|
||||
view.$el.trigger('click');
|
||||
});
|
||||
|
||||
test("undelegate with handler and selector", 2, function() {
|
||||
view = new Backbone.View({el: '#testElement'});
|
||||
view.delegate('click', function() { ok(true); });
|
||||
var handler = function(){ ok(false); };
|
||||
view.delegate('click', 'h1', handler);
|
||||
view.undelegate('click', 'h1', handler);
|
||||
view.$('h1').trigger('click');
|
||||
view.$el.trigger('click');
|
||||
});
|
||||
|
||||
test("tagName can be provided as a string", 1, function() {
|
||||
var View = Backbone.View.extend({
|
||||
tagName: 'span'
|
||||
});
|
||||
|
||||
equal(new View().el.tagName, 'SPAN');
|
||||
});
|
||||
|
||||
test("tagName can be provided as a function", 1, function() {
|
||||
var View = Backbone.View.extend({
|
||||
tagName: function() {
|
||||
return 'p';
|
||||
}
|
||||
});
|
||||
|
||||
ok(new View().$el.is('p'));
|
||||
});
|
||||
|
||||
test("_ensureElement with DOM node el", 1, function() {
|
||||
var View = Backbone.View.extend({
|
||||
el: document.body
|
||||
@@ -201,26 +281,19 @@
|
||||
equal(5, count);
|
||||
});
|
||||
|
||||
test("custom events, with namespaces", 2, function() {
|
||||
var count = 0;
|
||||
|
||||
test("custom events", 2, function() {
|
||||
var View = Backbone.View.extend({
|
||||
el: $('body'),
|
||||
events: function() {
|
||||
return {"fake$event.namespaced": "run"};
|
||||
},
|
||||
run: function() {
|
||||
count++;
|
||||
events: {
|
||||
"fake$event": function() { ok(true); }
|
||||
}
|
||||
});
|
||||
|
||||
var view = new View;
|
||||
$('body').trigger('fake$event').trigger('fake$event');
|
||||
equal(count, 2);
|
||||
|
||||
$('body').off('.namespaced');
|
||||
$('body').off('fake$event');
|
||||
$('body').trigger('fake$event');
|
||||
equal(count, 2);
|
||||
});
|
||||
|
||||
test("#1048 - setElement uses provided object.", 2, function() {
|
||||
@@ -264,21 +337,11 @@
|
||||
ok(!view2.el.id);
|
||||
});
|
||||
|
||||
test("#1228 - tagName can be provided as a function", 1, function() {
|
||||
var View = Backbone.View.extend({
|
||||
tagName: function() {
|
||||
return 'p';
|
||||
}
|
||||
});
|
||||
|
||||
ok(new View().$el.is('p'));
|
||||
});
|
||||
|
||||
test("views stopListening", 0, function() {
|
||||
var View = Backbone.View.extend({
|
||||
initialize: function() {
|
||||
this.listenTo(this.model, 'all x', function(){ ok(false); }, this);
|
||||
this.listenTo(this.collection, 'all x', function(){ ok(false); }, this);
|
||||
this.listenTo(this.model, 'all x', function(){ ok(false); });
|
||||
this.listenTo(this.collection, 'all x', function(){ ok(false); });
|
||||
}
|
||||
});
|
||||
|
||||
@@ -324,4 +387,19 @@
|
||||
equal(counter, 2);
|
||||
});
|
||||
|
||||
test("remove", 1, function() {
|
||||
var view = new Backbone.View;
|
||||
document.body.appendChild(view.el);
|
||||
|
||||
view.delegate('click', function() { ok(false); });
|
||||
view.listenTo(view, 'all x', function() { ok(false); });
|
||||
|
||||
view.remove();
|
||||
view.$el.trigger('click');
|
||||
view.trigger('x');
|
||||
|
||||
// In IE8 and below, parentNode still exists but is not document.body.
|
||||
notEqual(view.el.parentNode, document.body);
|
||||
});
|
||||
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user