diff options
Diffstat (limited to 'test/index_test.ts')
| -rw-r--r-- | test/index_test.ts | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/test/index_test.ts b/test/index_test.ts new file mode 100644 index 0000000..5c25b55 --- /dev/null +++ b/test/index_test.ts @@ -0,0 +1,190 @@ +import mitt, { Emitter } from '..'; +import chai, { expect } from 'chai'; +import { spy } from 'sinon'; +import sinonChai from 'sinon-chai'; +chai.use(sinonChai); + +describe('mitt', () => { + it('should default export be a function', () => { + expect(mitt).to.be.a('function'); + }); + + it('should accept an optional event handler map', () => { + expect(() => mitt(new Map())).not.to.throw; + const map = new Map(); + const a = spy(); + const b = spy(); + map.set('foo', [a, b]); + const events = mitt(map); + events.emit('foo'); + expect(a).to.have.been.calledOnce; + expect(b).to.have.been.calledOnce; + }); +}); + +describe('mitt#', () => { + let events, inst: Emitter; + + beforeEach( () => { + events = new Map(); + inst = mitt(events); + }); + + describe('properties', () => { + it('should expose the event handler map', () => { + expect(inst) + .to.have.property('all') + .that.is.a('map'); + }); + }); + + describe('on()', () => { + it('should be a function', () => { + expect(inst) + .to.have.property('on') + .that.is.a('function'); + }); + + it('should register handler for new type', () => { + const foo = () => {}; + inst.on('foo', foo); + + expect(events.get('foo')).to.deep.equal([foo]); + }); + + it('should register handlers for any type strings', () => { + const foo = () => {}; + inst.on('constructor', foo); + + expect(events.get('constructor')).to.deep.equal([foo]); + }); + + it('should append handler for existing type', () => { + const foo = () => {}; + const bar = () => {}; + inst.on('foo', foo); + inst.on('foo', bar); + + expect(events.get('foo')).to.deep.equal([foo, bar]); + }); + + it('should NOT normalize case', () => { + const foo = () => {}; + inst.on('FOO', foo); + inst.on('Bar', foo); + inst.on('baz:baT!', foo); + + expect(events.get('FOO')).to.deep.equal([foo]); + expect(events.has('foo')).to.equal(false); + expect(events.get('Bar')).to.deep.equal([foo]); + expect(events.has('bar')).to.equal(false); + expect(events.get('baz:baT!')).to.deep.equal([foo]); + }); + + it('can take symbols for event types', () => { + const foo = () => {}; + const eventType = Symbol('eventType'); + inst.on(eventType, foo); + expect(events.get(eventType)).to.deep.equal([foo]); + }); + + // Adding the same listener multiple times should register it multiple times. + // See https://nodejs.org/api/events.html#events_emitter_on_eventname_listener + it('should add duplicate listeners', () => { + const foo = () => {}; + inst.on('foo', foo); + inst.on('foo', foo); + expect(events.get('foo')).to.deep.equal([foo, foo]); + }); + }); + + describe('off()', () => { + it('should be a function', () => { + expect(inst) + .to.have.property('off') + .that.is.a('function'); + }); + + it('should remove handler for type', () => { + const foo = () => {}; + inst.on('foo', foo); + inst.off('foo', foo); + + expect(events.get('foo')).to.be.empty; + }); + + it('should NOT normalize case', () => { + const foo = () => {}; + inst.on('FOO', foo); + inst.on('Bar', foo); + inst.on('baz:bat!', foo); + + inst.off('FOO', foo); + inst.off('Bar', foo); + inst.off('baz:baT!', foo); + + expect(events.get('FOO')).to.be.empty; + expect(events.has('foo')).to.equal(false); + expect(events.get('Bar')).to.be.empty; + expect(events.has('bar')).to.equal(false); + expect(events.get('baz:bat!')).to.have.lengthOf(1); + }); + + it('should remove only the first matching listener', () => { + const foo = () => {}; + inst.on('foo', foo); + inst.on('foo', foo); + inst.off('foo', foo); + expect(events.get('foo')).to.deep.equal([foo]); + inst.off('foo', foo); + expect(events.get('foo')).to.deep.equal([]); + }); + }); + + describe('emit()', () => { + it('should be a function', () => { + expect(inst) + .to.have.property('emit') + .that.is.a('function'); + }); + + it('should invoke handler for type', () => { + const event = { a: 'b' }; + + inst.on('foo', (one, two?) => { + expect(one).to.deep.equal(event); + expect(two).to.be.an('undefined'); + }); + + inst.emit('foo', event); + }); + + it('should NOT ignore case', () => { + const onFoo = spy(), + onFOO = spy(); + events.set('Foo', [onFoo]); + events.set('FOO', [onFOO]); + + inst.emit('Foo', 'Foo arg'); + inst.emit('FOO', 'FOO arg'); + + expect(onFoo).to.have.been.calledOnce.and.calledWith('Foo arg'); + expect(onFOO).to.have.been.calledOnce.and.calledWith('FOO arg'); + }); + + it('should invoke * handlers', () => { + const star = spy(), + ea = { a: 'a' }, + eb = { b: 'b' }; + + events.set('*', [star]); + + inst.emit('foo', ea); + expect(star).to.have.been.calledOnce.and.calledWith('foo', ea); + star.resetHistory(); + + inst.emit('bar', eb); + expect(star).to.have.been.calledOnce.and.calledWith('bar', eb); + }); + }); +}); |
