Add & test createReducer
This commit is contained in:
parent
dca9691d7d
commit
82ec4c321a
@ -6,11 +6,12 @@ import bodyParser from 'body-parser'
|
|||||||
import express from 'express'
|
import express from 'express'
|
||||||
import {AddressInfo} from 'net'
|
import {AddressInfo} from 'net'
|
||||||
import {Server} from 'http'
|
import {Server} from 'http'
|
||||||
|
import {TPendingActions, TAllActions} from './types'
|
||||||
import {createReduxClient, createReducer} from './redux'
|
import {createReduxClient, createReducer} from './redux'
|
||||||
import {createRemoteClient} from './remote'
|
import {createRemoteClient} from './remote'
|
||||||
|
import {createStore} from '@rondo/client'
|
||||||
import {jsonrpc} from './express'
|
import {jsonrpc} from './express'
|
||||||
import {keys} from 'ts-transformer-keys'
|
import {keys} from 'ts-transformer-keys'
|
||||||
import {TPendingActions, TAllActions} from './types'
|
|
||||||
|
|
||||||
describe('createReduxClient', () => {
|
describe('createReduxClient', () => {
|
||||||
|
|
||||||
@ -77,29 +78,37 @@ describe('createReduxClient', () => {
|
|||||||
type AllActions = TAllActions<typeof client>
|
type AllActions = TAllActions<typeof client>
|
||||||
|
|
||||||
const defaultState = {
|
const defaultState = {
|
||||||
sum: 1,
|
loading: 0,
|
||||||
|
error: '',
|
||||||
|
add: 0,
|
||||||
|
addStringsAsync: '',
|
||||||
}
|
}
|
||||||
|
|
||||||
const create = createReducer('myService', defaultState)
|
const reducer = createReducer('myService', defaultState)
|
||||||
<typeof client>((state, action) => {
|
<typeof client>((state, action) => {
|
||||||
switch (action.method) {
|
switch (action.method) {
|
||||||
case 'add':
|
case 'add':
|
||||||
const r1: number = action.payload
|
|
||||||
return state
|
|
||||||
case 'addAsync':
|
case 'addAsync':
|
||||||
const r2: number = action.payload
|
|
||||||
return state
|
|
||||||
case 'addStringsAsync':
|
|
||||||
const r3: string = action.payload
|
|
||||||
return state
|
|
||||||
case 'addWithContext':
|
case 'addWithContext':
|
||||||
const r4: number = action.payload
|
case 'addAsyncWithContext':
|
||||||
return state
|
const r1: number = action.payload
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
add: r1,
|
||||||
|
}
|
||||||
|
case 'addStringsAsync':
|
||||||
|
const r2: string = action.payload
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
addStringsAsync: r2,
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const store = createStore({reducer})()
|
||||||
|
|
||||||
function handleAction(state: any, action: AllActions) {
|
function handleAction(state: any, action: AllActions) {
|
||||||
if (action.type !== 'myService') {
|
if (action.type !== 'myService') {
|
||||||
return
|
return
|
||||||
@ -123,60 +132,56 @@ describe('createReduxClient', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return client
|
return {client, store}
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('action creators', () => {
|
describe('action creators', () => {
|
||||||
describe('add', () => {
|
describe('add', () => {
|
||||||
it('creates a redux action with type, method and status', async () => {
|
it('creates a redux action with type, method and status', async () => {
|
||||||
const client = getClient()
|
const {client, store} = getClient()
|
||||||
const action = client.add(3, 7)
|
const action = client.add(3, 7)
|
||||||
expect(action.method).toEqual('add')
|
expect(action.method).toEqual('add')
|
||||||
expect(action.type).toEqual('myService')
|
expect(action.type).toEqual('myService')
|
||||||
expect(action.status).toEqual('pending')
|
expect(action.status).toEqual('pending')
|
||||||
const result = await action.payload
|
const result: number = await store.dispatch(action).payload
|
||||||
expect(result).toEqual(3 + 7)
|
expect(result).toEqual(3 + 7)
|
||||||
// compilation test
|
expect(store.getState().add).toEqual(10)
|
||||||
expect(result + 2).toEqual(12)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('addAsync', () => {
|
describe('addAsync', () => {
|
||||||
it('creates a redux action with type, method and status', async () => {
|
it('creates a redux action with type, method and status', async () => {
|
||||||
const client = getClient()
|
const {client, store} = getClient()
|
||||||
const action = client.addAsync(3, 7)
|
const action = client.addAsync(3, 7)
|
||||||
expect(action.method).toEqual('addAsync')
|
expect(action.method).toEqual('addAsync')
|
||||||
expect(action.type).toEqual('myService')
|
expect(action.type).toEqual('myService')
|
||||||
expect(action.status).toEqual('pending')
|
expect(action.status).toEqual('pending')
|
||||||
const result = await action.payload
|
const result: number = await store.dispatch(action).payload
|
||||||
expect(result).toEqual(3 + 7)
|
expect(result).toEqual(3 + 7)
|
||||||
// compilation test
|
expect(store.getState().add).toEqual(10)
|
||||||
expect(result + 2).toEqual(12)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('addWithContext', () => {
|
describe('addWithContext', () => {
|
||||||
it('creates a redux action with type, method and status', async () => {
|
it('creates a redux action with type, method and status', async () => {
|
||||||
const client = getClient()
|
const {client, store} = getClient()
|
||||||
const action = client.addWithContext(3, 7)
|
const action = client.addWithContext(3, 7)
|
||||||
expect(action.method).toEqual('addWithContext')
|
expect(action.method).toEqual('addWithContext')
|
||||||
expect(action.type).toEqual('myService')
|
expect(action.type).toEqual('myService')
|
||||||
expect(action.status).toEqual('pending')
|
expect(action.status).toEqual('pending')
|
||||||
const result = await action.payload
|
const result: number = await store.dispatch(action).payload
|
||||||
expect(result).toEqual(3 + 7 + 1000)
|
expect(result).toEqual(3 + 7 + 1000)
|
||||||
// compilation test
|
expect(store.getState().add).toEqual(1010)
|
||||||
expect(result + 2).toEqual(1012)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('addAsyncWithContext', () => {
|
describe('addAsyncWithContext', () => {
|
||||||
it('creates a redux action with type, method and status', async () => {
|
it('creates a redux action with type, method and status', async () => {
|
||||||
const client = getClient()
|
const {client, store} = getClient()
|
||||||
const action = client.addAsyncWithContext(3, 7)
|
const action = client.addAsyncWithContext(3, 7)
|
||||||
expect(action.method).toEqual('addAsyncWithContext')
|
expect(action.method).toEqual('addAsyncWithContext')
|
||||||
expect(action.type).toEqual('myService')
|
expect(action.type).toEqual('myService')
|
||||||
expect(action.status).toEqual('pending')
|
expect(action.status).toEqual('pending')
|
||||||
const result = await action.payload
|
const result: number = await store.dispatch(action).payload
|
||||||
expect(result).toEqual(3 + 7 + 1000)
|
expect(result).toEqual(3 + 7 + 1000)
|
||||||
// compilation test
|
expect(store.getState().add).toEqual(1010)
|
||||||
expect(result + 2).toEqual(1012)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -27,25 +27,38 @@ export function createReduxClient<T, ActionType extends string>(
|
|||||||
return service as TReduxed<T, ActionType>
|
return service as TReduxed<T, ActionType>
|
||||||
}
|
}
|
||||||
|
|
||||||
export const createReducer = <ActionType extends string, State>(
|
export interface IState {
|
||||||
|
loading: number
|
||||||
|
error: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const createReducer = <ActionType extends string, State extends IState>(
|
||||||
actionType: ActionType,
|
actionType: ActionType,
|
||||||
defaultState: State,
|
defaultState: State,
|
||||||
) => <R extends IReduxed<ActionType>>(
|
) => <R extends IReduxed<ActionType>>(
|
||||||
handleAction: (state: State, action: TResolvedActions<R>) => State,
|
handleAction: (state: State, action: TResolvedActions<R>) => State,
|
||||||
) => (state: State = defaultState, action?: TAllActions<R>): State => {
|
) => (state: State = defaultState, action: TAllActions<R>): State => {
|
||||||
if (!action) {
|
|
||||||
return state
|
|
||||||
}
|
|
||||||
if (action.type !== actionType) {
|
if (action.type !== actionType) {
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
if (action.status === 'pending') {
|
if (action.status === 'pending') {
|
||||||
// TODO handle loading
|
return {
|
||||||
|
...state,
|
||||||
|
loading: state.loading + 1,
|
||||||
|
error: '',
|
||||||
|
}
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
if (action.status === 'rejected') {
|
if (action.status === 'rejected') {
|
||||||
// TODO handle rejected
|
return {
|
||||||
return state
|
...state,
|
||||||
|
loading: state.loading - 1,
|
||||||
|
error: action.payload.message,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return handleAction(state, action)
|
return handleAction({
|
||||||
|
...state,
|
||||||
|
loading: state.loading - 1,
|
||||||
|
error: '',
|
||||||
|
}, action)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user