From cbb2735f3bc727a4790886679f5405ec51fb0dd4 Mon Sep 17 00:00:00 2001 From: Gregory Beaver Date: Thu, 13 Apr 2017 10:51:39 -0500 Subject: [PATCH] small update to make testing apps that use the router easier --- README.md | 38 +++++++++++++++++++++++++++++++++++ enhancers.js | 1 + package.json | 2 +- src/index.js | 9 +++++++++ test/index.test.js | 49 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 enhancers.js diff --git a/README.md b/README.md index ff6027c..c16bbef 100644 --- a/README.md +++ b/README.md @@ -963,6 +963,44 @@ Everything is properly isolated, and testable. You can easily unit test your ro stateFromParams and paramsFromState and updateState properties. Components are simply components, no magic. +To set up routes for testing in a unit test, the `synchronousMakeRoutes` functions is +available. Pass in an array of routes, and use the return in the reducer + +```javascript +import { synchronousMakeRoutes, routerReducer } from 'react-redux-saga-router' + +describe('some component that uses routes', () => { + let fakeState + beforeEach(() => { + const action = synchronousMakeRoutes([ + { + name: 'route1', + path: '/route1' + }, + { + name: 'route1', + path: '/route2/:thing', + stateToParams: state => state, + paramsToState: params => params, + update: { + thing: thing => ({ type: 'changething', payload: thing }) + } + } + ]) + fakeState = { + routing: routerReducer(undefined, action) + } + }) + it('test something', () => { + // use components that have or + }) +}) +``` + +You will need to set this up for any `` components that use route to generate +the path, and any components that contain `` or `` tags when rendering +them. + ## License MIT License diff --git a/enhancers.js b/enhancers.js new file mode 100644 index 0000000..8c8e944 --- /dev/null +++ b/enhancers.js @@ -0,0 +1 @@ +module.exports = require('./lib/enhancers.js') diff --git a/package.json b/package.json index 0d3a068..8cc6e81 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-redux-saga-router", - "version": "0.9.0", + "version": "0.9.1", "description": "elegant powerful routing based on the simplicity of storing url as state", "main": "lib/index.js", "directories": { diff --git a/src/index.js b/src/index.js index 25b1c1a..c8d4a09 100644 --- a/src/index.js +++ b/src/index.js @@ -5,6 +5,7 @@ import historyChannel from './historyChannel' import routerReducer from './reducer' import * as actions from './actions' import * as sagas from './sagas' +import * as enhancers from './enhancers' import { connectLink } from './Link' import { connectRoutes } from './Routes' import { connectToggle } from './Toggle' @@ -57,6 +58,14 @@ export const setEnhancedRoutes = (r) => { options.enhancedRoutes = r } +// for unit-testing purposes +export function synchronousMakeRoutes(routes) { + const action = actions.batchRoutes(routes) + setEnhancedRoutes(Object.keys(action.payload.routes).reduce((en, route) => + enhancers.save(action.payload.routes[route], en), options.enhancedRoutes)) + return action +} + export function *router(connect, routeDefinitions, history, channel, isServer) { options.server = !!isServer yield [ diff --git a/test/index.test.js b/test/index.test.js index 6523be8..fabb314 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -172,4 +172,53 @@ describe('react-redux-saga-router', () => { expect(middleware.run.args[0]).eqls([index.router, connect, routes, a, b, true]) index.default(middleware, connect, routes) // for coverage }) + it('synchronousMakeRoutes', () => { + const routes = [{ + name: 'campers', + path: '/campers/:year(/:id)', + paramsFromState: state => ({ + id: state.campers.selectedCamper ? state.campers.selectedCamper : undefined, + year: state.currentYear + '' // eslint-disable-line + }), + stateFromParams: params => ({ + id: params.id ? params.id : false, + year: +params.year + }), + updateState: { + id: id => ({ type: 'select', payload: id }), + year: year => ({ type: 'year', payload: year }) + } + }, { + name: 'ensembles', + path: '/ensembles(/:id)', + paramsFromState: state => ({ + id: state.ensembleTypes.selectedEnsembleType ? + state.ensembleTypes.selectedEnsembleType : undefined, + }), + stateFromParams: params => ({ + id: params.id ? params.id : false, + }), + updateState: { + id: id => ({ type: 'ensemble', payload: id }), + } + }, { + name: 'foo', + path: '/my/:fancy/path(/:wow/*supercomplicated(/:thing))', + }] + expect(index.synchronousMakeRoutes(routes)).eqls(actions.batchRoutes(routes)) + expect(index.options.enhancedRoutes).eqls({ + campers: { + ...enhancers.enhanceRoute(routes[0]), + parent: undefined, + }, + ensembles: { + ...enhancers.enhanceRoute(routes[1]), + parent: undefined, + }, + foo: { + ...enhancers.enhanceRoute(routes[2]), + parent: undefined, + } + }) + }) })