Permalink
Browse files

Changed implementation of interests to throw an exception of the call…

…back specified is not a function so as to align the behavior of interests with events in Backbone. Updated Specs.
  • Loading branch information...
1 parent cde0565 commit 71d3c673fe02239ecc2384d31840f7761560a64f @efeminella committed Apr 2, 2013
View
8 build/templates/backbone-eventbroker.js
@@ -8,16 +8,16 @@
;(function($, _, Backbone) {
"use strict";
{{body}}
- //EXPORTS
- //AMD (RequireJS) - For exporting as a module when Backbone and jQuery are on the page
- //If using RequireJS to load Backbone, Underscore and jQuery, use the AMD-specific file
+ // exports ...
+ // AMD (RequireJS) - For exporting as a module when Backbone and jQuery are on the page
+ // If using RequireJS to load Backbone, Underscore and jQuery, use the AMD-specific file
if (typeof define === 'function' && define.amd) {
return define(function() {
return Backbone.EventBroker;
});
}
- //CommonJS (NodeJS)
+ // CommonJS (node)
if (typeof module === 'object' && typeof module.exports === 'object') {
module.exports = Backbone.EventBroker;
return;
View
11 dist/backbone-eventbroker.amd.js
@@ -32,15 +32,20 @@ define( function($, Backbone, _) {
* Implements the registering and unregistering of event/callback mappings
* for specific objects registered with an EventBroker.
*/
- var _registration = function( interests, context, broker, method ) {
- var event;
+ var _registration = function(interests, context, broker, method) {
+ var event, callback;
if (!context && interests.interests) {
context = interests;
interests = interests.interests;
}
for ( event in interests ) {
if ( interests.hasOwnProperty(event) ) {
- broker[method]( event, context[interests[event]], context );
+ callback = context[interests[event]]
+ if ( _.isFunction(callback) ) {
+ broker[method](event, callback, context);
+ } else {
+ throw new Error('method \'' + interests[event] + '\' not found for event \'' + event + '\'');
+ }
}
}
return broker;
View
2 dist/backbone-eventbroker.amd.min.js
@@ -1 +1 @@
-define(function(e,t,n){var n=require("underscore"),e=require("jquery"),t=require("backbone");return"use strict",t.EventBroker=t.EventBroker||function(){var e={},r=function(e,t,n,r){var i;!t&&e.interests&&(t=e,e=e.interests);for(i in e)e.hasOwnProperty(i)&&n[r](i,t[e[i]],t);return n},i={register:function(e,t){return e||t?r(e,t,this,"on"):this},unregister:function(e,t){return e||t?r(e,t,this,"off"):this}};return n.extend({namespace:"",get:function(r){return e[r]===undefined&&(e[r]=n.extend({namespace:r},t.Events,i)),e[r]},has:function(t){return e[t]!==undefined},destroy:function(t){if(!t)for(t in e)e.hasOwnProperty(t)&&this.destroy(t);else e[t]&&(e[t].off(),delete e[t]);return this}},t.Events,i)}(),t.EventBroker})
+define(function(e,t,n){var n=require("underscore"),e=require("jquery"),t=require("backbone");return"use strict",t.EventBroker=t.EventBroker||function(){var e={},r=function(e,t,r,i){var s,o;!t&&e.interests&&(t=e,e=e.interests);for(s in e)if(e.hasOwnProperty(s)){o=t[e[s]];if(!n.isFunction(o))throw new Error("method '"+e[s]+"' not found for event '"+s+"'");r[i](s,o,t)}return r},i={register:function(e,t){return e||t?r(e,t,this,"on"):this},unregister:function(e,t){return e||t?r(e,t,this,"off"):this}};return n.extend({namespace:"",get:function(r){return e[r]===undefined&&(e[r]=n.extend({namespace:r},t.Events,i)),e[r]},has:function(t){return e[t]!==undefined},destroy:function(t){if(!t)for(t in e)e.hasOwnProperty(t)&&this.destroy(t);else e[t]&&(e[t].off(),delete e[t]);return this}},t.Events,i)}(),t.EventBroker})
View
19 dist/backbone-eventbroker.js
@@ -24,15 +24,20 @@
* Implements the registering and unregistering of event/callback mappings
* for specific objects registered with an EventBroker.
*/
- var _registration = function( interests, context, broker, method ) {
- var event;
+ var _registration = function(interests, context, broker, method) {
+ var event, callback;
if (!context && interests.interests) {
context = interests;
interests = interests.interests;
}
for ( event in interests ) {
if ( interests.hasOwnProperty(event) ) {
- broker[method]( event, context[interests[event]], context );
+ callback = context[interests[event]]
+ if ( _.isFunction(callback) ) {
+ broker[method](event, callback, context);
+ } else {
+ throw new Error('method \'' + interests[event] + '\' not found for event \'' + event + '\'');
+ }
}
}
return broker;
@@ -211,16 +216,16 @@
}
}, Backbone.Events, EventRegistry );
}());
- //EXPORTS
- //AMD (RequireJS) - For exporting as a module when Backbone and jQuery are on the page
- //If using RequireJS to load Backbone, Underscore and jQuery, use the AMD-specific file
+ // exports ...
+ // AMD (RequireJS) - For exporting as a module when Backbone and jQuery are on the page
+ // If using RequireJS to load Backbone, Underscore and jQuery, use the AMD-specific file
if (typeof define === 'function' && define.amd) {
return define(function() {
return Backbone.EventBroker;
});
}
- //CommonJS (NodeJS)
+ // CommonJS (node)
if (typeof module === 'object' && typeof module.exports === 'object') {
module.exports = Backbone.EventBroker;
return;
View
2 dist/backbone-eventbroker.min.js
@@ -1 +1 @@
-(function(e,t,n){"use strict";n.EventBroker=n.EventBroker||function(){var e={},r=function(e,t,n,r){var i;!t&&e.interests&&(t=e,e=e.interests);for(i in e)e.hasOwnProperty(i)&&n[r](i,t[e[i]],t);return n},i={register:function(e,t){return e||t?r(e,t,this,"on"):this},unregister:function(e,t){return e||t?r(e,t,this,"off"):this}};return t.extend({namespace:"",get:function(r){return e[r]===undefined&&(e[r]=t.extend({namespace:r},n.Events,i)),e[r]},has:function(t){return e[t]!==undefined},destroy:function(t){if(!t)for(t in e)e.hasOwnProperty(t)&&this.destroy(t);else e[t]&&(e[t].off(),delete e[t]);return this}},n.Events,i)}();if(typeof define=="function"&&define.amd)return define(function(){return n.EventBroker});if(typeof module=="object"&&typeof module.exports=="object"){module.exports=n.EventBroker;return}})(jQuery,_,Backbone)
+(function(e,t,n){"use strict";n.EventBroker=n.EventBroker||function(){var e={},r=function(e,n,r,i){var s,o;!n&&e.interests&&(n=e,e=e.interests);for(s in e)if(e.hasOwnProperty(s)){o=n[e[s]];if(!t.isFunction(o))throw new Error("method '"+e[s]+"' not found for event '"+s+"'");r[i](s,o,n)}return r},i={register:function(e,t){return e||t?r(e,t,this,"on"):this},unregister:function(e,t){return e||t?r(e,t,this,"off"):this}};return t.extend({namespace:"",get:function(r){return e[r]===undefined&&(e[r]=t.extend({namespace:r},n.Events,i)),e[r]},has:function(t){return e[t]!==undefined},destroy:function(t){if(!t)for(t in e)e.hasOwnProperty(t)&&this.destroy(t);else e[t]&&(e[t].off(),delete e[t]);return this}},n.Events,i)}();if(typeof define=="function"&&define.amd)return define(function(){return n.EventBroker});if(typeof module=="object"&&typeof module.exports=="object"){module.exports=n.EventBroker;return}})(jQuery,_,Backbone)
View
416 spec/backbone-eventbroker-spec.js
@@ -1,206 +1,220 @@
-describe( "Backbone.EventBroker", function() {
- beforeEach( function() {
- addMatchers({
- toStrictlyEqual: function( expected ) {
- return this.actual === expected;
- }
- });
- Backbone.EventBroker.destroy();
- });
-
- describe( "The Broker API", function() {
-
- it( "should implement the Backbone.Events API", function() {
- _.forEach( Backbone.Events, function( method, name ) {
- expect( Backbone.EventBroker[ name ] ).toBeTruthy();
- }, this );
- });
-
- });
-
- describe( "Backbone.EventBroker namespace", function() {
-
- it( "should default to an empty string", function() {
- expect( Backbone.EventBroker.namespace ).toEqual( '' );
- });
-
- });
-
- describe( "Namespaced EventBroker namespaces", function() {
-
- it( "should be equal their unique namespace", function() {
- expect( Backbone.EventBroker.get( 'ns1' ).namespace ).toEqual( 'ns1' );
- expect( Backbone.EventBroker.get( 'ns2' ).namespace ).toEqual( 'ns2' );
- });
-
- });
-
- describe( "the get method", function() {
-
- it( "should create brokers which implement the Backbone.Events API", function() {
- var broker = Backbone.EventBroker.get( 'broker' );
-
- _.forEach( Backbone.Events, function( method, name ) {
- expect( broker[ name ] ).toBeTruthy();
- }, this );
- });
-
- it( "should create a unique broker per namespace", function() {
- var broker1 = Backbone.EventBroker.get( 'ns1' ),
- broker2 = Backbone.EventBroker.get( 'ns2' );
-
- expect( broker2 ).not.toStrictlyEqual( broker1 );
- });
-
- it( "should only create one unique broker per namespace", function() {
- var broker1 = Backbone.EventBroker.get( 'someBroker' ),
- broker2 = Backbone.EventBroker.get( 'someBroker' );
-
- expect( broker2 ).toEqual( broker1 );
- });
-
- });
-
- describe( "The has method", function() {
-
- it( "should return false if a broker has not been created for the given namespace", function() {
- expect( Backbone.EventBroker.has( 'ns1' ) ).toBeFalsy();
- });
-
- it( "should return true if a broker has been created for the given namespace", function() {
- var broker1 = Backbone.EventBroker.get( 'ns1' );
-
- expect( Backbone.EventBroker.has( 'ns1' ) ).toBeTruthy();
- });
-
- });
-
- describe( "The destroy method", function() {
-
- describe( "When invoked with a specific namespace", function() {
-
- it( "should only delete the broker for the given namespace", function() {
- Backbone.EventBroker.get( 'ns1' ),
- Backbone.EventBroker.get( 'ns2' );
-
- Backbone.EventBroker.destroy( 'ns1' );
-
- expect( Backbone.EventBroker.has( 'ns1' ) ).toBeFalsy();
- expect( Backbone.EventBroker.has( 'ns2' ) ).toBeTruthy();
- });
-
- });
-
- describe( "When invoked with a multiple namespaces", function() {
-
- it( "should only delete the broker for the given namespace", function() {
- var EventBroker = Backbone.EventBroker;
- EventBroker.get( 'ns1' );
- EventBroker.get( 'ns2' );
- EventBroker.get( 'ns3' );
- EventBroker.get( 'ns4' );
-
- EventBroker.destroy( 'ns1' ).destroy( 'ns2' ).destroy( 'ns3' );
-
- expect( EventBroker.has( 'ns1' ) ).toBeFalsy();
- expect( EventBroker.has( 'ns2' ) ).toBeFalsy();
- expect( EventBroker.has( 'ns3' ) ).toBeFalsy();
- expect( EventBroker.has( 'ns4' ) ).toBeTruthy();
- });
-
- });
-
- describe( "When invoked with no arguments", function() {
-
- it( "should delete all brokers for all namespaces", function() {
- Backbone.EventBroker.get( 'ns1' ),
- Backbone.EventBroker.get( 'ns2' );
-
- Backbone.EventBroker.destroy();
-
- expect( Backbone.EventBroker.has( 'ns1' ) ).toBeFalsy();
- expect( Backbone.EventBroker.has( 'ns2' ) ).toBeFalsy();
- });
-
- });
-
- });
-
- describe( "interests", function() {
+describe('EventBroker', function()
+{
+ // cache a local reference to the EventBroker...
+ var EventBroker = Backbone.EventBroker;
+ // spec set-up ...
beforeEach( function() {
- this.broker = Backbone.EventBroker;
-
- this.interests = {
- 'users:add' : 'add',
- 'users:delete': 'remove'
- };
- this.user = {id: '123'};
- this.users = {
- users: {},
- add: function( user ) {
- this.users[user.id] = user;
- },
- remove: function( user ) {
- delete this.users[user.id];
- }
- };
- this.broker.off( 'users:add', this.users.add, this.users );
- this.broker.off( 'users:delete', this.users.add, this.remove );
- });
-
- describe( "When registering explicit interests", function() {
-
- it( "should register all event/callback mappings", function() {
- this.broker.register( this.interests, this.users );
-
- this.broker.trigger( 'users:add', this.user );
- expect( this.users.users[ this.user.id ] ).toEqual( this.user );
-
- this.broker.trigger( 'users:delete', this.user );
- expect( this.users.users[ this.user.id ] ).toBeUndefined();
- });
-
- });
-
- describe( "When unregistering explicit interests", function() {
-
- it( "should unregister all event/callback mappings", function() {
- this.broker.unregister( this.interests, this.users );
-
- this.broker.trigger( 'users:add', this.user );
- expect( _.isEmpty( this.users.users ) ).toBeTruthy( this.user );
- });
-
- });
-
- describe( "When registering implied interests", function() {
-
- it( "should register all event/callback mappings", function() {
- this.users.interests = this.interests;
-
- this.broker.register( this.users );
-
- this.broker.trigger( 'users:add', this.user );
- expect( this.users.users[ this.user.id ] ).toEqual( this.user );
-
- this.broker.trigger( 'users:delete', this.user );
- expect( this.users.users[ this.user.id ] ).toBeUndefined();
- });
-
- });
-
- describe( "When unregistering implied interests", function() {
-
- it( "should unregister all event/callback mappings", function() {
- this.users.interests = this.interests;
- this.broker.register( this.users ).unregister( this.users );
-
- this.broker.trigger( 'users:add', this.user );
- expect( _.isEmpty( this.users.users ) ).toBeTruthy( this.user );
- });
-
+ // add utility matcher for each expect call
+ addMatchers({
+ toStrictlyEqual : function(expected) {
+ return this.actual === expected;
+ }
+ });
+ // reset the EventBroker after each spec
+ EventBroker.destroy();
+ });
+
+ it ('should extend Backbone.Events', function() {
+ _.forEach(Backbone.Events, function(method, name) {
+ expect(EventBroker[name]).toBeTruthy();
+ }, this);
+ });
+
+ describe('namespace', function() {
+ it ('should default to an empty string', function() {
+ expect(EventBroker.namespace).toEqual('');
+ });
+ });
+
+ describe('namespaced instances', function() {
+ it ('should resolve to their unique namespace', function() {
+ expect(EventBroker.get('ns1').namespace).toEqual('ns1');
+ expect(EventBroker.get('ns2').namespace).toEqual('ns2');
+ });
+ it ('should reference the same EventBroker instance for each unique namespace', function() {
+ expect(EventBroker.get('ns1')).toStrictlyEqual(EventBroker.get('ns1'));
+ expect(EventBroker.get('ns2')).toStrictlyEqual(EventBroker.get('ns2'));
+ });
+ });
+
+ describe('get', function() {
+ it ('should create brokers which implement the Backbone.Events API', function() {
+ var broker = EventBroker.get('broker');
+ _.forEach(Backbone.Events, function(method, name) {
+ expect(broker[name]).toBeTruthy();
+ }, this);
+ });
+
+ it ('should create a unique broker per namespace', function() {
+ var broker1 = EventBroker.get('ns1'), broker2 = EventBroker.get('ns2');
+ expect(broker2).not.toStrictlyEqual(broker1);
+ });
+
+ it ('should only create one unique broker per namespace', function() {
+ var broker1 = EventBroker.get('someBroker')
+ , broker2 = EventBroker.get('someBroker');
+ expect(broker2).toStrictlyEqual(broker1);
+ });
+ });
+
+ describe('has', function() {
+ it ('should return false if a broker has not been created for the given namespace', function() {
+ expect(EventBroker.has('ns1')).toBeFalsy();
+ });
+ it ('should return true if a broker has been created for the given namespace', function() {
+ var broker1 = EventBroker.get('ns1');
+ expect(EventBroker.has('ns1')).toBeTruthy();
+ });
+
+ });
+
+ describe('destroy', function() {
+ describe('when invoked with a specific namespace', function() {
+ it ('should only delete the broker for the given namespace', function() {
+ EventBroker.get('ns1');
+ EventBroker.get('ns2');
+ EventBroker.destroy('ns1');
+ expect(EventBroker.has('ns1')).toBeFalsy();
+ expect(EventBroker.has('ns2')).toBeTruthy();
+ });
+ });
+
+ describe('when invoked with multiple namespaces', function() {
+ it ('should only delete brokers for the given namespaces', function() {
+ EventBroker.get('ns1');
+ EventBroker.get('ns2');
+ EventBroker.get('ns3');
+ EventBroker.get('ns4');
+
+ EventBroker.destroy('ns1').destroy('ns2').destroy('ns3');
+
+ expect(EventBroker.has('ns1')).toBeFalsy();
+ expect(EventBroker.has('ns2')).toBeFalsy();
+ expect(EventBroker.has('ns3')).toBeFalsy();
+ expect(EventBroker.has('ns4')).toBeTruthy();
+ });
+ });
+
+ describe('when invoked with no arguments', function() {
+ it ('should delete all brokers for all namespaces', function() {
+ EventBroker.get('ns1');
+ EventBroker.get('ns2');
+
+ EventBroker.destroy();
+
+ expect(EventBroker.has('ns1')).toBeFalsy();
+ expect(EventBroker.has('ns2')).toBeFalsy();
+ });
+ });
+ });
+
+ describe('when registering events via .on', function(){
+ it ('should register an event for the given callback and context', function() {
+ var client = {
+ test: function(){
+ }
+ };
+ spyOn(client, 'test');
+ EventBroker.on('some:event', client.test, client);
+
+ EventBroker.trigger('some:event', 'test');
+ expect(client.test).toHaveBeenCalledWith('test');
+ });
+ });
+
+ describe('when unregistering events via .off', function(){
+ it ('should unregister an event from the given callback and context', function() {
+ var client = {
+ test: function(){}
+ };
+ spyOn(client, 'test');
+ EventBroker.on('some:event', client.test, client);
+ EventBroker.off('some:event', client.test, client);
+ EventBroker.trigger('some:event', 'test');
+ expect(client.test).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('interests', function() {
+ beforeEach(function() {
+ this.broker = EventBroker;
+
+ this.interests = {
+ 'users:add': 'add',
+ 'users:delete': 'remove'
+ };
+ this.user = {
+ 'id': '123'
+ };
+ this.users = {
+ 'users': {},
+ 'add': function(user) {
+ this.users[user.id] = user;
+ },
+ 'remove': function(user) {
+ delete this.users[user.id];
+ }
+ };
+ this.broker.off('users:add', this.users.add, this.users);
+ this.broker.off('users:delete', this.users.add, this.remove);
+ });
+
+ describe('when registering explicit interests', function() {
+ it ('should register each event / callback mapping', function() {
+ spyOn(this.users, 'remove');
+ this.broker.register(this.interests, this.users);
+ this.broker.trigger('users:delete', this.user);
+ expect(this.users.remove).toHaveBeenCalled();
+ expect(this.users.remove).toHaveBeenCalledWith(this.user);
+ expect(this.users.users[this.user.id]).toBeUndefined();
+ });
+ });
+
+ describe('when unregistering explicit interests', function() {
+ it ('should unregister each event / callback mappings', function() {
+ this.broker.unregister(this.interests, this.users);
+ this.broker.trigger('users:add', this.user);
+ expect(_.isEmpty(this.users.users)).toBeTruthy(this.user);
+ });
+ });
+
+ describe('registering interests for undefined methods', function() {
+ it ('should throw an exception if the given callback is not a function', function() {
+ var interests = {'users:update':'update'}
+ , context = this.users
+ , wrapper = function(){EventBroker.register(interests, context)};
+
+ expect(wrapper).toThrow(new Error("method 'update' not found for event 'users:update'"));
+ context.update = '';
+
+ wrapper = function(){EventBroker.register(interests, context)};
+ expect(wrapper).toThrow(new Error("method 'update' not found for event 'users:update'"));
+ });
+ });
+
+ describe('registering implied interests', function() {
+ it ('should register all event/callback mappings', function() {
+ this.users.interests = this.interests;
+ this.broker.register(this.users);
+
+ this.broker.trigger('users:add', this.user);
+ expect(this.users.users[this.user.id]).toEqual(this.user);
+
+ this.broker.trigger('users:delete', this.user);
+ expect(this.users.users[this.user.id]).toBeUndefined();
+ });
+ });
+
+ describe('when unregistering implied interests', function() {
+ it ('should unregister all event/callback mappings', function() {
+ this.users.interests = this.interests;
+ this.broker.register(this.users).unregister(this.users);
+
+ this.broker.trigger('users:add', this.user);
+ expect(_.isEmpty(this.users.users)).toBeTruthy(this.user);
+ });
+ });
});
- });
});
View
11 src/backbone-eventbroker.js
@@ -15,15 +15,20 @@
* Implements the registering and unregistering of event/callback mappings
* for specific objects registered with an EventBroker.
*/
- var _registration = function( interests, context, broker, method ) {
- var event;
+ var _registration = function(interests, context, broker, method) {
+ var event, callback;
if (!context && interests.interests) {
context = interests;
interests = interests.interests;
}
for ( event in interests ) {
if ( interests.hasOwnProperty(event) ) {
- broker[method]( event, context[interests[event]], context );
+ callback = context[interests[event]]
+ if ( _.isFunction(callback) ) {
+ broker[method](event, callback, context);
+ } else {
+ throw new Error('method \'' + interests[event] + '\' not found for event \'' + event + '\'');
+ }
}
}
return broker;

0 comments on commit 71d3c67

Please sign in to comment.