Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

pubsub-js

Package Overview
Dependencies
Maintainers
1
Versions
28
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

pubsub-js - npm Package Compare versions

Comparing version 1.5.7 to 1.5.8

.eslintrc.js

27

CONTRIBUTING.md

@@ -33,28 +33,1 @@ # Contributing to PubSubJS

Install [Editor Config](http://editorconfig.org) for your text editor, this will ensure that the correct formatting is applied for each file type.
## Development
There are grunt tasks for helping with linting and testing the codebase.
### Test setup
The tests are implemented using [BusterJS](http://busterjs.org) and the excellent [Sinon.JS](http://sinonjs.org/). All dependencies can be installed with `npm install` (assuming you already have nodejs installed).
### Linting
```bash
$ grunt lint
```
### Testing with PhantomJS
If you have PhantomJS installed on your system, you can run the Buster tests by running
```bash
$ grunt test
```
or by running
```bash
$ npm test
```

19

package.json
{
"name": "pubsub-js",
"version": "1.5.7",
"version": "1.5.8",
"description": "Dependency free publish/subscribe library",

@@ -11,4 +11,5 @@ "main": "./src/pubsub.js",

"scripts": {
"lint": "$(npm bin)/jslint src/**/*.js test/**/*.js",
"test": "npm run lint && $(npm bin)/grunt test"
"coverage": "nyc --reporter=lcov --reporter=text --reporter=json-summary npm test",
"lint": "eslint src/ test/",
"test": "mocha"
},

@@ -33,10 +34,8 @@ "repository": {

"devDependencies": {
"buster": "0.7.18",
"grunt": "0.4.5",
"grunt-buster": "0.3.2",
"grunt-cli": "0.1.13",
"grunt-contrib-concat": "0.5.0",
"jslint": "0.7.2",
"phantomjs": "1.9.13"
"eslint": "^4.14.0",
"mocha": "^4.0.1",
"nyc": "^11.4.1",
"referee": "^1.2.0",
"sinon": "^4.1.3"
}
}

@@ -5,3 +5,3 @@ # PubSubJS

![npm version](https://img.shields.io/npm/v/pubsub-js.svg) ![npm license](https://img.shields.io/npm/l/pubsub-js.svg) ![npm downloads per month](https://img.shields.io/npm/dm/pubsub-js.svg)
![Bower version](https://img.shields.io/bower/v/pubsub-js.svg)
[![Coverage Status](https://coveralls.io/repos/github/mroderick/PubSubJS/badge.svg)](https://coveralls.io/github/mroderick/PubSubJS)

@@ -32,7 +32,10 @@ PubSubJS is a [topic-based](http://en.wikipedia.org/wiki/Publish–subscribe_pattern#Message_filtering) [publish/subscribe](http://en.wikipedia.org/wiki/Publish/subscribe) library written in JavaScript.

* Install via npm (`npm install pubsub-js`)
* Use it directly from a CDN directly
- http://www.jsdelivr.com/#!pubsubjs
- https://cdnjs.com/libraries/pubsub-js
* [Download a tagged version](https://github.com/mroderick/PubSubJS/tags) from GitHub
* Install via npm (`npm install pubsub-js`)
* Install via bower (`bower install pubsub-js`)
* Use it via CDN directly (http://www.jsdelivr.com/#!pubsubjs)
**Note: the last version of this library available via bower is v1.5.4**
## Examples

@@ -44,3 +47,3 @@

// create a function to subscribe to topics
var mySubscriber = function( msg, data ){
var mySubscriber = function (msg, data) {
console.log( msg, data );

@@ -52,6 +55,6 @@ };

// from the topic later on
var token = PubSub.subscribe( 'MY TOPIC', mySubscriber );
var token = PubSub.subscribe('MY TOPIC', mySubscriber);
// publish a topic asyncronously
PubSub.publish( 'MY TOPIC', 'hello world!' );
PubSub.publish('MY TOPIC', 'hello world!');

@@ -62,3 +65,3 @@ // publish a topic syncronously, which is faster in some environments,

// USE WITH CAUTION, HERE BE DRAGONS!!!
PubSub.publishSync( 'MY TOPIC', 'hello world!' );
PubSub.publishSync('MY TOPIC', 'hello world!');
```

@@ -70,4 +73,4 @@

// create a function to receive the topic
var mySubscriber = function( msg, data ){
console.log( msg, data );
var mySubscriber = function (msg, data) {
console.log(msg, data);
};

@@ -78,6 +81,6 @@

// from the topic later on
var token = PubSub.subscribe( 'MY TOPIC', mySubscriber );
var token = PubSub.subscribe('MY TOPIC', mySubscriber);
// unsubscribe this subscriber from this topic
PubSub.unsubscribe( token );
PubSub.unsubscribe(token);
```

@@ -89,8 +92,8 @@

// create a function to receive the topic
var mySubscriber = function( msg, data ){
console.log( msg, data );
var mySubscriber = function(msg, data) {
console.log(msg, data);
};
// unsubscribe mySubscriber from ALL topics
PubSub.unsubscribe( mySubscriber );
PubSub.unsubscribe(mySubscriber);
```

@@ -121,21 +124,21 @@

// create a subscriber to receive all topics from a hierarchy of topics
var myToplevelSubscriber = function( msg, data ){
console.log( 'top level: ', msg, data );
var myToplevelSubscriber = function (msg, data) {
console.log('top level: ', msg, data);
}
// subscribe to all topics in the 'car' hierarchy
PubSub.subscribe( 'car', myToplevelSubscriber );
PubSub.subscribe('car', myToplevelSubscriber);
// create a subscriber to receive only leaf topic from hierarchy op topics
var mySpecificSubscriber = function( msg, data ){
console.log('specific: ', msg, data );
var mySpecificSubscriber = function (msg, data) {
console.log('specific: ', msg, data);
}
// subscribe only to 'car.drive' topics
PubSub.subscribe( 'car.drive', mySpecificSubscriber );
PubSub.subscribe('car.drive', mySpecificSubscriber);
// Publish some topics
PubSub.publish( 'car.purchase', { name : 'my new car' } );
PubSub.publish( 'car.drive', { speed : '14' } );
PubSub.publish( 'car.sell', { newOwner : 'someone else' } );
PubSub.publish('car.purchase', {name: 'my new car'});
PubSub.publish('car.drive', {speed: '14'});
PubSub.publish('car.sell', {newOwner: 'someone else'});

@@ -157,15 +160,15 @@ // In this scenario, myToplevelSubscriber will be called for all

// BAD
PubSub.subscribe("hello", function( msg, data ){
console.log( data )
PubSub.subscribe('hello', function (msg, data) {
console.log(data)
});
PubSub.publish("helo", "world");
PubSub.publish('helo', 'world');
// BETTER
var MY_TOPIC = "hello";
PubSub.subscribe(MY_TOPIC, function( msg, data ){
console.log( data )
var MY_TOPIC = 'hello';
PubSub.subscribe(MY_TOPIC, function (msg, data) {
console.log(data)
});
PubSub.publish(MY_TOPIC, "world");
PubSub.publish(MY_TOPIC, 'world');
```

@@ -175,7 +178,7 @@

As of versions 1.3.2, you can force immediate exceptions (instead of delayed execeptions), which has the benefit of maintaining the stack trace when viewed in dev tools.
As of version 1.3.2, you can force immediate exceptions (instead of delayed execeptions), which has the benefit of maintaining the stack trace when viewed in dev tools.
This should be considered a development only option, as PubSubJS was designed to try to deliver your topics to all subscribers, even when some fail.
Setting immediate exceptions in development is easy, just tell PubSubJS about it after it's been loaded.
Setting immediate exceptions in development is easy, just tell PubSubJS about it after it has been loaded.

@@ -186,41 +189,2 @@ ```javascript

## Plugin for jQuery
By default PubSubJS can be used in any browser or CommonJS environment, including [node](http://nodejs.org). Additionally, PubSubJS can be built specifically for jQuery using Rake.
$ rake jquery
or using Grunt
$ grunt jquery
Produces jquery.pubsub.js
### Use with jQuery
```javascript
var topic = 'greeting',
data = 'world',
subscriber = function sayHello( data ){
console.log( 'hello ' + data );
};
// add a subscription
var token = $.pubsub('subscribe', topic, subscriber );
// unsubscribing
$.pubsub('unsubscribe', token); // remove a specific subscription
$.pubsub('unsubscribe', subscriber); // remove all subscriptions for subscriber
// publishing a topic
$.pubsub('publish', topic, data);
// publishing topic syncronously
$.pubsub('publishSync', topic, data);
```
In the jQuery build, the global ```PubSub``` global is still available, so you can mix and match both ```Pubsub``` and ```$.pubsub``` as needed.
There is also an article about [Using PubSubJS with jQuery](http://roderick.dk/resources/using-pubsubjs-with-jquery/)
## Contributing to PubSubJS

@@ -230,7 +194,3 @@

## Future of PubSubJS
* Better and more extensive usage examples
## More about Publish/Subscribe

@@ -237,0 +197,0 @@

@@ -8,124 +8,127 @@ /*

(function (root, factory){
'use strict';
'use strict';
var PubSub = {};
root.PubSub = PubSub;
factory(PubSub);
var PubSub = {};
root.PubSub = PubSub;
// AMD support
if (typeof define === 'function' && define.amd){
define(function() { return PubSub; });
var define = root.define;
// CommonJS and Node.js module support
} else if (typeof exports === 'object'){
if (module !== undefined && module.exports) {
exports = module.exports = PubSub; // Node.js specific `module.exports`
}
exports.PubSub = PubSub; // CommonJS module 1.1.1 spec
module.exports = exports = PubSub; // CommonJS
}
factory(PubSub);
// AMD support
if (typeof define === 'function' && define.amd){
define(function() { return PubSub; });
// CommonJS and Node.js module support
} else if (typeof exports === 'object'){
if (module !== undefined && module.exports) {
exports = module.exports = PubSub; // Node.js specific `module.exports`
}
exports.PubSub = PubSub; // CommonJS module 1.1.1 spec
module.exports = exports = PubSub; // CommonJS
}
}(( typeof window === 'object' && window ) || this, function (PubSub){
'use strict';
'use strict';
var messages = {},
lastUid = -1;
var messages = {},
lastUid = -1;
function hasKeys(obj){
var key;
function hasKeys(obj){
var key;
for (key in obj){
if ( obj.hasOwnProperty(key) ){
return true;
}
}
return false;
}
for (key in obj){
if ( obj.hasOwnProperty(key) ){
return true;
}
}
return false;
}
/**
/**
* Returns a function that throws the passed exception, for use as argument for setTimeout
* @param { Object } ex An Error object
*/
function throwException( ex ){
return function reThrowException(){
throw ex;
};
}
function throwException( ex ){
return function reThrowException(){
throw ex;
};
}
function callSubscriberWithDelayedExceptions( subscriber, message, data ){
try {
subscriber( message, data );
} catch( ex ){
setTimeout( throwException( ex ), 0);
}
}
function callSubscriberWithDelayedExceptions( subscriber, message, data ){
try {
subscriber( message, data );
} catch( ex ){
setTimeout( throwException( ex ), 0);
}
}
function callSubscriberWithImmediateExceptions( subscriber, message, data ){
subscriber( message, data );
}
function callSubscriberWithImmediateExceptions( subscriber, message, data ){
subscriber( message, data );
}
function deliverMessage( originalMessage, matchedMessage, data, immediateExceptions ){
var subscribers = messages[matchedMessage],
callSubscriber = immediateExceptions ? callSubscriberWithImmediateExceptions : callSubscriberWithDelayedExceptions,
s;
function deliverMessage( originalMessage, matchedMessage, data, immediateExceptions ){
var subscribers = messages[matchedMessage],
callSubscriber = immediateExceptions ? callSubscriberWithImmediateExceptions : callSubscriberWithDelayedExceptions,
s;
if ( !messages.hasOwnProperty( matchedMessage ) ) {
return;
}
if ( !messages.hasOwnProperty( matchedMessage ) ) {
return;
}
for (s in subscribers){
if ( subscribers.hasOwnProperty(s)){
callSubscriber( subscribers[s], originalMessage, data );
}
}
}
for (s in subscribers){
if ( subscribers.hasOwnProperty(s)){
callSubscriber( subscribers[s], originalMessage, data );
}
}
}
function createDeliveryFunction( message, data, immediateExceptions ){
return function deliverNamespaced(){
var topic = String( message ),
position = topic.lastIndexOf( '.' );
function createDeliveryFunction( message, data, immediateExceptions ){
return function deliverNamespaced(){
var topic = String( message ),
position = topic.lastIndexOf( '.' );
// deliver the message as it is now
deliverMessage(message, message, data, immediateExceptions);
// deliver the message as it is now
deliverMessage(message, message, data, immediateExceptions);
// trim the hierarchy and deliver message to each level
while( position !== -1 ){
topic = topic.substr( 0, position );
position = topic.lastIndexOf('.');
deliverMessage( message, topic, data, immediateExceptions );
}
};
}
// trim the hierarchy and deliver message to each level
while( position !== -1 ){
topic = topic.substr( 0, position );
position = topic.lastIndexOf('.');
deliverMessage( message, topic, data, immediateExceptions );
}
};
}
function messageHasSubscribers( message ){
var topic = String( message ),
found = Boolean(messages.hasOwnProperty( topic ) && hasKeys(messages[topic])),
position = topic.lastIndexOf( '.' );
function messageHasSubscribers( message ){
var topic = String( message ),
found = Boolean(messages.hasOwnProperty( topic ) && hasKeys(messages[topic])),
position = topic.lastIndexOf( '.' );
while ( !found && position !== -1 ){
topic = topic.substr( 0, position );
position = topic.lastIndexOf( '.' );
found = Boolean(messages.hasOwnProperty( topic ) && hasKeys(messages[topic]));
}
while ( !found && position !== -1 ){
topic = topic.substr( 0, position );
position = topic.lastIndexOf( '.' );
found = Boolean(messages.hasOwnProperty( topic ) && hasKeys(messages[topic]));
}
return found;
}
return found;
}
function publish( message, data, sync, immediateExceptions ){
var deliver = createDeliveryFunction( message, data, immediateExceptions ),
hasSubscribers = messageHasSubscribers( message );
function publish( message, data, sync, immediateExceptions ){
var deliver = createDeliveryFunction( message, data, immediateExceptions ),
hasSubscribers = messageHasSubscribers( message );
if ( !hasSubscribers ){
return false;
}
if ( !hasSubscribers ){
return false;
}
if ( sync === true ){
deliver();
} else {
setTimeout( deliver, 0 );
}
return true;
}
if ( sync === true ){
deliver();
} else {
setTimeout( deliver, 0 );
}
return true;
}
/**
/**
* PubSub.publish( message[, data] ) -> Boolean

@@ -136,7 +139,7 @@ * - message (String): The message to publish

**/
PubSub.publish = function( message, data ){
return publish( message, data, false, PubSub.immediateExceptions );
};
PubSub.publish = function( message, data ){
return publish( message, data, false, PubSub.immediateExceptions );
};
/**
/**
* PubSub.publishSync( message[, data] ) -> Boolean

@@ -147,7 +150,7 @@ * - message (String): The message to publish

**/
PubSub.publishSync = function( message, data ){
return publish( message, data, true, PubSub.immediateExceptions );
};
PubSub.publishSync = function( message, data ){
return publish( message, data, true, PubSub.immediateExceptions );
};
/**
/**
* PubSub.subscribe( message, func ) -> String

@@ -159,39 +162,39 @@ * - message (String): The message to subscribe to

**/
PubSub.subscribe = function( message, func ){
if ( typeof func !== 'function'){
return false;
}
PubSub.subscribe = function( message, func ){
if ( typeof func !== 'function'){
return false;
}
// message is not registered yet
if ( !messages.hasOwnProperty( message ) ){
messages[message] = {};
}
// message is not registered yet
if ( !messages.hasOwnProperty( message ) ){
messages[message] = {};
}
// forcing token as String, to allow for future expansions without breaking usage
// and allow for easy use as key names for the 'messages' object
var token = 'uid_' + String(++lastUid);
messages[message][token] = func;
// forcing token as String, to allow for future expansions without breaking usage
// and allow for easy use as key names for the 'messages' object
var token = 'uid_' + String(++lastUid);
messages[message][token] = func;
// return token for unsubscribing
return token;
};
// return token for unsubscribing
return token;
};
/* Public: Clears all subscriptions
/* Public: Clears all subscriptions
*/
PubSub.clearAllSubscriptions = function clearAllSubscriptions(){
messages = {};
};
PubSub.clearAllSubscriptions = function clearAllSubscriptions(){
messages = {};
};
/*Public: Clear subscriptions by the topic
/*Public: Clear subscriptions by the topic
*/
PubSub.clearSubscriptions = function clearSubscriptions(topic){
var m;
for (m in messages){
if (messages.hasOwnProperty(m) && m.indexOf(topic) === 0){
delete messages[m];
}
}
};
PubSub.clearSubscriptions = function clearSubscriptions(topic){
var m;
for (m in messages){
if (messages.hasOwnProperty(m) && m.indexOf(topic) === 0){
delete messages[m];
}
}
};
/* Public: removes subscriptions.
/* Public: removes subscriptions.
* When passed a token, removes a specific subscription.

@@ -215,49 +218,49 @@ * When passed a function, removes all subscriptions for that function

*/
PubSub.unsubscribe = function(value){
var descendantTopicExists = function(topic) {
var m;
for ( m in messages ){
if ( messages.hasOwnProperty(m) && m.indexOf(topic) === 0 ){
// a descendant of the topic exists:
return true;
}
}
PubSub.unsubscribe = function(value){
var descendantTopicExists = function(topic) {
var m;
for ( m in messages ){
if ( messages.hasOwnProperty(m) && m.indexOf(topic) === 0 ){
// a descendant of the topic exists:
return true;
}
}
return false;
},
isTopic = typeof value === 'string' && ( messages.hasOwnProperty(value) || descendantTopicExists(value) ),
isToken = !isTopic && typeof value === 'string',
isFunction = typeof value === 'function',
result = false,
m, message, t;
return false;
},
isTopic = typeof value === 'string' && ( messages.hasOwnProperty(value) || descendantTopicExists(value) ),
isToken = !isTopic && typeof value === 'string',
isFunction = typeof value === 'function',
result = false,
m, message, t;
if (isTopic){
PubSub.clearSubscriptions(value);
return;
}
if (isTopic){
PubSub.clearSubscriptions(value);
return;
}
for ( m in messages ){
if ( messages.hasOwnProperty( m ) ){
message = messages[m];
for ( m in messages ){
if ( messages.hasOwnProperty( m ) ){
message = messages[m];
if ( isToken && message[value] ){
delete message[value];
result = value;
// tokens are unique, so we can just stop here
break;
}
if ( isToken && message[value] ){
delete message[value];
result = value;
// tokens are unique, so we can just stop here
break;
}
if (isFunction) {
for ( t in message ){
if (message.hasOwnProperty(t) && message[t] === value){
delete message[t];
result = true;
}
}
}
}
}
if (isFunction) {
for ( t in message ){
if (message.hasOwnProperty(t) && message[t] === value){
delete message[t];
result = true;
}
}
}
}
}
return result;
};
return result;
};
}));
(function(root, factory){
'use strict';
'use strict';
// CommonJS
if (typeof exports === 'object'){
module.exports = factory();
var define = root.define;
// AMD
} else if (typeof define === 'function' && define.amd){
define(factory);
// Browser
} else {
root.TestHelper = factory();
}
// CommonJS
if (typeof exports === 'object'){
module.exports = factory();
// AMD
} else if (typeof define === 'function' && define.amd){
define(factory);
// Browser
} else {
root.TestHelper = factory();
}
}( ( typeof window === 'object' && window ) || this, function(){
'use strict';
'use strict';
var TestHelper = {},
assert = buster.assert;
var TestHelper = {},
assert = require('referee').assert;
// helps us make sure that the order of the tests have no impact on their succes
function getUniqueString(){
if ( getUniqueString.uid === undefined ){
getUniqueString.uid = 0;
}
getUniqueString.uid++;
// helps us make sure that the order of the tests have no impact on their succes
function getUniqueString(){
if ( getUniqueString.uid === undefined ){
getUniqueString.uid = 0;
}
getUniqueString.uid++;
return "my unique String number " + getUniqueString.uid.toString();
}
return 'my unique String number ' + getUniqueString.uid.toString();
}
// makes sure that all tokens in the passed array are different
function assertAllTokensDifferent( tokens ){
var length = tokens.length,
j, k;
assert( tokens.length > 0 );
// compare all tokens
for ( j = 0; j < length; j++ ){
for ( k = j + 1; k < length; k++ ){
assert( tokens[j] !== tokens[k] );
}
}
// makes sure that all tokens in the passed array are different
function assertAllTokensDifferent( tokens ){
var length = tokens.length,
j, k;
assert( tokens.length > 0 );
// compare all tokens
for ( j = 0; j < length; j++ ){
for ( k = j + 1; k < length; k++ ){
assert( tokens[j] !== tokens[k] );
}
}
// make sure we actually tested something
assert.equals( j, length );
assert.equals( k, length );
}
// make sure we actually tested something
assert.equals( j, length );
assert.equals( k, length );
}
TestHelper.getUniqueString = getUniqueString;
TestHelper.assertAllTokensDifferent = assertAllTokensDifferent;
TestHelper.getUniqueString = getUniqueString;
TestHelper.assertAllTokensDifferent = assertAllTokensDifferent;
return TestHelper;
return TestHelper;
}));

@@ -1,52 +0,50 @@

(function( global ){
"use strict";
'use strict';
var PubSub = global.PubSub || require("../src/pubsub"),
assert = buster.assert;
var PubSub = require('../src/pubsub'),
assert = require('referee').assert,
sinon = require('sinon');
/**
* This is a test proving that bug 9 has been fixed.
* See https://github.com/mroderick/PubSubJS/issues/9
*/
buster.testCase( "Bug 9, publish method", {
/**
* This is a test proving that bug 9 has been fixed.
* See https://github.com/mroderick/PubSubJS/issues/9
*/
describe( 'Bug 9, publish method', function() {
it('should notify all subscribers in a hierarchy', function( done ){
var subscriber1 = sinon.spy(),
subscriber2 = sinon.spy(),
subscriber3 = sinon.spy(),
clock = sinon.useFakeTimers();
"should notify all subscribers in a hierarchy" : function( done ){
var subscriber1 = this.spy(),
subscriber2 = this.spy(),
subscriber3 = this.spy(),
clock = this.useFakeTimers();
PubSub.subscribe( 'a.b.c', subscriber1 );
PubSub.subscribe( 'a.b', subscriber2 );
PubSub.subscribe( 'a', subscriber3 );
PubSub.subscribe( 'a.b.c', subscriber1 );
PubSub.subscribe( 'a.b', subscriber2 );
PubSub.subscribe( 'a', subscriber3 );
PubSub.publish( 'a.b.c.d' );
PubSub.publish( 'a.b.c.d' );
clock.tick(1);
clock.tick(1);
assert( subscriber1.calledOnce );
assert( subscriber2.calledOnce );
assert( subscriber3.calledOnce );
assert( subscriber1.calledOnce );
assert( subscriber2.calledOnce );
assert( subscriber3.calledOnce );
done();
clock.restore();
});
done();
clock.restore();
},
it('should notify individual subscribers, even when there are no subscribers further up', function( done ){
"should notify individual subscribers, even when there are no subscribers further up" : function( done ){
var rootTopic = 'a.b.c',
subscriber = sinon.spy(),
clock = sinon.useFakeTimers();
var rootTopic = 'a.b.c',
subscriber = this.spy(),
clock = this.useFakeTimers();
PubSub.subscribe(rootTopic, subscriber);
PubSub.publish(rootTopic + '.d');
PubSub.subscribe(rootTopic, subscriber);
PubSub.publish(rootTopic + '.d');
clock.tick(1);
clock.tick(1);
assert( subscriber.calledOnce );
assert( subscriber.calledOnce );
done();
clock.restore();
}
});
}(this));
done();
clock.restore();
});
});

@@ -1,25 +0,24 @@

(function( global ){
'use strict';
'use strict';
var PubSub = global.PubSub || require('../src/pubsub'),
TestHelper = global.TestHelper || require('../test/helper'),
refute = buster.refute;
var PubSub = require('../src/pubsub'),
TestHelper = require('./helper'),
refute = require('referee').refute,
sinon = require('sinon');
buster.testCase( 'clearAllSubscriptions method', {
'must clear all subscriptions' : function(){
var topic = TestHelper.getUniqueString(),
spy1 = sinon.spy(),
spy2 = sinon.spy();
describe('clearAllSubscriptions method', function () {
it('must clear all subscriptions', function () {
var topic = TestHelper.getUniqueString(),
spy1 = sinon.spy(),
spy2 = sinon.spy();
PubSub.subscribe(topic, spy1);
PubSub.subscribe(topic, spy2);
PubSub.subscribe(topic, spy1);
PubSub.subscribe(topic, spy2);
PubSub.clearAllSubscriptions();
PubSub.clearAllSubscriptions();
PubSub.publishSync(topic, TestHelper.getUniqueString());
PubSub.publishSync(topic, TestHelper.getUniqueString());
refute(spy1.called);
refute(spy2.called);
}
});
}(this));
refute(spy1.called);
refute(spy2.called);
});
});

@@ -1,209 +0,204 @@

(function( global ){
"use strict";
'use strict';
var PubSub = global.PubSub || require("../src/pubsub"),
TestHelper = global.TestHelper || require("../test/helper"),
assert = buster.assert;
var PubSub = global.PubSub || require('../src/pubsub'),
TestHelper = global.TestHelper || require('../test/helper'),
assert = require('referee').assert,
sinon = require('sinon');
buster.testCase( "Hierarchical addressing", {
describe( 'Hierarchical addressing', function () {
beforeEach(function(){
this.clock = sinon.useFakeTimers();
});
setUp : function(){
this.clock = this.useFakeTimers();
},
afterEach(function(){
this.clock.restore();
});
tearDown: function(){
this.clock.restore();
},
it('publish method should not call any children in a namespace', function( done ) {
var messages = ['library', 'library.music'],
spy = sinon.spy(),
data = TestHelper.getUniqueString();
"publish method should not call any children in a namespace" : function( done ) {
var messages = ['library', 'library.music'],
spy = this.spy(),
data = TestHelper.getUniqueString();
PubSub.subscribe( messages[0], spy ); //This should be called
PubSub.subscribe( messages[1], spy );
PubSub.publish( messages[0], data );
PubSub.subscribe( messages[0], spy ); //This should be called
PubSub.subscribe( messages[1], spy );
PubSub.publish( messages[0], data );
assert.equals( spy.callCount, 0 );
this.clock.tick(1);
assert.equals( spy.callCount, 1 );
assert.equals( spy.callCount, 0 );
this.clock.tick(1);
assert.equals( spy.callCount, 1 );
done();
});
done();
},
it('publish method should call a parent namespace', function( done ) {
// Publishing library.music should trigger parent library
var messages = ['library', 'library.music'],
spy = sinon.spy(),
data = TestHelper.getUniqueString();
"publish method should call a parent namespace" : function( done ) {
// Publishing library.music should trigger parent library
var messages = ['library', 'library.music'],
spy = this.spy(),
data = TestHelper.getUniqueString();
PubSub.subscribe( messages[0], spy ); //This should be called
PubSub.subscribe( messages[1], spy ); //This should be called
PubSub.publish( messages[1], data );
PubSub.subscribe( messages[0], spy ); //This should be called
PubSub.subscribe( messages[1], spy ); //This should be called
PubSub.publish( messages[1], data );
assert.equals( spy.callCount, 0 );
this.clock.tick(1);
assert.equals( spy.callCount, 2 );
assert.equals( spy.callCount, 0 );
this.clock.tick(1);
assert.equals( spy.callCount, 2 );
done();
});
done();
},
it('publish method should call only a parent namespace', function( done ) {
//Publishing library.music should only trigger parents descendants
//Even if it has a child
var messages = ['library', 'library.music', 'library.music.jazz'],
spy = sinon.spy(),
data = TestHelper.getUniqueString();
"publish method should call only a parent namespace" : function( done ) {
//Publishing library.music should only trigger parents descendants
//Even if it has a child
var messages = ['library', 'library.music', 'library.music.jazz'],
spy = this.spy(),
data = TestHelper.getUniqueString();
PubSub.subscribe( messages[0], spy ); //This should be called
PubSub.subscribe( messages[1], spy ); //This should be called
PubSub.subscribe( messages[2], spy );
PubSub.publish( messages[1], data );
PubSub.subscribe( messages[0], spy ); //This should be called
PubSub.subscribe( messages[1], spy ); //This should be called
PubSub.subscribe( messages[2], spy );
PubSub.publish( messages[1], data );
assert.equals( spy.callCount, 0 );
this.clock.tick(1);
assert.equals( spy.callCount, 2 );
assert.equals( spy.callCount, 0 );
this.clock.tick(1);
assert.equals( spy.callCount, 2 );
done();
});
done();
},
it('publish method should call all parent namespaces', function( done ) {
//Publishing library.music.jazz should trigger all parents
var messages = ['library', 'library.music', 'library.music.jazz'],
spy = sinon.spy(),
data = TestHelper.getUniqueString();
"publish method should call all parent namespaces" : function( done ) {
//Publishing library.music.jazz should trigger all parents
var messages = ['library', 'library.music', 'library.music.jazz'],
spy = this.spy(),
data = TestHelper.getUniqueString();
PubSub.subscribe( messages[0], spy ); //This should be called
PubSub.subscribe( messages[1], spy ); //This should be called
PubSub.subscribe( messages[2], spy ); //This should be called
PubSub.publish( messages[2], data );
PubSub.subscribe( messages[0], spy ); //This should be called
PubSub.subscribe( messages[1], spy ); //This should be called
PubSub.subscribe( messages[2], spy ); //This should be called
PubSub.publish( messages[2], data );
assert.equals( spy.callCount, 0 );
this.clock.tick(1);
assert.equals( spy.callCount, 3 );
assert.equals( spy.callCount, 0 );
this.clock.tick(1);
assert.equals( spy.callCount, 3 );
done();
});
done();
},
it('publish method should call only parent descendants', function( done ) {
//Publishing library.music.jazz should trigger only all parents descendants
//Skipping library.playlist and library.playlist.*
var messages = [
'library',
'library.music',
'library.music.jazz',
'library.playlist',
'library.playlist.mine'
],
spy = sinon.spy(),
data = TestHelper.getUniqueString();
"publish method should call only parent descendants" : function( done ) {
//Publishing library.music.jazz should trigger only all parents descendants
//Skipping library.playlist and library.playlist.*
var messages = [
'library',
'library.music',
'library.music.jazz',
'library.playlist',
'library.playlist.mine'
],
spy = this.spy(),
data = TestHelper.getUniqueString();
PubSub.subscribe( messages[0], spy ); //This should be called
PubSub.subscribe( messages[1], spy ); //This should be called
PubSub.subscribe( messages[2], spy ); //This should be called
PubSub.subscribe( messages[3], spy );
PubSub.subscribe( messages[4], spy );
PubSub.publish( messages[2], data );
PubSub.subscribe( messages[0], spy ); //This should be called
PubSub.subscribe( messages[1], spy ); //This should be called
PubSub.subscribe( messages[2], spy ); //This should be called
PubSub.subscribe( messages[3], spy );
PubSub.subscribe( messages[4], spy );
PubSub.publish( messages[2], data );
assert.equals( spy.callCount, 0 );
this.clock.tick(1);
assert.equals( spy.callCount, 3 );
assert.equals( spy.callCount, 0 );
this.clock.tick(1);
assert.equals( spy.callCount, 3 );
done();
});
done();
},
it('publish method should call all parent descendants deeply', function( done ) {
//Publishing library.music.jazz.soft.swing should trigger all but
//library.music.playlist.jazz
var messages = [
'library',
'library.music',
'library.music.jazz',
'library.music.jazz.soft',
'library.music.jazz.soft.swing',
'library.music.playlist.jazz'
],
spy = sinon.spy(),
data = TestHelper.getUniqueString();
"publish method should call all parent descendants deeply" : function( done ) {
//Publishing library.music.jazz.soft.swing should trigger all but
//library.music.playlist.jazz
var messages = [
'library',
'library.music',
'library.music.jazz',
'library.music.jazz.soft',
'library.music.jazz.soft.swing',
'library.music.playlist.jazz'
],
spy = this.spy(),
data = TestHelper.getUniqueString();
PubSub.subscribe( messages[0], spy ); //This should be called
PubSub.subscribe( messages[1], spy ); //This should be called
PubSub.subscribe( messages[2], spy ); //This should be called
PubSub.subscribe( messages[3], spy ); //This should be called
PubSub.subscribe( messages[4], spy ); //This should be called
PubSub.subscribe( messages[5], spy ); //This should be called
PubSub.subscribe( messages[6], spy );
PubSub.publish( messages[4], data );
PubSub.subscribe( messages[0], spy ); //This should be called
PubSub.subscribe( messages[1], spy ); //This should be called
PubSub.subscribe( messages[2], spy ); //This should be called
PubSub.subscribe( messages[3], spy ); //This should be called
PubSub.subscribe( messages[4], spy ); //This should be called
PubSub.subscribe( messages[5], spy ); //This should be called
PubSub.subscribe( messages[6], spy );
PubSub.publish( messages[4], data );
assert.equals( spy.callCount, 0 );
this.clock.tick(1);
assert.equals( spy.callCount, 5 );
assert.equals( spy.callCount, 0 );
this.clock.tick(1);
assert.equals( spy.callCount, 5 );
done();
});
done();
},
it('publish method should still call all parents, even when middle child is unsubscribed', function( done ) {
var messages = ['library', 'library.music', 'library.music.jazz'],
spy = sinon.spy(),
data = TestHelper.getUniqueString(),
token;
"publish method should still call all parents, even when middle child is unsubscribed" : function( done ) {
var messages = ['library', 'library.music', 'library.music.jazz'],
spy = this.spy(),
data = TestHelper.getUniqueString(),
token;
PubSub.subscribe( messages[0], spy ); //This should be called
PubSub.subscribe( messages[2], spy ); //This should be called
token = PubSub.subscribe( messages[1], spy );
PubSub.subscribe( messages[0], spy ); //This should be called
PubSub.subscribe( messages[2], spy ); //This should be called
PubSub.unsubscribe( token ); //Take out middle child
token = PubSub.subscribe( messages[1], spy );
PubSub.publish( messages[2], data );
PubSub.unsubscribe( token ); //Take out middle child
assert.equals( spy.callCount, 0 );
this.clock.tick(1);
assert.equals( spy.callCount, 2 );
PubSub.publish( messages[2], data );
done();
});
assert.equals( spy.callCount, 0 );
this.clock.tick(1);
assert.equals( spy.callCount, 2 );
it('unsubscribe method should return tokens when succesfully removing namespaced message', function(){
var func = function(){ return undefined; },
messages = ['playlist.music', 'playlist.music.jazz'],
token1 = PubSub.subscribe( messages[0], func),
token2 = PubSub.subscribe( messages[1], func ),
result1 = PubSub.unsubscribe( token1 ),
result2 = PubSub.unsubscribe( token2 );
done();
},
assert.equals( result1, token1 );
assert.equals( result2, token2 );
});
"unsubscribe method should return tokens when succesfully removing namespaced message" : function(){
var func = function(){ return undefined; },
messages = ['playlist.music', 'playlist.music.jazz'],
token1 = PubSub.subscribe( messages[0], func),
token2 = PubSub.subscribe( messages[1], func ),
result1 = PubSub.unsubscribe( token1 ),
result2 = PubSub.unsubscribe( token2 );
it('unsubscribe method should unsubscribe parent without affecting orphans', function( done ){
var data = TestHelper.getUniqueString(),
spy = sinon.spy(),
messages = ['playlist', 'playlist.music', 'playlist.music.jazz'],
token;
assert.equals( result1, token1 );
assert.equals( result2, token2 );
},
token = PubSub.subscribe( messages[0], spy ); //Gets unsubscribed
PubSub.subscribe( messages[1], spy ); //This should be called
PubSub.subscribe( messages[2], spy ); //This should be called
"unsubscribe method should unsubscribe parent without affecting orphans" : function( done ){
var data = TestHelper.getUniqueString(),
spy = this.spy(),
messages = ['playlist', 'playlist.music', 'playlist.music.jazz'],
token;
PubSub.unsubscribe( token );
token = PubSub.subscribe( messages[0], spy ); //Gets unsubscribed
PubSub.subscribe( messages[1], spy ); //This should be called
PubSub.subscribe( messages[2], spy ); //This should be called
PubSub.publish( messages[2], data );
PubSub.unsubscribe( token );
assert.equals( spy.callCount, 0 );
this.clock.tick(1);
assert.equals( spy.callCount, 2 );
PubSub.publish( messages[2], data );
assert.equals( spy.callCount, 0 );
this.clock.tick(1);
assert.equals( spy.callCount, 2 );
done();
}
});
}(this));
done();
});
});

@@ -1,44 +0,43 @@

(function( global ){
"use strict";
'use strict';
var PubSub = global.PubSub || require("../src/pubsub"),
TestHelper = global.TestHelper || require("../test/helper"),
assert = buster.assert;
var PubSub = require('../src/pubsub'),
TestHelper = require('../test/helper'),
assert = require('referee').assert,
sinon = require('sinon');
/**
* This is a test proving that bug 54 has been fixed.
* See https://github.com/mroderick/PubSubJS/issues/54
*/
buster.testCase( "Issue 54, publish method", {
/**
* This is a test proving that bug 54 has been fixed.
* See https://github.com/mroderick/PubSubJS/issues/54
*/
describe( 'Issue 54, publish method', function () {
"should notify all subscribers, even when one is unsubscribed" : function( done ){
var topic = TestHelper.getUniqueString(),
token1,
token1Unsubscribed = false,
subscriber1 = function(){
PubSub.unsubscribe(token1);
token1Unsubscribed = true;
},
spy1 = sinon.spy(subscriber1),
spy2 = this.spy(),
spy3 = this.spy(),
clock = this.useFakeTimers();
it('should notify all subscribers, even when one is unsubscribed', function( done ){
var topic = TestHelper.getUniqueString(),
token1,
token1Unsubscribed = false,
subscriber1 = function(){
PubSub.unsubscribe(token1);
token1Unsubscribed = true;
},
spy1 = sinon.spy(subscriber1),
spy2 = sinon.spy(),
spy3 = sinon.spy(),
clock = sinon.useFakeTimers();
token1 = PubSub.subscribe( topic, spy1 );
PubSub.subscribe( topic, spy2 );
PubSub.subscribe( topic, spy3 );
token1 = PubSub.subscribe( topic, spy1 );
PubSub.subscribe( topic, spy2 );
PubSub.subscribe( topic, spy3 );
PubSub.publish( topic );
PubSub.publish( topic );
clock.tick(1);
clock.tick(1);
assert( token1Unsubscribed === true );
assert( spy1.calledOnce );
assert( spy2.calledOnce );
assert( spy3.calledOnce );
assert( token1Unsubscribed === true );
assert( spy1.calledOnce );
assert( spy2.calledOnce );
assert( spy3.calledOnce );
done();
clock.restore();
}
});
}(this));
done();
clock.restore();
});
});

@@ -1,213 +0,211 @@

(function( global ){
"use strict";
'use strict';
var PubSub = global.PubSub || require("../src/pubsub"),
TestHelper = global.TestHelper || require("../test/helper"),
assert = buster.assert,
refute = buster.refute;
var PubSub = require('../src/pubsub'),
TestHelper = require('../test/helper'),
assert = require('referee').assert,
refute = require('referee').refute,
sinon = require('sinon');
buster.testCase( "publish method", {
describe( 'publish method', function () {
it('should return false if there are no subscribers', function(){
var message = TestHelper.getUniqueString();
assert.equals( PubSub.publish( message ), false );
});
"publish method should return false if there are no subscribers" : function(){
var message = TestHelper.getUniqueString();
assert.equals( PubSub.publish( message ), false );
},
it('should return true if there are subscribers to a message', function(){
var message = TestHelper.getUniqueString(),
func = function(){ return undefined; };
"publish method should return true if there are subscribers to a message" : function(){
var message = TestHelper.getUniqueString(),
func = function(){ return undefined; };
PubSub.subscribe( message, func );
assert( PubSub.publish( message ) );
});
PubSub.subscribe( message, func );
assert( PubSub.publish( message ) );
},
it('should return false, when there are no longer any subscribers to a message', function(){
var message = TestHelper.getUniqueString(),
func = function(){ return undefined; },
token = PubSub.subscribe(message, func);
"should return false, when there are no longer any subscribers to a message" : function(){
var message = TestHelper.getUniqueString(),
func = function(){ return undefined; },
token = PubSub.subscribe(message, func);
PubSub.unsubscribe(token);
assert.equals( PubSub.publish(message), false );
});
PubSub.unsubscribe(token);
assert.equals( PubSub.publish(message), false );
},
it('should call all subscribers for a message exactly once', function(){
var message = TestHelper.getUniqueString(),
spy1 = sinon.spy(),
spy2 = sinon.spy();
"publish method should call all subscribers for a message exactly once" : function(){
var message = TestHelper.getUniqueString(),
spy1 = this.spy(),
spy2 = this.spy();
PubSub.subscribe( message, spy1 );
PubSub.subscribe( message, spy2 );
PubSub.subscribe( message, spy1 );
PubSub.subscribe( message, spy2 );
PubSub.publishSync( message, 'my payload' ); // force sync here, easier to test
PubSub.publishSync( message, 'my payload' ); // force sync here, easier to test
assert( spy1.calledOnce );
assert( spy2.calledOnce );
});
assert( spy1.calledOnce );
assert( spy2.calledOnce );
},
it('should call all ONLY subscribers of the published message', function(){
var message1 = TestHelper.getUniqueString(),
message2 = TestHelper.getUniqueString(),
spy1 = sinon.spy(),
spy2 = sinon.spy();
"publish method should call all ONLY subscribers of the published message" : function(){
var message1 = TestHelper.getUniqueString(),
message2 = TestHelper.getUniqueString(),
spy1 = this.spy(),
spy2 = this.spy();
PubSub.subscribe( message1, spy1 );
PubSub.subscribe( message2, spy2 );
PubSub.subscribe( message1, spy1 );
PubSub.subscribe( message2, spy2 );
PubSub.publishSync( message1, 'some payload' );
PubSub.publishSync( message1, 'some payload' );
// ensure the first subscriber IS called
assert( spy1.called );
// ensure the second subscriber IS NOT called
assert.equals( spy2.callCount, 0 );
});
// ensure the first subscriber IS called
assert( spy1.called );
// ensure the second subscriber IS NOT called
assert.equals( spy2.callCount, 0 );
},
it('should call subscribers with message as first argument', function(){
var message = TestHelper.getUniqueString(),
spy = sinon.spy();
"publish method should call subscribers with message as first argument" : function(){
var message = TestHelper.getUniqueString(),
spy = this.spy();
PubSub.subscribe( message, spy );
PubSub.publishSync( message, 'some payload' );
PubSub.subscribe( message, spy );
PubSub.publishSync( message, 'some payload' );
assert( spy.calledWith( message ) );
});
assert( spy.calledWith( message ) );
},
it('should call subscribers with data as second argument', function(){
var message = TestHelper.getUniqueString(),
spy = sinon.spy(),
data = TestHelper.getUniqueString();
"publish method should call subscribers with data as second argument" : function(){
var message = TestHelper.getUniqueString(),
spy = this.spy(),
data = TestHelper.getUniqueString();
PubSub.subscribe( message, spy );
PubSub.publishSync( message, data );
PubSub.subscribe( message, spy );
PubSub.publishSync( message, data );
assert( spy.calledWith( message, data ) );
});
assert( spy.calledWith( message, data ) );
},
it('should publish method asyncronously', function( done ){
var message = TestHelper.getUniqueString(),
spy = sinon.spy(),
data = TestHelper.getUniqueString(),
clock = sinon.useFakeTimers();
"publish method should publish method asyncronously" : function( done ){
var message = TestHelper.getUniqueString(),
spy = this.spy(),
data = TestHelper.getUniqueString(),
clock = this.useFakeTimers();
PubSub.subscribe( message, spy );
PubSub.publish( message, data );
PubSub.subscribe( message, spy );
PubSub.publish( message, data );
assert.equals( spy.callCount, 0 );
clock.tick(1);
assert.equals( spy.callCount, 1 );
assert.equals( spy.callCount, 0 );
clock.tick(1);
assert.equals( spy.callCount, 1 );
done();
clock.restore();
});
done();
clock.restore();
},
it('publishSync method should allow syncronous publication', function(){
var message = TestHelper.getUniqueString(),
spy = sinon.spy(),
data = TestHelper.getUniqueString();
"publishSync method should allow syncronous publication" : function(){
var message = TestHelper.getUniqueString(),
spy = this.spy(),
data = TestHelper.getUniqueString();
PubSub.subscribe( message, spy );
PubSub.publishSync( message, data );
PubSub.subscribe( message, spy );
PubSub.publishSync( message, data );
assert.equals( spy.callCount, 1 );
});
assert.equals( spy.callCount, 1 );
},
it('should call all subscribers, even if there are exceptions', function( done ){
var message = TestHelper.getUniqueString(),
func1 = function(){
throw('some error');
},
spy1 = sinon.spy(),
spy2 = sinon.spy(),
clock = sinon.useFakeTimers();
"publish method should call all subscribers, even if there are exceptions" : function( done ){
var message = TestHelper.getUniqueString(),
func1 = function(){
throw('some error');
},
spy1 = this.spy(),
spy2 = this.spy(),
clock = this.useFakeTimers();
PubSub.subscribe( message, func1 );
PubSub.subscribe( message, spy1 );
PubSub.subscribe( message, spy2 );
PubSub.subscribe( message, func1 );
PubSub.subscribe( message, spy1 );
PubSub.subscribe( message, spy2 );
assert.exception( function(){
PubSub.publishSync( message, 'some data' );
clock.tick(1);
});
assert.exception( function(){
PubSub.publishSync( message, 'some data' );
clock.tick(1);
});
assert( spy1.called );
assert( spy2.called );
assert( spy1.called );
assert( spy2.called );
done();
clock.restore();
});
done();
clock.restore();
},
it('should fail immediately on exceptions when immediateExceptions is true', function(){
var message = TestHelper.getUniqueString(),
func1 = function(){
throw('some error');
},
spy1 = sinon.spy(),
spy2 = sinon.spy();
"publish method should fail immediately on exceptions when immediateExceptions is true" : function(){
var message = TestHelper.getUniqueString(),
func1 = function(){
throw('some error');
},
spy1 = this.spy(),
spy2 = this.spy();
PubSub.subscribe( message, func1 );
PubSub.subscribe( message, spy1 );
PubSub.subscribe( message, func1 );
PubSub.subscribe( message, spy1 );
PubSub.immediateExceptions = true;
PubSub.immediateExceptions = true;
assert.exception( function(){
PubSub.publishSync( message, 'some data' );
});
assert.exception( function(){
PubSub.publishSync( message, 'some data' );
});
refute( spy1.called );
refute( spy2.called );
refute( spy1.called );
refute( spy2.called );
// make sure we restore PubSub to it's original state
delete PubSub.immediateExceptions;
});
// make sure we restore PubSub to it's original state
delete PubSub.immediateExceptions;
},
it('should fail immediately on exceptions in namespaces when immediateExceptions is true', function(){
var func1 = function(){
throw('some error');
},
spy1 = sinon.spy();
"publish method should fail immediately on exceptions in namespaces when immediateExceptions is true" : function(){
var func1 = function(){
throw('some error');
},
spy1 = this.spy();
PubSub.subscribe( 'buy', func1 );
PubSub.subscribe( 'buy', spy1 );
PubSub.subscribe( 'buy', func1 );
PubSub.subscribe( 'buy', spy1 );
PubSub.immediateExceptions = true;
PubSub.immediateExceptions = true;
assert.exception( function(){
PubSub.publishSync( 'buy.tomatoes', 'some data' );
});
assert.exception( function(){
PubSub.publishSync( 'buy.tomatoes', 'some data' );
});
refute( spy1.called );
refute( spy1.called );
// make sure we restore PubSub to it's original state
delete PubSub.immediateExceptions;
});
// make sure we restore PubSub to it's original state
delete PubSub.immediateExceptions;
},
it('should call all subscribers, even when there are unsubscriptions within', function(done){
var topic = TestHelper.getUniqueString(),
spy1 = sinon.spy(),
func1 = function func1(){
PubSub.unsubscribe(func1);
spy1();
},
"publish should call all subscribers, even when there are unsubscriptions within" : function(done){
var topic = TestHelper.getUniqueString(),
spy1 = this.spy(),
func1 = function func1(){
PubSub.unsubscribe(func1);
spy1();
},
spy2 = sinon.spy(),
func2 = function func2(){
PubSub.unsubscribe(func2);
spy2();
},
spy2 = this.spy(),
func2 = function func2(){
PubSub.unsubscribe(func2);
spy2();
},
clock = sinon.useFakeTimers();
clock = this.useFakeTimers();
PubSub.subscribe(topic, func1);
PubSub.subscribe(topic, func2);
PubSub.subscribe(topic, func1);
PubSub.subscribe(topic, func2);
PubSub.publish(topic, 'some data');
clock.tick(1);
PubSub.publish(topic, 'some data');
clock.tick(1);
assert(spy1.called, 'expected spy1 to be called');
assert(spy2.called, 'expected spy2 to be called');
assert(spy1.called, 'expected spy1 to be called');
assert(spy2.called, 'expected spy2 to be called');
clock.restore();
done();
}
});
}(this));
clock.restore();
done();
});
});

@@ -1,96 +0,92 @@

(function( global ){
"use strict";
'use strict';
var PubSub = global.PubSub || require("../src/pubsub"),
TestHelper = global.TestHelper || require("../test/helper"),
assert = buster.assert,
refute = buster.refute;
var PubSub = require('../src/pubsub'),
TestHelper = require('../test/helper'),
assert = require('referee').assert,
refute = require('referee').refute;
buster.testCase( "subscribe method", {
describe( 'subscribe method', function() {
it('should return token as String', function(){
var func = function(){ return undefined; },
message = TestHelper.getUniqueString(),
token = PubSub.subscribe( message , func );
"should return token as String" : function(){
var func = function(){ return undefined; },
message = TestHelper.getUniqueString(),
token = PubSub.subscribe( message , func );
assert.isString( token );
});
assert.isString( token );
},
it('should return new token for several subscriptions with same function', function(){
var func = function(){ return undefined; },
tokens = [],
iterations = 10,
message = TestHelper.getUniqueString(),
i;
"should return new token for several subscriptions with same function" : function(){
var func = function(){ return undefined; },
tokens = [],
iterations = 10,
message = TestHelper.getUniqueString(),
i;
// build an array of tokens
for ( i = 0; i < iterations; i++ ){
tokens.push( PubSub.subscribe( message, func ) );
}
// make sure all tokens are different
TestHelper.assertAllTokensDifferent( tokens );
});
// build an array of tokens
for ( i = 0; i < iterations; i++ ){
tokens.push( PubSub.subscribe( message, func ) );
}
// make sure all tokens are different
TestHelper.assertAllTokensDifferent( tokens );
},
it('should return unique tokens for each namespaced subscription', function(){
var func = function(){ return undefined; },
tokens = [],
messages = ['library', 'library.music', 'library.music.jazz'],
i;
"should return unique tokens for each namespaced subscription" : function(){
var func = function(){ return undefined; },
tokens = [],
messages = ['library', 'library.music', 'library.music.jazz'],
i;
// build an array of tokens
for ( i = 0; i < messages.length; i++ ){
tokens.push( PubSub.subscribe( messages[i], func ) );
}
// make sure all tokens are different
TestHelper.assertAllTokensDifferent( tokens );
});
// build an array of tokens
for ( i = 0; i < messages.length; i++ ){
tokens.push( PubSub.subscribe( messages[i], func ) );
}
// make sure all tokens are different
TestHelper.assertAllTokensDifferent( tokens );
},
it('should return unique token for unique functions', function(){
var tokens = [],
iterations = 10,
message = TestHelper.getUniqueString(),
i;
"should return unique token for unique functions" : function(){
var tokens = [],
iterations = 10,
message = TestHelper.getUniqueString(),
i;
function bakeFunc( value ){
return function(){
return value;
};
}
function bakeFunc( value ){
return function(){
return value;
};
}
// build an array of tokens, passing in a different function for each subscription
for ( i = 0; i < iterations; i++ ){
tokens.push( PubSub.subscribe( message, bakeFunc( i ) ) );
}
// build an array of tokens, passing in a different function for each subscription
for ( i = 0; i < iterations; i++ ){
tokens.push( PubSub.subscribe( message, bakeFunc( i ) ) );
}
// make sure all tokens are different
TestHelper.assertAllTokensDifferent( tokens );
});
// make sure all tokens are different
TestHelper.assertAllTokensDifferent( tokens );
},
it('should return false when subscriber argument is not a function', function(){
var invalidSubscribers = [undefined, null, 'a string', 123, [], {}, new Date()],
topic = TestHelper.getUniqueString(),
i;
'should return false when subscriber argument is not a function' : function(){
var invalidSubscribers = [undefined, null, 'a string', 123, [], {}, new Date()],
topic = TestHelper.getUniqueString(),
i;
for ( i = 0; i < invalidSubscribers.length; i++ ){
assert.equals(PubSub.subscribe(topic, invalidSubscribers[i]), false);
}
for ( i = 0; i < invalidSubscribers.length; i++ ){
assert.equals(PubSub.subscribe(topic, invalidSubscribers[i]), false);
}
assert.equals(i, invalidSubscribers.length);
});
assert.equals(i, invalidSubscribers.length);
},
it('must not throw errors when publishing with invalid subscribers', function(){
var invalidSubscribers = [undefined, null, 'a string', 123, [], {}, new Date()],
topic = TestHelper.getUniqueString(),
i;
'must not throw errors when publishing with invalid subscribers' : function(){
var invalidSubscribers = [undefined, null, 'a string', 123, [], {}, new Date()],
topic = TestHelper.getUniqueString(),
i;
for (i = 0; i < invalidSubscribers.length; i++){
PubSub.subscribe(topic, invalidSubscribers[i]);
}
for (i = 0; i < invalidSubscribers.length; i++){
PubSub.subscribe(topic, invalidSubscribers[i]);
}
refute.exception(function(){
PubSub.publish(topic, TestHelper.getUniqueString());
});
}
});
}(this));
refute.exception(function(){
PubSub.publish(topic, TestHelper.getUniqueString());
});
});
});

@@ -1,163 +0,159 @@

(function( global ){
"use strict";
'use strict';
var PubSub = global.PubSub || require("../src/pubsub"),
TestHelper = global.TestHelper || require("../test/helper"),
assert = buster.assert,
refute = buster.refute;
var PubSub = require('../src/pubsub'),
TestHelper = require('../test/helper'),
assert = require('referee').assert,
refute = require('referee').refute,
sinon = require('sinon');
buster.testCase( "unsubscribe method", {
describe( 'unsubscribe method', function() {
it('should return token when succesful', function(){
var func = function(){ return undefined; },
message = TestHelper.getUniqueString(),
token = PubSub.subscribe( message, func),
result = PubSub.unsubscribe( token );
"should return token when succesful" : function(){
var func = function(){ return undefined; },
message = TestHelper.getUniqueString(),
token = PubSub.subscribe( message, func),
result = PubSub.unsubscribe( token );
assert.equals( result, token );
});
assert.equals( result, token );
},
it('should return false when unsuccesful', function(){
var unknownToken = 'my unknown token',
result = PubSub.unsubscribe( unknownToken ),
func = function(){ return undefined; },
message = TestHelper.getUniqueString(),
token = PubSub.subscribe( message, func );
"should return false when unsuccesful" : function(){
var unknownToken = 'my unknown token',
result = PubSub.unsubscribe( unknownToken ),
func = function(){ return undefined; },
message = TestHelper.getUniqueString(),
token = PubSub.subscribe( message, func );
// first, let's try a completely unknown token
assert.equals( result, false );
// first, let's try a completely unknown token
assert.equals( result, false );
// now let's try unsubscribing the same method twice
PubSub.unsubscribe( token );
assert.equals( PubSub.unsubscribe( token ), false );
});
// now let's try unsubscribing the same method twice
PubSub.unsubscribe( token );
assert.equals( PubSub.unsubscribe( token ), false );
},
it('with function argument should return true when succesful', function(){
var func = function(){ return undefined; },
message = TestHelper.getUniqueString(),
result;
PubSub.subscribe( message, func);
result = PubSub.unsubscribe( func );
"with function argument should return true when succesful" : function(){
var func = function(){ return undefined; },
message = TestHelper.getUniqueString(),
result;
assert.equals( result, true );
});
PubSub.subscribe( message, func);
result = PubSub.unsubscribe( func );
it('with function argument should return false when unsuccesful', function(){
var func = function(){ return undefined; },
message = TestHelper.getUniqueString(),
unknownToken = 'my unknown token',
result = PubSub.unsubscribe( unknownToken );
assert.equals( result, true );
},
// first, let's try a completely unknown token
"with function argument should return false when unsuccesful" : function(){
var func = function(){ return undefined; },
message = TestHelper.getUniqueString(),
unknownToken = 'my unknown token',
result = PubSub.unsubscribe( unknownToken );
assert.equals( result, false );
// first, let's try a completely unknown token
// now let's try unsubscribing the same method twice
PubSub.subscribe( message, func );
PubSub.subscribe( message, func );
PubSub.subscribe( message, func );
assert.equals( result, false );
// unsubscribe once, this should remove all subscriptions for message
PubSub.unsubscribe( func );
// now let's try unsubscribing the same method twice
PubSub.subscribe( message, func );
PubSub.subscribe( message, func );
PubSub.subscribe( message, func );
// unsubscribe again
assert.equals( PubSub.unsubscribe( func ), false );
});
// unsubscribe once, this should remove all subscriptions for message
PubSub.unsubscribe( func );
it('with topic argument, must clear all exactly matched subscriptions', function(){
var topic = TestHelper.getUniqueString(),
spy1 = sinon.spy(),
spy2 = sinon.spy();
// unsubscribe again
assert.equals( PubSub.unsubscribe( func ), false );
},
PubSub.subscribe(topic, spy1);
PubSub.subscribe(topic, spy2);
'with topic argument, must clear all exactly matched subscriptions': function(){
var topic = TestHelper.getUniqueString(),
spy1 = sinon.spy(),
spy2 = sinon.spy();
PubSub.unsubscribe(topic);
PubSub.subscribe(topic, spy1);
PubSub.subscribe(topic, spy2);
PubSub.publishSync(topic, TestHelper.getUniqueString());
PubSub.unsubscribe(topic);
refute(spy1.called);
refute(spy2.called);
});
PubSub.publishSync(topic, TestHelper.getUniqueString());
it('with topic argument, must only clear matched subscriptions', function(){
var topic1 = TestHelper.getUniqueString(),
topic2 = TestHelper.getUniqueString(),
spy1 = sinon.spy(),
spy2 = sinon.spy();
refute(spy1.called);
refute(spy2.called);
},
PubSub.subscribe(topic1, spy1);
PubSub.subscribe(topic2, spy2);
'with topic argument, must only clear matched subscriptions': function(){
var topic1 = TestHelper.getUniqueString(),
topic2 = TestHelper.getUniqueString(),
spy1 = sinon.spy(),
spy2 = sinon.spy();
PubSub.unsubscribe(topic1);
PubSub.subscribe(topic1, spy1);
PubSub.subscribe(topic2, spy2);
PubSub.publishSync(topic1, TestHelper.getUniqueString());
PubSub.publishSync(topic2, TestHelper.getUniqueString());
PubSub.unsubscribe(topic1);
refute(spy1.called);
assert(spy2.called);
});
PubSub.publishSync(topic1, TestHelper.getUniqueString());
PubSub.publishSync(topic2, TestHelper.getUniqueString());
it('with topic argument, must clear all matched hierarchical subscriptions', function(){
var topic = TestHelper.getUniqueString(),
topicA = topic + '.a',
topicB = topic + '.a.b',
topicC = topic + '.a.b.c',
spyA = sinon.spy(),
spyB = sinon.spy(),
spyC = sinon.spy();
refute(spy1.called);
assert(spy2.called);
},
PubSub.subscribe(topicA, spyA);
PubSub.subscribe(topicB, spyB);
PubSub.subscribe(topicC, spyC);
'with topic argument, must clear all matched hierarchical subscriptions': function(){
var topic = TestHelper.getUniqueString(),
topicA = topic + '.a',
topicB = topic + '.a.b',
topicC = topic + '.a.b.c',
spyA = sinon.spy(),
spyB = sinon.spy(),
spyC = sinon.spy();
PubSub.unsubscribe(topicB);
PubSub.subscribe(topicA, spyA);
PubSub.subscribe(topicB, spyB);
PubSub.subscribe(topicC, spyC);
PubSub.publishSync(topicC, TestHelper.getUniqueString());
PubSub.unsubscribe(topicB);
assert(spyA.called);
refute(spyB.called);
refute(spyC.called);
});
PubSub.publishSync(topicC, TestHelper.getUniqueString());
it('with parent topic argument, must clear all child subscriptions', function() {
var topic = TestHelper.getUniqueString(),
topicA = topic + '.a',
topicB = topic + '.a.b',
topicC = topic + '.a.b.c',
spyB = sinon.spy(),
spyC = sinon.spy();
assert(spyA.called);
refute(spyB.called);
refute(spyC.called);
},
// subscribe only to children:
PubSub.subscribe(topicB, spyB);
PubSub.subscribe(topicC, spyC);
'with parent topic argument, must clear all child subscriptions': function() {
var topic = TestHelper.getUniqueString(),
topicA = topic + '.a',
topicB = topic + '.a.b',
topicC = topic + '.a.b.c',
spyB = sinon.spy(),
spyC = sinon.spy();
// but unsubscribe from a parent:
PubSub.unsubscribe(topicA);
// subscribe only to children:
PubSub.subscribe(topicB, spyB);
PubSub.subscribe(topicC, spyC);
PubSub.publishSync(topicB, TestHelper.getUniqueString());
PubSub.publishSync(topicC, TestHelper.getUniqueString());
// but unsubscribe from a parent:
PubSub.unsubscribe(topicA);
refute(spyB.called);
refute(spyC.called);
});
PubSub.publishSync(topicB, TestHelper.getUniqueString());
PubSub.publishSync(topicC, TestHelper.getUniqueString());
it('must not throw exception when unsubscribing as part of publishing', function(){
refute.exception(function(){
var topic = TestHelper.getUniqueString(),
sub1 = function(){
PubSub.unsubscribe(sub1);
},
sub2 = function(){ return undefined; };
refute(spyB.called);
refute(spyC.called);
},
PubSub.subscribe( topic, sub1 );
PubSub.subscribe( topic, sub2 );
'must not throw exception when unsubscribing as part of publishing' : function(){
refute.exception(function(){
var topic = TestHelper.getUniqueString(),
sub1 = function(){
PubSub.unsubscribe(sub1);
},
sub2 = function(){ return undefined; };
PubSub.subscribe( topic, sub1 );
PubSub.subscribe( topic, sub2 );
PubSub.publishSync( topic, 'hello world!' );
});
}
});
}(this));
PubSub.publishSync( topic, 'hello world!' );
});
});
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc