import { test } from 'tap'; import sinon from 'sinon'; import { buildMiddleware } from './index.js'; import { action } from '../actions.js'; test('single effect', async (t) => { const effect = (api) => (next) => (action) => { t.same(action, { type: 'foo' }); t.has(api, { actions: {}, selectors: {}, }); next(); }; const middleware = buildMiddleware([effect]); await new Promise((resolve) => { middleware({})(resolve)({ type: 'foo' }); }); }); test('augmented api', async (t) => { const effect = (api) => (next) => async (action) => { await t.test('selectors', async (t) => { t.same(api.getState.getB(), 1); t.same(api.selectors.getB({ a: { b: 2 } }), 2); t.same(api.getState(), { a: { b: 1 } }); }); await t.test('dispatch', async (t) => { t.same(api.actions.actionOne(), { type: 'actionOne' }); api.dispatch.actionOne('the payload'); }); next(); }; const middleware = buildMiddleware( [effect], { actionOne: action('actionOne'), }, { getB: (state) => state.a.b, } ); const getState = sinon.fake.returns({ a: { b: 1 } }); const dispatch = sinon.fake.returns(); await new Promise((resolve) => { middleware({ getState, dispatch, })(resolve)({ type: 'foo' }); }); t.ok(dispatch.calledOnce); t.ok(dispatch.calledWith({ type: 'actionOne', payload: 'the payload' })); }); test('subduxes', async (t) => { const effect1 = (api) => (next) => (action) => { next({ type: action.type, payload: [...action.payload, 1], }); }; const effect2 = (api) => (next) => (action) => { next({ type: action.type, payload: [...action.payload, 2], }); }; const effect3 = (api) => (next) => (action) => { next({ type: action.type, payload: [...action.payload, 3], }); }; const mw = buildMiddleware( [effect1], {}, {}, { a: { middleware: effect2 }, b: { middleware: effect3 }, } ); mw({})(({ payload }) => { t.same(payload, [1, 2, 3]); })({ type: 'foo', payload: [] }); t.test('api for subduxes', async (t) => { const effect = (api) => (next) => (action) => { t.same(api.getState(), 3); next(); }; const mwInner = buildMiddleware([effect]); const mwOuter = buildMiddleware( [], {}, {}, { alpha: { middleware: mwInner } } ); await new Promise((resolve) => { mwOuter({ getState: () => ({ alpha: 3 }), })(resolve)({ type: 'foo' }); }); }); });