From be22130fa96902c00974a32c29e4f85a8f70767b Mon Sep 17 00:00:00 2001 From: Oskar Hane Date: Mon, 13 Feb 2017 15:36:16 +0100 Subject: [PATCH 1/2] Add reset function To remove all subscribers on all channels. Also, fix tests file structure. --- src/bus.js | 3 +- src/bus.test.js | 425 +++++++++++++++++++++++++----------------------- 2 files changed, 224 insertions(+), 204 deletions(-) diff --git a/src/bus.js b/src/bus.js index ee7d905..ad65bd7 100644 --- a/src/bus.js +++ b/src/bus.js @@ -37,6 +37,7 @@ const wrapReduxMiddleware = (mw) => { } // Exposed bus methods +const reset = () => Object.keys(subscriptions).forEach((key) => delete subscriptions[key]) const take = (channel, fn, filterFn = null, once = false) => { if (!channel || !fn) return false return addChannelSubscriber(channel, fn, filterFn, once) @@ -57,7 +58,7 @@ const _self = (channel, message, fn) => { let nextId = 0 const subscriptions = {} let middlewares = [] -const bus = { take, one, send, self: _self } +const bus = { take, one, send, reset, self: _self } // Exported functions export const getBus = () => bus diff --git a/src/bus.test.js b/src/bus.test.js index 35faca5..4318213 100644 --- a/src/bus.test.js +++ b/src/bus.test.js @@ -1,208 +1,227 @@ -/* global test, expect, jest */ +/* global describe, beforeEach, test, expect, jest */ import { getBus, applyMiddleware, resetMiddlewares } from './bus' -test('can get the bus', () => { - // Given - const b = getBus() - - // Then - expect(b).toBeTruthy() -}) - -test('can send messages on the bus', () => { - // Given - const b = getBus() - let cb = jest.fn() - const channel = 'my channel' - const data = {id: 1} - - // When - b.take(channel, cb) - - // Then - expect(b.send).toBeDefined() - expect(cb).not.toHaveBeenCalled() - - // When - b.send(channel, data) - - // Then - expect(cb).toHaveBeenCalledWith(data) -}) - -test('can take one or multiple messages', () => { - // Given - const b = getBus() - let cb = jest.fn() - let cb2 = jest.fn() - const channel = 'my channel' - const data = {id: 1} - - // When - b.take(channel, cb) - b.one(channel, cb2) - - b.send(channel, data) - b.send(channel, data) - b.send(channel, data) - - // Then - expect(cb).toHaveBeenCalledTimes(3) - expect(cb2).toHaveBeenCalledTimes(1) -}) - -test('can have multiple subscribers for a channel', () => { - // Given - const b = getBus() - let cb1 = jest.fn() - let cb2 = jest.fn() - let cb3 = jest.fn() - const channel = 'my channel 2' - const nonSentchannel = 'nochannel' - const data = {id: 2} - - // When - b.take(channel, cb1) - b.take(channel, cb2) - b.take(nonSentchannel, cb3) - b.send(channel, data) - - // Then - expect(cb1).toHaveBeenCalledWith(data) - expect(cb2).toHaveBeenCalledWith(data) - expect(cb3).not.toHaveBeenCalled() -}) - -test('self passes on `responseChannel` to tell subs where to respond', () => { - // Given - const b = getBus() - let cb = jest.fn() - const data = {id: 1} - const data2 = {id: 2} - const cb2 = (data) => { - b.send(data._responseChannel, data2) - } - const channel = 'my channel' - - // When - b.take(channel, cb2) - b.self(channel, data, cb) - - // Then - expect(cb).toHaveBeenCalledTimes(1) - expect(cb).toHaveBeenCalledWith(data2) -}) - -test('can catch all messages with "*" channel', () => { - // Given - const b = getBus() - let cb1 = jest.fn() - let cb2 = jest.fn() - let catchAllCb = jest.fn() - const channel = 'my channel 2' - const noSubscriberChannel = 'no direct subscribers' - const data = {id: 2} - - // When - b.take(channel, cb1) - b.take(channel, cb2) - b.take('*', catchAllCb) - b.send(channel, data) - b.send(noSubscriberChannel, data) - - // Then - expect(cb1).toHaveBeenCalledWith(data) - expect(cb2).toHaveBeenCalledWith(data) - expect(catchAllCb).toHaveBeenCalledTimes(2) -}) - -test('subscribers filter function', () => { - // Given - const b = getBus() - let cb = jest.fn() - let cb2 = jest.fn() - const channel = 'filter channel' - const filterFn = (data) => data.id === 1 - const filterFn2 = (data) => data.id === 2 - const data = {id: 1} - - // When - b.take(channel, cb, filterFn) - b.take(channel, cb2, filterFn2) - b.send(channel, data) - - // Then - expect(cb).toHaveBeenCalledWith(data) - expect(cb2).not.toHaveBeenCalled() -}) - -test('subscribers can unsubscribe', () => { - // Given - const b = getBus() - let cb = jest.fn() - const channel = 'my unsub channel' - const data = {id: 1} - - // When - const unsub = b.take(channel, cb) - expect(unsub).toBeTruthy() - b.send(channel, data) - - // Then - expect(cb).toHaveBeenCalledWith(data) - - // When - unsub() - b.send(channel, data) - - // - expect(cb).toHaveBeenCalledTimes(1) -}) - -test('exposes applyMiddleware', () => { - // Given - const b = getBus() - let cb = jest.fn() - let myInnerMw = jest.fn() - let myMw = (send) => myInnerMw - const channel = 'emitSubject' - const data = {id: 10} - const source = 'test' - - // When - b.take(channel, cb) - applyMiddleware(myMw) - b.send(channel, data, source) - - // Then - expect(cb).toHaveBeenCalledWith(data) - expect(myInnerMw).toHaveBeenCalledWith(channel, data, source) +describe('Suber core testing', () => { + let b = null + beforeEach(() => { + b = getBus() + b.reset() + }) + + test('can send messages on the bus', () => { + // Given + let cb = jest.fn() + const channel = 'my channel' + const data = {id: 1} + + // When + b.take(channel, cb) + + // Then + expect(b.send).toBeDefined() + expect(cb).not.toHaveBeenCalled() + + // When + b.send(channel, data) + + // Then + expect(cb).toHaveBeenCalledWith(data) + }) + + test('reset removes all subscribers', () => { + // Given + let cb = jest.fn() + const channel = 'my channel' + const data = {id: 1} + + // When + b.take(channel, cb) + b.send(channel, data) + + // Then + expect(cb).toHaveBeenCalledWith(data) + expect(cb).toHaveBeenCalledTimes(1) + + // When + b.reset() + b.send(channel, data) + expect(cb).toHaveBeenCalledTimes(1) + }) + + test('can take one or multiple messages', () => { + // Given + let cb = jest.fn() + let cb2 = jest.fn() + const channel = 'my channel' + const data = {id: 1} + + // When + b.take(channel, cb) + b.one(channel, cb2) + + b.send(channel, data) + b.send(channel, data) + b.send(channel, data) + + // Then + expect(cb).toHaveBeenCalledTimes(3) + expect(cb2).toHaveBeenCalledTimes(1) + }) + + test('self passes on `_responseChannel` to tell subs where to respond', () => { + // Given + const b = getBus() + let cb = jest.fn() + const data = {id: 1} + const data2 = {id: 2} + const cb2 = (data) => { + b.send(data._responseChannel, data2) + } + const channel = 'my channel' + + // When + b.take(channel, cb2) + b.self(channel, data, cb) + + // Then + expect(cb).toHaveBeenCalledTimes(1) + expect(cb).toHaveBeenCalledWith(data2) + }) + + test('can have multiple subscribers for a channel', () => { + // Given + let cb1 = jest.fn() + let cb2 = jest.fn() + let cb3 = jest.fn() + const channel = 'my channel 2' + const nonSentchannel = 'nochannel' + const data = {id: 2} + + // When + b.take(channel, cb1) + b.take(channel, cb2) + b.take(nonSentchannel, cb3) + b.send(channel, data) + + // Then + expect(cb1).toHaveBeenCalledWith(data) + expect(cb2).toHaveBeenCalledWith(data) + expect(cb3).not.toHaveBeenCalled() + }) + + test('can catch all messages with "*" channel', () => { + // Given + let cb1 = jest.fn() + let cb2 = jest.fn() + let catchAllCb = jest.fn() + const channel = 'my channel 2' + const noSubscriberChannel = 'no direct subscribers' + const data = {id: 2} + + // When + b.take(channel, cb1) + b.take(channel, cb2) + b.take('*', catchAllCb) + b.send(channel, data) + b.send(noSubscriberChannel, data) + + // Then + expect(cb1).toHaveBeenCalledWith(data) + expect(cb2).toHaveBeenCalledWith(data) + expect(catchAllCb).toHaveBeenCalledTimes(2) + }) + + test('subscribers filter function', () => { + // Given + let cb = jest.fn() + let cb2 = jest.fn() + const channel = 'filter channel' + const filterFn = (data) => data.id === 1 + const filterFn2 = (data) => data.id === 2 + const data = {id: 1} + + // When + b.take(channel, cb, filterFn) + b.take(channel, cb2, filterFn2) + b.send(channel, data) + + // Then + expect(cb).toHaveBeenCalledWith(data) + expect(cb2).not.toHaveBeenCalled() + }) + + test('subscribers can unsubscribe', () => { + // Given + let cb = jest.fn() + const channel = 'my unsub channel' + const data = {id: 1} + + // When + const unsub = b.take(channel, cb) + expect(unsub).toBeTruthy() + b.send(channel, data) + + // Then + expect(cb).toHaveBeenCalledWith(data) + + // When + unsub() + b.send(channel, data) + + // + expect(cb).toHaveBeenCalledTimes(1) + }) }) -test('exposes setMiddleware', () => { - // Given - const b = getBus() - let cb = jest.fn() - let myInnerMw = jest.fn() - let myMw = (send) => myInnerMw - const channel = 'emitSubject' - const data = {id: 10} - const source = 'test' - - // When - b.take(channel, cb) - applyMiddleware(myMw) - b.send(channel, data, source) - - // Then - expect(cb).toHaveBeenCalledWith(data) - expect(myInnerMw).toHaveBeenCalledWith(channel, data, source) - - // When - resetMiddlewares() - b.send(channel, data, source) - - // Then - expect(cb).toHaveBeenCalledTimes(2) - expect(myInnerMw).toHaveBeenCalledTimes(1) +describe('Utility functions', () => { + let b = null + beforeEach(() => { + b = getBus() + b.reset() + }) + test('exposes applyMiddleware', () => { + // Given + let cb = jest.fn() + let myInnerMw = jest.fn() + let myMw = (send) => myInnerMw + const channel = 'emitSubject' + const data = {id: 10} + const source = 'test' + + // When + b.take(channel, cb) + applyMiddleware(myMw) + b.send(channel, data, source) + + // Then + expect(cb).toHaveBeenCalledWith(data) + expect(myInnerMw).toHaveBeenCalledWith(channel, data, source) + }) + test('exposes resetMiddlewares', () => { + // Given + const b = getBus() + let cb = jest.fn() + let myInnerMw = jest.fn() + let myMw = (send) => myInnerMw + const channel = 'emitSubject' + const data = {id: 10} + const source = 'test' + + // When + b.take(channel, cb) + applyMiddleware(myMw) + b.send(channel, data, source) + + // Then + expect(cb).toHaveBeenCalledWith(data) + expect(myInnerMw).toHaveBeenCalledWith(channel, data, source) + + // When + resetMiddlewares() + b.send(channel, data, source) + + // Then + expect(cb).toHaveBeenCalledTimes(2) + expect(myInnerMw).toHaveBeenCalledTimes(1) + }) }) From dca87e78599ac778b60ad5feafb9aeecb4afea90 Mon Sep 17 00:00:00 2001 From: Oskar Hane Date: Mon, 13 Feb 2017 16:00:09 +0100 Subject: [PATCH 2/2] =?UTF-8?q?Add=20`bus.reset()`=20to=20README=20?= =?UTF-8?q?=F0=9F=93=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9fd8055..90e1488 100644 --- a/README.md +++ b/README.md @@ -144,6 +144,7 @@ response is Redux or single component state. - [`one`](#one) - [`send`](#send) - [`self`](#self) +- [`reset`](#reset) ### Utility functions - [`applyMiddleware`](#applyMiddleware) @@ -198,6 +199,14 @@ subscriber to respond on. See tests file for an example. #### Returns `void` +### `reset()` +Removes all subscribers on all channels. + +#### Arguments +_No arguments_ + +#### Returns `void` + ## Utility functions Functions to configure or extend the bus. @@ -213,7 +222,7 @@ Add middleware to Suber. All messages on all channels gets passed to the middlew Removes all active all middlewares. #### Arguments -- No arguments +_No arguments_ #### Returns `void`