updux/src/effects.test.ts

163 lines
3.8 KiB
TypeScript

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({} as any)(next)(dux.actions.bar());
expect(next).toHaveBeenCalled();
expect(spy).not.toHaveBeenCalled();
next.mockReset();
mw({} as any)(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({} as any)(next)(dux.actions.bar());
expect(next).toHaveBeenCalled();
expect(spy).not.toHaveBeenCalled();
next.mockReset();
mw({} as any)(next)(dux.actions.foo());
expect(next).toHaveBeenCalled();
expect(spy).toHaveBeenCalled();
});
// TODO subdux effects
// TODO allow to subscribe / unsubscribe effects?