Extract context helpers to separate file

This commit is contained in:
Vesa Luusua 2017-03-31 15:50:21 +03:00
parent fda12bb732
commit 8971c9b29a
9 changed files with 87 additions and 57 deletions

View file

@ -4,7 +4,7 @@ import { connect } from 'react-redux';
import { Switch, Route, withRouter } from 'react-router-dom';
import { NotFoundPage } from './containers';
import { NamedRedirect } from './components';
import { withFlattenedRoutes } from './util/routes';
import { withFlattenedRoutes } from './util/contextHelpers';
import * as propTypes from './util/propTypes';
const { bool, arrayOf, object, func, shape, string, any } = PropTypes;

View file

@ -20,7 +20,8 @@
import React, { PropTypes } from 'react';
import { Link, withRouter } from 'react-router-dom';
import classNames from 'classnames';
import { pathByRouteName, withFlattenedRoutes } from '../../util/routes';
import { pathByRouteName } from '../../util/routes';
import { withFlattenedRoutes } from '../../util/contextHelpers';
import * as propTypes from '../../util/propTypes';
export const NamedLinkComponent = props => {

View file

@ -4,7 +4,8 @@
*/
import React, { PropTypes } from 'react';
import { Redirect } from 'react-router-dom';
import { pathByRouteName, withFlattenedRoutes } from '../../util/routes';
import { pathByRouteName } from '../../util/routes';
import { withFlattenedRoutes } from '../../util/contextHelpers';
import * as propTypes from '../../util/propTypes';
const NamedRedirect = props => {

View file

@ -0,0 +1,7 @@
exports[`util/contextHelpers.js withFlattenedRoutes should inject the provided routes 1`] = `<withFlattenedRoutes(CompComp) />`;
exports[`util/contextHelpers.js withFlattenedRoutes should inject the provided routes 2`] = `
<div>
SomePage
</div>
`;

View file

@ -1,7 +0,0 @@
exports[`util/routes.js withFlattenedRoutes should inject the provided routes 1`] = `<withFlattenedRoutes(CompComp) />`;
exports[`util/routes.js withFlattenedRoutes should inject the provided routes 2`] = `
<div>
SomePage
</div>
`;

View file

@ -0,0 +1,25 @@
import React, { PropTypes } from 'react';
import * as propTypes from './propTypes';
/**
* 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) => (
<Component flattenedRoutes={context.flattenedRoutes} {...props} />
);
WithFlattenedRoutesComponent.displayName = `withFlattenedRoutes(${Component.displayName || Component.name})`;
const { arrayOf } = PropTypes;
WithFlattenedRoutesComponent.contextTypes = {
flattenedRoutes: arrayOf(propTypes.route).isRequired,
};
return WithFlattenedRoutesComponent;
};

View file

@ -0,0 +1,49 @@
import React, { PropTypes } from 'react';
import { PageLayout, RoutesProvider } from '../components';
import routesConfiguration from '../routesConfiguration';
import { flattenRoutes } from './routes';
import { renderDeep, renderShallow } from './test-helpers';
import * as propTypes from './propTypes';
import { withFlattenedRoutes, withTogglePageClasses } from './contextHelpers';
const { arrayOf, func } = PropTypes;
describe('util/contextHelpers.js', () => {
describe('withFlattenedRoutes', () => {
it('should inject the provided routes', () => {
const CompComp = props => <div>{props.flattenedRoutes[0].name}</div>;
CompComp.propTypes = { flattenedRoutes: arrayOf(propTypes.route).isRequired };
const Comp = withFlattenedRoutes(CompComp);
const routes = [{ name: 'SomePage', path: 'some-page', component: () => null }];
const shallowTree = renderShallow(
<RoutesProvider flattenedRoutes={routes}>
<Comp />
</RoutesProvider>
);
expect(shallowTree).toMatchSnapshot();
const deepTree = renderDeep(
<RoutesProvider flattenedRoutes={routes}>
<Comp />
</RoutesProvider>
);
expect(deepTree).toMatchSnapshot();
});
});
describe('withTogglePageClasses', () => {
it('should inject the provided function', () => {
const CompComp = props => <div>{typeof props.togglePageClasses}</div>;
CompComp.propTypes = { togglePageClasses: func.isRequired };
const Comp = withTogglePageClasses(CompComp);
const deepTree = renderDeep(
<RoutesProvider flattenedRoutes={flattenRoutes(routesConfiguration)}>
<PageLayout title="testing withTogglePageClasses">
<Comp />
</PageLayout>
</RoutesProvider>
);
expect(deepTree).toMatchSnapshot();
});
});
});

View file

@ -1,9 +1,7 @@
import React, { PropTypes } from 'react';
import { find } from 'lodash';
import { matchPath } from 'react-router-dom';
import pathToRegexp from 'path-to-regexp';
import { stringify } from './urlHelpers';
import * as propTypes from './propTypes';
// Flatten the routes config.
// TODO: flatten the original config and remove this function
@ -70,29 +68,6 @@ export const matchPathname = (pathname, 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) => (
<Component flattenedRoutes={context.flattenedRoutes} {...props} />
);
WithFlattenedRoutesComponent.displayName = `withFlattenedRoutes(${Component.displayName || Component.name})`;
const { arrayOf } = PropTypes;
WithFlattenedRoutesComponent.contextTypes = {
flattenedRoutes: arrayOf(propTypes.route).isRequired,
};
return WithFlattenedRoutesComponent;
};
/**
* ResourceLocatorString is used to direct webapp to correct page.
* In contrast to Universal Resource Locator (URL), this doesn't contain protocol, host, or port.

View file

@ -3,32 +3,11 @@ import { RoutesProvider } from '../components';
import routesConfiguration from '../routesConfiguration';
import { renderDeep, renderShallow } from './test-helpers';
import * as propTypes from './propTypes';
import { createResourceLocatorString, flattenRoutes, withFlattenedRoutes } from './routes';
import { createResourceLocatorString, flattenRoutes } from './routes';
const { arrayOf } = PropTypes;
describe('util/routes.js', () => {
describe('withFlattenedRoutes', () => {
it('should inject the provided routes', () => {
const CompComp = props => <div>{props.flattenedRoutes[0].name}</div>;
CompComp.propTypes = { flattenedRoutes: arrayOf(propTypes.route).isRequired };
const Comp = withFlattenedRoutes(CompComp);
const routes = [{ name: 'SomePage', path: 'some-page', component: () => null }];
const shallowTree = renderShallow(
<RoutesProvider flattenedRoutes={routes}>
<Comp />
</RoutesProvider>
);
expect(shallowTree).toMatchSnapshot();
const deepTree = renderDeep(
<RoutesProvider flattenedRoutes={routes}>
<Comp />
</RoutesProvider>
);
expect(deepTree).toMatchSnapshot();
});
});
describe('createResourceLocatorString', () => {
const flattenedRoutes = flattenRoutes(routesConfiguration);