updux/src/subscriptions.test.js

193 lines
4.7 KiB
JavaScript
Raw Normal View History

2021-10-15 17:35:43 +00:00
import u from 'updeep';
2020-06-19 23:29:12 +00:00
2021-10-15 17:35:43 +00:00
import { Updux } from './Updux';
import { action } from './actions';
2020-06-19 23:29:12 +00:00
2021-10-15 17:35:43 +00:00
test('subscriptions', () => {
2021-10-08 23:56:55 +00:00
const inc = action('inc');
const set_copy = action('set_copy');
2020-06-19 23:29:12 +00:00
2021-10-08 23:56:55 +00:00
const dux = new Updux({
initial: {
x: 0,
copy: 0,
},
actions: {
inc,
set_copy,
},
mutations: {
inc: (payload) => u({ x: (x) => x + 1 }),
set_copy: (copy) => u({ copy }),
},
});
2020-06-19 23:29:12 +00:00
2021-10-08 23:56:55 +00:00
dux.addSubscription((store) => (state, previous, unsubscribe) => {
if (state.x > 2) return unsubscribe();
2020-06-19 23:29:12 +00:00
2021-10-08 23:56:55 +00:00
store.dispatch(set_copy(state.x));
});
2020-06-19 23:29:12 +00:00
2021-10-08 23:56:55 +00:00
const store = dux.createStore();
2020-06-19 23:29:12 +00:00
2021-10-08 23:56:55 +00:00
store.dispatch(inc());
2020-06-19 23:29:12 +00:00
2021-10-15 17:35:43 +00:00
expect(store.getState()).toMatchObject({ x: 1, copy: 1 });
2021-10-08 19:33:45 +00:00
2021-10-08 23:56:55 +00:00
store.dispatch(inc());
store.dispatch(inc());
2021-10-08 19:33:45 +00:00
2021-10-15 17:35:43 +00:00
expect(store.getState()).toMatchObject({ x: 3, copy: 2 });
2021-10-08 23:56:55 +00:00
});
2020-06-19 23:29:12 +00:00
2021-10-15 17:35:43 +00:00
test('subduxes subscriptions', () => {
2020-06-19 23:29:12 +00:00
const inc_top = action('inc_top');
const inc_bar = action('inc_bar');
2021-10-08 19:33:45 +00:00
const transform_bar = action('transform_bar');
2020-06-19 23:29:12 +00:00
const bar = new Updux({
initial: 'a',
2021-10-08 23:56:55 +00:00
actions: { inc_bar, transform_bar },
mutations: {
inc_bar: () => (state) => state + 'a',
transform_bar: (outcome) => () => outcome,
},
2021-10-15 17:35:43 +00:00
reactions: [
2021-10-08 23:56:55 +00:00
(store) => (state, previous, unsubscribe) => {
2020-06-19 23:29:12 +00:00
if (state.length <= 2) return;
unsubscribe();
store.dispatch(transform_bar('look at ' + state));
},
],
});
const dux = new Updux({
initial: {
count: 0,
},
2021-10-08 23:56:55 +00:00
subduxes: { bar },
actions: {
inc_top,
},
mutations: {
inc_top: () => u({ count: (count) => count + 1 }),
},
effects: {
'*': () => (next) => (action) => {
next(action);
},
2020-06-19 23:29:12 +00:00
},
2021-10-15 17:35:43 +00:00
reactions: [
2021-10-08 23:56:55 +00:00
(store) => {
return ({ count }, { count: previous } = {}) => {
2020-06-19 23:29:12 +00:00
if (count !== previous) {
previous = count;
2021-10-08 23:56:55 +00:00
store.dispatch.inc_bar();
2020-06-19 23:29:12 +00:00
}
};
},
],
});
const store = dux.createStore();
store.dispatch(inc_top());
store.dispatch(inc_top());
2021-10-15 17:35:43 +00:00
expect(store.getState()).toMatchObject({
2020-06-19 23:29:12 +00:00
count: 2,
bar: 'look at look at aaa',
});
store.dispatch(inc_top());
2021-10-15 17:35:43 +00:00
expect(store.getState()).toMatchObject({
2020-06-19 23:29:12 +00:00
count: 3,
bar: 'look at look at aaaa',
});
});
2021-10-09 16:13:50 +00:00
2021-10-15 17:35:43 +00:00
test('subscription within subduxes', () => {
let innerState = jest.fn(() => null);
let outerState = jest.fn(() => null);
2021-10-18 13:02:20 +00:00
const resetMocks = () => [innerState, outerState].map((f) => f.mockReset());
2021-10-09 16:13:50 +00:00
const inner = new Updux({
initial: 1,
actions: { inc: null },
mutations: {
2021-10-09 17:15:35 +00:00
inc: () => (state) => state + 1,
2021-10-09 16:13:50 +00:00
},
2021-10-15 17:35:43 +00:00
reactions: [
2021-10-09 17:15:35 +00:00
(store) => (state, previous, unsub) => {
if (!previous) return;
store.subscribe(innerState);
2021-10-09 16:13:50 +00:00
unsub();
2021-10-09 17:15:35 +00:00
},
2021-10-09 16:13:50 +00:00
],
2021-10-09 17:15:35 +00:00
});
2021-10-09 16:13:50 +00:00
const dux = new Updux({
2021-10-09 17:15:35 +00:00
initial: { x: 0 },
2021-10-09 16:13:50 +00:00
subduxes: { inner },
2021-10-09 17:15:35 +00:00
actions: {
incOuter: null,
},
mutations: {
incOuter: () => (state) => ({ ...state, x: state.x + 1 }),
},
2021-10-15 17:35:43 +00:00
reactions: [
2021-10-09 17:15:35 +00:00
(store) => (state, previous, unsub) => {
if (!previous) return;
store.subscribe(outerState);
2021-10-09 16:13:50 +00:00
unsub();
2021-10-09 17:15:35 +00:00
},
2021-10-09 16:13:50 +00:00
],
});
const store = dux.createStore();
store.dispatch({ type: 'noop' });
store.dispatch({ type: 'noop' });
2021-10-15 17:35:43 +00:00
expect(innerState).not.toHaveBeenCalled();
expect(outerState).not.toHaveBeenCalled();
2021-10-09 16:13:50 +00:00
store.dispatch.inc();
2021-10-09 17:15:35 +00:00
// not called yet
2021-10-15 17:35:43 +00:00
expect(innerState).not.toBeCalled();
expect(outerState).not.toBeCalled();
2021-10-09 17:15:35 +00:00
store.dispatch.inc();
2021-10-15 17:35:43 +00:00
expect(outerState).toBeCalledTimes(1);
expect(outerState).toHaveBeenCalledWith(
{ inner: 3, x: 0 },
undefined,
expect.anything()
);
2021-10-09 17:15:35 +00:00
2021-10-15 17:35:43 +00:00
expect(innerState).toHaveBeenCalled();
expect(innerState).toHaveBeenCalledWith(3, undefined, expect.anything());
2021-10-09 17:15:35 +00:00
2021-10-15 17:35:43 +00:00
resetMocks();
2021-10-09 16:13:50 +00:00
store.dispatch.inc();
2021-10-15 17:35:43 +00:00
expect(outerState).toBeCalled();
expect(outerState).toBeCalledWith(
{ inner: 4, x: 0 },
expect.anything(),
expect.anything()
);
2021-10-09 16:13:50 +00:00
2021-10-15 17:35:43 +00:00
expect(innerState).toBeCalledWith(4, 3, expect.anything());
2021-10-09 17:15:35 +00:00
2021-10-15 17:35:43 +00:00
// state of subdux doesnt change
resetMocks();
2021-10-09 17:15:35 +00:00
2021-10-15 17:35:43 +00:00
store.dispatch.incOuter();
expect(outerState).toBeCalled();
expect(innerState).not.toBeCalled();
2021-10-09 17:15:35 +00:00
});