Update Backbone tests to 1.1.1.

This commit is contained in:
John-David Dalton
2014-02-15 14:32:56 -08:00
parent 486ba5fe0a
commit 88d5f5d76c
8 changed files with 300 additions and 121 deletions

View File

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

View File

@@ -1,20 +1,36 @@
// Backbone.js 1.1.0
// Backbone.js 1.1.1
// (c) 2010-2011 Jeremy Ashkenas, DocumentCloud Inc.
// (c) 2011-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
// (c) 2010-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
// Backbone may be freely distributed under the MIT license.
// For all details and documentation:
// http://backbonejs.org
(function(){
(function(root, factory) {
// Set up Backbone appropriately for the environment. Start with AMD.
if (typeof define === 'function' && define.amd) {
define(['underscore', 'jquery', 'exports'], function(_, $, exports) {
// Export global even in AMD case in case this script is loaded with
// others that may still expect a global Backbone.
root.Backbone = factory(root, exports, _, $);
});
// Next for Node.js or CommonJS. jQuery may not be needed as a module.
} else if (typeof exports !== 'undefined') {
var _ = require('underscore'), $;
try { $ = require('jquery'); } catch(e) {}
factory(root, exports, _, $);
// Finally, as a browser global.
} else {
root.Backbone = factory(root, {}, root._, (root.jQuery || root.Zepto || root.ender || root.$));
}
}(this, function(root, Backbone, _, $) {
// Initial Setup
// -------------
// Save a reference to the global object (`window` in the browser, `exports`
// on the server).
var root = this;
// Save the previous value of the `Backbone` variable, so that it can be
// restored later on, if `noConflict` is used.
var previousBackbone = root.Backbone;
@@ -25,25 +41,12 @@
var slice = array.slice;
var splice = array.splice;
// The top-level namespace. All public Backbone classes and modules will
// be attached to this. Exported for both the browser and the server.
var Backbone;
if (typeof exports !== 'undefined') {
Backbone = exports;
} else {
Backbone = root.Backbone = {};
}
// Current version of the library. Keep in sync with `package.json`.
Backbone.VERSION = '1.1.0';
// Require Underscore, if we're on the server, and it's not already present.
var _ = root._;
if (!_ && (typeof require !== 'undefined')) _ = require('underscore');
Backbone.VERSION = '1.1.1';
// For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns
// the `$` variable.
Backbone.$ = root.jQuery || root.Zepto || root.ender || root.$;
Backbone.$ = $;
// Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable
// to its previous owner. Returns a reference to this Backbone object.
@@ -109,7 +112,7 @@
var retain, ev, events, names, i, l, j, k;
if (!this._events || !eventsApi(this, 'off', name, [callback, context])) return this;
if (!name && !callback && !context) {
this._events = {};
this._events = void 0;
return this;
}
names = name ? [name] : _.keys(this._events);
@@ -205,7 +208,7 @@
case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;
case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;
case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;
default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args);
default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args); return;
}
};
@@ -350,7 +353,7 @@
// Trigger all relevant attribute changes.
if (!silent) {
if (changes.length) this._pending = true;
if (changes.length) this._pending = options;
for (var i = 0, l = changes.length; i < l; i++) {
this.trigger('change:' + changes[i], this, current[changes[i]], options);
}
@@ -361,6 +364,7 @@
if (changing) return this;
if (!silent) {
while (this._pending) {
options = this._pending;
this._pending = false;
this.trigger('change', this, options);
}
@@ -528,9 +532,12 @@
// using Backbone's restful methods, override this to change the endpoint
// that will be called.
url: function() {
var base = _.result(this, 'urlRoot') || _.result(this.collection, 'url') || urlError();
var base =
_.result(this, 'urlRoot') ||
_.result(this.collection, 'url') ||
urlError();
if (this.isNew()) return base;
return base + (base.charAt(base.length - 1) === '/' ? '' : '/') + encodeURIComponent(this.id);
return base.replace(/([^\/])$/, '$1/') + encodeURIComponent(this.id);
},
// **parse** converts a response into the hash of attributes to be `set` on
@@ -546,7 +553,7 @@
// A model is new if it has never been saved to the server, and lacks an id.
isNew: function() {
return this.id == null;
return !this.has(this.idAttribute);
},
// Check if the model is currently in a valid state.
@@ -650,7 +657,7 @@
options.index = index;
model.trigger('remove', model, this, options);
}
this._removeReference(model);
this._removeReference(model, options);
}
return singular ? models[0] : models;
},
@@ -676,11 +683,11 @@
// Turn bare objects into model references, and prevent invalid models
// from being added.
for (i = 0, l = models.length; i < l; i++) {
attrs = models[i];
attrs = models[i] || {};
if (attrs instanceof Model) {
id = model = attrs;
} else {
id = attrs[targetModel.prototype.idAttribute];
id = attrs[targetModel.prototype.idAttribute || 'id'];
}
// If a duplicate is found, prevent it from being added and
@@ -700,14 +707,13 @@
model = models[i] = this._prepareModel(attrs, options);
if (!model) continue;
toAdd.push(model);
// Listen to added models' events, and index models for lookup by
// `id` and by `cid`.
model.on('all', this._onModelEvent, this);
this._byId[model.cid] = model;
if (model.id != null) this._byId[model.id] = model;
this._addReference(model, options);
}
if (order) order.push(existing || model);
// Do not add multiple models with the same `id`.
model = existing || model;
if (order && (model.isNew() || !modelMap[model.id])) order.push(model);
modelMap[model.id] = true;
}
// Remove nonexistent models if appropriate.
@@ -745,7 +751,7 @@
}
if (sort || (order && order.length)) this.trigger('sort', this, options);
}
// Return the added (or merged) model (or models).
return singular ? models[0] : models;
},
@@ -757,7 +763,7 @@
reset: function(models, options) {
options || (options = {});
for (var i = 0, l = this.models.length; i < l; i++) {
this._removeReference(this.models[i]);
this._removeReference(this.models[i], options);
}
options.previousModels = this.models;
this._reset();
@@ -798,7 +804,7 @@
// Get a model from the set by id.
get: function(obj) {
if (obj == null) return void 0;
return this._byId[obj.id] || this._byId[obj.cid] || this._byId[obj];
return this._byId[obj] || this._byId[obj.id] || this._byId[obj.cid];
},
// Get the model at the given index.
@@ -874,7 +880,7 @@
if (!options.wait) this.add(model, options);
var collection = this;
var success = options.success;
options.success = function(model, resp, options) {
options.success = function(model, resp) {
if (options.wait) collection.add(model, options);
if (success) success(model, resp, options);
};
@@ -904,10 +910,7 @@
// Prepare a hash of attributes (or other model) to be added to this
// collection.
_prepareModel: function(attrs, options) {
if (attrs instanceof Model) {
if (!attrs.collection) attrs.collection = this;
return attrs;
}
if (attrs instanceof Model) return attrs;
options = options ? _.clone(options) : {};
options.collection = this;
var model = new this.model(attrs, options);
@@ -916,8 +919,16 @@
return false;
},
// Internal method to create a model's ties to a collection.
_addReference: function(model, options) {
this._byId[model.cid] = model;
if (model.id != null) this._byId[model.id] = model;
if (!model.collection) model.collection = this;
model.on('all', this._onModelEvent, this);
},
// Internal method to sever a model's ties to a collection.
_removeReference: function(model) {
_removeReference: function(model, options) {
if (this === model.collection) delete model.collection;
model.off('all', this._onModelEvent, this);
},
@@ -946,7 +957,7 @@
'reject', 'every', 'all', 'some', 'any', 'include', 'contains', 'invoke',
'max', 'min', 'toArray', 'size', 'first', 'head', 'take', 'initial', 'rest',
'tail', 'drop', 'last', 'without', 'difference', 'indexOf', 'shuffle',
'lastIndexOf', 'isEmpty', 'chain'];
'lastIndexOf', 'isEmpty', 'chain', 'sample'];
// Mix in each Underscore method as a proxy to `Collection#models`.
_.each(methods, function(method) {
@@ -958,7 +969,7 @@
});
// Underscore methods that take a property name as an argument.
var attributeMethods = ['groupBy', 'countBy', 'sortBy'];
var attributeMethods = ['groupBy', 'countBy', 'sortBy', 'indexBy'];
// Use attributes instead of properties.
_.each(attributeMethods, function(method) {
@@ -1180,7 +1191,9 @@
return xhr;
};
var noXhrPatch = typeof window !== 'undefined' && !!window.ActiveXObject && !(window.XMLHttpRequest && (new XMLHttpRequest).dispatchEvent);
var noXhrPatch =
typeof window !== 'undefined' && !!window.ActiveXObject &&
!(window.XMLHttpRequest && (new XMLHttpRequest).dispatchEvent);
// Map from CRUD to HTTP for our default `Backbone.sync` implementation.
var methodMap = {
@@ -1239,7 +1252,7 @@
var router = this;
Backbone.history.route(route, function(fragment) {
var args = router._extractParameters(route, fragment);
callback && callback.apply(router, args);
router.execute(callback, args);
router.trigger.apply(router, ['route:' + name].concat(args));
router.trigger('route', name, args);
Backbone.history.trigger('route', router, name, args);
@@ -1247,6 +1260,12 @@
return this;
},
// Execute a route handler with the provided parameters. This is an
// excellent place to do pre-route setup or post-route cleanup.
execute: function(callback, args) {
if (callback) callback.apply(this, args);
},
// Simple proxy to `Backbone.history` to save a fragment into the history.
navigate: function(fragment, options) {
Backbone.history.navigate(fragment, options);
@@ -1271,10 +1290,10 @@
route = route.replace(escapeRegExp, '\\$&')
.replace(optionalParam, '(?:$1)?')
.replace(namedParam, function(match, optional) {
return optional ? match : '([^\/]+)';
return optional ? match : '([^/?]+)';
})
.replace(splatParam, '(.*?)');
return new RegExp('^' + route + '$');
.replace(splatParam, '([^?]*?)');
return new RegExp('^' + route + '(?:\\?(.*))?$');
},
// Given a route, and a URL fragment that it matches, return the array of
@@ -1282,7 +1301,9 @@
// treated as `null` to normalize cross-browser behavior.
_extractParameters: function(route, fragment) {
var params = route.exec(fragment).slice(1);
return _.map(params, function(param) {
return _.map(params, function(param, i) {
// Don't decode the search params.
if (i === params.length - 1) return param || null;
return param ? decodeURIComponent(param) : null;
});
}
@@ -1320,8 +1341,8 @@
// Cached regex for removing a trailing slash.
var trailingSlash = /\/$/;
// Cached regex for stripping urls of hash and query.
var pathStripper = /[?#].*$/;
// Cached regex for stripping urls of hash.
var pathStripper = /#.*$/;
// Has the history handling already been started?
History.started = false;
@@ -1333,6 +1354,11 @@
// twenty times a second.
interval: 50,
// Are we at the app root?
atRoot: function() {
return this.location.pathname.replace(/[^\/]$/, '$&/') === this.root;
},
// Gets the true hash value. Cannot use location.hash directly due to bug
// in Firefox where location.hash will always be decoded.
getHash: function(window) {
@@ -1345,7 +1371,7 @@
getFragment: function(fragment, forcePushState) {
if (fragment == null) {
if (this._hasPushState || !this._wantsHashChange || forcePushState) {
fragment = this.location.pathname;
fragment = decodeURI(this.location.pathname + this.location.search);
var root = this.root.replace(trailingSlash, '');
if (!fragment.indexOf(root)) fragment = fragment.slice(root.length);
} else {
@@ -1376,7 +1402,8 @@
this.root = ('/' + this.root + '/').replace(rootStripper, '/');
if (oldIE && this._wantsHashChange) {
this.iframe = Backbone.$('<iframe src="javascript:0" tabindex="-1" />').hide().appendTo('body')[0].contentWindow;
var frame = Backbone.$('<iframe src="javascript:0" tabindex="-1">');
this.iframe = frame.hide().appendTo('body')[0].contentWindow;
this.navigate(fragment);
}
@@ -1394,7 +1421,6 @@
// opened by a non-pushState browser.
this.fragment = fragment;
var loc = this.location;
var atRoot = loc.pathname.replace(/[^\/]$/, '$&/') === this.root;
// Transition from hashChange to pushState or vice versa if both are
// requested.
@@ -1402,17 +1428,17 @@
// 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...
if (!this._hasPushState && !atRoot) {
if (!this._hasPushState && !this.atRoot()) {
this.fragment = this.getFragment(null, true);
this.location.replace(this.root + this.location.search + '#' + this.fragment);
this.location.replace(this.root + '#' + this.fragment);
// Return immediately as browser will do redirect to new url
return true;
// Or if we've started out with a hash-based route, but we're currently
// in a browser where it could be `pushState`-based instead...
} else if (this._hasPushState && atRoot && loc.hash) {
} else if (this._hasPushState && this.atRoot() && loc.hash) {
this.fragment = this.getHash().replace(routeStripper, '');
this.history.replaceState({}, document.title, this.root + this.fragment + loc.search);
this.history.replaceState({}, document.title, this.root + this.fragment);
}
}
@@ -1472,7 +1498,7 @@
var url = this.root + (fragment = this.getFragment(fragment || ''));
// Strip the fragment of the query and hash for matching.
// Strip the hash for matching.
fragment = fragment.replace(pathStripper, '');
if (this.fragment === fragment) return;
@@ -1578,4 +1604,6 @@
};
};
}).call(this);
return Backbone;
}));

View File

@@ -85,6 +85,11 @@
equal(col2.get(model.clone()), col2.first());
});
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();
col.add([
@@ -107,7 +112,7 @@
equal(col.pluck('label').join(' '), 'a b c d');
});
test("add", 10, function() {
test("add", 14, function() {
var added, opts, secondAdded;
added = opts = secondAdded = null;
e = new Backbone.Model({id: 10, label : 'e'});
@@ -136,6 +141,18 @@
equal(atCol.length, 4);
equal(atCol.at(1), e);
equal(atCol.last(), h);
var coll = new Backbone.Collection(new Array(2));
var addCount = 0;
coll.on('add', function(){
addCount += 1;
});
coll.add([undefined, f, g]);
equal(coll.length, 5);
equal(addCount, 3);
coll.add(new Array(4));
equal(coll.length, 9);
equal(addCount, 7);
});
test("add multiple models", 6, function() {
@@ -535,7 +552,7 @@
equal(coll.findWhere({a: 4}), void 0);
});
test("Underscore methods", 14, function() {
test("Underscore methods", 16, function() {
equal(col.map(function(model){ return model.get('label'); }).join(' '), 'a b c d');
equal(col.any(function(model){ return model.id === 100; }), false);
equal(col.any(function(model){ return model.id === 0; }), true);
@@ -554,9 +571,12 @@
.value(),
[4, 0]);
deepEqual(col.difference([c, d]), [a, b]);
ok(col.include(col.sample()));
var first = col.first();
ok(col.indexBy('id')[first.id] === first);
});
test("reset", 12, function() {
test("reset", 16, function() {
var resetCount = 0;
var models = col.models;
col.on('reset', function() { resetCount += 1; });
@@ -576,6 +596,15 @@
col.reset();
equal(col.length, 0);
equal(resetCount, 4);
var f = new Backbone.Model({id: 20, label : 'f'});
col.reset([undefined, f]);
equal(col.length, 2);
equal(resetCount, 5);
col.reset(new Array(4));
equal(col.length, 4);
equal(resetCount, 6);
});
test ("reset with different values", function(){
@@ -942,20 +971,6 @@
strictEqual(c.length, 0);
});
test("set with many models does not overflow the stack", function() {
var n = 150000;
var collection = new Backbone.Collection();
var models = [];
for (var i = 0; i < n; i++) {
models.push({id: i});
}
collection.set(models);
equal(collection.length, n);
collection.reset();
collection.set(models, {at: 0});
equal(collection.length, n);
});
test("set with only cids", 3, function() {
var m1 = new Backbone.Model;
var m2 = new Backbone.Model;
@@ -1274,4 +1289,50 @@
equal(job.items.get(2).subItems.get(3).get('subName'), 'NewThree');
});
test('_addReference binds all collection events & adds to the lookup hashes', 9, function() {
var calls = {add: 0, remove: 0};
var Collection = Backbone.Collection.extend({
_addReference: function(model) {
Backbone.Collection.prototype._addReference.apply(this, arguments);
calls.add++;
equal(model, this._byId[model.id]);
equal(model, this._byId[model.cid]);
equal(model._events.all.length, 1);
},
_removeReference: function(model) {
Backbone.Collection.prototype._removeReference.apply(this, arguments);
calls.remove++;
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);
}
});
var collection = new Collection();
var model = collection.add({id: 1});
collection.remove(model);
equal(calls.add, 1);
equal(calls.remove, 1);
});
test('Do not allow duplicate models to be `add`ed or `set`', function() {
var c = new Backbone.Collection();
c.add([{id: 1}, {id: 1}]);
equal(c.length, 1);
equal(c.models.length, 1);
c.set([{id: 1}, {id: 1}]);
equal(c.length, 1);
equal(c.models.length, 1);
});
})();

View File

@@ -4,10 +4,16 @@
var ajax = Backbone.ajax;
var emulateHTTP = Backbone.emulateHTTP;
var emulateJSON = Backbone.emulateJSON;
var history = window.history;
var pushState = history.pushState;
var replaceState = history.replaceState;
QUnit.testStart(function() {
var env = this.config.current.testEnvironment;
// We never want to actually call these during tests.
history.pushState = history.replaceState = function(){};
// Capture ajax settings for comparison.
Backbone.ajax = function(settings) {
env.ajaxSettings = settings;
@@ -30,6 +36,8 @@
Backbone.ajax = ajax;
Backbone.emulateHTTP = emulateHTTP;
Backbone.emulateJSON = emulateJSON;
history.pushState = pushState;
history.replaceState = replaceState;
});
})();

View File

@@ -305,7 +305,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');
throws(function() {
raises(function() {
view.trigger('test');
});
});

View File

@@ -262,6 +262,26 @@
model.set({result: void 0});
});
test("nested set triggers with the correct options", function() {
var model = new Backbone.Model();
var o1 = {};
var o2 = {};
var o3 = {};
model.on('change', function(__, options) {
switch (model.get('a')) {
case 1:
equal(options, o1);
return model.set('a', 2, o2);
case 2:
equal(options, o2);
return model.set('a', 3, o3);
case 3:
equal(options, o3);
}
});
model.set('a', 1, o1);
});
test("multiple unsets", 1, function() {
var i = 0;
var counter = function(){ i++; };

View File

@@ -5,10 +5,10 @@
var lastRoute = null;
var lastArgs = [];
function onRoute(router, route, args) {
var onRoute = function(router, route, args) {
lastRoute = route;
lastArgs = args;
}
};
var Location = function(href) {
this.replace(href);
@@ -16,8 +16,11 @@
_.extend(Location.prototype, {
parser: document.createElement('a'),
replace: function(href) {
_.extend(this, _.pick($('<a></a>', {href: href})[0],
this.parser.href = href;
_.extend(this, _.pick(this.parser,
'href',
'hash',
'host',
@@ -64,7 +67,7 @@
this.value = value;
}
};
_.bindAll(ExternalObject);
_.bindAll(ExternalObject, 'routingFunction');
var Router = Backbone.Router.extend({
@@ -87,7 +90,7 @@
":repo/compare/*from...*to": "github",
"decode/:named/*splat": "decode",
"*first/complex-*part/*rest": "complex",
":entity?*args": "query",
"query/:entity": "query",
"function/:value": ExternalObject.routingFunction,
"*anything": "anything"
},
@@ -208,6 +211,11 @@
equal(router.page, '20');
});
test("routes via navigate with params", 1, function() {
Backbone.history.navigate('query/test?a=b', {trigger: true});
equal(router.queryArgs, 'a=b');
});
test("routes via navigate for backwards-compatibility", 2, function() {
Backbone.history.navigate('search/manhattan/p20', true);
equal(router.query, 'manhattan');
@@ -285,7 +293,7 @@
});
test("routes (query)", 5, function() {
location.replace('http://example.com#mandel?a=b&c=d');
location.replace('http://example.com#query/mandel?a=b&c=d');
Backbone.history.checkUrl();
equal(router.entity, 'mandel');
equal(router.queryArgs, 'a=b&c=d');
@@ -535,7 +543,7 @@
Backbone.history.stop();
location.replace('http://example.com/root/x/y?a=b');
location.replace = function(url) {
strictEqual(url, '/root/?a=b#x/y');
strictEqual(url, '/root/#x/y?a=b');
};
Backbone.history = _.extend(new Backbone.History, {
location: location,
@@ -552,7 +560,7 @@
test("#1695 - hashChange to pushState with search.", 1, function() {
Backbone.history.stop();
location.replace('http://example.com/root?a=b#x/y');
location.replace('http://example.com/root#x/y?a=b');
Backbone.history = _.extend(new Backbone.History, {
location: location,
history: {
@@ -601,7 +609,7 @@
test("#2062 - Trigger 'route' event on router instance.", 2, function() {
router.on('route', function(name, args) {
strictEqual(name, 'routeEvent');
deepEqual(args, ['x']);
deepEqual(args, ['x', null]);
});
location.replace('http://example.com#route-event/x');
Backbone.history.checkUrl();
@@ -684,7 +692,7 @@
}
});
location.replace('http://example.com/root/path');
Backbone.history.start({pushState: true, root: 'root'});
Backbone.history.start({pushState: true, hashChange: false, root: 'root'});
Backbone.history.navigate('');
});
@@ -699,7 +707,7 @@
}
});
location.replace('http://example.com/path');
Backbone.history.start({pushState: true});
Backbone.history.start({pushState: true, hashChange: false});
Backbone.history.navigate('');
});
@@ -722,8 +730,66 @@
var router = new Router;
location.replace('http://example.com/');
Backbone.history.start({pushState: true});
Backbone.history.start({pushState: true, hashChange: false});
Backbone.history.navigate('path?query#hash', true);
});
test('Do not decode the search params.', function() {
var Router = Backbone.Router.extend({
routes: {
path: function(params){
strictEqual(params, 'x=y%20z');
}
}
});
var router = new Router;
Backbone.history.navigate('path?x=y%20z', true);
});
test('Navigate to a hash url.', function() {
Backbone.history.stop();
Backbone.history = _.extend(new Backbone.History, {location: location});
Backbone.history.start({pushState: true});
var Router = Backbone.Router.extend({
routes: {
path: function(params) {
strictEqual(params, 'x=y');
}
}
});
var router = new Router;
location.replace('http://example.com/path?x=y#hash');
Backbone.history.checkUrl();
});
test('#navigate to a hash url.', function() {
Backbone.history.stop();
Backbone.history = _.extend(new Backbone.History, {location: location});
Backbone.history.start({pushState: true});
var Router = Backbone.Router.extend({
routes: {
path: function(params) {
strictEqual(params, 'x=y');
}
}
});
var router = new Router;
Backbone.history.navigate('path?x=y#hash', true);
});
test('unicode pathname', 1, function() {
location.replace('http://example.com/myyjä');
Backbone.history.stop();
Backbone.history = _.extend(new Backbone.History, {location: location});
var Router = Backbone.Router.extend({
routes: {
myyjä: function() {
ok(true);
}
}
});
var router = new Router;
Backbone.history.start({pushState: true});
});
})();

View File

@@ -39,23 +39,23 @@
test("delegateEvents", 6, function() {
var counter1 = 0, counter2 = 0;
var view = new Backbone.View({el: '<p><a id="test"></a></p>'});
var view = new Backbone.View({el: '#testElement'});
view.increment = function(){ counter1++; };
view.$el.on('click', function(){ counter2++; });
var events = {'click #test': 'increment'};
var events = {'click h1': 'increment'};
view.delegateEvents(events);
view.$('#test').trigger('click');
view.$('h1').trigger('click');
equal(counter1, 1);
equal(counter2, 1);
view.$('#test').trigger('click');
view.$('h1').trigger('click');
equal(counter1, 2);
equal(counter2, 2);
view.delegateEvents(events);
view.$('#test').trigger('click');
view.$('h1').trigger('click');
equal(counter1, 3);
equal(counter2, 3);
});
@@ -92,24 +92,24 @@
test("undelegateEvents", 6, function() {
var counter1 = 0, counter2 = 0;
var view = new Backbone.View({el: '<p><a id="test"></a></p>'});
var view = new Backbone.View({el: '#testElement'});
view.increment = function(){ counter1++; };
view.$el.on('click', function(){ counter2++; });
var events = {'click #test': 'increment'};
var events = {'click h1': 'increment'};
view.delegateEvents(events);
view.$('#test').trigger('click');
view.$('h1').trigger('click');
equal(counter1, 1);
equal(counter2, 1);
view.undelegateEvents();
view.$('#test').trigger('click');
view.$('h1').trigger('click');
equal(counter1, 1);
equal(counter2, 2);
view.delegateEvents(events);
view.$('#test').trigger('click');
view.$('h1').trigger('click');
equal(counter1, 2);
equal(counter2, 3);
});
@@ -218,7 +218,7 @@
$('body').trigger('fake$event').trigger('fake$event');
equal(count, 2);
$('body').unbind('.namespaced');
$('body').off('.namespaced');
$('body').trigger('fake$event');
equal(count, 2);
});
@@ -304,28 +304,24 @@
ok(view.$el.has('a'));
});
test("events passed in options", 2, function() {
test("events passed in options", 1, function() {
var counter = 0;
var View = Backbone.View.extend({
el: '<p><a id="test"></a></p>',
el: '#testElement',
increment: function() {
counter++;
}
});
var view = new View({events:{'click #test':'increment'}});
var view2 = new View({events:function(){
return {'click #test':'increment'};
}});
var view = new View({
events: {
'click h1': 'increment'
}
});
view.$('#test').trigger('click');
view2.$('#test').trigger('click');
view.$('h1').trigger('click').trigger('click');
equal(counter, 2);
view.$('#test').trigger('click');
view2.$('#test').trigger('click');
equal(counter, 4);
});
})();