Skip to content

Instantly share code, notes, and snippets.

@lourd
Created March 23, 2017 17:10
Show Gist options
  • Save lourd/005f957bb42db50d686ef068ed564cd2 to your computer and use it in GitHub Desktop.
Save lourd/005f957bb42db50d686ef068ed564cd2 to your computer and use it in GitHub Desktop.
Example of making a channel in redux-saga with a generic emitter source and testing it with jest
import { eventChannel } from 'redux-saga'
function emitterChannel(emitter, eventType) {
return eventChannel(emit => {
emitter.on(eventType, emit)
return () => emitter.off(eventType, emit)
})
}
describe('emitterChannel', () => {
let emitter
beforeEach(() => {
emitter = new FakeEmitter()
})
it('should subscribe to the emitter, emit what it emits, and unsubscribe when closed', async () => {
const type = 'bambino'
const channel = emitterChannel(emitter, type)
for (let i = 0; i < 3; i++) {
const taken = new Promise(resolve => channel.take(resolve))
const event = { type, value: i }
emitter.emit(event)
const e = await taken
expect(e).toEqual(event)
}
emitter.off = jest.fn((eType, listener) => {
expect(eType).toBe(type)
expect(listener).toBeInstanceOf(Function)
})
channel.close()
// Calling close multiple times only unsubscribes once
channel.close()
expect(emitter.off).toHaveBeenCalledTimes(1)
})
})
class FakeEmitter {
constructor() {
this.subs = []
this.count = 0
}
on(type, listener) {
this.subs.push({
type,
listener,
id: this.count++,
})
}
off(type, listener) {
this.subs = this.subs.filter(sub => sub.listener !== listener)
}
emit(event) {
this.subs.forEach(({ type, listener }) => {
if (type === event.type) listener(event)
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment