120 lines
3.6 KiB
JavaScript
120 lines
3.6 KiB
JavaScript
import { buildEffectsMiddleware } from './effects.js';
|
|
import Updux, { createAction } from './index.js';
|
|
test('buildEffectsMiddleware', () => {
|
|
let seen = 0;
|
|
const mw = buildEffectsMiddleware([
|
|
(api) => (next) => (action) => {
|
|
seen++;
|
|
expect(api).toHaveProperty('getState');
|
|
expect(api.getState).toBeTypeOf('function');
|
|
expect(api.getState()).toEqual('the state');
|
|
expect(action).toHaveProperty('type');
|
|
expect(next).toBeTypeOf('function');
|
|
expect(api).toHaveProperty('actions');
|
|
expect(api.actions.action1()).toHaveProperty('type', 'action1');
|
|
api.dispatch.action1();
|
|
expect(api.selectors.getFoo(2)).toBe(2);
|
|
expect(api.getState.getFoo()).toBe('the state');
|
|
expect(api.getState.getBar(2)).toBe('the state2');
|
|
next(action);
|
|
},
|
|
], {
|
|
action1: createAction('action1'),
|
|
}, {
|
|
getFoo: (state) => state,
|
|
getBar: (state) => (i) => state + i,
|
|
});
|
|
expect(seen).toEqual(0);
|
|
const dispatch = vi.fn();
|
|
mw({ getState: () => 'the state', dispatch })(() => { })({
|
|
type: 'noop',
|
|
});
|
|
expect(seen).toEqual(1);
|
|
expect(dispatch).toHaveBeenCalledWith({ type: 'action1' });
|
|
});
|
|
test('basic', () => {
|
|
const dux = new Updux({
|
|
initialState: {
|
|
loaded: true,
|
|
},
|
|
actions: {
|
|
foo: 0,
|
|
},
|
|
});
|
|
let seen = 0;
|
|
dux.addEffect((api) => (next) => (action) => {
|
|
seen++;
|
|
expect(api).toHaveProperty('getState');
|
|
expect(api.getState()).toHaveProperty('loaded');
|
|
expect(action).toHaveProperty('type');
|
|
expect(next).toBeTypeOf('function');
|
|
next(action);
|
|
});
|
|
const store = dux.createStore();
|
|
expect(seen).toEqual(0);
|
|
store.dispatch.foo();
|
|
expect(seen).toEqual(1);
|
|
});
|
|
test('subdux', () => {
|
|
const bar = new Updux({
|
|
initialState: 'bar state',
|
|
actions: { foo: 0 },
|
|
});
|
|
let seen = 0;
|
|
bar.addEffect((api) => (next) => (action) => {
|
|
seen++;
|
|
expect(api.getState()).toBe('bar state');
|
|
next(action);
|
|
});
|
|
const dux = new Updux({
|
|
initialState: {
|
|
loaded: true,
|
|
},
|
|
subduxes: {
|
|
bar,
|
|
},
|
|
});
|
|
const store = dux.createStore();
|
|
expect(seen).toEqual(0);
|
|
store.dispatch.foo();
|
|
expect(seen).toEqual(1);
|
|
});
|
|
test('addEffect with actionCreator', () => {
|
|
const dux = new Updux({
|
|
actions: {
|
|
foo: null,
|
|
bar: null,
|
|
},
|
|
});
|
|
const next = vi.fn();
|
|
const spy = vi.fn();
|
|
const mw = dux.addEffect(dux.actions.foo, (api) => (next) => (action) => next(spy(action)));
|
|
mw({})(next)(dux.actions.bar());
|
|
expect(next).toHaveBeenCalled();
|
|
expect(spy).not.toHaveBeenCalled();
|
|
next.mockReset();
|
|
mw({})(next)(dux.actions.foo());
|
|
expect(next).toHaveBeenCalled();
|
|
expect(spy).toHaveBeenCalled();
|
|
});
|
|
test('addEffect with function', () => {
|
|
const dux = new Updux({
|
|
actions: {
|
|
foo: () => { },
|
|
bar: () => { },
|
|
},
|
|
});
|
|
const next = vi.fn();
|
|
const spy = vi.fn();
|
|
const mw = dux.addEffect((action) => action.type[0] === 'f', (api) => (next) => (action) => next(spy(action)));
|
|
mw({})(next)(dux.actions.bar());
|
|
expect(next).toHaveBeenCalled();
|
|
expect(spy).not.toHaveBeenCalled();
|
|
next.mockReset();
|
|
mw({})(next)(dux.actions.foo());
|
|
expect(next).toHaveBeenCalled();
|
|
expect(spy).toHaveBeenCalled();
|
|
});
|
|
// TODO subdux effects
|
|
// TODO allow to subscribe / unsubscribe effects?
|