--- /dev/null
+import { createStore } from '../src'
+
+describe('Subscriptions', () => {
+ const useStore = createStore('main', () => ({
+ name: 'Eduardo',
+ })).bind(null, true)
+
+ let store: ReturnType<typeof useStore>
+ beforeEach(() => {
+ store = useStore()
+ })
+
+ it('fires callback when patch is applied', () => {
+ const spy = jest.fn()
+ store.subscribe(spy)
+ store.state.name = 'Cleiton'
+ expect(spy).toHaveBeenCalledTimes(1)
+ })
+
+ it('unsubscribes callback when unsubscribe is called', () => {
+ const spy = jest.fn()
+ const unsubscribe = store.subscribe(spy)
+ unsubscribe()
+ store.state.name = 'Cleiton'
+ expect(spy).not.toHaveBeenCalled()
+ })
+
+ it('listeners are not affected when unsubscribe is called multiple times', () => {
+ const func1 = jest.fn()
+ const func2 = jest.fn()
+ const unsubscribe1 = store.subscribe(func1)
+ store.subscribe(func2)
+ unsubscribe1()
+ unsubscribe1()
+ store.state.name = 'Cleiton'
+ expect(func1).not.toHaveBeenCalled()
+ expect(func2).toHaveBeenCalledTimes(1)
+ })
+})
})
}
- function subscribe(callback: SubscriptionCallback<S>): void {
+ function subscribe(callback: SubscriptionCallback<S>) {
subscriptions.push(callback)
- // TODO: return function to remove subscription
+ return () => {
+ const idx = subscriptions.indexOf(callback)
+ if (idx > -1) {
+ subscriptions.splice(idx, 1)
+ }
+ }
}
function reset() {
/**
* Setups a callback to be called whenever the state changes.
- * @param callback callback that is called whenever the state changes
+ * @param callback callback that is called whenever the state
+ * @returns function that removes callback from subscriptions
*/
- subscribe(callback: SubscriptionCallback<S>): void
+ subscribe(callback: SubscriptionCallback<S>): () => void
}
export interface DevtoolHook {