From 24eeb7e7f605bf6ebd6f487b2d1ba24aca151064 Mon Sep 17 00:00:00 2001 From: wesmangum Date: Fri, 10 Nov 2017 12:19:36 -0600 Subject: [PATCH] refactor and reorganize view trigger and entity events unit tests --- test/unit/view.entity-events.spec.js | 229 ++++++++++++++++----------- test/unit/view.triggers.spec.js | 189 +++++++++++++--------- 2 files changed, 248 insertions(+), 170 deletions(-) diff --git a/test/unit/view.entity-events.spec.js b/test/unit/view.entity-events.spec.js index 4e23302b3a..331c6f2d32 100644 --- a/test/unit/view.entity-events.spec.js +++ b/test/unit/view.entity-events.spec.js @@ -1,237 +1,274 @@ +import _ from 'underscore'; +import Backbone from 'backbone'; +import View from '../../src/view'; + describe('view entity events', function() { 'use strict'; + let model; + let collection; + let fooStub; + let barStub; + let modelEventsStub + let collectionEventsStub; + beforeEach(function() { - this.model = new Backbone.Model(); - this.collection = new Backbone.Collection(); + model = new Backbone.Model(); + collection = new Backbone.Collection(); - this.fooStub = this.sinon.stub(); - this.barStub = this.sinon.stub(); + fooStub = this.sinon.stub(); + barStub = this.sinon.stub(); - this.modelEventsStub = this.sinon.stub().returns({'foo': this.fooStub}); - this.collectionEventsStub = this.sinon.stub().returns({'bar': this.barStub}); + modelEventsStub = this.sinon.stub().returns({'foo': fooStub}); + collectionEventsStub = this.sinon.stub().returns({'bar': barStub}); }); describe('when a view has string-based model and collection event configuration', function() { + let fooOneStub; + let fooTwoStub; + let barOneStub; + let barTwoStub; + let TestView; + beforeEach(function() { - this.fooOneStub = this.sinon.stub(); - this.fooTwoStub = this.sinon.stub(); - this.barOneStub = this.sinon.stub(); - this.barTwoStub = this.sinon.stub(); + fooOneStub = this.sinon.stub(); + fooTwoStub = this.sinon.stub(); + barOneStub = this.sinon.stub(); + barTwoStub = this.sinon.stub(); - this.View = Marionette.View.extend({ + TestView = View.extend({ modelEvents: {'foo': 'fooOne fooTwo'}, collectionEvents: {'bar': 'barOne barTwo'}, - fooOne: this.fooOneStub, - fooTwo: this.fooTwoStub, - barOne: this.barOneStub, - barTwo: this.barTwoStub + fooOne: fooOneStub, + fooTwo: fooTwoStub, + barOne: barOneStub, + barTwo: barTwoStub }); - this.view = new this.View({ - model: this.model, - collection: this.collection + new TestView({ + model: model, + collection: collection }); }); it('should wire up model events', function() { - this.model.trigger('foo'); - expect(this.fooOneStub).to.have.been.calledOnce; - expect(this.fooTwoStub).to.have.been.calledOnce; + model.trigger('foo'); + expect(fooOneStub).to.have.been.calledOnce; + expect(fooTwoStub).to.have.been.calledOnce; }); it('should wire up collection events', function() { - this.collection.trigger('bar'); - expect(this.barOneStub).to.have.been.calledOnce; - expect(this.barTwoStub).to.have.been.calledOnce; + collection.trigger('bar'); + expect(barOneStub).to.have.been.calledOnce; + expect(barTwoStub).to.have.been.calledOnce; }); }); describe('when a view has function-based model and collection event configuration', function() { + let TestView; + beforeEach(function() { - this.View = Marionette.View.extend({ - modelEvents: {'foo': this.fooStub}, - collectionEvents: {'bar': this.barStub} + TestView = View.extend({ + modelEvents: {'foo': fooStub}, + collectionEvents: {'bar': barStub} }); - this.view = new this.View({ - model: this.model, - collection: this.collection + new TestView({ + model: model, + collection: collection }); }); it('should wire up model events', function() { - this.model.trigger('foo'); - expect(this.fooStub).to.have.been.calledOnce; + model.trigger('foo'); + expect(fooStub).to.have.been.calledOnce; }); it('should wire up collection events', function() { - this.collection.trigger('bar'); - expect(this.barStub).to.have.been.calledOnce; + collection.trigger('bar'); + expect(barStub).to.have.been.calledOnce; }); }); describe('when a view has model event config with a specified handler method that doesnt exist', function() { - beforeEach(function() { - var suite = this; + let MyView; + let getBadViewInstance; - this.View = Marionette.View.extend({ + beforeEach(function() { + MyView = View.extend({ modelEvents: {foo: 'doesNotExist'}, - model: this.model + model: model }); - this.getBadViewInstance = function() { - return new suite.View(); + getBadViewInstance = function() { + return new MyView(); }; }); it('should error when method doesnt exist', function() { - var errorMessage = 'Method "doesNotExist" was configured as an event handler, but does not exist.'; - expect(this.getBadViewInstance).to.throw(errorMessage); + const errorMessage = 'Method "doesNotExist" was configured as an event handler, but does not exist.'; + expect(getBadViewInstance).to.throw(errorMessage); }); }); describe('when configuring entity events with a function', function() { + let TestView; + let view; + beforeEach(function() { - this.View = Marionette.View.extend({ - modelEvents: this.modelEventsStub, - collectionEvents: this.collectionEventsStub + TestView = View.extend({ + modelEvents: modelEventsStub, + collectionEvents: collectionEventsStub }); - this.view = new this.View({ - model: this.model, - collection: this.collection + view = new TestView({ + model: model, + collection: collection }); }); it('should trigger the model event', function() { - this.view.model.trigger('foo'); - expect(this.fooStub).to.have.been.calledOnce; + view.model.trigger('foo'); + expect(fooStub).to.have.been.calledOnce; }); it('should trigger the collection event', function() { - this.view.collection.trigger('bar'); - expect(this.barStub).to.have.been.calledOnce; + view.collection.trigger('bar'); + expect(barStub).to.have.been.calledOnce; }); }); describe('when undelegating entity events on a view', function() { + let TestView; + let view; + beforeEach(function() { - this.View = Marionette.View.extend({ + TestView = View.extend({ modelEvents: {'foo': 'foo'}, collectionEvents: {'bar': 'bar'}, - foo: this.fooStub, - bar: this.barStub + foo: fooStub, + bar: barStub }); - this.view = new this.View({ - model: this.model, - collection: this.collection + view = new TestView({ + model: model, + collection: collection }); - this.sinon.spy(this.view, 'undelegateEntityEvents'); - this.view.undelegateEntityEvents(); + this.sinon.spy(view, 'undelegateEntityEvents'); + view.undelegateEntityEvents(); - this.model.trigger('foo'); - this.collection.trigger('bar'); + model.trigger('foo'); + collection.trigger('bar'); }); it('should undelegate the model events', function() { - expect(this.fooStub).not.to.have.been.calledOnce; + expect(fooStub).not.to.have.been.calledOnce; }); it('should undelegate the collection events', function() { - expect(this.barStub).not.to.have.been.calledOnce; + expect(barStub).not.to.have.been.calledOnce; }); it('should return the view', function() { - expect(this.view.undelegateEntityEvents).to.have.returned(this.view); + expect(view.undelegateEntityEvents).to.have.returned(view); }); }); describe('when undelegating events on a view, delegating them again, and then triggering a model event', function() { + let TestView; + let view; + beforeEach(function() { - this.View = Marionette.View.extend({ + TestView = View.extend({ modelEvents: {'foo': 'foo'}, collectionEvents: {'bar': 'bar'}, - foo: this.fooStub, - bar: this.barStub + foo: fooStub, + bar: barStub }); - this.view = new this.View({ - model: this.model, - collection: this.collection + view = new TestView({ + model: model, + collection: collection }); - this.view.undelegateEntityEvents(); - this.sinon.spy(this.view, 'delegateEntityEvents'); - this.view.delegateEntityEvents(); + view.undelegateEntityEvents(); + this.sinon.spy(view, 'delegateEntityEvents'); + view.delegateEntityEvents(); }); it('should fire the model event once', function() { - this.model.trigger('foo'); - expect(this.fooStub).to.have.been.calledOnce; + model.trigger('foo'); + expect(fooStub).to.have.been.calledOnce; }); it('should fire the collection event once', function() { - this.collection.trigger('bar'); - expect(this.barStub).to.have.been.calledOnce; + collection.trigger('bar'); + expect(barStub).to.have.been.calledOnce; }); it('should return the view from delegateEntityEvents', function() { - expect(this.view.delegateEntityEvents).to.have.returned(this.view); + expect(view.delegateEntityEvents).to.have.returned(view); }); }); describe('when View bound to modelEvent replaces region with new view', function() { + let Layout; + let TestView; + let layoutView; + let itemViewOne; + let itemViewTwo; + beforeEach(function() { - this.Layout = Marionette.View.extend({ + Layout = View.extend({ template: _.template('
'), regions: {child: '#child'}, modelEvents: {'baz': 'foo'}, - foo: this.fooStub + foo: fooStub }); - this.View = Marionette.View.extend({ + TestView = View.extend({ template: _.template('bar'), modelEvents: {'baz': 'bar'}, - bar: this.barStub + bar: barStub }); - this.layoutView = new this.Layout({model: this.model}); - this.itemViewOne = new this.View({model: this.model}); - this.itemViewTwo = new this.View({model: this.model}); + layoutView = new Layout({model: model}); + itemViewOne = new TestView({model: model}); + itemViewTwo = new TestView({model: model}); - this.layoutView.render(); - this.layoutView.getRegion('child').show(this.itemViewOne); - this.layoutView.getRegion('child').show(this.itemViewTwo); + layoutView.render(); + layoutView.getRegion('child').show(itemViewOne); + layoutView.getRegion('child').show(itemViewTwo); - this.model.trigger('baz'); + model.trigger('baz'); }); it('should leave the layoutView\'s modelEvent binded', function() { - expect(this.fooStub).to.have.been.calledOnce; + expect(fooStub).to.have.been.calledOnce; }); it('should unbind the previous child view\'s modelEvents', function() { - expect(this.barStub).to.have.been.calledOnce; + expect(barStub).to.have.been.calledOnce; }); }); // Fixes https://github.com/marionettejs/backbone.marionette/issues/3527 describe('when entity events are added in initialize', function() { + let view; + it('should not undelegate them', function() { - const View = Marionette.View.extend({ + let TestView = View.extend({ template: false, initialize() { - this.listenTo(this.model, 'foo', this.onFoo); + this.listenTo(model, 'foo', this.onFoo); }, onFoo: this.sinon.stub() }); - const model = new Backbone.Model(); + model = new Backbone.Model(); - const view = new View({ model }); + view = new TestView({ model }); model.trigger('foo'); diff --git a/test/unit/view.triggers.spec.js b/test/unit/view.triggers.spec.js index 520d167bcd..54a757204d 100644 --- a/test/unit/view.triggers.spec.js +++ b/test/unit/view.triggers.spec.js @@ -1,109 +1,138 @@ +import Backbone from 'backbone'; +import { setEnabled } from '../../src/config/features'; +import View from '../../src/view'; + describe('view triggers', function() { 'use strict'; + let triggersHash; + let eventsHash; + let fooHandlerStub; + let barHandlerStub; + let fooEvent; + let barEvent; + beforeEach(function() { - this.triggersHash = {'foo': 'fooHandler'}; - this.eventsHash = {'bar': 'barHandler'}; + triggersHash = {'foo': 'fooHandler'}; + eventsHash = {'bar': 'barHandler'}; - this.fooHandlerStub = this.sinon.stub(); - this.barHandlerStub = this.sinon.stub(); + fooHandlerStub = this.sinon.stub(); + barHandlerStub = this.sinon.stub(); - this.fooEvent = $.Event('foo'); - this.barEvent = $.Event('bar'); + fooEvent = $.Event('foo'); + barEvent = $.Event('bar'); }); describe('when DOM events are configured to trigger a view event, and the DOM events are fired', function() { + let model; + let collection; + let TestView; + let view; + beforeEach(function() { - this.model = new Backbone.Model(); - this.collection = new Backbone.Collection(); + model = new Backbone.Model(); + collection = new Backbone.Collection(); - this.View = Marionette.View.extend({triggers: this.triggersHash}); - this.view = new this.View({ - model: this.model, - collection: this.collection + TestView = View.extend({triggers: triggersHash}); + view = new TestView({ + model: model, + collection: collection }); - this.view.on('fooHandler', this.fooHandlerStub); - this.view.$el.trigger(this.fooEvent); + view.on('fooHandler', fooHandlerStub); + view.$el.trigger(fooEvent); }); it('should trigger the first view event', function() { - expect(this.fooHandlerStub).to.have.been.calledOnce; + expect(fooHandlerStub).to.have.been.calledOnce; }); it('should include the view in the event', function() { - expect(this.fooHandlerStub.lastCall.args[0]).to.contain(this.view); + expect(fooHandlerStub.lastCall.args[0]).to.contain(view); }); it('should include the event object in the event', function() { - expect(this.fooHandlerStub.lastCall.args[1]).to.be.an.instanceOf($.Event); + expect(fooHandlerStub.lastCall.args[1]).to.be.an.instanceOf($.Event); }); }); describe('when triggers and standard events are both configured', function() { + let TestView; + let view; + beforeEach(function() { - this.View = Marionette.View.extend({ - triggers: this.triggersHash, - events: this.eventsHash, - barHandler: this.barHandlerStub + TestView = View.extend({ + triggers: triggersHash, + events: eventsHash, + barHandler: barHandlerStub }); - this.view = new this.View(); - this.view.on('fooHandler', this.fooHandlerStub); + view = new TestView(); + view.on('fooHandler', fooHandlerStub); - this.view.$el.trigger(this.fooEvent); - this.view.$el.trigger(this.barEvent); + view.$el.trigger(fooEvent); + view.$el.trigger(barEvent); }); it('should fire the trigger', function() { - expect(this.fooHandlerStub).to.have.been.calledOnce; + expect(fooHandlerStub).to.have.been.calledOnce; }); it('should fire the standard event', function() { - expect(this.barHandlerStub).to.have.been.calledOnce; + expect(barHandlerStub).to.have.been.calledOnce; }); }); describe('when triggers are configured with a function', function() { + let triggersStub; + let TestView; + let view; + beforeEach(function() { - this.triggersStub = this.sinon.stub().returns(this.triggersHash); - this.View = Marionette.View.extend({triggers: this.triggersStub}); - this.view = new this.View(); - this.view.on('fooHandler', this.fooHandlerStub); + triggersStub = this.sinon.stub().returns(triggersHash); + TestView = View.extend({triggers: triggersStub}); + view = new TestView(); + view.on('fooHandler', fooHandlerStub); - this.view.$el.trigger(this.fooEvent); + view.$el.trigger(fooEvent); }); it('should call the function', function() { - expect(this.triggersStub).to.have.been.calledOnce.and.calledOn(this.view); + expect(triggersStub).to.have.been.calledOnce.and.calledOn(view); }); it('should trigger the first view event', function() { - expect(this.fooHandlerStub).to.have.been.calledOnce; + expect(fooHandlerStub).to.have.been.calledOnce; }); }); describe('triggers should stop propagation and events by default', function() { + let TestView; + let view; + beforeEach(function() { - this.View = Marionette.View.extend({triggers: this.triggersHash}); - this.view = new this.View(); - this.view.on('fooHandler', this.fooHandlerStub); + TestView = View.extend({triggers: triggersHash}); + view = new TestView(); + view.on('fooHandler', fooHandlerStub); - this.view.$el.trigger(this.fooEvent); + view.$el.trigger(fooEvent); }); it('should stop propagation by default', function() { - expect(this.fooEvent.isPropagationStopped()).to.be.true; + expect(fooEvent.isPropagationStopped()).to.be.true; }); it('should prevent default by default', function() { - expect(this.fooEvent.isDefaultPrevented()).to.be.true; + expect(fooEvent.isDefaultPrevented()).to.be.true; }); }); describe('when triggers items are manually configured', function() { + let TestView; + let view; + beforeEach(function() { - this.View = Marionette.View.extend({ + TestView = View.extend({ triggers: { 'foo': { event: 'fooHandler', @@ -112,48 +141,54 @@ describe('view triggers', function() { } } }); - this.view = new this.View(); - this.view.on('fooHandler', this.fooHandlerStub); + view = new TestView(); + view.on('fooHandler', fooHandlerStub); - this.view.$el.trigger(this.fooEvent); + view.$el.trigger(fooEvent); }); it('should prevent and dont stop the first view event', function() { - expect(this.fooEvent.isDefaultPrevented()).to.be.true; - expect(this.fooEvent.isPropagationStopped()).to.be.false; + expect(fooEvent.isDefaultPrevented()).to.be.true; + expect(fooEvent.isPropagationStopped()).to.be.false; }); }); describe('when triggersPreventDefault flag is set to false', function() { beforeEach(function() { - Marionette.setEnabled('triggersPreventDefault', false); + setEnabled('triggersPreventDefault', false); }); afterEach(function() { - Marionette.setEnabled('triggersPreventDefault', true); + setEnabled('triggersPreventDefault', true); }); describe('triggers should not prevent events by default', function() { + let TestView; + let view; + beforeEach(function() { - this.View = Marionette.View.extend({triggers: this.triggersHash}); - this.view = new this.View(); - this.view.on('fooHandler', this.fooHandlerStub); + TestView = View.extend({triggers: triggersHash}); + view = new TestView(); + view.on('fooHandler', fooHandlerStub); - this.view.$el.trigger(this.fooEvent); + view.$el.trigger(fooEvent); }); it('should stop propagation by default', function() { - expect(this.fooEvent.isPropagationStopped()).to.be.true; + expect(fooEvent.isPropagationStopped()).to.be.true; }); it('should not prevent default by default', function() { - expect(this.fooEvent.isDefaultPrevented()).to.be.false; + expect(fooEvent.isDefaultPrevented()).to.be.false; }); }); describe('when triggers items are manually configured', function() { + let TestView; + let view; + beforeEach(function() { - this.View = Marionette.View.extend({ + TestView = View.extend({ triggers: { 'foo': { event: 'fooHandler', @@ -162,49 +197,55 @@ describe('view triggers', function() { } } }); - this.view = new this.View(); - this.view.on('fooHandler', this.fooHandlerStub); + view = new TestView(); + view.on('fooHandler', fooHandlerStub); - this.view.$el.trigger(this.fooEvent); + view.$el.trigger(fooEvent); }); it('should prevent and stop the first view event', function() { - expect(this.fooEvent.isDefaultPrevented()).to.be.true; - expect(this.fooEvent.isPropagationStopped()).to.be.true; + expect(fooEvent.isDefaultPrevented()).to.be.true; + expect(fooEvent.isPropagationStopped()).to.be.true; }); }); }); describe('when triggersStopPropagation flag is set to false', function() { beforeEach(function() { - Marionette.setEnabled('triggersStopPropagation', false); + setEnabled('triggersStopPropagation', false); }); afterEach(function() { - Marionette.setEnabled('triggersStopPropagation', true); + setEnabled('triggersStopPropagation', true); }); describe('triggers should not stop propagation by default', function() { + let TestView; + let view; + beforeEach(function() { - this.View = Marionette.View.extend({triggers: this.triggersHash}); - this.view = new this.View(); - this.view.on('fooHandler', this.fooHandlerStub); + TestView = View.extend({triggers: triggersHash}); + view = new TestView(); + view.on('fooHandler', fooHandlerStub); - this.view.$el.trigger(this.fooEvent); + view.$el.trigger(fooEvent); }); it('should stop propagation by default', function() { - expect(this.fooEvent.isPropagationStopped()).to.be.false; + expect(fooEvent.isPropagationStopped()).to.be.false; }); it('should prevent default by default', function() { - expect(this.fooEvent.isDefaultPrevented()).to.be.true; + expect(fooEvent.isDefaultPrevented()).to.be.true; }); }); describe('when triggers items are manually configured', function() { + let TestView; + let view; + beforeEach(function() { - this.View = Marionette.View.extend({ + TestView = View.extend({ triggers: { 'foo': { event: 'fooHandler', @@ -213,15 +254,15 @@ describe('view triggers', function() { } } }); - this.view = new this.View(); - this.view.on('fooHandler', this.fooHandlerStub); + view = new TestView(); + view.on('fooHandler', fooHandlerStub); - this.view.$el.trigger(this.fooEvent); + view.$el.trigger(fooEvent); }); it('should prevent and stop the first view event', function() { - expect(this.fooEvent.isDefaultPrevented()).to.be.true; - expect(this.fooEvent.isPropagationStopped()).to.be.true; + expect(fooEvent.isDefaultPrevented()).to.be.true; + expect(fooEvent.isPropagationStopped()).to.be.true; }); }); });