Skip to content

Commit

Permalink
Merge pull request #13 from dlmr/support-async-routes
Browse files Browse the repository at this point in the history
Adds support for async routes
  • Loading branch information
dlmr committed Nov 2, 2016
2 parents 43abc90 + 1dacfc7 commit ee5e493
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 29 deletions.
2 changes: 1 addition & 1 deletion src/RedialContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import getAllComponents from './getAllComponents';

function hydrate(renderProps) {
if (typeof __REDIAL_PROPS__ !== 'undefined' && Array.isArray(__REDIAL_PROPS__)) {
const getMapKeyForComponent = createMapKeys(renderProps.routes);
const getMapKeyForComponent = createMapKeys(renderProps.routes, renderProps.components);
const components = getAllComponents(renderProps.components);
const componentKeys = components.map(getMapKeyForComponent);
return createMap(componentKeys, __REDIAL_PROPS__);
Expand Down
2 changes: 1 addition & 1 deletion src/triggerHooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export default function triggerHooks({
const getProps = (key) =>
() => redialMap.get(key) || {};

const getMapKeyForComponent = createMapKeys(renderProps.routes);
const getMapKeyForComponent = createMapKeys(renderProps.routes, renderProps.components);

const completeLocals = (component) => {
const key = getMapKeyForComponent(component);
Expand Down
49 changes: 30 additions & 19 deletions src/util/findRouteByComponent.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,35 @@
export default function findRouteByComponent(component, routes) {
import isPlainObject from 'lodash.isplainobject';

const isNamedComponents = isPlainObject;

function searchNamedComponents(component, namedComponents, correspondingRoute, result) {
return Object.keys(namedComponents)
.some(name => {
const isMatch = namedComponents[name] === component;
if (isMatch) {
/* eslint-disable no-param-reassign */
result.name = name;
result.route = correspondingRoute;
/* eslint-enable no-param-reassign */
}
return isMatch;
});
}

export default function findRouteByComponent(component, matchedRoutes, matchedComponents) {
const result = {};
for (const route of routes) {
if (route.component === component) {
result.route = route;
return result;

matchedComponents.some((matchedComponent, i) => {
if (isNamedComponents(matchedComponent)) {
return searchNamedComponents(component, matchedComponent, matchedRoutes[i], result);
}
if (route.components) {
const foundNamedComponent = Object.keys(route.components)
.some(key => {
const found = route.components[key] === component;
if (found) {
result.name = key;
}
return found;
});
if (foundNamedComponent) {
result.route = route;
return result;
}

const isMatch = component === matchedComponent;
if (isMatch) {
result.route = matchedRoutes[i];
}
}
return isMatch;
});

return result;
}
4 changes: 2 additions & 2 deletions src/util/mapKeys.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import findRouteByComponent from './findRouteByComponent';
import getRoutePath from './getRoutePath';

export default function createGenerateMapKeyByMatchedRoutes(routes) {
export default function createGenerateMapKeyByMatchedRoutes(routes, components) {
return (component) => {
const { route, name } = findRouteByComponent(component, routes);
const { route, name } = findRouteByComponent(component, routes, components);
if (!route) {
throw new Error('`component` not found among the matched `routes`');
}
Expand Down
17 changes: 13 additions & 4 deletions tests/util/findRouteByComponent.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@ import expect from 'expect';

import findRouteByComponent from '../../src/util/findRouteByComponent';

function toMatchedComponents(routes) {
return routes.map(route => route.component || route.components);
}

describe('findRouteByComponent', () => {
const component = () => {};
it('Returns an empty object for empty routes', () => {
expect(findRouteByComponent(component, [])).toEqual({});
expect(findRouteByComponent(component, [], [])).toEqual({});
});
it('Returns an empty object when the component cannot be found among the routes', () => {
const routes = [
Expand All @@ -16,7 +20,7 @@ describe('findRouteByComponent', () => {
component: function andNotThisOnceEither() {},
},
];
expect(findRouteByComponent(component, routes)).toEqual({});
expect(findRouteByComponent(component, routes, toMatchedComponents(routes))).toEqual({});
});
it('Returns the first matched route', () => {
const routes = [
Expand All @@ -27,7 +31,9 @@ describe('findRouteByComponent', () => {
component,
},
];
expect(findRouteByComponent(component, routes)).toEqual({ route: routes[1] });
expect(findRouteByComponent(component, routes, toMatchedComponents(routes))).toEqual({
route: routes[1],
});
});
it('Handles `components` for named routes', () => {
const routes = [
Expand All @@ -43,6 +49,9 @@ describe('findRouteByComponent', () => {
},
},
];
expect(findRouteByComponent(component, routes)).toEqual({ route: routes[1], name: 'c' });
expect(findRouteByComponent(component, routes, toMatchedComponents(routes))).toEqual({
route: routes[1],
name: 'c',
});
});
});
4 changes: 2 additions & 2 deletions tests/util/mapKeys.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ describe('mapKeys', () => {
];

describe('regular routes', () => {
const mapKeyByComponent = createGenerateMapKeyByMatchedRoutes(routes);
const mapKeyByComponent = createGenerateMapKeyByMatchedRoutes(routes, routes.map(route => route.component || route.components));

it('Throws an Error when the component cannot be found among the matched routes', () => {
expect(() => mapKeyByComponent(() => {}, routes)).toThrow(
Expand All @@ -55,7 +55,7 @@ describe('mapKeys', () => {
});

describe('named routes', () => {
const mapKeyByComponent = createGenerateMapKeyByMatchedRoutes(namedRoutes);
const mapKeyByComponent = createGenerateMapKeyByMatchedRoutes(namedRoutes, namedRoutes.map(route => route.component || route.components));
it('Gives the path up to the matched route', () => {
expect(mapKeyByComponent(namedRoutes[0].component, namedRoutes)).toBe('/');
expect(mapKeyByComponent(namedRoutes[1].component, namedRoutes)).toBe('//');
Expand Down

0 comments on commit ee5e493

Please sign in to comment.