70 lines
1.7 KiB
TypeScript
70 lines
1.7 KiB
TypeScript
import React from 'react'
|
|
import ReactDOM from 'react-dom'
|
|
import T from 'react-dom/test-utils'
|
|
import {Connector, IStateSelector} from '../redux'
|
|
import {Provider} from 'react-redux'
|
|
import {createStore} from '../store'
|
|
import {
|
|
Action,
|
|
AnyAction,
|
|
DeepPartial,
|
|
Reducer,
|
|
ReducersMapObject,
|
|
combineReducers,
|
|
} from 'redux'
|
|
|
|
interface IRenderParams<State> {
|
|
reducers: ReducersMapObject<State, any>
|
|
state?: DeepPartial<State>
|
|
connector: Connector
|
|
select: IStateSelector<State, any>
|
|
}
|
|
|
|
export class TestUtils {
|
|
/**
|
|
* Create a redux store
|
|
*/
|
|
readonly createStore = createStore
|
|
|
|
render(jsx: JSX.Element) {
|
|
const component = T.renderIntoDocument(jsx) as React.Component<any>
|
|
const node = ReactDOM.findDOMNode(component) as Element
|
|
return {component, node}
|
|
}
|
|
|
|
combineReducers<S>(reducers: ReducersMapObject<S, any>): Reducer<S>
|
|
combineReducers<S, A extends Action = AnyAction>(
|
|
reducers: ReducersMapObject<S, A>,
|
|
): Reducer<S, A> {
|
|
return combineReducers(reducers)
|
|
}
|
|
|
|
/**
|
|
* Creates a redux store, connects a component, and provides the `render`
|
|
* method to render the connected component with a `Provider`.
|
|
*/
|
|
withProvider<State, A extends Action<any> = AnyAction>(
|
|
params: IRenderParams<State>,
|
|
) {
|
|
const store = this.createStore({
|
|
reducers: params.reducers,
|
|
state: params.state,
|
|
})
|
|
const Component = params.connector.connect(params.select)
|
|
|
|
const render = (additionalProps: {[key: string]: any} = {}) => {
|
|
return this.render(
|
|
<Provider store={store}>
|
|
<Component {...additionalProps} />
|
|
</Provider>,
|
|
)
|
|
}
|
|
|
|
return {
|
|
render,
|
|
store,
|
|
Component,
|
|
}
|
|
}
|
|
}
|