Skip to content
This repository has been archived by the owner on May 3, 2024. It is now read-only.

Commit

Permalink
prepare for integration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
cellog committed Apr 11, 2017
1 parent 6419e87 commit f564067
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 6 deletions.
41 changes: 41 additions & 0 deletions test/integration/url.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import * as effects from 'redux-saga/effects'
import { delay } from 'redux-saga'
import * as helpers from '../test_helper'

describe('react-redux-saga-router integration tests: url changes', () => {

function another() {
return 'hi'
}

function *foo(d) {
while (true) {
yield effects.take('hi')
yield delay(d)
yield effects.call(another)
yield effects.put({ type: 'there', payload: 'wheee' })
}
}

const run = helpers.testSaga()
it('proof of concept', (done) => {
run([
[foo, 1500]
], function *() {
yield effects.put.resolve(helpers.START)
yield effects.put({ type: 'hi', payload: 'there' })
let input = yield effects.take('take')

expect(input.effect).eqls(effects.take('hi'))

yield effects.take('promise')
input = yield effects.take('call')
expect(input.effect).eqls(effects.call(another))

input = yield effects.take('put')
expect(input.effect).eqls(effects.put({ type: 'there', payload: 'wheee' }))

yield effects.call(done)
})
})
})
112 changes: 106 additions & 6 deletions test/test_helper.jsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,117 @@
import React, { Component } from 'react'
import createSagaMiddleware, { runSaga } from 'redux-saga'
import * as effects from 'redux-saga/effects'
import * as utils from 'redux-saga/utils'
import teaspoon from 'teaspoon'
import { Provider, connect } from 'react-redux'
import { createStore, combineReducers, applyMiddleware } from 'redux'
import reducer from '../src/reducer'

const fakeWeekReducer = (state = 1) => state

function renderComponent(ComponentClass, props = {}, state = {}, returnStore = false) {
export const tests = Object.keys(utils.asEffect).reduce((effects, name) => ({
...effects,
[name]: effect => utils.is.notUndef(utils.asEffect[name](effect))
}), {
isPromise: effect => utils.is.promise(effect),
isHelper: effect => utils.is.helper(effect),
isIterator: effect => utils.is.iterator(effect),
takeEvery: effect => utils.is.helper(effect),
takeLatest: effect => utils.is.helper(effect),
throttle: effect => utils.is.helper(effect),
takem: effect => utils.is.notUndef(utils.asEffect.take(effect)) && effect.TAKE.maybe,
apply: () => false,
spawn: effect => utils.is.notUndef(utils.asEffect.fork(effect)) && effect.FORK.detached,
})

function sagaStore(state, reducers = { routing: reducer, week: fakeWeekReducer }) {
const log = []
const logger = store => next => action => { // eslint-disable-line
log.push(action)
return next(action)
}
const monitor = {
}
const sagaMiddleware = createSagaMiddleware({ sagaMonitor: monitor })

const store = createStore(combineReducers(reducers),
state, applyMiddleware(logger, sagaMiddleware))
return {
log,
store,
sagaMiddleware,
monitor,
}
}

const store = createStore(combineReducers({ routing: reducer, week: fakeWeekReducer }),
state, applyMiddleware(logger))
export const effectNames =
Object.keys(utils.asEffect).reduce((effects, name) => ({
...effects,
[name]: name,
}), {
isPromise: 'promise',
isHelper: 'helper',
isIterator: 'iterator',
takeEvery: 'takeEvery',
takeLatest: 'takeLatest',
throttle: 'throttle',
takem: 'takem',
apply: 'apply',
spawn: 'spawn',
})

export const effectName = effect =>
effectNames[Object.keys(tests).map(test => tests[test](effect) && test).filter(t => t)[0]]

export const toEffectAction = effect => ({
type: effectName(effect),
effect
})

export const START = { type: '###@@@start' }

export function testSaga(state = undefined) {
const { sagaMiddleware, store, monitor } = sagaStore(state)
return (sagas, test) => {
sagaMiddleware.run(function*() {
yield effects.take('###@@@start')
yield sagas.map(args => effects.fork(...args))
})
runSaga(test(), {
subscribe: (callback) => {
monitor.effectTriggered = ({ effect }) => {
if (effect.length) {
effect.forEach((e) => {
callback(toEffectAction(e))
})
} else {
callback(toEffectAction(effect))
}
}
return () => null
},
dispatch: (output) => {
store.dispatch(output)
}
})
}
}

function renderComponent(ComponentClass, props = {}, state = {}, returnStore = false,
sagaStore = false) {
let store
let log
const sagaMiddleware = createSagaMiddleware()
if (!sagaStore) {
log = []
const logger = store => next => action => { // eslint-disable-line
log.push(action)
return next(action)
}

store = createStore(combineReducers({ routing: reducer, week: fakeWeekReducer }),
state, applyMiddleware(logger, sagaMiddleware))
}

class Tester extends Component {
constructor(props) {
Expand All @@ -28,7 +125,7 @@ function renderComponent(ComponentClass, props = {}, state = {}, returnStore = f
}
render() {
return (
<Provider store={store}>
<Provider store={sagaStore ? sagaStore.store : store}>
<ComponentClass {...this.state} />
</Provider>
)
Expand All @@ -39,9 +136,12 @@ function renderComponent(ComponentClass, props = {}, state = {}, returnStore = f
).render()
const ret = componentInstance
if (returnStore) {
return [ret, store, log]
if (sagaStore) {
return [ret, sagaStore.store, sagaStore.log, sagaStore.sagaMiddleware]
}
return [ret, store, log, sagaMiddleware]
}
return ret
}

export { renderComponent, connect } // eslint-disable-line
export { renderComponent, connect, sagaStore } // eslint-disable-line

0 comments on commit f564067

Please sign in to comment.