5 QUnit.module('Backbone.View', {
7 beforeEach: function(assert) {
8 $('#qunit-fixture').append(
9 '<div id="testElement"><h1>Test</h1></div>'
12 view = new Backbone.View({
14 className: 'test-view',
15 other: 'non-special-option'
19 afterEach: function() {
20 $('#testElement').remove();
21 $('#test-view').remove();
26 QUnit.test('constructor', function(assert) {
28 assert.equal(view.el.id, 'test-view');
29 assert.equal(view.el.className, 'test-view');
30 assert.equal(view.el.other, void 0);
33 QUnit.test('$', function(assert) {
35 var myView = new Backbone.View;
36 myView.setElement('<p><a><b>test</b></a></p>');
37 var result = myView.$('a b');
39 assert.strictEqual(result[0].innerHTML, 'test');
40 assert.ok(result.length === +result.length);
43 QUnit.test('$el', function(assert) {
45 var myView = new Backbone.View;
46 myView.setElement('<p><a><b>test</b></a></p>');
47 assert.strictEqual(myView.el.nodeType, 1);
49 assert.ok(myView.$el instanceof Backbone.$);
50 assert.strictEqual(myView.$el[0], myView.el);
53 QUnit.test('initialize', function(assert) {
55 var View = Backbone.View.extend({
56 initialize: function() {
61 assert.strictEqual(new View().one, 1);
64 QUnit.test('render', function(assert) {
66 var myView = new Backbone.View;
67 assert.equal(myView.render(), myView, '#render returns the view instance');
70 QUnit.test('delegateEvents', function(assert) {
72 var counter1 = 0, counter2 = 0;
74 var myView = new Backbone.View({el: '#testElement'});
75 myView.increment = function(){ counter1++; };
76 myView.$el.on('click', function(){ counter2++; });
78 var events = {'click h1': 'increment'};
80 myView.delegateEvents(events);
81 myView.$('h1').trigger('click');
82 assert.equal(counter1, 1);
83 assert.equal(counter2, 1);
85 myView.$('h1').trigger('click');
86 assert.equal(counter1, 2);
87 assert.equal(counter2, 2);
89 myView.delegateEvents(events);
90 myView.$('h1').trigger('click');
91 assert.equal(counter1, 3);
92 assert.equal(counter2, 3);
95 QUnit.test('delegate', function(assert) {
97 var myView = new Backbone.View({el: '#testElement'});
98 myView.delegate('click', 'h1', function() {
101 myView.delegate('click', function() {
104 myView.$('h1').trigger('click');
106 assert.equal(myView.delegate(), myView, '#delegate returns the view instance');
109 QUnit.test('delegateEvents allows functions for callbacks', function(assert) {
111 var myView = new Backbone.View({el: '<p></p>'});
120 myView.delegateEvents(events);
121 myView.$el.trigger('click');
122 assert.equal(myView.counter, 1);
124 myView.$el.trigger('click');
125 assert.equal(myView.counter, 2);
127 myView.delegateEvents(events);
128 myView.$el.trigger('click');
129 assert.equal(myView.counter, 3);
133 QUnit.test('delegateEvents ignore undefined methods', function(assert) {
135 var myView = new Backbone.View({el: '<p></p>'});
136 myView.delegateEvents({'click': 'undefinedMethod'});
137 myView.$el.trigger('click');
140 QUnit.test('undelegateEvents', function(assert) {
142 var counter1 = 0, counter2 = 0;
144 var myView = new Backbone.View({el: '#testElement'});
145 myView.increment = function(){ counter1++; };
146 myView.$el.on('click', function(){ counter2++; });
148 var events = {'click h1': 'increment'};
150 myView.delegateEvents(events);
151 myView.$('h1').trigger('click');
152 assert.equal(counter1, 1);
153 assert.equal(counter2, 1);
155 myView.undelegateEvents();
156 myView.$('h1').trigger('click');
157 assert.equal(counter1, 1);
158 assert.equal(counter2, 2);
160 myView.delegateEvents(events);
161 myView.$('h1').trigger('click');
162 assert.equal(counter1, 2);
163 assert.equal(counter2, 3);
165 assert.equal(myView.undelegateEvents(), myView, '#undelegateEvents returns the view instance');
168 QUnit.test('undelegate', function(assert) {
170 var myView = new Backbone.View({el: '#testElement'});
171 myView.delegate('click', function() { assert.ok(false); });
172 myView.delegate('click', 'h1', function() { assert.ok(false); });
174 myView.undelegate('click');
176 myView.$('h1').trigger('click');
177 myView.$el.trigger('click');
179 assert.equal(myView.undelegate(), myView, '#undelegate returns the view instance');
182 QUnit.test('undelegate with passed handler', function(assert) {
184 var myView = new Backbone.View({el: '#testElement'});
185 var listener = function() { assert.ok(false); };
186 myView.delegate('click', listener);
187 myView.delegate('click', function() { assert.ok(true); });
188 myView.undelegate('click', listener);
189 myView.$el.trigger('click');
192 QUnit.test('undelegate with selector', function(assert) {
194 var myView = new Backbone.View({el: '#testElement'});
195 myView.delegate('click', function() { assert.ok(true); });
196 myView.delegate('click', 'h1', function() { assert.ok(false); });
197 myView.undelegate('click', 'h1');
198 myView.$('h1').trigger('click');
199 myView.$el.trigger('click');
202 QUnit.test('undelegate with handler and selector', function(assert) {
204 var myView = new Backbone.View({el: '#testElement'});
205 myView.delegate('click', function() { assert.ok(true); });
206 var handler = function(){ assert.ok(false); };
207 myView.delegate('click', 'h1', handler);
208 myView.undelegate('click', 'h1', handler);
209 myView.$('h1').trigger('click');
210 myView.$el.trigger('click');
213 QUnit.test('tagName can be provided as a string', function(assert) {
215 var View = Backbone.View.extend({
219 assert.equal(new View().el.tagName, 'SPAN');
222 QUnit.test('tagName can be provided as a function', function(assert) {
224 var View = Backbone.View.extend({
225 tagName: function() {
230 assert.ok(new View().$el.is('p'));
233 QUnit.test('_ensureElement with DOM node el', function(assert) {
235 var View = Backbone.View.extend({
239 assert.equal(new View().el, document.body);
242 QUnit.test('_ensureElement with string el', function(assert) {
244 var View = Backbone.View.extend({
247 assert.strictEqual(new View().el, document.body);
249 View = Backbone.View.extend({
250 el: '#testElement > h1'
252 assert.strictEqual(new View().el, $('#testElement > h1').get(0));
254 View = Backbone.View.extend({
257 assert.ok(!new View().el);
260 QUnit.test('with className and id functions', function(assert) {
262 var View = Backbone.View.extend({
263 className: function() {
271 assert.strictEqual(new View().el.className, 'className');
272 assert.strictEqual(new View().el.id, 'id');
275 QUnit.test('with attributes', function(assert) {
277 var View = Backbone.View.extend({
284 assert.strictEqual(new View().el.className, 'class');
285 assert.strictEqual(new View().el.id, 'id');
288 QUnit.test('with attributes as a function', function(assert) {
290 var View = Backbone.View.extend({
291 attributes: function() {
292 return {'class': 'dynamic'};
296 assert.strictEqual(new View().el.className, 'dynamic');
299 QUnit.test('should default to className/id properties', function(assert) {
301 var View = Backbone.View.extend({
302 className: 'backboneClass',
305 'class': 'attributeClass',
310 var myView = new View;
311 assert.strictEqual(myView.el.className, 'backboneClass');
312 assert.strictEqual(myView.el.id, 'backboneId');
313 assert.strictEqual(myView.$el.attr('class'), 'backboneClass');
314 assert.strictEqual(myView.$el.attr('id'), 'backboneId');
317 QUnit.test('multiple views per element', function(assert) {
320 var $el = $('<p></p>');
322 var View = Backbone.View.extend({
331 var view1 = new View;
332 $el.trigger('click');
333 assert.equal(1, count);
335 var view2 = new View;
336 $el.trigger('click');
337 assert.equal(3, count);
339 view1.delegateEvents();
340 $el.trigger('click');
341 assert.equal(5, count);
344 QUnit.test('custom events', function(assert) {
346 var View = Backbone.View.extend({
349 fake$event: function() { assert.ok(true); }
353 var myView = new View;
354 $('body').trigger('fake$event').trigger('fake$event');
356 $('body').off('fake$event');
357 $('body').trigger('fake$event');
360 QUnit.test('#1048 - setElement uses provided object.', function(assert) {
364 var myView = new Backbone.View({el: $el});
365 assert.ok(myView.$el === $el);
367 myView.setElement($el = $($el));
368 assert.ok(myView.$el === $el);
371 QUnit.test('#986 - Undelegate before changing element.', function(assert) {
373 var button1 = $('<button></button>');
374 var button2 = $('<button></button>');
376 var View = Backbone.View.extend({
379 assert.ok(myView.el === e.target);
384 var myView = new View({el: button1});
385 myView.setElement(button2);
387 button1.trigger('click');
388 button2.trigger('click');
391 QUnit.test('#1172 - Clone attributes object', function(assert) {
393 var View = Backbone.View.extend({
394 attributes: {foo: 'bar'}
397 var view1 = new View({id: 'foo'});
398 assert.strictEqual(view1.el.id, 'foo');
400 var view2 = new View();
401 assert.ok(!view2.el.id);
404 QUnit.test('views stopListening', function(assert) {
406 var View = Backbone.View.extend({
407 initialize: function() {
408 this.listenTo(this.model, 'all x', function(){ assert.ok(false); });
409 this.listenTo(this.collection, 'all x', function(){ assert.ok(false); });
413 var myView = new View({
414 model: new Backbone.Model,
415 collection: new Backbone.Collection
418 myView.stopListening();
419 myView.model.trigger('x');
420 myView.collection.trigger('x');
423 QUnit.test('Provide function for el.', function(assert) {
425 var View = Backbone.View.extend({
427 return '<p><a></a></p>';
431 var myView = new View;
432 assert.ok(myView.$el.is('p'));
433 assert.ok(myView.$el.has('a'));
436 QUnit.test('events passed in options', function(assert) {
440 var View = Backbone.View.extend({
442 increment: function() {
447 var myView = new View({
449 'click h1': 'increment'
453 myView.$('h1').trigger('click').trigger('click');
454 assert.equal(counter, 2);
457 QUnit.test('remove', function(assert) {
459 var myView = new Backbone.View;
460 document.body.appendChild(view.el);
462 myView.delegate('click', function() { assert.ok(false); });
463 myView.listenTo(myView, 'all x', function() { assert.ok(false); });
465 assert.equal(myView.remove(), myView, '#remove returns the view instance');
466 myView.$el.trigger('click');
469 // In IE8 and below, parentNode still exists but is not document.body.
470 assert.notEqual(myView.el.parentNode, document.body);
473 QUnit.test('setElement', function(assert) {
475 var myView = new Backbone.View({
477 click: function() { assert.ok(false); }
481 click: function() { assert.ok(true); }
483 var oldEl = myView.el;
484 var $oldEl = myView.$el;
486 myView.setElement(document.createElement('div'));
491 assert.notEqual(oldEl, myView.el);
492 assert.notEqual($oldEl, myView.$el);