From 54b79e42b95df37aa8df4180f00cfd208bad35ae Mon Sep 17 00:00:00 2001 From: Adam Krebs Date: Wed, 19 Mar 2014 00:56:58 +0200 Subject: [PATCH 01/11] remove remaining jQuery from View tests --- test/view.js | 295 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 183 insertions(+), 112 deletions(-) diff --git a/test/view.js b/test/view.js index 392a50f79..ff8d851b3 100644 --- a/test/view.js +++ b/test/view.js @@ -1,11 +1,14 @@ (function() { + // When testing alternative View implementations, change this varaible. + var View = Backbone.View; + var view; module("Backbone.View", { setup: function() { - view = new Backbone.View({ + view = new View({ id : 'test-view', className : 'test-view', other : 'non-special-option' @@ -21,7 +24,7 @@ }); test("$", 2, function() { - var view = new Backbone.View; + var view = new View; view.setElement('

test

'); var result = view.$('a b'); @@ -29,62 +32,67 @@ ok(result.length === +result.length); }); - test("$el", 3, function() { - var view = new Backbone.View; + + test("$el", function() { + var view = new View; view.setElement('

test

'); strictEqual(view.el.nodeType, 1); - ok(view.$el instanceof Backbone.$); - strictEqual(view.$el[0], view.el); + if (Backbone.$) { + ok(Backbone.$ ? view.$el instanceof Backbone.$ : true); + strictEqual(Backbone.$ ? view.$el[0] : view.el, view.el); + } }); test("initialize", 1, function() { - var View = Backbone.View.extend({ + var Test = View.extend({ initialize: function() { this.one = 1; } }); - strictEqual(new View().one, 1); + strictEqual(new Test().one, 1); }); test("delegateEvents", 6, function() { var counter1 = 0, counter2 = 0; - var view = new Backbone.View({el: '#testElement'}); + var view = new View({el: '#testElement'}); view.increment = function(){ counter1++; }; - view.$el.on('click', function(){ counter2++; }); + addEventListener.call(view.el, 'click', function(){ counter2++; }); var events = {'click h1': 'increment'}; view.delegateEvents(events); - view.$('h1').trigger('click'); + click(view.$('h1')[0]); equal(counter1, 1); equal(counter2, 1); - view.$('h1').trigger('click'); + click(view.$('h1')[0]); equal(counter1, 2); equal(counter2, 2); view.delegateEvents(events); - view.$('h1').trigger('click'); + click(view.$('h1')[0]); equal(counter1, 3); equal(counter2, 3); }); + test("delegate", 2, function() { - var view = new Backbone.View({el: '#testElement'}); + var view = new View({el: '#testElement'}); view.delegate('click', 'h1', function() { ok(true); }); view.delegate('click', function() { ok(true); }); - view.$('h1').trigger('click'); + click(view.$('h1')[0]); }); + test("delegateEvents allows functions for callbacks", 3, function() { - var view = new Backbone.View({el: '

'}); + view = new View({el: '

'}); view.counter = 0; var events = { @@ -93,87 +101,97 @@ } }; + document.body.appendChild(view.el); + view.delegateEvents(events); - view.$el.trigger('click'); + click(view.el); equal(view.counter, 1); - view.$el.trigger('click'); + click(view.el); equal(view.counter, 2); view.delegateEvents(events); - view.$el.trigger('click'); + click(view.el); equal(view.counter, 3); + + document.body.removeChild(view.el); }); test("delegateEvents ignore undefined methods", 0, function() { - var view = new Backbone.View({el: '

'}); + view = new View({el: '

'}); + + document.body.appendChild(view.el); + view.delegateEvents({'click': 'undefinedMethod'}); - view.$el.trigger('click'); + click(view.el); + + document.body.removeChild(view.el); }); test("undelegateEvents", 6, function() { var counter1 = 0, counter2 = 0; - var view = new Backbone.View({el: '#testElement'}); + view = new View({el: '#testElement'}); view.increment = function(){ counter1++; }; - view.$el.on('click', function(){ counter2++; }); + addEventListener.call(view.el, 'click', function(){ counter2++; }); var events = {'click h1': 'increment'}; view.delegateEvents(events); - view.$('h1').trigger('click'); + click(view.$('h1')[0]); equal(counter1, 1); equal(counter2, 1); view.undelegateEvents(); - view.$('h1').trigger('click'); + click(view.$('h1')[0]); equal(counter1, 1); equal(counter2, 2); view.delegateEvents(events); - view.$('h1').trigger('click'); + click(view.$('h1')[0]); equal(counter1, 2); equal(counter2, 3); }); + test("undelegate", 0, function() { - view = new Backbone.View({el: '#testElement'}); + view = new 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'); + click(view.$('h1')[0]); + click(view.el); }); test("undelegate with passed handler", 1, function() { - view = new Backbone.View({el: '#testElement'}); + view = new 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'); + click(view.el); }); test("undelegate with selector", 2, function() { - view = new Backbone.View({el: '#testElement'}); + view = new 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'); + click(view.$('h1')[0]); + click(view.el); }); test("undelegate with handler and selector", 2, function() { - view = new Backbone.View({el: '#testElement'}); + view = new 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'); + click(view.$('h1')[0]); + click(view.el); }); test("tagName can be provided as a string", 1, function() { @@ -191,36 +209,39 @@ } }); - ok(new View().$el.is('p')); + equal(new View().el.tagName, 'P'); }); test("_ensureElement with DOM node el", 1, function() { - var View = Backbone.View.extend({ + var Test = View.extend({ el: document.body }); - equal(new View().el, document.body); + equal(new Test().el, document.body); }); test("_ensureElement with string el", 3, function() { - var View = Backbone.View.extend({ + var Test = View.extend({ el: "body" }); - strictEqual(new View().el, document.body); + strictEqual(new Test().el, document.body); - View = Backbone.View.extend({ + Test = View.extend({ el: "#testElement > h1" }); - strictEqual(new View().el, $("#testElement > h1").get(0)); + var h1 = _.filter(document.getElementById('testElement').childNodes, function(node) { + return node.nodeType == 1; + })[0]; + strictEqual(new Test().el, h1); - View = Backbone.View.extend({ + Test = View.extend({ el: "#nonexistent" }); - ok(!new View().el); + ok(!new Test().el); }); test("with className and id functions", 2, function() { - var View = Backbone.View.extend({ + var Test = View.extend({ className: function() { return 'className'; }, @@ -229,38 +250,38 @@ } }); - strictEqual(new View().el.className, 'className'); - strictEqual(new View().el.id, 'id'); + strictEqual(new Test().el.className, 'className'); + strictEqual(new Test().el.id, 'id'); }); test("with attributes", 2, function() { - var View = Backbone.View.extend({ + var Test = View.extend({ attributes: { id: 'id', 'class': 'class' } }); - strictEqual(new View().el.className, 'class'); - strictEqual(new View().el.id, 'id'); + strictEqual(new Test().el.className, 'class'); + strictEqual(new Test().el.id, 'id'); }); test("with attributes as a function", 1, function() { - var View = Backbone.View.extend({ + var Test = View.extend({ attributes: function() { return {'class': 'dynamic'}; } }); - strictEqual(new View().el.className, 'dynamic'); + strictEqual(new Test().el.className, 'dynamic'); }); test("multiple views per element", 3, function() { var count = 0; - var $el = $('

'); + var el = document.createElement('p'); - var View = Backbone.View.extend({ - el: $el, + var Test = View.extend({ + el: el, events: { click: function() { count++; @@ -268,84 +289,103 @@ } }); - var view1 = new View; - $el.trigger("click"); + document.body.appendChild(el); + + var view1 = new Test; + click(el); equal(1, count); - var view2 = new View; - $el.trigger("click"); + var view2 = new Test; + click(el); equal(3, count); view1.delegateEvents(); - $el.trigger("click"); + click(el); equal(5, count); + + document.body.removeChild(el); }); - test("custom events", 2, function() { - var View = Backbone.View.extend({ - el: $('body'), - events: { - "fake$event": function() { ok(true); } - } - }); + if (Backbone.$) { + test("custom events", 2, function() { + var count = 0; - var view = new View; - $('body').trigger('fake$event').trigger('fake$event'); + var Test = View.extend({ + el: 'body', + events: function() { + return {"fake$event": "run"}; + }, + run: function() { + count++; + } + }); - $('body').off('fake$event'); - $('body').trigger('fake$event'); - }); + var view = new Test; + $('body').trigger('fake$event').trigger('fake$event'); + equal(count, 2); + + $('body').off('fake$event'); + $('body').trigger('fake$event'); + equal(count, 2); + }); + } test("#1048 - setElement uses provided object.", 2, function() { - var $el = $('body'); + var el = document.body; - var view = new Backbone.View({el: $el}); - ok(view.$el === $el); + view = new View({el: el}); + ok(view.el === el); - view.setElement($el = $($el)); - ok(view.$el === $el); + view.setElement(el = document.body); + ok(view.el === el); }); test("#986 - Undelegate before changing element.", 1, function() { - var button1 = $(''); - var button2 = $(''); + var button1 = document.createElement('button'); + var button2 = document.createElement('button'); - var View = Backbone.View.extend({ + document.body.appendChild(button1); + document.body.appendChild(button2); + + var Test = View.extend({ events: { click: function(e) { - ok(view.el === e.target); + ok(view.el === e.target || e.srcElement); } } }); - var view = new View({el: button1}); + var view = new Test({el: button1}); view.setElement(button2); - button1.trigger('click'); - button2.trigger('click'); + click(button1); + click(button2); + + document.body.removeChild(button1); + document.body.removeChild(button2); }); test("#1172 - Clone attributes object", 2, function() { - var View = Backbone.View.extend({ + var Test = View.extend({ attributes: {foo: 'bar'} }); - var view1 = new View({id: 'foo'}); + var view1 = new Test({id: 'foo'}); strictEqual(view1.el.id, 'foo'); - var view2 = new View(); + var view2 = new Test(); ok(!view2.el.id); }); test("views stopListening", 0, function() { - var View = Backbone.View.extend({ + var Test = View.extend({ initialize: function() { - this.listenTo(this.model, 'all x', function(){ ok(false); }); - this.listenTo(this.collection, 'all x', function(){ ok(false); }); + this.listenTo(this.model, 'all x', function(){ ok(false); }, this); + this.listenTo(this.collection, 'all x', function(){ ok(false); }, this); } }); - var view = new View({ + var view = new Test({ model: new Backbone.Model, collection: new Backbone.Collection }); @@ -356,50 +396,81 @@ }); test("Provide function for el.", 2, function() { - var View = Backbone.View.extend({ + var Test = View.extend({ el: function() { return "

"; } }); + var view = new Test; + ok(view.el.tagName.toLowerCase() == 'p'); + ok(view.$('a').length != 0); + }); + + test("remove", 1, function() { var view = new View; - ok(view.$el.is('p')); - ok(view.$el.has('a')); + document.body.appendChild(view.el); + + view.delegate('click', function() { ok(false); }); + view.listenTo(view, 'all x', function() { ok(false); }); + + view.remove(); + click(view.el); + view.trigger('x'); + + // In IE8 and below, parentNode still exists but is not document.body. + notEqual(view.el.parentNode, document.body); }); test("events passed in options", 1, function() { var counter = 0; - var View = Backbone.View.extend({ + var Test = View.extend({ el: '#testElement', increment: function() { counter++; } }); - var view = new View({ + var view = new Test({ events: { 'click h1': 'increment' } }); - view.$('h1').trigger('click').trigger('click'); + click(view.$('h1')[0]); + click(view.$('h1')[0]); 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'); + // Cross-browser helpers + var addEventListener = typeof Element != 'undefined' && Element.prototype.addEventListener || function(eventName, listener) { + return this.attachEvent('on' + eventName, listener); + }; + + function click(element) { + var event; + if (document.createEvent) { + event = document.createEvent('MouseEvent'); + var args = [ + 'click', true, true, + // IE 10+ and Firefox require these + event.view, event.detail, event.screenX, event.screenY, event.clientX, + event.clientY, event.ctrlKey, event.altKey, event.shiftKey, + event.metaKey, event.button, event.relatedTarget + ]; + (event.initMouseEvent || event.initEvent).apply(event, args); + } else { + event = document.createEventObject(); + event.type = 'click'; + event.bubbles = true; + event.cancelable = true; + } - // In IE8 and below, parentNode still exists but is not document.body. - notEqual(view.el.parentNode, document.body); - }); + if (element.dispatchEvent) { + return element.dispatchEvent(event); + } + element.fireEvent('onclick', event); + } })(); From 10c0b2e4429faac51dcc5ff4ab508924954160e7 Mon Sep 17 00:00:00 2001 From: Adam Krebs Date: Wed, 19 Mar 2014 01:03:00 +0200 Subject: [PATCH 02/11] use native CustomEvent constructor for DOM element --- test/view.js | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/test/view.js b/test/view.js index ff8d851b3..03f594c56 100644 --- a/test/view.js +++ b/test/view.js @@ -306,29 +306,29 @@ document.body.removeChild(el); }); - if (Backbone.$) { - test("custom events", 2, function() { - var count = 0; - - var Test = View.extend({ - el: 'body', - events: function() { - return {"fake$event": "run"}; - }, - run: function() { - count++; - } - }); - - var view = new Test; - $('body').trigger('fake$event').trigger('fake$event'); - equal(count, 2); + test("custom events", 2, function() { + var count = 0; - $('body').off('fake$event'); - $('body').trigger('fake$event'); - equal(count, 2); + var Test = View.extend({ + el: 'body', + events: function() { + return {"fake$event": "run"}; + }, + run: function() { + count++; + } }); - } + + var view = new Test; + var event = new CustomEvent("fake$event"); + document.body.dispatchEvent(event); + document.body.dispatchEvent(event); + equal(count, 2); + + view.undelegate("fake$event"); + document.body.dispatchEvent(event); + equal(count, 2); + }); test("#1048 - setElement uses provided object.", 2, function() { var el = document.body; From 235fcc9ac8a88d17dafa642febddc83e8d6b7464 Mon Sep 17 00:00:00 2001 From: Adam Krebs Date: Wed, 19 Mar 2014 15:25:36 +0200 Subject: [PATCH 03/11] remove superfluous this from listento --- test/view.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/view.js b/test/view.js index 03f594c56..9224bd5d1 100644 --- a/test/view.js +++ b/test/view.js @@ -380,8 +380,8 @@ test("views stopListening", 0, function() { var Test = 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); }); } }); From 93b3eb561b2d8964b42d34e627d9bf8dcee19658 Mon Sep 17 00:00:00 2001 From: Adam Krebs Date: Wed, 19 Mar 2014 15:34:23 +0200 Subject: [PATCH 04/11] break out trigger shim --- test/view.js | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/test/view.js b/test/view.js index 9224bd5d1..1d3a81d38 100644 --- a/test/view.js +++ b/test/view.js @@ -321,12 +321,11 @@ var view = new Test; var event = new CustomEvent("fake$event"); - document.body.dispatchEvent(event); - document.body.dispatchEvent(event); + trigger(document.body, event, 'fake$event'); equal(count, 2); view.undelegate("fake$event"); - document.body.dispatchEvent(event); + trigger(document.body, event, 'fake$event'); equal(count, 2); }); @@ -444,10 +443,20 @@ }); // Cross-browser helpers - var addEventListener = typeof Element != 'undefined' && Element.prototype.addEventListener || function(eventName, listener) { + var ElementProto = (typeof Element != 'undefined' && Element.prototype) || {}; + + var addEventListener = ElementProto.addEventListener || function(eventName, listener) { return this.attachEvent('on' + eventName, listener); }; + function trigger(element, event, eventName) { + if (element.dispatchEvent) { + element.dispatchEvent(event); + } else { + element.fireEvent(eventName, event); + } + } + function click(element) { var event; if (document.createEvent) { @@ -466,11 +475,7 @@ event.bubbles = true; event.cancelable = true; } - - if (element.dispatchEvent) { - return element.dispatchEvent(event); - } - element.fireEvent('onclick', event); + trigger(element, event, 'onclick'); } })(); From e4e5852247d17e8880f5d13baf1f211830465067 Mon Sep 17 00:00:00 2001 From: Adam Krebs Date: Wed, 19 Mar 2014 15:44:59 +0200 Subject: [PATCH 05/11] fix typo --- test/view.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/view.js b/test/view.js index 1d3a81d38..c787db36f 100644 --- a/test/view.js +++ b/test/view.js @@ -1,6 +1,6 @@ (function() { - // When testing alternative View implementations, change this varaible. + // When testing alternative View implementations, change this variable. var View = Backbone.View; var view; From 9b2081fdd1d82b12da9ebd5bc9921773ae3e735f Mon Sep 17 00:00:00 2001 From: Adam Krebs Date: Wed, 19 Mar 2014 15:48:54 +0200 Subject: [PATCH 06/11] shorter filterer fn with findWhere --- test/view.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/view.js b/test/view.js index c787db36f..3fcad26bc 100644 --- a/test/view.js +++ b/test/view.js @@ -229,9 +229,8 @@ Test = View.extend({ el: "#testElement > h1" }); - var h1 = _.filter(document.getElementById('testElement').childNodes, function(node) { - return node.nodeType == 1; - })[0]; + var children = document.getElementById('testElement').childNodes; + var h1 = _.findWhere(children, {nodeType: 1}); strictEqual(new Test().el, h1); Test = View.extend({ From ec574673b128bca86fc97f982305c18ed08d99fc Mon Sep 17 00:00:00 2001 From: Adam Krebs Date: Wed, 19 Mar 2014 16:19:14 +0200 Subject: [PATCH 07/11] remove extra Backbone.$ checks --- test/view.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/view.js b/test/view.js index 3fcad26bc..a6edef686 100644 --- a/test/view.js +++ b/test/view.js @@ -39,8 +39,8 @@ strictEqual(view.el.nodeType, 1); if (Backbone.$) { - ok(Backbone.$ ? view.$el instanceof Backbone.$ : true); - strictEqual(Backbone.$ ? view.$el[0] : view.el, view.el); + ok(view.$el instanceof Backbone.$); + strictEqual(view.$el[0], view.el); } }); From 71ce73e3b37d01d03ce672b8e74a54442aadf634 Mon Sep 17 00:00:00 2001 From: Adam Krebs Date: Thu, 20 Mar 2014 00:15:37 +0200 Subject: [PATCH 08/11] change back View -> Backbone.View --- test/view.js | 103 +++++++++++++++++++++++++-------------------------- 1 file changed, 50 insertions(+), 53 deletions(-) diff --git a/test/view.js b/test/view.js index a6edef686..f52abf477 100644 --- a/test/view.js +++ b/test/view.js @@ -1,14 +1,10 @@ (function() { - - // When testing alternative View implementations, change this variable. - var View = Backbone.View; - var view; module("Backbone.View", { setup: function() { - view = new View({ + view = new Backbone.View({ id : 'test-view', className : 'test-view', other : 'non-special-option' @@ -24,7 +20,7 @@ }); test("$", 2, function() { - var view = new View; + var view = new Backbone.View; view.setElement('

test

'); var result = view.$('a b'); @@ -34,7 +30,7 @@ test("$el", function() { - var view = new View; + var view = new Backbone.View; view.setElement('

test

'); strictEqual(view.el.nodeType, 1); @@ -45,19 +41,19 @@ }); test("initialize", 1, function() { - var Test = View.extend({ + var View = Backbone.View.extend({ initialize: function() { this.one = 1; } }); - strictEqual(new Test().one, 1); + strictEqual(new View().one, 1); }); test("delegateEvents", 6, function() { var counter1 = 0, counter2 = 0; - var view = new View({el: '#testElement'}); + var view = new Backbone.View({el: '#testElement'}); view.increment = function(){ counter1++; }; addEventListener.call(view.el, 'click', function(){ counter2++; }); @@ -80,7 +76,7 @@ test("delegate", 2, function() { - var view = new View({el: '#testElement'}); + var view = new Backbone.View({el: '#testElement'}); view.delegate('click', 'h1', function() { ok(true); }); @@ -92,7 +88,7 @@ test("delegateEvents allows functions for callbacks", 3, function() { - view = new View({el: '

'}); + var view = new Backbone.View({el: '

'}); view.counter = 0; var events = { @@ -119,7 +115,7 @@ test("delegateEvents ignore undefined methods", 0, function() { - view = new View({el: '

'}); + var view = new Backbone.View({el: '

'}); document.body.appendChild(view.el); @@ -132,7 +128,7 @@ test("undelegateEvents", 6, function() { var counter1 = 0, counter2 = 0; - view = new View({el: '#testElement'}); + var view = new Backbone.View({el: '#testElement'}); view.increment = function(){ counter1++; }; addEventListener.call(view.el, 'click', function(){ counter2++; }); @@ -156,7 +152,7 @@ test("undelegate", 0, function() { - view = new View({el: '#testElement'}); + var view = new Backbone.View({el: '#testElement'}); view.delegate('click', function() { ok(false); }); view.delegate('click', 'h1', function() { ok(false); }); @@ -167,7 +163,7 @@ }); test("undelegate with passed handler", 1, function() { - view = new View({el: '#testElement'}); + var view = new Backbone.View({el: '#testElement'}); var listener = function() { ok(false); }; view.delegate('click', listener); view.delegate('click', function() { ok(true); }); @@ -176,7 +172,7 @@ }); test("undelegate with selector", 2, function() { - view = new View({el: '#testElement'}); + var view = new Backbone.View({el: '#testElement'}); view.delegate('click', function() { ok(true); }); view.delegate('click', 'h1', function() { ok(false); }); view.undelegate('click', 'h1'); @@ -185,7 +181,7 @@ }); test("undelegate with handler and selector", 2, function() { - view = new View({el: '#testElement'}); + var view = new Backbone.View({el: '#testElement'}); view.delegate('click', function() { ok(true); }); var handler = function(){ ok(false); }; view.delegate('click', 'h1', handler); @@ -213,34 +209,34 @@ }); test("_ensureElement with DOM node el", 1, function() { - var Test = View.extend({ + var View = Backbone.View.extend({ el: document.body }); - equal(new Test().el, document.body); + equal(new View().el, document.body); }); test("_ensureElement with string el", 3, function() { - var Test = View.extend({ + var View = Backbone.View.extend({ el: "body" }); - strictEqual(new Test().el, document.body); + strictEqual(new View().el, document.body); - Test = View.extend({ + View = View.extend({ el: "#testElement > h1" }); var children = document.getElementById('testElement').childNodes; var h1 = _.findWhere(children, {nodeType: 1}); - strictEqual(new Test().el, h1); + strictEqual(new View().el, h1); - Test = View.extend({ + View = Backbone.View.extend({ el: "#nonexistent" }); - ok(!new Test().el); + ok(!new View().el); }); test("with className and id functions", 2, function() { - var Test = View.extend({ + var View = Backbone.View.extend({ className: function() { return 'className'; }, @@ -249,37 +245,37 @@ } }); - strictEqual(new Test().el.className, 'className'); - strictEqual(new Test().el.id, 'id'); + strictEqual(new View().el.className, 'className'); + strictEqual(new View().el.id, 'id'); }); test("with attributes", 2, function() { - var Test = View.extend({ + var View = Backbone.View.extend({ attributes: { id: 'id', 'class': 'class' } }); - strictEqual(new Test().el.className, 'class'); - strictEqual(new Test().el.id, 'id'); + strictEqual(new View().el.className, 'class'); + strictEqual(new View().el.id, 'id'); }); test("with attributes as a function", 1, function() { - var Test = View.extend({ + var View = Backbone.View.extend({ attributes: function() { return {'class': 'dynamic'}; } }); - strictEqual(new Test().el.className, 'dynamic'); + strictEqual(new View().el.className, 'dynamic'); }); test("multiple views per element", 3, function() { var count = 0; var el = document.createElement('p'); - var Test = View.extend({ + var View = Backbone.View.extend({ el: el, events: { click: function() { @@ -290,11 +286,11 @@ document.body.appendChild(el); - var view1 = new Test; + var view1 = new View; click(el); equal(1, count); - var view2 = new Test; + var view2 = new View; click(el); equal(3, count); @@ -308,7 +304,7 @@ test("custom events", 2, function() { var count = 0; - var Test = View.extend({ + var View = Backbone.View.extend({ el: 'body', events: function() { return {"fake$event": "run"}; @@ -318,9 +314,10 @@ } }); - var view = new Test; + var view = new View; var event = new CustomEvent("fake$event"); trigger(document.body, event, 'fake$event'); + trigger(document.body, event, 'fake$event'); equal(count, 2); view.undelegate("fake$event"); @@ -331,7 +328,7 @@ test("#1048 - setElement uses provided object.", 2, function() { var el = document.body; - view = new View({el: el}); + var view = new Backbone.View({el: el}); ok(view.el === el); view.setElement(el = document.body); @@ -345,7 +342,7 @@ document.body.appendChild(button1); document.body.appendChild(button2); - var Test = View.extend({ + var View = Backbone.View.extend({ events: { click: function(e) { ok(view.el === e.target || e.srcElement); @@ -353,7 +350,7 @@ } }); - var view = new Test({el: button1}); + var view = new View({el: button1}); view.setElement(button2); click(button1); @@ -364,26 +361,26 @@ }); test("#1172 - Clone attributes object", 2, function() { - var Test = View.extend({ + var View = Backbone.View.extend({ attributes: {foo: 'bar'} }); - var view1 = new Test({id: 'foo'}); + var view1 = new View({id: 'foo'}); strictEqual(view1.el.id, 'foo'); - var view2 = new Test(); + var view2 = new View(); ok(!view2.el.id); }); test("views stopListening", 0, function() { - var Test = View.extend({ + var View = Backbone.View.extend({ initialize: function() { this.listenTo(this.model, 'all x', function(){ ok(false); }); this.listenTo(this.collection, 'all x', function(){ ok(false); }); } }); - var view = new Test({ + var view = new View({ model: new Backbone.Model, collection: new Backbone.Collection }); @@ -394,19 +391,19 @@ }); test("Provide function for el.", 2, function() { - var Test = View.extend({ + var View = Backbone.View.extend({ el: function() { return "

"; } }); - var view = new Test; - ok(view.el.tagName.toLowerCase() == 'p'); + var view = new View; + ok(view.el.tagName == 'P'); ok(view.$('a').length != 0); }); test("remove", 1, function() { - var view = new View; + var view = new Backbone.View; document.body.appendChild(view.el); view.delegate('click', function() { ok(false); }); @@ -423,14 +420,14 @@ test("events passed in options", 1, function() { var counter = 0; - var Test = View.extend({ + var View = Backbone.View.extend({ el: '#testElement', increment: function() { counter++; } }); - var view = new Test({ + var view = new View({ events: { 'click h1': 'increment' } From aecb76ccbfd9430855c582fbabb3bb1729912138 Mon Sep 17 00:00:00 2001 From: Adam Krebs Date: Thu, 20 Mar 2014 00:19:47 +0200 Subject: [PATCH 09/11] remove setup method --- test/view.js | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/test/view.js b/test/view.js index f52abf477..3d92812c2 100644 --- a/test/view.js +++ b/test/view.js @@ -1,19 +1,14 @@ (function() { var view; - module("Backbone.View", { - - setup: function() { - view = new Backbone.View({ - id : 'test-view', - className : 'test-view', - other : 'non-special-option' - }); - } - - }); + module("Backbone.View"); test("constructor", 3, function() { + var view = new Backbone.View({ + id : 'test-view', + className : 'test-view', + other : 'non-special-option' + }); equal(view.el.id, 'test-view'); equal(view.el.className, 'test-view'); equal(view.el.other, void 0); From f724fa13c4587febd6a6ddfa7b65b7024bbf8947 Mon Sep 17 00:00:00 2001 From: Adam Krebs Date: Thu, 20 Mar 2014 14:54:19 +0200 Subject: [PATCH 10/11] remove extra lines and small fixes --- test/view.js | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/test/view.js b/test/view.js index 3d92812c2..f3095c2ff 100644 --- a/test/view.js +++ b/test/view.js @@ -1,6 +1,4 @@ (function() { - var view; - module("Backbone.View"); test("constructor", 3, function() { @@ -23,7 +21,6 @@ ok(result.length === +result.length); }); - test("$el", function() { var view = new Backbone.View; view.setElement('

test

'); @@ -69,7 +66,6 @@ equal(counter2, 3); }); - test("delegate", 2, function() { var view = new Backbone.View({el: '#testElement'}); view.delegate('click', 'h1', function() { @@ -81,7 +77,6 @@ click(view.$('h1')[0]); }); - test("delegateEvents allows functions for callbacks", 3, function() { var view = new Backbone.View({el: '

'}); view.counter = 0; @@ -108,7 +103,6 @@ document.body.removeChild(view.el); }); - test("delegateEvents ignore undefined methods", 0, function() { var view = new Backbone.View({el: '

'}); @@ -145,7 +139,6 @@ equal(counter2, 3); }); - test("undelegate", 0, function() { var view = new Backbone.View({el: '#testElement'}); view.delegate('click', function() { ok(false); }); @@ -217,7 +210,7 @@ }); strictEqual(new View().el, document.body); - View = View.extend({ + View = Backbone.View.extend({ el: "#testElement > h1" }); var children = document.getElementById('testElement').childNodes; From 2efebb36ec6d4a4b6f8fe11f74d075cf5a46fea9 Mon Sep 17 00:00:00 2001 From: Adam Krebs Date: Fri, 4 Apr 2014 12:16:41 -0400 Subject: [PATCH 11/11] wrap custom events test in a Backbone.$ check --- test/view.js | 52 ++++++++++++++++++++++------------------------------ 1 file changed, 22 insertions(+), 30 deletions(-) diff --git a/test/view.js b/test/view.js index f3095c2ff..5a9644c4f 100644 --- a/test/view.js +++ b/test/view.js @@ -289,29 +289,25 @@ document.body.removeChild(el); }); - test("custom events", 2, function() { - var count = 0; + if (Backbone.$) { + test("custom events", 1, function() { + var View = Backbone.View.extend({ + el: 'body', + events: function() { + return {"fake$event": "run"}; + }, + run: function() { + ok(true); + } + }); - var View = Backbone.View.extend({ - el: 'body', - events: function() { - return {"fake$event": "run"}; - }, - run: function() { - count++; - } - }); + var view = new View; + Backbone.$('body').trigger('fake$event'); - var view = new View; - var event = new CustomEvent("fake$event"); - trigger(document.body, event, 'fake$event'); - trigger(document.body, event, 'fake$event'); - equal(count, 2); - - view.undelegate("fake$event"); - trigger(document.body, event, 'fake$event'); - equal(count, 2); - }); + view.undelegate("fake$event"); + Backbone.$('body').trigger('fake$event'); + }); + } test("#1048 - setElement uses provided object.", 2, function() { var el = document.body; @@ -433,14 +429,6 @@ return this.attachEvent('on' + eventName, listener); }; - function trigger(element, event, eventName) { - if (element.dispatchEvent) { - element.dispatchEvent(event); - } else { - element.fireEvent(eventName, event); - } - } - function click(element) { var event; if (document.createEvent) { @@ -459,7 +447,11 @@ event.bubbles = true; event.cancelable = true; } - trigger(element, event, 'onclick'); + if (element.dispatchEvent) { + element.dispatchEvent(event); + } else { + element.fireEvent(eventName, event); + } } })();