- Basic synchronous event-emitting (node-compatible)
- Basic synchronous event-emitting (NOT compatible with node)
- Next Gen feature: async emitting
- Next Gen feature: contexts
- Next Gen feature: contexts queue
- Next Gen feature: contexts serialization
should add one listener and emit should trigger it, using 'new'.
var bus = new NextGenEvents() ;
var triggered = 0 ;
bus.on( 'hello' , function() { triggered ++ ; } ) ;
bus.emit( 'hello' ) ;
expect( triggered ).to.be( 1 ) ;
should add one listener and emit should trigger it, using 'Object.create()'.
var bus = Object.create( NextGenEvents.prototype ) ;
var triggered = 0 ;
bus.on( 'hello' , function() { triggered ++ ; } ) ;
bus.emit( 'hello' ) ;
expect( triggered ).to.be( 1 ) ;
should emit with argument.
var bus = Object.create( NextGenEvents.prototype ) ;
var triggered = 0 ;
bus.on( 'hello' , function( arg1 , arg2 ) {
triggered ++ ;
expect( arg1 ).to.be( 'world' ) ;
expect( arg2 ).to.be( '!' ) ;
} ) ;
bus.emit( 'hello' , 'world' , '!' ) ;
expect( triggered ).to.be( 1 ) ;
should add many basic listeners for many events, and multiple emits should trigger only relevant listener.
var bus = Object.create( NextGenEvents.prototype ) ;
var onFoo1 , onBar1 , onBar2 , onBaz1 , onBaz2 , onBaz3 ;
var triggered = { foo1: 0 , bar1: 0 , bar2: 0 , baz1: 0 , baz2: 0 , baz3: 0 , qux: 0 } ;
// 1 listener for 'foo'
bus.on( 'foo' , onFoo1 = function() { triggered.foo1 ++ ; } ) ;
// 2 listeners for 'bar'
bus.on( 'bar' , onBar1 = function() { triggered.bar1 ++ ; } ) ;
bus.on( 'bar' , onBar2 = function() { triggered.bar2 ++ ; } ) ;
// 3 listeners for 'baz'
bus.on( 'baz' , onBaz1 = function() { triggered.baz1 ++ ; } ) ;
bus.on( 'baz' , onBaz2 = function() { triggered.baz2 ++ ; } ) ;
bus.on( 'baz' , onBaz3 = function() { triggered.baz3 ++ ; } ) ;
bus.emit( 'foo' ) ;
expect( triggered ).to.eql( { foo1: 1 , bar1: 0 , bar2: 0 , baz1: 0 , baz2: 0 , baz3: 0 , qux: 0 } ) ;
bus.emit( 'bar' ) ;
expect( triggered ).to.eql( { foo1: 1 , bar1: 1 , bar2: 1 , baz1: 0 , baz2: 0 , baz3: 0 , qux: 0 } ) ;
bus.emit( 'baz' ) ;
expect( triggered ).to.eql( { foo1: 1 , bar1: 1 , bar2: 1 , baz1: 1 , baz2: 1 , baz3: 1 , qux: 0 } ) ;
bus.emit( 'qux' ) ;
expect( triggered ).to.eql( { foo1: 1 , bar1: 1 , bar2: 1 , baz1: 1 , baz2: 1 , baz3: 1 , qux: 0 } ) ;
bus.emit( 'foo' ) ;
bus.emit( 'foo' ) ;
expect( triggered ).to.eql( { foo1: 3 , bar1: 1 , bar2: 1 , baz1: 1 , baz2: 1 , baz3: 1 , qux: 0 } ) ;
bus.emit( 'qux' ) ;
bus.emit( 'qux' ) ;
expect( triggered ).to.eql( { foo1: 3 , bar1: 1 , bar2: 1 , baz1: 1 , baz2: 1 , baz3: 1 , qux: 0 } ) ;
bus.emit( 'baz' ) ;
bus.emit( 'baz' ) ;
expect( triggered ).to.eql( { foo1: 3 , bar1: 1 , bar2: 1 , baz1: 3 , baz2: 3 , baz3: 3 , qux: 0 } ) ;
should add and remove listeners.
var bus = Object.create( NextGenEvents.prototype ) ;
var onFoo1 , onBar1 , onBar2 , onBaz1 , onBaz2 , onBaz3 ;
var triggered = { foo1: 0 , bar1: 0 , bar2: 0 , baz1: 0 , baz2: 0 , baz3: 0 , qux: 0 } ;
// 1 listener for 'foo'
bus.on( 'foo' , onFoo1 = function() { triggered.foo1 ++ ; } ) ;
// 2 listeners for 'bar'
bus.on( 'bar' , onBar1 = function() { triggered.bar1 ++ ; } ) ;
bus.on( 'bar' , onBar2 = function() { triggered.bar2 ++ ; } ) ;
// 3 listeners for 'baz'
bus.on( 'baz' , onBaz1 = function() { triggered.baz1 ++ ; } ) ;
bus.on( 'baz' , onBaz2 = function() { triggered.baz2 ++ ; } ) ;
bus.on( 'baz' , onBaz3 = function() { triggered.baz3 ++ ; } ) ;
bus.emit( 'foo' ) ;
expect( triggered ).to.eql( { foo1: 1 , bar1: 0 , bar2: 0 , baz1: 0 , baz2: 0 , baz3: 0 , qux: 0 } ) ;
bus.emit( 'bar' ) ;
expect( triggered ).to.eql( { foo1: 1 , bar1: 1 , bar2: 1 , baz1: 0 , baz2: 0 , baz3: 0 , qux: 0 } ) ;
bus.removeListener( 'bar' , onBar2 ) ;
bus.emit( 'bar' ) ;
expect( triggered ).to.eql( { foo1: 1 , bar1: 2 , bar2: 1 , baz1: 0 , baz2: 0 , baz3: 0 , qux: 0 } ) ;
bus.removeListener( 'bar' , onBar2 ) ;
bus.emit( 'bar' ) ;
expect( triggered ).to.eql( { foo1: 1 , bar1: 3 , bar2: 1 , baz1: 0 , baz2: 0 , baz3: 0 , qux: 0 } ) ;
bus.removeListener( 'foo' , onBar1 ) ; // Not listening for this event!
bus.removeListener( 'bar' , function() {} ) ; // Not event registered
bus.emit( 'foo' ) ;
bus.emit( 'bar' ) ;
expect( triggered ).to.eql( { foo1: 2 , bar1: 4 , bar2: 1 , baz1: 0 , baz2: 0 , baz3: 0 , qux: 0 } ) ;
.removeAllListeners() should remove all listeners for an event.
var bus = Object.create( NextGenEvents.prototype ) ;
var onFoo1 , onBar1 , onBar2 , onBaz1 , onBaz2 , onBaz3 ;
var triggered = { foo1: 0 , bar1: 0 , bar2: 0 , baz1: 0 , baz2: 0 , baz3: 0 , qux: 0 } ;
// 1 listener for 'foo'
bus.on( 'foo' , onFoo1 = function() { triggered.foo1 ++ ; } ) ;
// 2 listeners for 'bar'
bus.on( 'bar' , onBar1 = function() { triggered.bar1 ++ ; } ) ;
bus.on( 'bar' , onBar2 = function() { triggered.bar2 ++ ; } ) ;
// 3 listeners for 'baz'
bus.on( 'baz' , onBaz1 = function() { triggered.baz1 ++ ; } ) ;
bus.on( 'baz' , onBaz2 = function() { triggered.baz2 ++ ; } ) ;
bus.on( 'baz' , onBaz3 = function() { triggered.baz3 ++ ; } ) ;
bus.emit( 'foo' ) ;
bus.emit( 'bar' ) ;
bus.emit( 'baz' ) ;
expect( triggered ).to.eql( { foo1: 1 , bar1: 1 , bar2: 1 , baz1: 1 , baz2: 1 , baz3: 1 , qux: 0 } ) ;
bus.removeAllListeners( 'bar' ) ;
bus.emit( 'bar' ) ;
expect( triggered ).to.eql( { foo1: 1 , bar1: 1 , bar2: 1 , baz1: 1 , baz2: 1 , baz3: 1 , qux: 0 } ) ;
bus.emit( 'foo' ) ;
expect( triggered ).to.eql( { foo1: 2 , bar1: 1 , bar2: 1 , baz1: 1 , baz2: 1 , baz3: 1 , qux: 0 } ) ;
bus.removeAllListeners( 'baz' ) ;
bus.emit( 'foo' ) ;
bus.emit( 'bar' ) ;
bus.emit( 'baz' ) ;
expect( triggered ).to.eql( { foo1: 3 , bar1: 1 , bar2: 1 , baz1: 1 , baz2: 1 , baz3: 1 , qux: 0 } ) ;
.removeAllListeners() without argument should all listeners for all events.
var bus = Object.create( NextGenEvents.prototype ) ;
var onFoo1 , onBar1 , onBar2 , onBaz1 , onBaz2 , onBaz3 ;
var triggered = { foo1: 0 , bar1: 0 , bar2: 0 , baz1: 0 , baz2: 0 , baz3: 0 , qux: 0 } ;
// 1 listener for 'foo'
bus.on( 'foo' , onFoo1 = function() { triggered.foo1 ++ ; } ) ;
// 2 listeners for 'bar'
bus.on( 'bar' , onBar1 = function() { triggered.bar1 ++ ; } ) ;
bus.on( 'bar' , onBar2 = function() { triggered.bar2 ++ ; } ) ;
// 3 listeners for 'baz'
bus.on( 'baz' , onBaz1 = function() { triggered.baz1 ++ ; } ) ;
bus.on( 'baz' , onBaz2 = function() { triggered.baz2 ++ ; } ) ;
bus.on( 'baz' , onBaz3 = function() { triggered.baz3 ++ ; } ) ;
bus.emit( 'foo' ) ;
bus.emit( 'bar' ) ;
bus.emit( 'baz' ) ;
expect( triggered ).to.eql( { foo1: 1 , bar1: 1 , bar2: 1 , baz1: 1 , baz2: 1 , baz3: 1 , qux: 0 } ) ;
bus.removeAllListeners() ;
bus.emit( 'foo' ) ;
bus.emit( 'bar' ) ;
bus.emit( 'baz' ) ;
bus.emit( 'qux' ) ;
expect( triggered ).to.eql( { foo1: 1 , bar1: 1 , bar2: 1 , baz1: 1 , baz2: 1 , baz3: 1 , qux: 0 } ) ;
.once() should add one time listener for an event, the event should stop listening after being triggered once.
var bus = Object.create( NextGenEvents.prototype ) ;
var onFoo1 , onBar1 , onBar2 , onBaz1 , onBaz2 , onBaz3 ;
var triggered = { foo1: 0 , bar1: 0 , bar2: 0 , baz1: 0 , baz2: 0 , qux: 0 } ;
// 1 listener for 'foo'
bus.once( 'foo' , onFoo1 = function() { triggered.foo1 ++ ; } ) ;
// 2 listeners for 'bar'
bus.on( 'bar' , onBar1 = function() { triggered.bar1 ++ ; } ) ;
bus.once( 'bar' , onBar2 = function() { triggered.bar2 ++ ; } ) ;
// 3 listeners for 'baz'
bus.on( 'baz' , onBaz1 = function() { triggered.baz1 ++ ; } ) ;
onBaz2 = function() { triggered.baz2 ++ ; } ;
bus.once( 'baz' , onBaz2 ) ;
bus.once( 'baz' , onBaz2 ) ;
bus.once( 'baz' , onBaz2 ) ;
bus.emit( 'foo' ) ;
bus.emit( 'bar' ) ;
bus.emit( 'baz' ) ;
expect( triggered ).to.eql( { foo1: 1 , bar1: 1 , bar2: 1 , baz1: 1 , baz2: 3 , qux: 0 } ) ;
bus.emit( 'foo' ) ;
expect( triggered ).to.eql( { foo1: 1 , bar1: 1 , bar2: 1 , baz1: 1 , baz2: 3 , qux: 0 } ) ;
bus.emit( 'bar' ) ;
expect( triggered ).to.eql( { foo1: 1 , bar1: 2 , bar2: 1 , baz1: 1 , baz2: 3 , qux: 0 } ) ;
bus.emit( 'baz' ) ;
expect( triggered ).to.eql( { foo1: 1 , bar1: 2 , bar2: 1 , baz1: 2 , baz2: 3 , qux: 0 } ) ;
unhandled 'error' event should throw whatever is passed to it.
var throwed = 0 , triggered = 0 ;
var bus = Object.create( NextGenEvents.prototype ) ;
var testError = new Error( 'Some error occurs!' ) ;
var onError = function( error ) {
triggered ++ ;
expect( error ).to.be( testError ) ;
} ;
try {
bus.emit( 'error' , testError ) ;
}
catch ( error ) {
throwed ++ ;
expect( error ).to.be( testError ) ;
}
expect( throwed ).to.be( 1 ) ;
bus.once( 'error' , onError ) ;
bus.emit( 'error' , testError ) ;
// Should not throw
expect( triggered ).to.be( 1 ) ;
try {
bus.emit( 'error' , testError ) ;
}
catch ( error ) {
throwed ++ ;
expect( error ).to.be( testError ) ;
}
expect( throwed ).to.be( 2 ) ;
NextGenEvents.listenerCount() should count listeners for an event.
var bus = Object.create( NextGenEvents.prototype ) ;
var onFoo1 ;
onFoo1 = function() {} ;
bus.on( 'foo' , onFoo1 ) ;
expect( NextGenEvents.listenerCount( bus , 'foo' ) ).to.be( 1 ) ;
expect( NextGenEvents.listenerCount( bus , 'bar' ) ).to.be( 0 ) ;
bus.on( 'foo' , onFoo1 ) ;
bus.on( 'foo' , onFoo1 ) ;
expect( NextGenEvents.listenerCount( bus , 'foo' ) ).to.be( 3 ) ;
expect( NextGenEvents.listenerCount( bus , 'bar' ) ).to.be( 0 ) ;
bus.removeListener( 'foo' , onFoo1 ) ;
expect( NextGenEvents.listenerCount( bus , 'foo' ) ).to.be( 0 ) ;
expect( NextGenEvents.listenerCount( bus , 'bar' ) ).to.be( 0 ) ;
bus.once( 'foo' , onFoo1 ) ;
expect( NextGenEvents.listenerCount( bus , 'foo' ) ).to.be( 1 ) ;
expect( NextGenEvents.listenerCount( bus , 'bar' ) ).to.be( 0 ) ;
bus.emit( 'foo' ) ;
expect( NextGenEvents.listenerCount( bus , 'foo' ) ).to.be( 0 ) ;
expect( NextGenEvents.listenerCount( bus , 'bar' ) ).to.be( 0 ) ;
should remove every occurences of a listener for one event.
var bus = Object.create( NextGenEvents.prototype ) ;
var onFoo1 , onBar1 , onBar2 ;
var triggered = { foo1: 0 , bar1: 0 , bar2: 0 } ;
onFoo1 = function() { triggered.foo1 ++ ; } ;
onBar1 = function() { triggered.bar1 ++ ; } ;
onBar2 = function() { triggered.bar2 ++ ; } ;
// 1 listener for 'foo'
bus.on( 'foo' , onFoo1 ) ;
// 2 listeners for 'bar'
bus.on( 'bar' , onBar1 ) ;
// Same listener added multiple times
bus.on( 'bar' , onBar2 ) ;
bus.on( 'bar' , onBar2 ) ;
bus.on( 'bar' , onBar2 ) ;
bus.emit( 'foo' ) ;
bus.emit( 'bar' ) ;
expect( triggered ).to.eql( { foo1: 1 , bar1: 1 , bar2: 3 } ) ;
bus.removeListener( 'bar' , onBar2 ) ;
bus.emit( 'bar' ) ;
expect( triggered ).to.eql( { foo1: 1 , bar1: 2 , bar2: 3 } ) ;
should emit 'newListener' every time a new listener is added, with an array of listener object.
var bus = Object.create( NextGenEvents.prototype ) ;
var stats = { count: {} , orders: [] } ;
bus.on( 'newListener' , genericListener.bind( undefined , 'new1' , stats , function( listeners ) {
expect( listeners.length ).to.be( 1 ) ;
expect( typeof listeners[ 0 ] ).to.be( 'object' ) ;
switch ( stats.count.new1 )
{
case 1 :
expect( listeners[ 0 ].event ).to.be( 'foo' ) ;
break ;
case 2 :
expect( listeners[ 0 ].event ).to.be( 'newListener' ) ;
break ;
case 3 :
expect( listeners[ 0 ].event ).to.be( 'bar' ) ;
break ;
default :
expect().fail() ;
}
} ) ) ;
expect( stats.count ).to.eql( {} ) ;
bus.on( 'foo' , genericListener.bind( undefined , 'foo' , stats , undefined ) ) ;
expect( stats.count ).to.eql( { new1: 1 } ) ;
expect( stats.orders ).to.eql( [ 'new1' ] ) ;
bus.emit( 'foo' ) ;
expect( stats.count ).to.eql( { new1: 1 , foo: 1 } ) ;
expect( stats.orders ).to.eql( [ 'new1' , 'foo' ] ) ;
bus.on( 'newListener' , genericListener.bind( undefined , 'new2' , stats , function( listeners ) {
expect( listeners.length ).to.be( 1 ) ;
expect( typeof listeners[ 0 ] ).to.be( 'object' ) ;
switch ( stats.count.new2 )
{
case 1 :
expect( listeners[ 0 ].event ).to.be( 'bar' ) ;
break ;
default :
expect().fail() ;
}
} ) ) ;
expect( stats.count ).to.eql( { new1: 2 , foo: 1 } ) ;
expect( stats.orders ).to.eql( [ 'new1' , 'foo' , 'new1' ] ) ;
bus.once( 'bar' , genericListener.bind( undefined , 'bar' , stats , undefined ) ) ;
expect( stats.count ).to.eql( { new1: 3 , new2: 1 , foo: 1 } ) ;
expect( stats.orders ).to.eql( [ 'new1' , 'foo' , 'new1' , 'new1' , 'new2' ] ) ;
bus.emit( 'bar' ) ;
expect( stats.count ).to.eql( { new1: 3 , new2: 1 , foo: 1 , bar: 1 } ) ;
expect( stats.orders ).to.eql( [ 'new1' , 'foo' , 'new1' , 'new1' , 'new2' , 'bar' ] ) ;
should emit 'removeListener' every time a new listener is removed (one time listener count as well once triggered), with an array of listener object.
var bus = Object.create( NextGenEvents.prototype ) ;
var stats = { count: {} , orders: [] } ;
var onFoo = genericListener.bind( undefined , 'foo' , stats , undefined ) ;
var onBar1 = genericListener.bind( undefined , 'bar1' , stats , undefined ) ;
var onBar2 = genericListener.bind( undefined , 'bar2' , stats , undefined ) ;
bus.on( 'removeListener' , genericListener.bind( undefined , 'rm1' , stats , function( listeners ) {
switch ( stats.count.rm1 )
{
case 1 :
expect( listeners.length ).to.be( 1 ) ;
expect( typeof listeners[ 0 ] ).to.be( 'object' ) ;
expect( listeners[ 0 ].event ).to.be( 'foo' ) ;
expect( listeners[ 0 ].id ).to.be( onFoo ) ;
break ;
case 2 :
expect( listeners.length ).to.be( 3 ) ;
expect( typeof listeners[ 0 ] ).to.be( 'object' ) ;
expect( typeof listeners[ 1 ] ).to.be( 'object' ) ;
expect( typeof listeners[ 2 ] ).to.be( 'object' ) ;
expect( listeners[ 0 ].event ).to.be( 'foo' ) ;
expect( listeners[ 0 ].id ).to.be( onFoo ) ;
expect( listeners[ 1 ].event ).to.be( 'foo' ) ;
expect( listeners[ 1 ].id ).to.be( onFoo ) ;
expect( listeners[ 2 ].event ).to.be( 'foo' ) ;
expect( listeners[ 2 ].id ).to.be( onFoo ) ;
break ;
case 3 :
expect( listeners.length ).to.be( 1 ) ;
expect( typeof listeners[ 0 ] ).to.be( 'object' ) ;
expect( listeners[ 0 ].event ).to.be( 'foo' ) ;
expect( listeners[ 0 ].id ).to.be( onFoo ) ;
break ;
case 4 :
expect( listeners.length ).to.be( 2 ) ;
expect( typeof listeners[ 0 ] ).to.be( 'object' ) ;
expect( typeof listeners[ 1 ] ).to.be( 'object' ) ;
expect( listeners[ 0 ].event ).to.be( 'bar' ) ;
expect( listeners[ 0 ].id ).to.be( onBar1 ) ;
expect( listeners[ 1 ].event ).to.be( 'bar' ) ;
expect( listeners[ 1 ].id ).to.be( onBar2 ) ;
break ;
default :
expect().fail() ;
}
} ) ) ;
expect( stats.count ).to.eql( {} ) ;
bus.on( 'foo' , onFoo ) ;
expect( stats.count ).to.eql( {} ) ;
expect( stats.orders ).to.eql( [] ) ;
bus.off( 'foo' , onFoo ) ;
expect( stats.count ).to.eql( { rm1: 1 } ) ;
expect( stats.orders ).to.eql( [ 'rm1' ] ) ;
bus.on( 'foo' , onFoo ) ;
bus.on( 'foo' , onFoo ) ;
bus.on( 'foo' , onFoo ) ;
expect( stats.count ).to.eql( { rm1: 1 } ) ;
expect( stats.orders ).to.eql( [ 'rm1' ] ) ;
bus.off( 'foo' , onFoo ) ;
expect( stats.count ).to.eql( { rm1: 2 } ) ;
expect( stats.orders ).to.eql( [ 'rm1' , 'rm1' ] ) ;
bus.once( 'foo' , onFoo ) ;
expect( stats.count ).to.eql( { rm1: 2 } ) ;
expect( stats.orders ).to.eql( [ 'rm1' , 'rm1' ] ) ;
bus.emit( 'foo' , onFoo ) ;
expect( stats.count ).to.eql( { rm1: 3 , foo: 1 } ) ;
expect( stats.orders ).to.eql( [ 'rm1' , 'rm1' , 'foo' , 'rm1' ] ) ;
bus.on( 'foo' , onFoo ) ;
bus.on( 'bar' , onBar1 ) ;
bus.on( 'bar' , onBar2 ) ;
bus.removeAllListeners( 'bar' ) ;
expect( stats.count ).to.eql( { rm1: 4 , foo: 1 } ) ;
expect( stats.orders ).to.eql( [ 'rm1' , 'rm1' , 'foo' , 'rm1' , 'rm1' ] ) ;
bus.on( 'foo' , onFoo ) ;
bus.on( 'bar' , onBar1 ) ;
bus.on( 'bar' , onBar2 ) ;
bus.removeAllListeners() ;
// 'removeListener' listener are not fired: they are already deleted
expect( stats.count ).to.eql( { rm1: 4 , foo: 1 } ) ;
expect( stats.orders ).to.eql( [ 'rm1' , 'rm1' , 'foo' , 'rm1' , 'rm1' ] ) ;
.listeners() should return all the listeners for an event.
var bus = Object.create( NextGenEvents.prototype ) ;
var listeners , onFoo1 ;
onFoo1 = function() {} ;
bus.on( 'foo' , onFoo1 ) ;
listeners = bus.listeners( 'foo' ) ;
expect( listeners.length ).to.be( 1 ) ;
expect( listeners[ 0 ].id ).to.be( onFoo1 ) ;
expect( listeners[ 0 ].fn ).to.be( onFoo1 ) ;
expect( listeners[ 0 ].event ).to.be( 'foo' ) ;
expect( bus.listeners( 'bar' ).length ).to.be( 0 ) ;
bus.on( 'foo' , onFoo1 ) ;
bus.on( 'foo' , onFoo1 ) ;
listeners = bus.listeners( 'foo' ) ;
expect( listeners.length ).to.be( 3 ) ;
expect( listeners[ 1 ].id ).to.be( onFoo1 ) ;
expect( listeners[ 1 ].fn ).to.be( onFoo1 ) ;
expect( listeners[ 1 ].event ).to.be( 'foo' ) ;
expect( listeners[ 2 ].id ).to.be( onFoo1 ) ;
expect( listeners[ 2 ].fn ).to.be( onFoo1 ) ;
expect( listeners[ 2 ].event ).to.be( 'foo' ) ;
expect( bus.listeners( 'bar' ).length ).to.be( 0 ) ;
bus.removeListener( 'foo' , onFoo1 ) ;
expect( bus.listeners( 'foo' ).length ).to.be( 0 ) ;
expect( bus.listeners( 'bar' ).length ).to.be( 0 ) ;
bus.once( 'foo' , onFoo1 ) ;
listeners = bus.listeners( 'foo' ) ;
expect( listeners.length ).to.be( 1 ) ;
expect( listeners[ 0 ].id ).to.be( onFoo1 ) ;
expect( listeners[ 0 ].fn ).to.be( onFoo1 ) ;
expect( listeners[ 0 ].event ).to.be( 'foo' ) ;
expect( bus.listeners( 'bar' ).length ).to.be( 0 ) ;
bus.emit( 'foo' ) ;
listeners = bus.listeners( 'foo' ) ;
expect( bus.listeners( 'foo' ).length ).to.be( 0 ) ;
expect( bus.listeners( 'bar' ).length ).to.be( 0 ) ;
should emit synchronously, with a synchronous flow (nice = NextGenEvents.SYNC).
asyncEventTest( NextGenEvents.SYNC , undefined , undefined , undefined , function( order ) {
expect( order ).to.eql( [ 'listener' , 'flow' , 'nextTick' , 'setImmediate' , 'setTimeout5' , 'setTimeout20' ] ) ;
done() ;
} ) ;
should emit asynchronously, with an asynchronous flow, as fast as possible (nice = NextGenEvents.NEXT_TICK).
asyncEventTest( NextGenEvents.NEXT_TICK , undefined , undefined , undefined , function( order ) {
expect( order ).to.eql( [ 'flow' , 'listener' , 'nextTick' , 'setImmediate' , 'setTimeout5' , 'setTimeout20' ] ) ;
done() ;
} ) ;
should emit asynchronously, with an asynchronous flow, almost as fast as possible (nice = NextGenEvents.IMMEDIATE).
asyncEventTest( NextGenEvents.IMMEDIATE , undefined , undefined , undefined , function( order ) {
expect( order ).to.eql( [ 'flow' , 'nextTick' , 'listener' , 'setImmediate' , 'setTimeout5' , 'setTimeout20' ] ) ;
done() ;
} ) ;
should emit asynchronously, with an asynchronous flow, with minimal delay (nice = NextGenEvents.TIMEOUT).
asyncEventTest( NextGenEvents.TIMEOUT , undefined , undefined , undefined , function( order ) {
try {
expect( order ).to.eql( [ 'flow' , 'nextTick' , 'setImmediate' , 'listener' , 'setTimeout5' , 'setTimeout20' ] ) ;
}
catch( error ) {
// Sometime setImmediate() is unpredictable and is slower than setTimeout(fn,0)
// It is a bug of V8, not a bug of the async lib
expect( order ).to.eql( [ 'flow' , 'nextTick' , 'listener' , 'setImmediate' , 'setTimeout5' , 'setTimeout20' ] ) ;
}
done() ;
} ) ;
should emit asynchronously, with an asynchronous flow, with a 10ms delay (nice = 1 -> setTimeout 10ms).
asyncEventTest( 1 , undefined , undefined , undefined , function( order ) {
expect( order ).to.eql( [ 'flow' , 'nextTick' , 'setImmediate' , 'setTimeout5' , 'listener' , 'setTimeout20' ] ) ;
done() ;
} ) ;
should emit asynchronously, with an asynchronous flow, with a 30ms delay (nice = 3 -> setTimeout 30ms).
asyncEventTest( 3 , undefined , undefined , undefined , function( order ) {
expect( order ).to.eql( [ 'flow' , 'nextTick' , 'setImmediate' , 'setTimeout5' , 'setTimeout20' , 'listener' ] ) ;
done() ;
} ) ;
.emit( nice , event , ... ) should overide emitter's nice value.
asyncEventTest( undefined , 1 , undefined , undefined , function( order ) {
expect( order ).to.eql( [ 'flow' , 'nextTick' , 'setImmediate' , 'setTimeout5' , 'listener' , 'setTimeout20' ] ) ;
asyncEventTest( NextGenEvents.SYNC , 1 , undefined , undefined , function( order ) {
expect( order ).to.eql( [ 'flow' , 'nextTick' , 'setImmediate' , 'setTimeout5' , 'listener' , 'setTimeout20' ] ) ;
asyncEventTest( 10 , 1 , undefined , undefined , function( order ) {
expect( order ).to.eql( [ 'flow' , 'nextTick' , 'setImmediate' , 'setTimeout5' , 'listener' , 'setTimeout20' ] ) ;
done() ;
} ) ;
} ) ;
} ) ;
should use the highest nice value between the context's nice, the listener's nice and the emitter's nice.
asyncEventTest( undefined , 1 , NextGenEvents.SYNC , NextGenEvents.SYNC , function( order ) {
expect( order ).to.eql( [ 'flow' , 'nextTick' , 'setImmediate' , 'setTimeout5' , 'listener' , 'setTimeout20' ] ) ;
asyncEventTest( undefined , NextGenEvents.SYNC , 1 , NextGenEvents.SYNC , function( order ) {
expect( order ).to.eql( [ 'flow' , 'nextTick' , 'setImmediate' , 'setTimeout5' , 'listener' , 'setTimeout20' ] ) ;
asyncEventTest( undefined , NextGenEvents.SYNC , NextGenEvents.SYNC , 1 , function( order ) {
expect( order ).to.eql( [ 'flow' , 'nextTick' , 'setImmediate' , 'setTimeout5' , 'listener' , 'setTimeout20' ] ) ;
done() ;
} ) ;
} ) ;
} ) ;
when a listener is tied to a context, it should stop receiving events if the context is disabled (implicit context declaration).
var bus = Object.create( NextGenEvents.prototype ) ;
var triggered = 0 ;
bus.on( 'foo' , {
context: 'bar' ,
fn: function() { triggered ++ ; }
} ) ;
bus.emit( 'foo' ) ;
expect( triggered ).to.be( 1 ) ;
bus.disableListenerContext( 'bar' ) ;
bus.emit( 'foo' ) ;
bus.emit( 'foo' ) ;
bus.emit( 'foo' ) ;
expect( triggered ).to.be( 1 ) ;
bus.enableListenerContext( 'bar' ) ;
bus.emit( 'foo' ) ;
expect( triggered ).to.be( 2 ) ;
when a listener is tied to a context, it should stop receiving events if the context is disabled (explicit context declaration).
var bus = Object.create( NextGenEvents.prototype ) ;
var triggered = 0 ;
bus.addListenerContext( 'bar' , { status: NextGenEvents.CONTEXT_DISABLED } ) ;
bus.on( 'foo' , {
context: 'bar' ,
fn: function() { triggered ++ ; }
} ) ;
bus.emit( 'foo' ) ;
bus.emit( 'foo' ) ;
bus.emit( 'foo' ) ;
expect( triggered ).to.be( 0 ) ;
bus.enableListenerContext( 'bar' ) ;
bus.emit( 'foo' ) ;
expect( triggered ).to.be( 1 ) ;
bus.disableListenerContext( 'bar' ) ;
bus.emit( 'foo' ) ;
expect( triggered ).to.be( 1 ) ;
bus.enableListenerContext( 'bar' ) ;
bus.emit( 'foo' ) ;
expect( triggered ).to.be( 2 ) ;
.destroyListenerContext() should destroy a context and all listeners tied to it.
var bus = Object.create( NextGenEvents.prototype ) ;
var stats = { count: {} , orders: [] } ;
bus.on( 'foo' , {
id: 'foo1' ,
context: 'bar' ,
fn: genericListener.bind( undefined , 'foo1' , stats , undefined )
} ) ;
bus.on( 'foo' , {
id: 'foo2' ,
context: 'bar' ,
fn: genericListener.bind( undefined , 'foo2' , stats , undefined )
} ) ;
bus.on( 'baz' , {
id: 'baz1' ,
context: 'bar' ,
fn: genericListener.bind( undefined , 'baz1' , stats , undefined )
} ) ;
bus.on( 'baz' , {
id: 'baz2' ,
context: 'qux' ,
fn: genericListener.bind( undefined , 'baz2' , stats , undefined )
} ) ;
bus.emit( 'foo' ) ;
expect( stats.count ).to.eql( { foo1: 1 , foo2: 1 } ) ;
bus.emit( 'baz' ) ;
expect( stats.count ).to.eql( { foo1: 1 , foo2: 1 , baz1: 1 , baz2: 1 } ) ;
bus.destroyListenerContext( 'bar' ) ;
bus.emit( 'foo' ) ;
expect( stats.count ).to.eql( { foo1: 1 , foo2: 1 , baz1: 1 , baz2: 1 } ) ;
bus.emit( 'baz' ) ;
expect( stats.count ).to.eql( { foo1: 1 , foo2: 1 , baz1: 1 , baz2: 2 } ) ;
bus.destroyListenerContext( 'qux' ) ;
bus.emit( 'foo' ) ;
expect( stats.count ).to.eql( { foo1: 1 , foo2: 1 , baz1: 1 , baz2: 2 } ) ;
bus.emit( 'baz' ) ;
expect( stats.count ).to.eql( { foo1: 1 , foo2: 1 , baz1: 1 , baz2: 2 } ) ;
.queueListenerContext() should pause the context, queueing events, .enableListenerContext() should resume pending events emitting.
var bus = Object.create( NextGenEvents.prototype ) ;
var stats = { count: {} , orders: [] } ;
bus.on( 'foo' , {
id: 'foobar' ,
context: 'qux' ,
fn: genericListener.bind( undefined , 'foobar' , stats , function() {
var args = Array.prototype.slice.call( arguments ) ;
switch ( stats.count.foobar )
{
case 1 :
expect( args ).to.eql( [ 'one' , 'two' , 'three' ] ) ;
break ;
case 2 :
expect( args ).to.eql( [ 'four' , 'five' , 'six' ] ) ;
break ;
case 3 :
expect( args ).to.eql( [] ) ;
break ;
case 4 :
expect( args ).to.eql( [ 'seven' ] ) ;
break ;
}
} )
} ) ;
bus.on( 'foo' , {
id: 'foobaz' ,
context: 'qux' ,
fn: genericListener.bind( undefined , 'foobaz' , stats , function() {
var args = Array.prototype.slice.call( arguments ) ;
switch ( stats.count.foobaz )
{
case 1 :
expect( args ).to.eql( [ 'one' , 'two' , 'three' ] ) ;
break ;
case 2 :
expect( args ).to.eql( [ 'four' , 'five' , 'six' ] ) ;
break ;
case 3 :
expect( args ).to.eql( [] ) ;
break ;
case 4 :
expect( args ).to.eql( [ 'seven' ] ) ;
break ;
}
} )
} ) ;
bus.on( 'qbar' , {
id: 'qbarbaz' ,
context: 'qbarbaz' ,
fn: genericListener.bind( undefined , 'qbarbaz' , stats , undefined )
} ) ;
bus.emit( 'foo' , 'one' , 'two' , 'three' ) ;
bus.emit( 'qbar' ) ;
expect( stats.count ).to.eql( { foobar: 1 , foobaz: 1 , qbarbaz: 1 } ) ;
bus.queueListenerContext( 'qux' ) ;
bus.emit( 'foo' , 'four' , 'five' , 'six' ) ;
bus.emit( 'foo' ) ;
bus.emit( 'foo' , 'seven' ) ;
bus.emit( 'qbar' ) ;
expect( stats.count ).to.eql( { foobar: 1 , foobaz: 1 , qbarbaz: 2 } ) ;
bus.enableListenerContext( 'qux' ) ;
expect( stats.count ).to.eql( { foobar: 4 , foobaz: 4 , qbarbaz: 2 } ) ;
3 async listeners for an event, tied to a serial context, each listener should be triggered one after the other.
var bus = Object.create( NextGenEvents.prototype ) ;
var stats = { count: {} , orders: [] } ;
bus.on( 'foo' , {
id: 'foobar' ,
context: 'qux' ,
async: true ,
fn: genericListener.bind( undefined , 'foobar' , stats , function() {
var callback = arguments[ arguments.length - 1 ] ;
setTimeout( callback , 30 ) ;
} )
} ) ;
bus.on( 'foo' , {
id: 'foobaz' ,
context: 'qux' ,
async: true ,
fn: genericListener.bind( undefined , 'foobaz' , stats , function() {
expect( stats.count ).to.eql( { foobar: 1 , foobaz: 1 } ) ;
var callback = arguments[ arguments.length - 1 ] ;
setTimeout( callback , 30 ) ;
} )
} ) ;
bus.on( 'foo' , {
id: 'foobarbaz' ,
context: 'qux' ,
async: true ,
fn: genericListener.bind( undefined , 'foobarbaz' , stats , function() {
expect( stats.count ).to.eql( { foobar: 1 , foobaz: 1 , foobarbaz: 1 } ) ;
var callback = arguments[ arguments.length - 1 ] ;
setTimeout( function() {
callback() ;
done() ;
} , 30 ) ;
} )
} ) ;
bus.serializeListenerContext( 'qux' ) ;
bus.emit( 'foo' ) ;
expect( stats.count ).to.eql( { foobar: 1 } ) ;
3 async listeners for 3 events, tied to a serial context, each listener should be triggered one after the other.
var bus = Object.create( NextGenEvents.prototype ) ;
var stats = { count: {} , orders: [] } ;
bus.on( 'bar' , {
id: 'foobar' ,
context: 'qux' ,
async: true ,
fn: genericListener.bind( undefined , 'foobar' , stats , function() {
var callback = arguments[ arguments.length - 1 ] ;
setTimeout( callback , 30 ) ;
} )
} ) ;
bus.on( 'baz' , {
id: 'foobaz' ,
context: 'qux' ,
async: true ,
fn: genericListener.bind( undefined , 'foobaz' , stats , function() {
expect( stats.count ).to.eql( { foobar: 1 , foobaz: 1 } ) ;
var callback = arguments[ arguments.length - 1 ] ;
setTimeout( callback , 30 ) ;
} )
} ) ;
bus.on( 'barbaz' , {
id: 'foobarbaz' ,
context: 'qux' ,
async: true ,
fn: genericListener.bind( undefined , 'foobarbaz' , stats , function() {
expect( stats.count ).to.eql( { foobar: 1 , foobaz: 1 , foobarbaz: 1 } ) ;
var callback = arguments[ arguments.length - 1 ] ;
setTimeout( function() {
callback() ;
done() ;
} , 30 ) ;
} )
} ) ;
bus.serializeListenerContext( 'qux' ) ;
bus.emit( 'bar' ) ;
bus.emit( 'baz' ) ;
bus.emit( 'barbaz' ) ;
expect( stats.count ).to.eql( { foobar: 1 } ) ;
mixing sync and async listeners tied to a serial context, sync event should not block (test 1).
var bus = Object.create( NextGenEvents.prototype ) ;
var stats = { count: {} , orders: [] } ;
bus.on( 'bar' , {
id: 'foobar' ,
context: 'qux' ,
fn: genericListener.bind( undefined , 'foobar' , stats , function() {
} )
} ) ;
bus.on( 'baz' , {
id: 'foobaz' ,
context: 'qux' ,
fn: genericListener.bind( undefined , 'foobaz' , stats , function() {
} )
} ) ;
bus.on( 'barbaz' , {
id: 'foobarbaz' ,
context: 'qux' ,
async: true ,
fn: genericListener.bind( undefined , 'foobarbaz' , stats , function() {
expect( stats.count ).to.eql( { foobar: 1 , foobaz: 1 , foobarbaz: 1 } ) ;
var callback = arguments[ arguments.length - 1 ] ;
setTimeout( function() {
callback() ;
done() ;
} , 30 ) ;
} )
} ) ;
bus.serializeListenerContext( 'qux' ) ;
bus.emit( 'bar' ) ;
bus.emit( 'baz' ) ;
bus.emit( 'barbaz' ) ;
expect( stats.count ).to.eql( { foobar: 1 , foobaz: 1 , foobarbaz: 1 } ) ;
mixing sync and async listeners tied to a serial context, sync event should not block (test 2).
var bus = Object.create( NextGenEvents.prototype ) ;
var stats = { count: {} , orders: [] } ;
bus.on( 'bar' , {
id: 'foobar' ,
context: 'qux' ,
fn: genericListener.bind( undefined , 'foobar' , stats , function() {
} )
} ) ;
bus.on( 'baz' , {
id: 'foobaz' ,
context: 'qux' ,
async: true ,
fn: genericListener.bind( undefined , 'foobaz' , stats , function() {
expect( stats.count ).to.eql( { foobar: 1 , foobaz: 1 } ) ;
var callback = arguments[ arguments.length - 1 ] ;
setTimeout( callback , 30 ) ;
} )
} ) ;
bus.on( 'barbaz' , {
id: 'foobarbaz' ,
context: 'qux' ,
async: true ,
fn: genericListener.bind( undefined , 'foobarbaz' , stats , function() {
expect( stats.count ).to.eql( { foobar: 1 , foobaz: 1 , foobarbaz: 1 } ) ;
var callback = arguments[ arguments.length - 1 ] ;
setTimeout( function() {
callback() ;
done() ;
} , 30 ) ;
} )
} ) ;
bus.serializeListenerContext( 'qux' ) ;
bus.emit( 'bar' ) ;
bus.emit( 'baz' ) ;
bus.emit( 'barbaz' ) ;
expect( stats.count ).to.eql( { foobar: 1 , foobaz: 1 } ) ;
mixing sync and async listeners tied to a serial context, sync event should not block (test 3).
var bus = Object.create( NextGenEvents.prototype ) ;
var stats = { count: {} , orders: [] } ;
bus.on( 'bar' , {
id: 'foobar' ,
context: 'qux' ,
async: true ,
fn: genericListener.bind( undefined , 'foobar' , stats , function() {
var callback = arguments[ arguments.length - 1 ] ;
setTimeout( callback , 30 ) ;
} )
} ) ;
bus.on( 'baz' , {
id: 'foobaz' ,
context: 'qux' ,
fn: genericListener.bind( undefined , 'foobaz' , stats , function() {
expect( stats.count ).to.eql( { foobar: 1 , foobaz: 1 } ) ;
// 'barbaz' should trigger immediately
process.nextTick( function() {
expect( stats.count ).to.eql( { foobar: 1 , foobaz: 1 , foobarbaz: 1 } ) ;
} ) ;
} )
} ) ;
bus.on( 'barbaz' , {
id: 'foobarbaz' ,
context: 'qux' ,
async: true ,
fn: genericListener.bind( undefined , 'foobarbaz' , stats , function() {
expect( stats.count ).to.eql( { foobar: 1 , foobaz: 1 , foobarbaz: 1 } ) ;
var callback = arguments[ arguments.length - 1 ] ;
setTimeout( function() {
callback() ;
done() ;
} , 30 ) ;
} )
} ) ;
bus.serializeListenerContext( 'qux' ) ;
bus.emit( 'bar' ) ;
bus.emit( 'baz' ) ;
bus.emit( 'barbaz' ) ;
expect( stats.count ).to.eql( { foobar: 1 } ) ;