From f1772cc532edf7d46606ca28c5f7bf965d709d8d Mon Sep 17 00:00:00 2001 From: Kimmo Puputti Date: Thu, 16 Feb 2017 11:36:33 +0200 Subject: [PATCH] Add withFlattenedRoutes HOC --- src/util/__snapshots__/routes.test.js.snap | 7 ++++++ src/util/routes.js | 26 ++++++++++++++++++++ src/util/routes.test.js | 28 ++++++++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 src/util/__snapshots__/routes.test.js.snap create mode 100644 src/util/routes.test.js diff --git a/src/util/__snapshots__/routes.test.js.snap b/src/util/__snapshots__/routes.test.js.snap new file mode 100644 index 00000000..402a114d --- /dev/null +++ b/src/util/__snapshots__/routes.test.js.snap @@ -0,0 +1,7 @@ +exports[`withFlattenedRoutes should inject the provided routes 1`] = ``; + +exports[`withFlattenedRoutes should inject the provided routes 2`] = ` +
+ SomePage +
+`; diff --git a/src/util/routes.js b/src/util/routes.js index 020fe5e5..097618e5 100644 --- a/src/util/routes.js +++ b/src/util/routes.js @@ -1,7 +1,9 @@ +import React, { PropTypes } from 'react'; import { find } from 'lodash'; import { matchPath } from 'react-router-dom'; import pathToRegexp from 'path-to-regexp'; import routesConfiguration from '../routesConfiguration'; +import * as propTypes from './propTypes'; export const flattenRoutes = routesArray => routesArray.reduce((a, b) => a.concat(b.routes ? [b].concat(flattenRoutes(b.routes)) : b), []); @@ -69,3 +71,27 @@ const matchPathnameCreator = routes => * matchRoutesToLocation helps to figure out which routes are related to given location. */ export const matchPathname = matchPathnameCreator(routesConfiguration); + +/** + * A higher order component (HOC) to take the flattened routes from + * the context that the RoutesProvider component has provided. + * + * Injects the routes as the `flattenedRoutes` prop in the given + * component. Works similarly as `withRouter` in React Router. + */ +export const withFlattenedRoutes = Component => { + const WithFlattenedRoutesComponent = (props, context) => ( + + ); + + WithFlattenedRoutesComponent.displayName = `withFlattenedRoutes(${Component.displayName || + Component.name})`; + + const { arrayOf } = PropTypes; + + WithFlattenedRoutesComponent.contextTypes = { + flattenedRoutes: arrayOf(propTypes.route).isRequired, + }; + + return WithFlattenedRoutesComponent; +}; diff --git a/src/util/routes.test.js b/src/util/routes.test.js new file mode 100644 index 00000000..5bf6985d --- /dev/null +++ b/src/util/routes.test.js @@ -0,0 +1,28 @@ +import React, { PropTypes } from 'react'; +import { RoutesProvider } from '../components'; +import { renderDeep, renderShallow } from './test-helpers'; +import * as propTypes from './propTypes'; +import { withFlattenedRoutes } from './routes'; + +const { arrayOf } = PropTypes; + +describe('withFlattenedRoutes', () => { + it('should inject the provided routes', () => { + const CompComp = props =>
{props.flattenedRoutes[0].name}
; + CompComp.propTypes = { flattenedRoutes: arrayOf(propTypes.route).isRequired }; + const Comp = withFlattenedRoutes(CompComp); + const routes = [{ name: 'SomePage', path: 'some-page', component: () => null }]; + const shallowTree = renderShallow( + + + , + ); + expect(shallowTree).toMatchSnapshot(); + const deepTree = renderDeep( + + + , + ); + expect(deepTree).toMatchSnapshot(); + }); +});