import { Updux } from './Updux';
import { action } from './actions';

test('basic', () => {
    const doIt = action('doIt');
    const thisToo = action('thisToo');

    const dux = new Updux({
        initial: '',
        actions: { doIt, thisToo },
        mutations: {
            doIt: () => () => 'bingo',
            thisToo: () => () => 'straight type',
        },
    });

    expect(dux.reducer(undefined, dux.actions.doIt())).toEqual('bingo');

    expect(dux.reducer(undefined, dux.actions.thisToo())).toEqual(
        'straight type'
    );
});

test('override', () => {
    const foo = action('foo');

    const dux = new Updux({
        initial: { alpha: [] },
        mutations: {
            '+': (payload, action) => (state) => ({
                ...state,
                alpha: [...state.alpha, action.type],
            }),
        },
        subduxes: {
            subbie: new Updux({
                initial: 0,
                actions: {
                    foo,
                },
                mutations: {
                    foo: () => (state) => state + 1,
                },
            }),
        },
    });

    let state = [foo(), { type: 'bar' }].reduce(
        (state, action) => dux.upreducer(action)(state),
        undefined
    );

    expect(state).toMatchObject({
        alpha: ['foo', 'bar'],
        subbie: 1,
    });
});

test('order of processing', () => {
    const foo = action('foo');

    const dux = new Updux({
        initial: {
            x: [],
        },
        mutations: {
            foo:
                () =>
                ({ x }) => ({ x: [...x, 'main'] }),
        },
        subduxes: {
            x: new Updux({
                actions: { foo },
                mutations: {
                    foo: () => (state) => [...state, 'subdux'],
                },
            }),
        },
    });

    expect(dux.reducer(undefined, foo())).toMatchObject({
        x: ['subdux', 'main'],
    });
});

test('setMutation', () => {
    const foo = action('foo');

    const dux = new Updux({
        initial: '',
    });

    // noop
    expect(dux.reducer(undefined, foo())).toEqual('');

    dux.setMutation('foo', () => () => 'foo');

    expect(dux.reducer(undefined, foo())).toEqual('foo');
});

test('setMutation, name as function', () => {
    const bar = action('bar');

    const dux = new Updux({
        initial: '',
    });
    dux.setMutation(bar, () => () => 'bar');

    expect(dux.reducer(undefined, bar())).toEqual('bar');
});
