+ render(, div, () => assertion(div.innerHTML))
+}
+
+describe('applyMiddleware', () => {
+
+ it('applies one middleware', (done) => {
+ run({
+ renderWithMiddleware: applyMiddleware(useFoo()),
+ Component: (props) => {props.fooFromContext}
+ }, (html) => {
+ expect(html).toContain(FOO_ROOT_CONTAINER_TEXT)
+ done()
+ })
+ })
+
+ it('applies more than one middleware', (done) => {
+ run({
+ renderWithMiddleware: applyMiddleware(useBar(), useFoo()),
+ Component: (props) => {props.fooFromContext} {props.barFromContext}
+ }, (html) => {
+ expect(html).toContain(FOO_ROOT_CONTAINER_TEXT)
+ expect(html).toContain(BAR_ROOT_CONTAINER_TEXT)
+ done()
+ })
+ })
+
+ it('applies more middleware with only `getContainer`', (done) => {
+ run({
+ renderWithMiddleware: applyMiddleware(
+ useBar(),
+ useFoo(),
+ useBaz(BAZ_CONTAINER_TEXT)
+ ),
+ Component: (props) => (
+
+ {props.fooFromContext}
+ {props.barFromContext}
+ {props.bazInjected}
+
+ )
+ }, (html) => {
+ expect(html).toContain(FOO_ROOT_CONTAINER_TEXT)
+ expect(html).toContain(BAR_ROOT_CONTAINER_TEXT)
+ expect(html).toContain(BAZ_CONTAINER_TEXT)
+ done()
+ })
+ })
+
+ it('applies middleware that only has `getContainer`', (done) => {
+ run({
+ renderWithMiddleware: applyMiddleware(
+ useBaz(BAZ_CONTAINER_TEXT)
+ ),
+ Component: (props) => (
+ {props.bazInjected}
+ )
+ }, (html) => {
+ expect(html).toContain(BAZ_CONTAINER_TEXT)
+ done()
+ })
+ })
+
+})
diff --git a/modules/applyRouterMiddleware.js b/modules/applyRouterMiddleware.js
new file mode 100644
index 0000000000..ab0001837d
--- /dev/null
+++ b/modules/applyRouterMiddleware.js
@@ -0,0 +1,30 @@
+import React, { createElement } from 'react'
+import RouterContext from './RouterContext'
+
+export default (...middlewares) => {
+ const withContext = middlewares.map(m => m.renderRouterContext).filter(f => f)
+ const withComponent = middlewares.map(m => m.renderRouteComponent).filter(f => f)
+ const makeCreateElement = (baseCreateElement = createElement) => (
+ (Component, props) => (
+ withComponent.reduceRight(
+ (previous, renderRouteComponent) => (
+ renderRouteComponent(previous, props)
+ ), baseCreateElement(Component, props)
+ )
+ )
+ )
+
+ return (renderProps) => (
+ withContext.reduceRight(
+ (previous, renderRouterContext) => (
+ renderRouterContext(previous, renderProps)
+ ), (
+
+ )
+ )
+ )
+}
+
diff --git a/modules/index.js b/modules/index.js
index f3f10f1fae..b82e692dcb 100644
--- a/modules/index.js
+++ b/modules/index.js
@@ -23,6 +23,7 @@ export PropTypes from './PropTypes'
export match from './match'
export useRouterHistory from './useRouterHistory'
export { formatPattern } from './PatternUtils'
+export applyRouterMiddleware from './applyRouterMiddleware'
/* histories */
export browserHistory from './browserHistory'