From bfd571e0af8c368de4ecbe40903d4fefd0b455f8 Mon Sep 17 00:00:00 2001 From: Ryan Florence Date: Sat, 5 Dec 2015 10:18:23 +0000 Subject: [PATCH] added context.router refs #2646 --- modules/RoutingContext.js | 23 ++++-- modules/__tests__/RoutingContext-test.js | 101 +++++++++++++++++++++++ 2 files changed, 118 insertions(+), 6 deletions(-) create mode 100644 modules/__tests__/RoutingContext-test.js diff --git a/modules/RoutingContext.js b/modules/RoutingContext.js index 1f1680df53..07d4c24458 100644 --- a/modules/RoutingContext.js +++ b/modules/RoutingContext.js @@ -5,15 +5,25 @@ import getRouteParams from './getRouteParams' const { array, func, object } = React.PropTypes -/** - * A renders the component tree for a given router state - * and sets the history object and the current location in context. - */ class RoutingContext extends Component { getChildContext() { const { history, location } = this.props - return { history, location } + const router = { + push(...args) { + history.push(...args) + }, + replace(...args) { + history.replace(...args) + }, + addRouteLeaveHook(...args) { + return history.listenBeforeLeavingRoute(...args) + }, + isActive(...args) { + return history.isActive(...args) + } + } + return { history, location, router } } createElement(component, props) { @@ -94,7 +104,8 @@ RoutingContext.defaultProps = { RoutingContext.childContextTypes = { history: object.isRequired, - location: object.isRequired + location: object.isRequired, + router: object.isRequired } export default RoutingContext diff --git a/modules/__tests__/RoutingContext-test.js b/modules/__tests__/RoutingContext-test.js new file mode 100644 index 0000000000..768d4baaf2 --- /dev/null +++ b/modules/__tests__/RoutingContext-test.js @@ -0,0 +1,101 @@ +import expect from 'expect' +import React from 'react' +import { render, unmountComponentAtNode } from 'react-dom' +import RoutingContext from '../RoutingContext' +import match from '../match' + +describe('For Real RoutingContext', () => { + let node, routes, context, history + + beforeEach(() => { + node = document.createElement('div') + history = { push() {}, replace() {} } + + class Component extends React.Component { + constructor(props, ctx) { + super(props, ctx) + context = ctx + } + render() { return null } + } + + Component.contextTypes = { + router: React.PropTypes.object.isRequired + } + + routes = { path: '/', component: Component } + }) + + afterEach(() => unmountComponentAtNode(node)) + + function renderTest(done) { + match({ location: '/', routes }, (err, redirect, renderProps) => { + render(, node) + done() + }) + } + + describe('2.0', () => { + it('exports only `router` to context') + }) + + it('exports a `router` object to routing context', (done) => { + renderTest(() => { + expect(context.router).toExist() + done() + }) + }) + + describe('interaction with history', () => { + it('proxies calls to `push` to `props.history`', (done) => { + const args = [ 1, 2, 3 ] + history.push = (...params) => { + expect(params).toEqual(args) + done() + } + renderTest(() => { + context.router.push(...args) + }) + }) + + it('proxies calls to `replace` to `props.history`', (done) => { + const args = [ 1, 2, 3 ] + history.replace = (...params) => { + expect(params).toEqual(args) + done() + } + renderTest(() => { + context.router.replace(...args) + }) + }) + + it('proxies calls to `addRouteLeaveHook` to `props.history`', (done) => { + const args = [ 1, 2, 3 ] + const retVal = function () {} + history.listenBeforeLeavingRoute = (...params) => { + expect(params).toEqual(args) + return retVal + } + renderTest(() => { + const remove = context.router.addRouteLeaveHook(...args) + expect(remove).toBe(retVal) + done() + }) + }) + + it('proxies calls to `isActive` to `props.history`', (done) => { + const args = [ 1, 2, 3 ] + const retVal = function () {} + history.isActive = (...params) => { + expect(params).toEqual(args) + return retVal + } + renderTest(() => { + const isActive = context.router.isActive(...args) + expect(isActive).toBe(retVal) + done() + }) + }) + }) + +})