test/events.spec.js
import chai, { expect } from 'chai'
import spies from 'chai-spies-next'
import EventHandler from '../src/events'
import Message from '../src/message'
chai.use(spies)
/** @test {EventHandler} */
describe('EventHandler', () => {
let handler
before(() => {
handler = new EventHandler()
})
/** @test {EventHandler#on} */
describe('on', () => {
let spy
let id
before(() => {
spy = chai.spy()
id = handler.on('/test/path', spy)
})
it('returns different subscription ids for each listener', () => {
const anotherId = handler.on(['test', 'path'], () => {})
expect(id !== anotherId).to.be.true
})
it('registers a handler which can be called', () => {
handler.notify('/test/path', {})
expect(spy).to.have.been.called()
})
})
/** @test {EventHandler#off} */
describe('off', () => {
let spy
let id
before(() => {
spy = chai.spy()
id = handler.on('/test/path', spy)
})
it('removes a handler', () => {
const success = handler.off('/test/path', id)
handler.notify('/test/path', {})
expect(spy).to.not.have.been.called()
expect(success).to.be.true
})
it('returns false when handler was not found', () => {
const success = handler.off('/test/path/which/does/not/exist', id)
expect(success).to.be.false
})
})
/** @test {EventHandler#notify} */
describe('notify', () => {
const testdata = {
test: 'data',
}
const spy = []
before(() => {
for (let i = 0; i < 12; i += 1) {
spy.push(chai.spy())
}
// regular address handlers
handler.on('/', spy[0])
handler.on('/one/test', spy[1])
handler.on('/and/another', spy[2])
handler.on('/two/test/path', spy[3])
handler.on(['two', 'test', 'path'], spy[4])
handler.on('/two/some/path', spy[5])
// system event handlers
handler.on('error', spy[6])
handler.on('close', spy[7])
handler.on('open', spy[8])
// pattern address handlers
handler.on('/two/*/path', spy[9])
handler.on('*', spy[10])
handler.on('/o?e/{test,bar}', spy[11])
})
afterEach(() => {
spy.forEach((item) => {
item.reset()
})
})
it('passes over the event data', () => {
handler.notify('/and/another', testdata)
expect(spy[2]).have.been.called.with(testdata)
})
it('accepts messages', () => {
handler.notify(new Message(['and', 'another']))
expect(spy[2]).have.been.called()
})
it('accepts binary packets', () => {
const binary = new Uint8Array([
47, 97, 110, 100, 47, 97, 110,
111, 116, 104, 101, 114, 0, 0, 0, 0, 44, 0, 0, 0,
])
handler.notify(binary)
expect(spy[2]).have.been.called()
})
describe('event listeners', () => {
it('notifies error callbacks', () => {
handler.notify('error', testdata)
expect(spy[6]).have.been.called.with(testdata)
})
it('notifies close callbacks', () => {
handler.notify('close', testdata)
expect(spy[7]).have.been.called.with(testdata)
})
it('notifies open callbacks', () => {
handler.notify('open', testdata)
expect(spy[8]).have.been.called.with(testdata)
})
})
describe('address listeners with timetags', () => {
it('calls the handler later', () => {
handler.notify('/', testdata, Date.now() + 5000)
expect(spy[0]).not.have.been.called()
})
})
describe('address listeners with regular strings', () => {
it('calls the root listener', () => {
handler.notify('/', testdata)
expect(spy[0]).have.been.called()
expect(spy[1]).not.have.been.called()
expect(spy[4]).not.have.been.called()
})
it('calls two listeners with the same address', () => {
handler.notify('/two/test/path', testdata)
expect(spy[3]).have.been.called()
expect(spy[4]).have.been.called()
})
it('works with {} wildcard', () => {
handler.notify('/two/{test,some}/path', testdata)
expect(spy[1]).not.have.been.called()
expect(spy[3]).have.been.called()
expect(spy[4]).have.been.called()
expect(spy[5]).have.been.called()
})
it('works with [] wildcard', () => {
handler.notify('/[pawgfo]ne/[bnit]est', testdata)
expect(spy[1]).have.been.called()
expect(spy[2]).not.have.been.called()
})
it('works with [!] wildcard', () => {
handler.notify('/two/[!s][eso][tspm][tea]/path', testdata)
expect(spy[3]).have.been.called()
expect(spy[5]).not.have.been.called()
})
it('works with [a-z] wildcard', () => {
handler.notify('/two/[a-z]est/p[a-c]t[e-i]', testdata)
expect(spy[3]).have.been.called()
expect(spy[5]).not.have.been.called()
})
it('works with * wildcard', () => {
handler.notify('/two/*', testdata)
expect(spy[3]).have.been.called()
expect(spy[4]).have.been.called()
expect(spy[5]).have.been.called()
expect(spy[1]).not.have.been.called()
})
it('works with * wildcard calling all', () => {
handler.notify('/*', testdata)
expect(spy[0]).have.been.called()
expect(spy[1]).have.been.called()
expect(spy[2]).have.been.called()
expect(spy[3]).have.been.called()
expect(spy[4]).have.been.called()
expect(spy[5]).have.been.called()
})
it('works with ? wildcard', () => {
handler.notify('/two/????/pa?h', testdata)
expect(spy[0]).not.have.been.called()
expect(spy[3]).have.been.called()
expect(spy[5]).have.been.called()
})
})
describe('address listeners with pattern matching', () => {
it('calls wildcard listeners', () => {
handler.notify('/two/bar/path', testdata)
expect(spy[9]).have.been.called()
expect(spy[10]).have.been.called()
expect(spy[4]).not.have.been.called()
})
it('calls group matching listener', () => {
handler.notify('/ose/test', testdata)
expect(spy[10]).have.been.called()
expect(spy[11]).have.been.called()
expect(spy[1]).not.have.been.called()
expect(spy[9]).not.have.been.called()
})
})
})
})