updux/src/splat.test.js

316 lines
7.4 KiB
JavaScript
Raw Normal View History

2021-10-16 15:41:04 +00:00
import { difference, omit } from 'lodash';
2021-10-12 13:42:30 +00:00
2021-10-16 15:41:04 +00:00
import { Updux } from './Updux';
2021-10-12 13:42:30 +00:00
2021-10-16 15:41:04 +00:00
test('initial', () => {
2021-10-12 13:42:30 +00:00
const dux = new Updux({
initial: {},
subduxes: {
'*': {
initial: { a: 1 },
},
},
});
2021-10-16 15:41:04 +00:00
expect(dux.initial).toMatchObject({});
2021-10-12 13:42:30 +00:00
});
2021-10-16 15:41:04 +00:00
test('actions', () => {
2021-10-12 13:42:30 +00:00
const dux = new Updux({
initial: {},
subduxes: {
'*': {
initial: { a: 1 },
actions: { foo: null },
},
},
});
2021-10-16 15:41:04 +00:00
expect(typeof dux.actions.foo).toBe('function');
2021-10-12 13:42:30 +00:00
});
2021-10-16 15:41:04 +00:00
test('selectors', () => {
2021-10-12 13:42:30 +00:00
const dux = new Updux({
initial: {},
subduxes: {
'*': {
initial: { a: 1 },
selectors: {
getA: ({ a }) => a,
},
},
},
});
2021-10-16 15:41:04 +00:00
expect(dux.selectors).toMatchObject({});
2021-10-12 13:42:30 +00:00
const getInner = (state) => (index) => state[index];
2021-10-16 15:41:04 +00:00
dux.setMappedSelector('getInner', getInner);
2021-10-12 13:42:30 +00:00
2021-10-16 15:41:04 +00:00
expect(typeof dux.selectors.getInner).toBe('function');
2021-10-12 13:42:30 +00:00
2021-10-16 15:41:04 +00:00
expect(
2021-10-12 13:42:30 +00:00
dux.selectors.getInner({
one: { a: 1 },
two: { a: 2 },
2021-10-16 15:41:04 +00:00
})('one')()
).toMatchObject({ a: 1 });
2021-10-12 13:42:30 +00:00
2021-10-16 15:41:04 +00:00
expect(
2021-10-12 13:42:30 +00:00
dux.selectors
.getInner({
one: { a: 1 },
two: { a: 2 },
})('one')
2021-10-16 15:41:04 +00:00
.getA()
).toBe(1);
2021-10-12 13:42:30 +00:00
// and now with the store
const store = dux.createStore({
one: { a: 1 },
two: { a: 2 },
});
2021-10-16 15:41:04 +00:00
expect(store.getState.getInner('two')()).toMatchObject({ a: 2 });
expect(store.getState.getInner('two').getA()).toEqual(2);
2021-10-12 13:42:30 +00:00
});
2021-10-16 15:41:04 +00:00
test('splat middleware', () => {
const snitch = jest.fn(() => true);
2021-10-12 13:42:30 +00:00
const dux = new Updux({
initial: {},
subduxes: {
'*': {
initial: { a: 1 },
actions: { foo: null },
effects: {
foo: (api) => (next) => (action) => {
snitch();
next(action);
},
},
},
},
});
const store = dux.createStore({ one: { a: 1 }, two: { a: 2 } });
store.dispatch.foo();
2021-10-16 15:41:04 +00:00
expect(snitch).not.toBeCalled();
2021-10-12 13:42:30 +00:00
});
2021-10-16 15:41:04 +00:00
test('splat subscriptions', () => {
const snitch = jest.fn(() => true);
2021-10-12 13:42:30 +00:00
const dux = new Updux({
initial: {},
subduxes: {
'*': {
initial: { a: 1 },
actions: { foo: null },
mutations: {
foo: (id) => (state) =>
state.a === i ? { ...state, b: 1 } : state,
},
subscriptions: [
(store) => (state, previous, unsub) => {
snitch(state);
},
],
},
},
});
const store = dux.createStore({ one: { a: 1 }, two: { a: 2 } });
store.dispatch({ type: 'noop' });
2021-10-16 15:41:04 +00:00
expect(snitch).not.toBeCalled();
2021-10-12 13:42:30 +00:00
});
2021-10-16 15:41:04 +00:00
test('splat subscriptions, more', () => {
const snitch = jest.fn(() => true);
2021-10-12 13:42:30 +00:00
const inner = new Updux({
initial: { a: 1 },
actions: { foo: null, incAll: null },
mutations: {
2021-10-16 15:41:04 +00:00
foo: (id) => (state) =>
state.a === id ? { ...state, b: 1 } : state,
2021-10-12 13:42:30 +00:00
incAll: () => (state) => ({ ...state, a: state.a + 1 }),
},
2021-10-16 15:41:04 +00:00
reactions: [() => snitch],
2021-10-12 13:42:30 +00:00
});
const dux = new Updux({
initial: {},
actions: {
delete: null,
newEntry: null,
},
mutations: {
delete: (id) => (state) => omit(state, id),
newEntry: (name) => (state) => ({ ...state, [name]: { a: 10 } }),
},
2021-10-16 15:41:04 +00:00
mappedReaction: true,
2021-10-12 13:42:30 +00:00
subduxes: {
'*': inner,
},
});
const store = dux.createStore({ one: { a: 1 }, two: { a: 2 } });
store.dispatch({ type: 'noop' });
2021-10-16 15:41:04 +00:00
expect(snitch).toHaveBeenCalledTimes(2);
2021-10-12 13:42:30 +00:00
2021-10-16 15:41:04 +00:00
expect(snitch).toHaveBeenCalledWith(
{ a: 1 },
undefined,
expect.anything()
);
expect(snitch).toHaveBeenCalledWith(
{ a: 2 },
undefined,
expect.anything()
);
2021-10-12 13:42:30 +00:00
2021-10-16 15:41:04 +00:00
snitch.mockReset();
2021-10-12 13:42:30 +00:00
store.dispatch.foo(2);
2021-10-16 15:41:04 +00:00
expect(snitch).toHaveBeenCalledWith(
{ a: 2, b: 1 },
expect.anything(),
expect.anything()
);
2021-10-12 13:42:30 +00:00
2021-10-16 15:41:04 +00:00
snitch.mockReset();
2021-10-12 13:42:30 +00:00
store.dispatch.delete('one');
2021-10-16 15:41:04 +00:00
expect(store.getState()).toMatchObject({
2021-10-12 13:42:30 +00:00
two: { a: 2, b: 1 },
});
2021-10-16 15:41:04 +00:00
expect(snitch).toHaveBeenCalledTimes(1);
2021-10-12 13:42:30 +00:00
2021-10-16 15:41:04 +00:00
expect(snitch).toHaveBeenCalledWith(
undefined,
{ a: 1 },
expect.anything()
2021-10-12 13:42:30 +00:00
);
2021-10-16 15:41:04 +00:00
// only one subscriber left
snitch.mockReset();
2021-10-12 13:42:30 +00:00
2021-10-16 15:41:04 +00:00
store.dispatch.incAll();
2021-10-12 13:42:30 +00:00
2021-10-16 15:41:04 +00:00
expect(snitch).toHaveBeenCalledTimes(1);
2021-10-12 13:42:30 +00:00
2021-10-16 15:41:04 +00:00
expect(snitch).toHaveBeenCalledWith(
{ a: 3, b: 1 },
{ a: 2, b: 1 },
expect.anything()
);
2021-10-12 13:42:30 +00:00
2021-10-16 15:41:04 +00:00
// new entry gets subscribed
snitch.mockReset();
store.dispatch.newEntry('newbie');
2021-10-12 13:42:30 +00:00
2021-10-16 15:41:04 +00:00
expect(snitch).toHaveBeenCalledTimes(1);
expect(snitch).toHaveBeenCalledWith(
{ a: 10 },
undefined,
expect.anything()
);
2021-10-12 13:42:30 +00:00
});
2021-10-16 15:41:04 +00:00
test('many levels down', () => {
const snitch = jest.fn(() => true);
2021-10-12 13:42:30 +00:00
const dux = new Updux({
2021-10-16 15:41:04 +00:00
mappedReaction: true,
2021-10-12 13:42:30 +00:00
actions: { remove: null },
mutations: {
remove: () => (state) => ({}),
},
subduxes: {
'*': {
subduxes: {
a: {
initial: 1,
actions: {
add: null,
},
mutations: {
add: () => (x) => x + 1,
},
2021-10-16 15:41:04 +00:00
reactions: [
2021-10-12 13:42:30 +00:00
(store) => (state) => snitch(state, store),
],
},
},
},
},
});
const store = dux.createStore({ one: { a: 1 } });
store.dispatch({ type: 'foo' });
2021-10-16 15:41:04 +00:00
expect(snitch).toHaveBeenCalled();
expect(snitch).toHaveBeenCalledWith(1, expect.anything());
2021-10-12 13:42:30 +00:00
2021-10-16 15:41:04 +00:00
snitch.mockReset();
2021-10-12 13:42:30 +00:00
store.dispatch.remove();
2021-10-16 15:41:04 +00:00
expect(snitch).toBeCalled();
expect(snitch).toHaveBeenCalledWith(undefined, expect.anything());
2021-10-12 13:42:30 +00:00
});
2021-10-16 15:41:04 +00:00
test('inherit info via the store', () => {
const snitch = jest.fn(() => true);
const splatSnitch = jest.fn(() => true);
2021-10-12 13:42:30 +00:00
const dux = new Updux({
2021-10-16 15:41:04 +00:00
mappedReaction: (store, key) => {
2021-10-12 13:42:30 +00:00
store.itemId = key;
splatSnitch();
return { itemId: key };
},
subduxes: {
'*': {
subduxes: {
a: {
initial: 1,
actions: {
add: null,
},
mutations: {
add: () => (x) => x + 1,
},
2021-10-16 15:41:04 +00:00
reactions: [
2021-10-12 13:42:30 +00:00
(store) => (state) => snitch(state, store.itemId),
],
},
},
},
},
});
const store = dux.createStore({
one: { a: 1 },
two: { a: 2 },
});
store.dispatch({ type: 'noop' });
2021-10-16 15:41:04 +00:00
expect(splatSnitch).toBeCalledTimes(2);
2021-10-12 13:42:30 +00:00
2021-10-16 15:41:04 +00:00
expect(snitch).toBeCalledTimes(2);
expect(snitch).toHaveBeenCalledWith(1, 'one');
expect(snitch).toHaveBeenCalledWith(2, 'two');
2021-10-12 13:42:30 +00:00
});