Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexandrHoroshih committed Dec 11, 2023
1 parent 4045855 commit c1f22e2
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 10 deletions.
98 changes: 94 additions & 4 deletions packages/redux-interop/src/lib/redux-interop.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,97 @@
import { reduxInterop } from './redux-interop';
import { createReduxInterop } from './redux-interop';
import { legacy_createStore } from 'redux';
import { configureStore } from '@reduxjs/toolkit';
import { createEvent, fork, allSettled } from 'effector';

describe('reduxInterop', () => {
it('should work', () => {
expect(reduxInterop()).toEqual('redux-interop');
describe('@withease/redux', () => {
test('Should throw if setup is not an effector unit', () => {
const reduxStore = legacy_createStore(() => ({}), {});
const setup = () => {
// ok
};

expect(() =>
// @ts-expect-error - setup is not an effector unit
createReduxInterop({ reduxStore, setup })
).toThrowErrorMatchingInlineSnapshot('"setup must be an effector unit"');
});

test('Should throw if reduxStore is not a Redux store', () => {
const reduxStore = {};
const setup = createEvent();

expect(() =>
// @ts-expect-error - reduxStore is not a Redux store
createReduxInterop({ reduxStore, setup })
).toThrowErrorMatchingInlineSnapshot(
'"reduxStore must be provided and should be a Redux store"'
);
});

describe('raw Redux', () => {
test('Should take redux store in', () => {
const reduxStore = legacy_createStore(() => ({}), {});
const setup = createEvent();
const interop = createReduxInterop({ reduxStore, setup });
setup();

expect(interop.$store.getState()).toBe(reduxStore);
});

test('Should allow dispatching actions', () => {
const reduxStore = legacy_createStore((_, x) => x, {});
const setup = createEvent();
const interop = createReduxInterop({ reduxStore, setup });
setup();

const action = { type: 'test' };
interop.dispatch(action);

expect(reduxStore.getState()).toEqual(action);
});

test('Should allow reading state', () => {
const reduxStore = legacy_createStore((_, x) => ({
value: (x as any).value || 'kek',
}));
const setup = createEvent();
const interop = createReduxInterop({ reduxStore, setup });
setup();

const $state = interop.fromState((x) => x['value']);

expect($state.getState()).toEqual('kek');

reduxStore.dispatch({ type: 'test', value: 'lol' });

expect($state.getState()).toEqual('lol');
});

test.only('Should work with Fork API', async () => {
const reduxStore = legacy_createStore(() => ({}), {});
const setup = createEvent();
const interop = createReduxInterop({ reduxStore, setup });

const $state = interop.fromState((x) => x['value']);

const mockStore = legacy_createStore((_, x) => ({
value: (x as any).value || 'kek',
}));

const scope = fork({
values: [[interop.$store, mockStore]],
});

await allSettled(setup, { scope });

expect(scope.getState($state)).toEqual('kek');

await allSettled(interop.dispatch, {
scope,
params: { type: 'test', value: 'lol' },
});

expect(scope.getState($state)).toEqual('lol');
});
});
});
17 changes: 11 additions & 6 deletions packages/redux-interop/src/lib/redux-interop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,14 @@ export function createReduxInterop<
serialize: 'ignore',
name: 'redux-interop/$store',
});

const stateUpdated = createEvent<State>();

const $state = createStore<State>(reduxStore.getState(), {
serialize: 'ignore',
name: 'redux-interop/$state',
});
skipVoid: false,
}).on(stateUpdated, (_, state) => state);

function fromState<R>(selector: (state: State) => R) {
return $state.map(selector);
Expand All @@ -72,12 +76,13 @@ export function createReduxInterop<
batch: false,
});

const stateUpdated = createEvent<State>();

const reduxInteropSetupFx = attach({
source: $store,
effect(store) {
const sendUpdate = scopeBind(stateUpdated, { safe: true });

sendUpdate(store.getState());

store.subscribe(() => {
sendUpdate(store.getState());
});
Expand All @@ -99,7 +104,7 @@ export function createReduxInterop<
return {
/**
* Effector store containing the Redux store
*
*
* You can use it to substitute Redux store instance, while writing tests via Effector's Fork API
* @example
* ```
Expand All @@ -113,7 +118,7 @@ export function createReduxInterop<
$store,
/**
* Effector's event, which will trigger Redux store dispatch
*
*
* @example
* ```
* const updateName = reduxInterop.dispatch.prepend((name: string) => updateNameAction(name));
Expand All @@ -122,7 +127,7 @@ export function createReduxInterop<
dispatch,
/**
* Function to get Effector store containing selected part of the Redux store
*
*
* @example
* ```
* const $user = reduxInterop.fromState(state => state.user);
Expand Down

0 comments on commit c1f22e2

Please sign in to comment.