diff --git a/.watchmanconfig b/.watchmanconfig deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/react-router-config/modules/__tests__/integration-test.js b/packages/react-router-config/modules/__tests__/integration-test.js index 369de78986..84db0c28c0 100644 --- a/packages/react-router-config/modules/__tests__/integration-test.js +++ b/packages/react-router-config/modules/__tests__/integration-test.js @@ -1,26 +1,28 @@ -import React from 'react' -import ReactDOMServer from 'react-dom/server' -import StaticRouter from 'react-router/StaticRouter' -import matchRoutes from '../matchRoutes' -import renderRoutes from '../renderRoutes' +import React from "react"; +import ReactDOMServer from "react-dom/server"; +import StaticRouter from "react-router/StaticRouter"; +import matchRoutes from "../matchRoutes"; +import renderRoutes from "../renderRoutes"; -describe('integration', () => { - it('generates the same matches in renderRoutes and matchRoutes', () => { - const rendered = [] +describe("integration", () => { + it("generates the same matches in renderRoutes and matchRoutes", () => { + const rendered = []; const Comp = ({ match, route: { routes } }) => ( - rendered.push(match), - renderRoutes(routes) - ) + rendered.push(match), renderRoutes(routes) + ); const routes = [ - { path: '/pepper', + { + path: "/pepper", component: Comp, routes: [ - { path: '/pepper/:type', + { + path: "/pepper/:type", component: Comp, routes: [ - { path: '/pepper/:type/scoville', + { + path: "/pepper/:type/scoville", component: Comp } ] @@ -28,47 +30,49 @@ describe('integration', () => { ] }, - { path: undefined, + { + path: undefined, component: Comp, routes: [ - { path: '/ghost', + { + path: "/ghost", component: Comp } ] } - ] + ]; - const pathname = '/pepper/jalepeno' - const branch = matchRoutes(routes, pathname) + const pathname = "/pepper/jalepeno"; + const branch = matchRoutes(routes, pathname); ReactDOMServer.renderToString( {renderRoutes(routes)} - ) - expect(branch.length).toEqual(2) - expect(rendered.length).toEqual(2) - expect(branch[0].match).toEqual(rendered[0]) - expect(branch[1].match).toEqual(rendered[1]) - }) + ); + expect(branch.length).toEqual(2); + expect(rendered.length).toEqual(2); + expect(branch[0].match).toEqual(rendered[0]); + expect(branch[1].match).toEqual(rendered[1]); + }); - - - it('generates the same matches in renderRoutes and matchRoutes with pathless routes', () => { - const rendered = [] + it("generates the same matches in renderRoutes and matchRoutes with pathless routes", () => { + const rendered = []; const Comp = ({ match, route: { routes } }) => ( - rendered.push(match), - renderRoutes(routes) - ) + rendered.push(match), renderRoutes(routes) + ); const routes = [ - { path: '/pepper', + { + path: "/pepper", component: Comp, routes: [ - { path: '/pepper/:type', + { + path: "/pepper/:type", component: Comp, routes: [ - { path: '/pepper/:type/scoville', + { + path: "/pepper/:type/scoville", component: Comp } ] @@ -76,115 +80,111 @@ describe('integration', () => { ] }, - { path: undefined, + { + path: undefined, component: Comp, routes: [ - { path: '/ghost', + { + path: "/ghost", component: Comp } ] } - ] + ]; - const pathname = '/ghost' - const branch = matchRoutes(routes, pathname) + const pathname = "/ghost"; + const branch = matchRoutes(routes, pathname); ReactDOMServer.renderToString( {renderRoutes(routes)} - ) - expect(branch.length).toEqual(2) - expect(rendered.length).toEqual(2) - expect(branch[0].match).toEqual(rendered[0]) - expect(branch[1].match).toEqual(rendered[1]) - }) - + ); + expect(branch.length).toEqual(2); + expect(rendered.length).toEqual(2); + expect(branch[0].match).toEqual(rendered[0]); + expect(branch[1].match).toEqual(rendered[1]); + }); - - it('generates the same matches in renderRoutes and matchRoutes with routes using exact', () => { - const rendered = [] + it("generates the same matches in renderRoutes and matchRoutes with routes using exact", () => { + const rendered = []; const Comp = ({ match, route: { routes } }) => ( - rendered.push(match), - renderRoutes(routes) - ) + rendered.push(match), renderRoutes(routes) + ); const routes = [ // should skip { - path: '/pepper/habanero', + path: "/pepper/habanero", component: Comp, exact: true }, // should match { - path: '/pepper', + path: "/pepper", component: Comp, exact: true } - ] + ]; - const pathname = '/pepper' - const branch = matchRoutes(routes, pathname) + const pathname = "/pepper"; + const branch = matchRoutes(routes, pathname); ReactDOMServer.renderToString( {renderRoutes(routes)} - ) - expect(branch.length).toEqual(1) - expect(rendered.length).toEqual(1) - expect(branch[0].match).toEqual(rendered[0]) - }) - - + ); + expect(branch.length).toEqual(1); + expect(rendered.length).toEqual(1); + expect(branch[0].match).toEqual(rendered[0]); + }); - it('generates the same matches in renderRoutes and matchRoutes with routes using exact + strict', () => { - const rendered = [] + it("generates the same matches in renderRoutes and matchRoutes with routes using exact + strict", () => { + const rendered = []; const Comp = ({ match, route: { routes } }) => ( - rendered.push(match), - renderRoutes(routes) - ) + rendered.push(match), renderRoutes(routes) + ); const routes = [ // should match { - path: '/pepper/', + path: "/pepper/", component: Comp, strict: true, exact: true, routes: [ // should skip { - path: '/pepper', + path: "/pepper", component: Comp, strict: true, exact: true } ] } - ] + ]; - let pathname = '/pepper' - let branch = matchRoutes(routes, pathname) + let pathname = "/pepper"; + let branch = matchRoutes(routes, pathname); ReactDOMServer.renderToString( {renderRoutes(routes)} - ) - expect(branch.length).toEqual(0) - expect(rendered.length).toEqual(0) + ); + expect(branch.length).toEqual(0); + expect(rendered.length).toEqual(0); - pathname = '/pepper/' - branch = matchRoutes(routes, pathname) + pathname = "/pepper/"; + branch = matchRoutes(routes, pathname); ReactDOMServer.renderToString( {renderRoutes(routes)} - ) + ); - expect(branch.length).toEqual(1) - expect(rendered.length).toEqual(1) - expect(branch[0].match).toEqual(rendered[0]) - }) -}) + expect(branch.length).toEqual(1); + expect(rendered.length).toEqual(1); + expect(branch[0].match).toEqual(rendered[0]); + }); +}); diff --git a/packages/react-router-config/modules/__tests__/matchRoutes-test.js b/packages/react-router-config/modules/__tests__/matchRoutes-test.js index 7ce9b0f7b3..185da5c027 100644 --- a/packages/react-router-config/modules/__tests__/matchRoutes-test.js +++ b/packages/react-router-config/modules/__tests__/matchRoutes-test.js @@ -1,96 +1,90 @@ -import matchRoutes from '../matchRoutes' +import matchRoutes from "../matchRoutes"; -it('finds matched routes', () => { +it("finds matched routes", () => { const routes = [ - { path: '/', + { + path: "/", exact: true }, - { path: '/pepper', + { + path: "/pepper", routes: [ - { path: '/pepper/:type', - routes: [ - { path: '/pepper/:type/scoville' } - ] + { + path: "/pepper/:type", + routes: [{ path: "/pepper/:type/scoville" }] } ] }, - { path: undefined, - routes: [ - { path: '/ghost' } - ] + { + path: undefined, + routes: [{ path: "/ghost" }] } - ] - - const branch = matchRoutes(routes, '/pepper/jalepeno') - expect(branch.length).toEqual(2) - expect(branch[0].route).toEqual(routes[1]) - expect(branch[1].route).toEqual(routes[1].routes[0]) -}) - -it('stops matching after finding the first match, just like ', () => { - const routes = [ - { path: '/static' }, - { path: '/:dynamic' } - ] - const branch = matchRoutes(routes, '/static') - expect(branch.length).toEqual(1) - expect(branch[0].route).toEqual(routes[0]) -}) + ]; + const branch = matchRoutes(routes, "/pepper/jalepeno"); + expect(branch.length).toEqual(2); + expect(branch[0].route).toEqual(routes[1]); + expect(branch[1].route).toEqual(routes[1].routes[0]); +}); -describe('pathless routes', () => { +it("stops matching after finding the first match, just like ", () => { + const routes = [{ path: "/static" }, { path: "/:dynamic" }]; + const branch = matchRoutes(routes, "/static"); + expect(branch.length).toEqual(1); + expect(branch[0].route).toEqual(routes[0]); +}); +describe("pathless routes", () => { const routes = [ - { path: '/', + { + path: "/", routes: [ - { path: undefined, - routes: [ - { path: '/habenero' } - ] + { + path: undefined, + routes: [{ path: "/habenero" }] } ] } - ] + ]; - it('matches child paths', () => { - const branch = matchRoutes(routes, '/habenero') - expect(branch.length).toEqual(3) - expect(branch[0].route).toEqual(routes[0]) - expect(branch[1].route).toEqual(routes[0].routes[0]) - expect(branch[2].route).toEqual(routes[0].routes[0].routes[0]) - }) + it("matches child paths", () => { + const branch = matchRoutes(routes, "/habenero"); + expect(branch.length).toEqual(3); + expect(branch[0].route).toEqual(routes[0]); + expect(branch[1].route).toEqual(routes[0].routes[0]); + expect(branch[2].route).toEqual(routes[0].routes[0].routes[0]); + }); - it('returns the parent match', () => { - const branch = matchRoutes(routes, '/habenero') - expect(branch.length).toBe(3) - expect(branch[1].match).toBe(branch[0].match) - }) + it("returns the parent match", () => { + const branch = matchRoutes(routes, "/habenero"); + expect(branch.length).toBe(3); + expect(branch[1].match).toBe(branch[0].match); + }); - describe('at the root', () => { + describe("at the root", () => { const routes = [ - { path: undefined, - routes: [ - { path: '/anaheim' } - ] + { + path: undefined, + routes: [{ path: "/anaheim" }] } - ] + ]; it('matches "/"', () => { - const branch = matchRoutes(routes, '/') - expect(branch.length).toEqual(1) - expect(branch[0].route).toEqual(routes[0]) - }) + const branch = matchRoutes(routes, "/"); + expect(branch.length).toEqual(1); + expect(branch[0].route).toEqual(routes[0]); + }); - it('returns a root match for a pathless root route', () => { - const branch = matchRoutes(routes, '/') + it("returns a root match for a pathless root route", () => { + const branch = matchRoutes(routes, "/"); expect(branch[0].match).toEqual({ - path: '/', - url: '/', + path: "/", + url: "/", params: {}, isExact: true - }) - }) - }) -}) + }); + }); + }); +}); diff --git a/packages/react-router-config/modules/__tests__/renderRoutes-test.js b/packages/react-router-config/modules/__tests__/renderRoutes-test.js index 7f98d623ba..9045225c43 100644 --- a/packages/react-router-config/modules/__tests__/renderRoutes-test.js +++ b/packages/react-router-config/modules/__tests__/renderRoutes-test.js @@ -1,394 +1,436 @@ -import React from 'react' -import ReactDOM from 'react-dom' -import ReactDOMServer from 'react-dom/server' -import StaticRouter from 'react-router/StaticRouter' -import Router from 'react-router/Router' -import renderRoutes from '../renderRoutes' -import createHistory from 'history/createMemoryHistory' - -describe('renderRoutes', () => { - let renderedRoutes - let renderedExtraProps +import React from "react"; +import ReactDOM from "react-dom"; +import ReactDOMServer from "react-dom/server"; +import StaticRouter from "react-router/StaticRouter"; +import Router from "react-router/Router"; +import renderRoutes from "../renderRoutes"; +import createHistory from "history/createMemoryHistory"; + +describe("renderRoutes", () => { + let renderedRoutes; + let renderedExtraProps; const Comp = ({ route, route: { routes }, ...extraProps }) => ( renderedRoutes.push(route), renderedExtraProps.push(extraProps), renderRoutes(routes) - ) + ); beforeEach(() => { - renderedRoutes = [] - renderedExtraProps = [] - }) + renderedRoutes = []; + renderedExtraProps = []; + }); - it('renders pathless routes', () => { + it("renders pathless routes", () => { const routeToMatch = { component: Comp - } - const routes = [routeToMatch] + }; + const routes = [routeToMatch]; ReactDOMServer.renderToString( - + {renderRoutes(routes)} - ) - expect(renderedRoutes.length).toEqual(1) - expect(renderedRoutes[0]).toEqual(routeToMatch) - }) + ); + expect(renderedRoutes.length).toEqual(1); + expect(renderedRoutes[0]).toEqual(routeToMatch); + }); - it('passes extraProps to the component rendered by a pathless route', () => { + it("passes extraProps to the component rendered by a pathless route", () => { const routeToMatch = { component: Comp - } - const routes = [routeToMatch] - const extraProps = { anExtraProp: 'anExtraPropValue' } + }; + const routes = [routeToMatch]; + const extraProps = { anExtraProp: "anExtraPropValue" }; ReactDOMServer.renderToString( - + {renderRoutes(routes, extraProps)} - ) - expect(renderedExtraProps.length).toEqual(1) - expect(renderedExtraProps[0].anExtraProp).toEqual('anExtraPropValue') - }) + ); + expect(renderedExtraProps.length).toEqual(1); + expect(renderedExtraProps[0].anExtraProp).toEqual("anExtraPropValue"); + }); - it('passes extraProps to the component rendered by a matched route', () => { + it("passes extraProps to the component rendered by a matched route", () => { const routeToMatch = { component: Comp, - path: '/' - } - const routes = [routeToMatch, { - component: Comp - }] - const extraProps = { anExtraProp: 'anExtraPropValue' } + path: "/" + }; + const routes = [ + routeToMatch, + { + component: Comp + } + ]; + const extraProps = { anExtraProp: "anExtraPropValue" }; ReactDOMServer.renderToString( - + {renderRoutes(routes, extraProps)} - ) - expect(renderedExtraProps.length).toEqual(1) - expect(renderedExtraProps[0].anExtraProp).toEqual('anExtraPropValue') - }) + ); + expect(renderedExtraProps.length).toEqual(1); + expect(renderedExtraProps[0].anExtraProp).toEqual("anExtraPropValue"); + }); - describe('Switch usage', () => { - it('renders the first matched route', () => { + describe("Switch usage", () => { + it("renders the first matched route", () => { const routeToMatch = { component: Comp, - path: '/' - } - const routes = [routeToMatch, { - component: Comp - }] + path: "/" + }; + const routes = [ + routeToMatch, + { + component: Comp + } + ]; ReactDOMServer.renderToString( - + {renderRoutes(routes)} - ) - expect(renderedRoutes.length).toEqual(1) - expect(renderedRoutes[0]).toEqual(routeToMatch) - }) + ); + expect(renderedRoutes.length).toEqual(1); + expect(renderedRoutes[0]).toEqual(routeToMatch); + }); - it('renders the first matched route in nested routes', () => { + it("renders the first matched route in nested routes", () => { const childRouteToMatch = { component: Comp, - path: '/' - } + path: "/" + }; const routeToMatch = { component: Comp, - path: '/', - routes: [childRouteToMatch, { + path: "/", + routes: [ + childRouteToMatch, + { + component: Comp + } + ] + }; + const routes = [ + routeToMatch, + { component: Comp - }] - } - const routes = [routeToMatch, { - component: Comp - }] + } + ]; ReactDOMServer.renderToString( - + {renderRoutes(routes)} - ) - expect(renderedRoutes.length).toEqual(2) - expect(renderedRoutes[0]).toEqual(routeToMatch) - expect(renderedRoutes[1]).toEqual(childRouteToMatch) - }) + ); + expect(renderedRoutes.length).toEqual(2); + expect(renderedRoutes[0]).toEqual(routeToMatch); + expect(renderedRoutes[1]).toEqual(childRouteToMatch); + }); - it('does not remount a ', () => { - const node = document.createElement('div') + it("does not remount a ", () => { + const node = document.createElement("div"); - let mountCount = 0 + let mountCount = 0; - const App = ({ route: { routes } }) => ( - renderRoutes(routes) - ) + const App = ({ route: { routes } }) => renderRoutes(routes); class Comp extends React.Component { componentDidMount() { - mountCount++ + mountCount++; } render() { - return
+ return
; } } const routes = [ - { path: '/', + { + path: "/", component: App, routes: [ - { path: '/one', + { + path: "/one", component: Comp, - key: 'comp' + key: "comp" }, - { path: '/two', + { + path: "/two", component: Comp, - key: 'comp' + key: "comp" }, - { path: '/three', - component: Comp, + { + path: "/three", + component: Comp } ] } - ] + ]; const history = createHistory({ - initialEntries: [ '/one' ] - }) + initialEntries: ["/one"] + }); - ReactDOM.render(( - - {renderRoutes(routes)} - - ), node) + ReactDOM.render( + {renderRoutes(routes)}, + node + ); - expect(mountCount).toBe(1) + expect(mountCount).toBe(1); - history.push('/one') - expect(mountCount).toBe(1) + history.push("/one"); + expect(mountCount).toBe(1); - history.push('/two') - expect(mountCount).toBe(1) + history.push("/two"); + expect(mountCount).toBe(1); - history.push('/three') - expect(mountCount).toBe(2) - }) + history.push("/three"); + expect(mountCount).toBe(2); + }); - it('passes props to Switch', () => { - const App = ({ route: { routes } }) => ( - renderRoutes(routes) - ) + it("passes props to Switch", () => { + const App = ({ route: { routes } }) => renderRoutes(routes); const routeToMatch = { component: Comp, - path: '/one' - } + path: "/one" + }; const routes = [ - { path: '/', + { + path: "/", component: App, routes: [ - { path: '/one', + { + path: "/one", component: Comp } ] } - ] + ]; ReactDOMServer.renderToString( - - {renderRoutes(routes, {}, {location: { pathname: '/one' }})} + + {renderRoutes(routes, {}, { location: { pathname: "/one" } })} - ) + ); - expect(renderedRoutes.length).toEqual(1) - expect(renderedRoutes[0]).toEqual(routeToMatch) - }) - }) + expect(renderedRoutes.length).toEqual(1); + expect(renderedRoutes[0]).toEqual(routeToMatch); + }); + }); - describe('routes with exact', () => { - it('renders the exact route', () => { + describe("routes with exact", () => { + it("renders the exact route", () => { const routeToMatch = { component: Comp, - path: '/path/child', + path: "/path/child", exact: true, - routes: [{ - component: Comp - }] - } - const routes = [{ - component: Comp, - path: '/path', - exact: true - }, routeToMatch] + routes: [ + { + component: Comp + } + ] + }; + const routes = [ + { + component: Comp, + path: "/path", + exact: true + }, + routeToMatch + ]; ReactDOMServer.renderToString( - + {renderRoutes(routes)} - ) - expect(renderedRoutes.length).toEqual(2) - expect(renderedRoutes[0]).toEqual(routeToMatch) - expect(renderedRoutes[1]).toEqual({ component: Comp }) - }) - - it('skips exact route and does not render it and any of its child routes', () => { - const routes = [{ - component: Comp, - path: '/path', - exact: true, - routes: [{ - component: Comp - }, { - component: Comp - }] - }] + ); + expect(renderedRoutes.length).toEqual(2); + expect(renderedRoutes[0]).toEqual(routeToMatch); + expect(renderedRoutes[1]).toEqual({ component: Comp }); + }); + + it("skips exact route and does not render it and any of its child routes", () => { + const routes = [ + { + component: Comp, + path: "/path", + exact: true, + routes: [ + { + component: Comp + }, + { + component: Comp + } + ] + } + ]; ReactDOMServer.renderToString( - + {renderRoutes(routes)} - ) + ); ReactDOMServer.renderToString( - + {renderRoutes(routes)} - ) - expect(renderedRoutes.length).toEqual(0) - }) + ); + expect(renderedRoutes.length).toEqual(0); + }); - it('renders the matched exact route but not its child routes if they do not match', () => { - const routes = [{ - // should render - component: Comp, - path: '/path', - exact: true, - routes: [{ - // should skip - component: Comp, - path: '/path/child', - exact: true - }, { + it("renders the matched exact route but not its child routes if they do not match", () => { + const routes = [ + { // should render - component: Comp - }] - }] + component: Comp, + path: "/path", + exact: true, + routes: [ + { + // should skip + component: Comp, + path: "/path/child", + exact: true + }, + { + // should render + component: Comp + } + ] + } + ]; ReactDOMServer.renderToString( - + {renderRoutes(routes)} - ) + ); ReactDOMServer.renderToString( - + {renderRoutes(routes)} - ) - expect(renderedRoutes.length).toEqual(2) - expect(renderedRoutes[0]).toEqual(routes[0]) - expect(renderedRoutes[1]).toEqual(routes[0].routes[1]) - }) - }) - - describe('routes with exact + strict', () => { - it('renders the exact strict route', () => { + ); + expect(renderedRoutes.length).toEqual(2); + expect(renderedRoutes[0]).toEqual(routes[0]); + expect(renderedRoutes[1]).toEqual(routes[0].routes[1]); + }); + }); + + describe("routes with exact + strict", () => { + it("renders the exact strict route", () => { const routeToMatch = { component: Comp, - path: '/path/', - exact: true, - strict: true - } - const routes = [{ - // should skip - component: Comp, - path: '/path', + path: "/path/", exact: true, strict: true - // should render - }, routeToMatch] + }; + const routes = [ + { + // should skip + component: Comp, + path: "/path", + exact: true, + strict: true + // should render + }, + routeToMatch + ]; ReactDOMServer.renderToString( - + {renderRoutes(routes)} - ) - expect(renderedRoutes.length).toEqual(1) - expect(renderedRoutes[0]).toEqual(routeToMatch) - }) + ); + expect(renderedRoutes.length).toEqual(1); + expect(renderedRoutes[0]).toEqual(routeToMatch); + }); - it('skips exact strict route and does not render it and any of its child routes', () => { - const routes = [{ - component: Comp, - path: '/path/', - exact: true, - strict: true, - routes: [{ - component: Comp - }, { - component: Comp - }] - }] + it("skips exact strict route and does not render it and any of its child routes", () => { + const routes = [ + { + component: Comp, + path: "/path/", + exact: true, + strict: true, + routes: [ + { + component: Comp + }, + { + component: Comp + } + ] + } + ]; ReactDOMServer.renderToString( - + {renderRoutes(routes)} - ) + ); ReactDOMServer.renderToString( - + {renderRoutes(routes)} - ) + ); ReactDOMServer.renderToString( - + {renderRoutes(routes)} - ) - expect(renderedRoutes.length).toEqual(0) - }) + ); + expect(renderedRoutes.length).toEqual(0); + }); - it('renders the matched exact strict route but not its child routes if they do not match', () => { - const routes = [{ - // should skip - component: Comp, - path: '/path', - exact: true, - strict: true - }, { - // should render - component: Comp, - path: '/path/', - exact: true, - strict: true, - routes: [{ + it("renders the matched exact strict route but not its child routes if they do not match", () => { + const routes = [ + { // should skip component: Comp, + path: "/path", exact: true, - strict: true, - path: '/path' - }, { + strict: true + }, + { // should render component: Comp, + path: "/path/", exact: true, strict: true, - path: '/path/' - }] - }] + routes: [ + { + // should skip + component: Comp, + exact: true, + strict: true, + path: "/path" + }, + { + // should render + component: Comp, + exact: true, + strict: true, + path: "/path/" + } + ] + } + ]; ReactDOMServer.renderToString( - + {renderRoutes(routes)} - ) + ); ReactDOMServer.renderToString( - + {renderRoutes(routes)} - ) - expect(renderedRoutes.length).toEqual(2) - expect(renderedRoutes[0]).toEqual(routes[1]) - expect(renderedRoutes[1]).toEqual(routes[1].routes[1]) - }) - }) -}) + ); + expect(renderedRoutes.length).toEqual(2); + expect(renderedRoutes[0]).toEqual(routes[1]); + expect(renderedRoutes[1]).toEqual(routes[1].routes[1]); + }); + }); +}); diff --git a/packages/react-router-config/modules/index.js b/packages/react-router-config/modules/index.js index 60265064be..5b1835849d 100644 --- a/packages/react-router-config/modules/index.js +++ b/packages/react-router-config/modules/index.js @@ -1,2 +1,2 @@ -export matchRoutes from './matchRoutes' -export renderRoutes from './renderRoutes' +export matchRoutes from "./matchRoutes"; +export renderRoutes from "./renderRoutes"; diff --git a/packages/react-router-config/modules/matchRoutes.js b/packages/react-router-config/modules/matchRoutes.js index f63b2d071e..358fc58382 100644 --- a/packages/react-router-config/modules/matchRoutes.js +++ b/packages/react-router-config/modules/matchRoutes.js @@ -1,29 +1,29 @@ -import matchPath from 'react-router/matchPath' -import Router from 'react-router/Router' +import matchPath from "react-router/matchPath"; +import Router from "react-router/Router"; // ensure we're using the exact code for default root match -const { computeMatch } = Router.prototype +const { computeMatch } = Router.prototype; -const matchRoutes = (routes, pathname, /*not public API*/branch = []) => { - routes.some((route) => { +const matchRoutes = (routes, pathname, /*not public API*/ branch = []) => { + routes.some(route => { const match = route.path ? matchPath(pathname, route) : branch.length ? branch[branch.length - 1].match // use parent match - : computeMatch(pathname) // use default "root" match + : computeMatch(pathname); // use default "root" match if (match) { - branch.push({ route, match }) + branch.push({ route, match }); if (route.routes) { - matchRoutes(route.routes, pathname, branch) + matchRoutes(route.routes, pathname, branch); } } - return match - }) + return match; + }); - return branch -} + return branch; +}; -export default matchRoutes +export default matchRoutes; diff --git a/packages/react-router-config/modules/renderRoutes.js b/packages/react-router-config/modules/renderRoutes.js index 843014410f..85286e5733 100644 --- a/packages/react-router-config/modules/renderRoutes.js +++ b/packages/react-router-config/modules/renderRoutes.js @@ -1,21 +1,22 @@ -import React from 'react' -import Switch from 'react-router/Switch' -import Route from 'react-router/Route' +import React from "react"; +import Switch from "react-router/Switch"; +import Route from "react-router/Route"; -const renderRoutes = (routes, extraProps = {}, switchProps = {}) => routes ? ( - - {routes.map((route, i) => ( - ( - - )} - /> - ))} - -) : null +const renderRoutes = (routes, extraProps = {}, switchProps = {}) => + routes ? ( + + {routes.map((route, i) => ( + ( + + )} + /> + ))} + + ) : null; -export default renderRoutes +export default renderRoutes; diff --git a/packages/react-router-config/rollup.config.js b/packages/react-router-config/rollup.config.js index e92bdc184a..b6b70754ea 100644 --- a/packages/react-router-config/rollup.config.js +++ b/packages/react-router-config/rollup.config.js @@ -1,42 +1,42 @@ -import babel from 'rollup-plugin-babel' -import uglify from 'rollup-plugin-uglify' -import replace from 'rollup-plugin-replace' -import commonjs from 'rollup-plugin-commonjs' -import resolve from 'rollup-plugin-node-resolve' +import babel from "rollup-plugin-babel"; +import uglify from "rollup-plugin-uglify"; +import replace from "rollup-plugin-replace"; +import commonjs from "rollup-plugin-commonjs"; +import resolve from "rollup-plugin-node-resolve"; const config = { - input: 'modules/index.js', - name: 'ReactRouterConfig', + input: "modules/index.js", + name: "ReactRouterConfig", globals: { - react: 'React', - 'react-router/Switch': 'ReactRouter.Switch', - 'react-router/Router': 'ReactRouter.Router', - 'react-router/Route': 'ReactRouter.Route', - 'react-router/matchPath': 'ReactRouter.matchPath', + react: "React", + "react-router/Switch": "ReactRouter.Switch", + "react-router/Router": "ReactRouter.Router", + "react-router/Route": "ReactRouter.Route", + "react-router/matchPath": "ReactRouter.matchPath" }, external: [ - 'react', - 'react-router/Switch', - 'react-router/Router', - 'react-router/Route', - 'react-router/matchPath', + "react", + "react-router/Switch", + "react-router/Router", + "react-router/Route", + "react-router/matchPath" ], plugins: [ babel({ - exclude: 'node_modules/**' + exclude: "node_modules/**" }), resolve(), commonjs({ include: /node_modules/ }), replace({ - 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) + "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV) }) ] -} +}; -if (process.env.NODE_ENV === 'production') { - config.plugins.push(uglify()) +if (process.env.NODE_ENV === "production") { + config.plugins.push(uglify()); } -export default config +export default config; diff --git a/packages/react-router-dom/modules/BrowserRouter.js b/packages/react-router-dom/modules/BrowserRouter.js index e18f8ab576..3bf05d2f23 100644 --- a/packages/react-router-dom/modules/BrowserRouter.js +++ b/packages/react-router-dom/modules/BrowserRouter.js @@ -1,8 +1,8 @@ -import warning from 'warning' -import React from 'react' -import PropTypes from 'prop-types' -import { createBrowserHistory as createHistory } from 'history' -import Router from './Router' +import warning from "warning"; +import React from "react"; +import PropTypes from "prop-types"; +import { createBrowserHistory as createHistory } from "history"; +import Router from "./Router"; /** * The public API for a that uses HTML5 history. @@ -14,21 +14,21 @@ class BrowserRouter extends React.Component { getUserConfirmation: PropTypes.func, keyLength: PropTypes.number, children: PropTypes.node - } + }; - history = createHistory(this.props) + history = createHistory(this.props); componentWillMount() { warning( !this.props.history, - ' ignores the history prop. To use a custom history, ' + - 'use `import { Router }` instead of `import { BrowserRouter as Router }`.' - ) + " ignores the history prop. To use a custom history, " + + "use `import { Router }` instead of `import { BrowserRouter as Router }`." + ); } render() { - return + return ; } } -export default BrowserRouter +export default BrowserRouter; diff --git a/packages/react-router-dom/modules/HashRouter.js b/packages/react-router-dom/modules/HashRouter.js index 54f67033ca..26f822728b 100644 --- a/packages/react-router-dom/modules/HashRouter.js +++ b/packages/react-router-dom/modules/HashRouter.js @@ -1,8 +1,8 @@ -import warning from 'warning' -import React from 'react' -import PropTypes from 'prop-types' -import { createHashHistory as createHistory } from 'history' -import Router from './Router' +import warning from "warning"; +import React from "react"; +import PropTypes from "prop-types"; +import { createHashHistory as createHistory } from "history"; +import Router from "./Router"; /** * The public API for a that uses window.location.hash. @@ -11,23 +11,23 @@ class HashRouter extends React.Component { static propTypes = { basename: PropTypes.string, getUserConfirmation: PropTypes.func, - hashType: PropTypes.oneOf([ 'hashbang', 'noslash', 'slash' ]), + hashType: PropTypes.oneOf(["hashbang", "noslash", "slash"]), children: PropTypes.node - } + }; - history = createHistory(this.props) + history = createHistory(this.props); componentWillMount() { warning( !this.props.history, - ' ignores the history prop. To use a custom history, ' + - 'use `import { Router }` instead of `import { HashRouter as Router }`.' - ) + " ignores the history prop. To use a custom history, " + + "use `import { Router }` instead of `import { HashRouter as Router }`." + ); } render() { - return + return ; } } -export default HashRouter +export default HashRouter; diff --git a/packages/react-router-dom/modules/Link.js b/packages/react-router-dom/modules/Link.js index e522143d77..ff38db4676 100644 --- a/packages/react-router-dom/modules/Link.js +++ b/packages/react-router-dom/modules/Link.js @@ -1,10 +1,10 @@ -import React from 'react' -import PropTypes from 'prop-types' -import invariant from 'invariant' -import { createLocation } from 'history' +import React from "react"; +import PropTypes from "prop-types"; +import invariant from "invariant"; +import { createLocation } from "history"; -const isModifiedEvent = (event) => - !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey) +const isModifiedEvent = event => + !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey); /** * The public API for rendering a history-aware . @@ -14,19 +14,13 @@ class Link extends React.Component { onClick: PropTypes.func, target: PropTypes.string, replace: PropTypes.bool, - to: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.object - ]).isRequired, - innerRef: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.func - ]) - } + to: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).isRequired, + innerRef: PropTypes.oneOfType([PropTypes.string, PropTypes.func]) + }; static defaultProps = { replace: false - } + }; static contextTypes = { router: PropTypes.shape({ @@ -36,11 +30,10 @@ class Link extends React.Component { createHref: PropTypes.func.isRequired }).isRequired }).isRequired - } + }; - handleClick = (event) => { - if (this.props.onClick) - this.props.onClick(event) + handleClick = event => { + if (this.props.onClick) this.props.onClick(event); if ( !event.defaultPrevented && // onClick prevented default @@ -48,38 +41,40 @@ class Link extends React.Component { !this.props.target && // let browser handle "target=_blank" etc. !isModifiedEvent(event) // ignore clicks with modifier keys ) { - event.preventDefault() + event.preventDefault(); - const { history } = this.context.router - const { replace, to } = this.props + const { history } = this.context.router; + const { replace, to } = this.props; if (replace) { - history.replace(to) + history.replace(to); } else { - history.push(to) + history.push(to); } } - } + }; render() { - const { replace, to, innerRef, ...props } = this.props // eslint-disable-line no-unused-vars + const { replace, to, innerRef, ...props } = this.props; // eslint-disable-line no-unused-vars invariant( this.context.router, - 'You should not use outside a ' - ) + "You should not use outside a " + ); - invariant( - to !== undefined, - 'You must specify the "to" property' - ) + invariant(to !== undefined, 'You must specify the "to" property'); - const { history } = this.context.router - const location = typeof to === 'string' ? createLocation(to, null, null, history.location) : to + const { history } = this.context.router; + const location = + typeof to === "string" + ? createLocation(to, null, null, history.location) + : to; - const href = history.createHref(location) - return + const href = history.createHref(location); + return ( + + ); } } -export default Link +export default Link; diff --git a/packages/react-router-dom/modules/MemoryRouter.js b/packages/react-router-dom/modules/MemoryRouter.js index e3df710ae9..1a1983f2f2 100644 --- a/packages/react-router-dom/modules/MemoryRouter.js +++ b/packages/react-router-dom/modules/MemoryRouter.js @@ -1,3 +1,3 @@ // Written in this round about way for babel-transform-imports -import { MemoryRouter } from 'react-router' -export default MemoryRouter +import { MemoryRouter } from "react-router"; +export default MemoryRouter; diff --git a/packages/react-router-dom/modules/NavLink.js b/packages/react-router-dom/modules/NavLink.js index 3daa32b3b3..6a3051b11e 100644 --- a/packages/react-router-dom/modules/NavLink.js +++ b/packages/react-router-dom/modules/NavLink.js @@ -1,7 +1,7 @@ -import React from 'react' -import PropTypes from 'prop-types' -import Route from './Route' -import Link from './Link' +import React from "react"; +import PropTypes from "prop-types"; +import Route from "./Route"; +import Link from "./Link"; /** * A wrapper that knows if it's "active" or not. @@ -16,13 +16,13 @@ const NavLink = ({ activeStyle, style, isActive: getIsActive, - 'aria-current': ariaCurrent, + "aria-current": ariaCurrent, ...rest }) => { - const path = typeof to === 'object' ? to.pathname : to + const path = typeof to === "object" ? to.pathname : to; // Regex taken from: https://github.com/pillarjs/path-to-regexp/blob/master/index.js#L202 - const escapedPath = path.replace(/([.+*?=^!:${}()[\]|/\\])/g, '\\$1') + const escapedPath = path.replace(/([.+*?=^!:${}()[\]|/\\])/g, "\\$1"); return ( { - const isActive = !!(getIsActive ? getIsActive(match, location) : match) + const isActive = !!(getIsActive ? getIsActive(match, location) : match); return ( i).join(' ') : className} + className={ + isActive + ? [className, activeClassName].filter(i => i).join(" ") + : className + } style={isActive ? { ...style, ...activeStyle } : style} - aria-current={isActive && ariaCurrent || null} + aria-current={(isActive && ariaCurrent) || null} {...rest} /> - ) + ); }} /> - ) -} + ); +}; NavLink.propTypes = { to: Link.propTypes.to, @@ -57,12 +61,19 @@ NavLink.propTypes = { activeStyle: PropTypes.object, style: PropTypes.object, isActive: PropTypes.func, - 'aria-current': PropTypes.oneOf(['page', 'step', 'location', 'date', 'time', 'true']) -} + "aria-current": PropTypes.oneOf([ + "page", + "step", + "location", + "date", + "time", + "true" + ]) +}; NavLink.defaultProps = { - activeClassName: 'active', - 'aria-current': 'true' -} + activeClassName: "active", + "aria-current": "true" +}; -export default NavLink +export default NavLink; diff --git a/packages/react-router-dom/modules/Prompt.js b/packages/react-router-dom/modules/Prompt.js index 206d983109..a4a8929735 100644 --- a/packages/react-router-dom/modules/Prompt.js +++ b/packages/react-router-dom/modules/Prompt.js @@ -1,3 +1,3 @@ // Written in this round about way for babel-transform-imports -import { Prompt } from 'react-router' -export default Prompt +import { Prompt } from "react-router"; +export default Prompt; diff --git a/packages/react-router-dom/modules/Redirect.js b/packages/react-router-dom/modules/Redirect.js index 3da36cc3e0..47d5b7e6ce 100644 --- a/packages/react-router-dom/modules/Redirect.js +++ b/packages/react-router-dom/modules/Redirect.js @@ -1,3 +1,3 @@ // Written in this round about way for babel-transform-imports -import { Redirect } from 'react-router' -export default Redirect +import { Redirect } from "react-router"; +export default Redirect; diff --git a/packages/react-router-dom/modules/Route.js b/packages/react-router-dom/modules/Route.js index 2d3a1ad16e..e4f048300e 100644 --- a/packages/react-router-dom/modules/Route.js +++ b/packages/react-router-dom/modules/Route.js @@ -1,3 +1,3 @@ // Written in this round about way for babel-transform-imports -import { Route } from 'react-router' -export default Route \ No newline at end of file +import { Route } from "react-router"; +export default Route; diff --git a/packages/react-router-dom/modules/Router.js b/packages/react-router-dom/modules/Router.js index 18d713a2ac..8c489f2b3d 100644 --- a/packages/react-router-dom/modules/Router.js +++ b/packages/react-router-dom/modules/Router.js @@ -1,3 +1,3 @@ // Written in this round about way for babel-transform-imports -import { Router } from 'react-router' -export default Router \ No newline at end of file +import { Router } from "react-router"; +export default Router; diff --git a/packages/react-router-dom/modules/StaticRouter.js b/packages/react-router-dom/modules/StaticRouter.js index 43e27a7f2d..c5cfe59add 100644 --- a/packages/react-router-dom/modules/StaticRouter.js +++ b/packages/react-router-dom/modules/StaticRouter.js @@ -1,3 +1,3 @@ // Written in this round about way for babel-transform-imports -import { StaticRouter } from 'react-router' -export default StaticRouter \ No newline at end of file +import { StaticRouter } from "react-router"; +export default StaticRouter; diff --git a/packages/react-router-dom/modules/Switch.js b/packages/react-router-dom/modules/Switch.js index 61cfaec35d..8947bd6f31 100644 --- a/packages/react-router-dom/modules/Switch.js +++ b/packages/react-router-dom/modules/Switch.js @@ -1,3 +1,3 @@ // Written in this round about way for babel-transform-imports -import { Switch } from 'react-router' -export default Switch \ No newline at end of file +import { Switch } from "react-router"; +export default Switch; diff --git a/packages/react-router-dom/modules/__tests__/BrowserRouter-test.js b/packages/react-router-dom/modules/__tests__/BrowserRouter-test.js index c0ae698531..a4a594cba5 100644 --- a/packages/react-router-dom/modules/__tests__/BrowserRouter-test.js +++ b/packages/react-router-dom/modules/__tests__/BrowserRouter-test.js @@ -1,44 +1,43 @@ -import React from 'react' -import ReactDOM from 'react-dom' -import PropTypes from 'prop-types' -import BrowserRouter from '../BrowserRouter' - -describe('A ', () => { - it('puts history on context.router', () => { - let history +import React from "react"; +import ReactDOM from "react-dom"; +import PropTypes from "prop-types"; +import BrowserRouter from "../BrowserRouter"; + +describe("A ", () => { + it("puts history on context.router", () => { + let history; const ContextChecker = (props, context) => { - history = context.router.history - return null - } + history = context.router.history; + return null; + }; ContextChecker.contextTypes = { router: PropTypes.object.isRequired - } + }; - const node = document.createElement('div') + const node = document.createElement("div"); - ReactDOM.render(( + ReactDOM.render( - - - ), node) + + , + node + ); - expect(typeof history).toBe('object') - }) + expect(typeof history).toBe("object"); + }); - it('warns when passed a history prop', () => { - const history = {} - const node = document.createElement('div') + it("warns when passed a history prop", () => { + const history = {}; + const node = document.createElement("div"); - spyOn(console, 'error') + spyOn(console, "error"); - ReactDOM.render(( - - ), node) + ReactDOM.render(, node); - expect(console.error).toHaveBeenCalledTimes(1) + expect(console.error).toHaveBeenCalledTimes(1); expect(console.error).toHaveBeenCalledWith( - expect.stringContaining(' ignores the history prop') - ) - }) -}) + expect.stringContaining(" ignores the history prop") + ); + }); +}); diff --git a/packages/react-router-dom/modules/__tests__/HashRouter-test.js b/packages/react-router-dom/modules/__tests__/HashRouter-test.js index 22bea95898..2bcc25578b 100644 --- a/packages/react-router-dom/modules/__tests__/HashRouter-test.js +++ b/packages/react-router-dom/modules/__tests__/HashRouter-test.js @@ -1,44 +1,43 @@ -import React from 'react' -import ReactDOM from 'react-dom' -import PropTypes from 'prop-types' -import HashRouter from '../HashRouter' - -describe('A ', () => { - it('puts history on context.router', () => { - let history +import React from "react"; +import ReactDOM from "react-dom"; +import PropTypes from "prop-types"; +import HashRouter from "../HashRouter"; + +describe("A ", () => { + it("puts history on context.router", () => { + let history; const ContextChecker = (props, context) => { - history = context.router.history - return null - } + history = context.router.history; + return null; + }; ContextChecker.contextTypes = { router: PropTypes.object.isRequired - } + }; - const node = document.createElement('div') + const node = document.createElement("div"); - ReactDOM.render(( + ReactDOM.render( - - - ), node) + + , + node + ); - expect(typeof history).toBe('object') - }) + expect(typeof history).toBe("object"); + }); - it('warns when passed a history prop', () => { - const history = {} - const node = document.createElement('div') + it("warns when passed a history prop", () => { + const history = {}; + const node = document.createElement("div"); - spyOn(console, 'error') + spyOn(console, "error"); - ReactDOM.render(( - - ), node) + ReactDOM.render(, node); - expect(console.error).toHaveBeenCalledTimes(1) + expect(console.error).toHaveBeenCalledTimes(1); expect(console.error).toHaveBeenCalledWith( - expect.stringContaining(' ignores the history prop') - ) - }) -}) + expect.stringContaining(" ignores the history prop") + ); + }); +}); diff --git a/packages/react-router-dom/modules/__tests__/Link-test.js b/packages/react-router-dom/modules/__tests__/Link-test.js index 91bdf2e3fc..6f65b038f8 100644 --- a/packages/react-router-dom/modules/__tests__/Link-test.js +++ b/packages/react-router-dom/modules/__tests__/Link-test.js @@ -1,159 +1,163 @@ -import React from 'react' -import ReactDOM from 'react-dom' -import MemoryRouter from 'react-router/MemoryRouter' -import HashRouter from '../HashRouter' -import Link from '../Link' +import React from "react"; +import ReactDOM from "react-dom"; +import MemoryRouter from "react-router/MemoryRouter"; +import HashRouter from "../HashRouter"; +import Link from "../Link"; -describe('A ', () => { +describe("A ", () => { it('accepts a location "to" prop', () => { const location = { - pathname: '/the/path', - search: 'the=query', - hash: '#the-hash' - } - const node = document.createElement('div') + pathname: "/the/path", + search: "the=query", + hash: "#the-hash" + }; + const node = document.createElement("div"); - ReactDOM.render(( + ReactDOM.render( link - - ), node) + , + node + ); - const href = node.querySelector('a').getAttribute('href') + const href = node.querySelector("a").getAttribute("href"); - expect(href).toEqual('/the/path?the=query#the-hash') - }) + expect(href).toEqual("/the/path?the=query#the-hash"); + }); - describe('to as a string', () => { - it('resolves to with no pathname using current location', () => { - const node = document.createElement('div') + describe("to as a string", () => { + it("resolves to with no pathname using current location", () => { + const node = document.createElement("div"); - ReactDOM.render(( - - link - - ), node) + ReactDOM.render( + + link + , + node + ); - const href = node.querySelector('a').getAttribute('href') + const href = node.querySelector("a").getAttribute("href"); - expect(href).toEqual('/somewhere?rendersWithPathname=true') - }) - }) + expect(href).toEqual("/somewhere?rendersWithPathname=true"); + }); + }); - it('throws with no ', () => { - const node = document.createElement('div') + it("throws with no ", () => { + const node = document.createElement("div"); - spyOn(console, 'error') + spyOn(console, "error"); expect(() => { - ReactDOM.render(( - link - ), node) - }).toThrow(/You should not use outside a /) + ReactDOM.render(link, node); + }).toThrow(/You should not use outside a /); - expect(console.error.calls.count()).toBe(2) + expect(console.error.calls.count()).toBe(2); expect(console.error.calls.argsFor(0)[0]).toContain( - 'The context `router` is marked as required in `Link`' - ) - }) + "The context `router` is marked as required in `Link`" + ); + }); it('throws with no "to" prop', () => { - const node = document.createElement('div') + const node = document.createElement("div"); - spyOn(console, 'error') + spyOn(console, "error"); expect(() => { - ReactDOM.render(( + ReactDOM.render( link - - ), node) - }).toThrow(/You must specify the "to" property/) + , + node + ); + }).toThrow(/You must specify the "to" property/); - expect(console.error.calls.count()).toBe(2) + expect(console.error.calls.count()).toBe(2); expect(console.error.calls.argsFor(0)[0]).toContain( - 'The prop `to` is marked as required in `Link`' - ) - }) + "The prop `to` is marked as required in `Link`" + ); + }); - it('exposes its ref via an innerRef prop', done => { - const node = document.createElement('div') + it("exposes its ref via an innerRef prop", done => { + const node = document.createElement("div"); const refCallback = n => { - expect(n.tagName).toEqual('A') - done() - } + expect(n.tagName).toEqual("A"); + done(); + }; ReactDOM.render( - link + + link + , node - ) - }) -}) + ); + }); +}); -describe('When a is clicked', () => { - it('calls its onClick handler') +describe("When a is clicked", () => { + it("calls its onClick handler"); - it('changes the location') + it("changes the location"); - describe('and the onClick handler calls event.preventDefault()', () => { - it('does not change the location') - }) -}) + describe("and the onClick handler calls event.preventDefault()", () => { + it("does not change the location"); + }); +}); -describe('A underneath a ', () => { - const node = document.createElement('div') +describe("A underneath a ", () => { + const node = document.createElement("div"); afterEach(() => { - ReactDOM.unmountComponentAtNode(node) - window.history.replaceState(null, '', '#') - }) + ReactDOM.unmountComponentAtNode(node); + window.history.replaceState(null, "", "#"); + }); const createLinkNode = (hashType, to) => { - ReactDOM.render(( + ReactDOM.render( - - - ), node) + + , + node + ); - return node.querySelector('a') - } + return node.querySelector("a"); + }; describe('with the "slash" hashType', () => { - it('has the correct href', () => { - const linkNode = createLinkNode('slash', '/foo') - expect(linkNode.getAttribute('href')).toEqual('#/foo') - }) + it("has the correct href", () => { + const linkNode = createLinkNode("slash", "/foo"); + expect(linkNode.getAttribute("href")).toEqual("#/foo"); + }); - it('has the correct href with a leading slash if it is missing', () => { - const linkNode = createLinkNode('slash', 'foo') - expect(linkNode.getAttribute('href')).toEqual('#/foo') - }) - }) + it("has the correct href with a leading slash if it is missing", () => { + const linkNode = createLinkNode("slash", "foo"); + expect(linkNode.getAttribute("href")).toEqual("#/foo"); + }); + }); describe('with the "hashbang" hashType', () => { - it('has the correct href', () => { - const linkNode = createLinkNode('hashbang', '/foo') - expect(linkNode.getAttribute('href')).toEqual('#!/foo') - }) + it("has the correct href", () => { + const linkNode = createLinkNode("hashbang", "/foo"); + expect(linkNode.getAttribute("href")).toEqual("#!/foo"); + }); - it('has the correct href with a leading slash if it is missing', () => { - const linkNode = createLinkNode('hashbang', 'foo') - expect(linkNode.getAttribute('href')).toEqual('#!/foo') - }) - }) + it("has the correct href with a leading slash if it is missing", () => { + const linkNode = createLinkNode("hashbang", "foo"); + expect(linkNode.getAttribute("href")).toEqual("#!/foo"); + }); + }); describe('with the "noslash" hashType', () => { - it('has the correct href', () => { - const linkNode = createLinkNode('noslash', 'foo') - expect(linkNode.getAttribute('href')).toEqual('#foo') - }) - - it('has the correct href and removes the leading slash', () => { - const linkNode = createLinkNode('noslash', '/foo') - expect(linkNode.getAttribute('href')).toEqual('#foo') - }) - }) -}) + it("has the correct href", () => { + const linkNode = createLinkNode("noslash", "foo"); + expect(linkNode.getAttribute("href")).toEqual("#foo"); + }); + + it("has the correct href and removes the leading slash", () => { + const linkNode = createLinkNode("noslash", "/foo"); + expect(linkNode.getAttribute("href")).toEqual("#foo"); + }); + }); +}); diff --git a/packages/react-router-dom/modules/__tests__/NavLink-test.js b/packages/react-router-dom/modules/__tests__/NavLink-test.js index 65ef3e249a..cf7a06d42f 100644 --- a/packages/react-router-dom/modules/__tests__/NavLink-test.js +++ b/packages/react-router-dom/modules/__tests__/NavLink-test.js @@ -1,352 +1,399 @@ -import React from 'react' -import ReactDOM from 'react-dom' -import MemoryRouter from 'react-router/MemoryRouter' -import NavLink from '../NavLink' +import React from "react"; +import ReactDOM from "react-dom"; +import MemoryRouter from "react-router/MemoryRouter"; +import NavLink from "../NavLink"; -describe('NavLink', () => { - const node = document.createElement('div') +describe("NavLink", () => { + const node = document.createElement("div"); afterEach(() => { - ReactDOM.unmountComponentAtNode(node) - }) - - describe('When a is active', () => { - it('applies its default activeClassName', () => { - ReactDOM.render(( - - Pizza! - - ), node) - const a = node.getElementsByTagName('a')[0] - expect(a.className).toEqual('active') - }) - - it('applies its passed activeClassName', () => { - ReactDOM.render(( - - Pizza! - - ), node) - const a = node.getElementsByTagName('a')[0] - expect(a.className).not.toContain('active') - expect(a.className).toEqual('selected') - }) - - it('applies its activeStyle', () => { - const defaultStyle = { color: 'black' } - const activeStyle = { color: 'red' } - - ReactDOM.render(( - - + ReactDOM.unmountComponentAtNode(node); + }); + + describe("When a is active", () => { + it("applies its default activeClassName", () => { + ReactDOM.render( + + Pizza! + , + node + ); + const a = node.getElementsByTagName("a")[0]; + expect(a.className).toEqual("active"); + }); + + it("applies its passed activeClassName", () => { + ReactDOM.render( + + Pizza! - - ), node) - const a = node.getElementsByTagName('a')[0] - expect(a.style.color).toBe(activeStyle.color) - }) - - it('applies aria-current of true if no override value is given', () => { - ReactDOM.render(( - - Pizza! - - ), node) - const a = node.getElementsByTagName('a')[0] - expect(a.getAttribute('aria-current')).toEqual('true') - }) - - it('applies the override aria-current value when given', () => { - ReactDOM.render(( - - Pizza! - - ), node) - const a = node.getElementsByTagName('a')[0] - expect(a.getAttribute('aria-current')).toEqual('page') - }) - - it('it properly escapes path-to-regexp special characters', () => { - ReactDOM.render(( - - Pizza! - - ), node) - - const href = node.querySelector('a').getAttribute('href') - expect(href).toEqual('/pizza (1)') - const a = node.getElementsByTagName('a')[0] - expect(a.className).toEqual('active') - }) - }) - - describe('When a is not active', () => { - it('does not apply its default activeClassName', () => { - ReactDOM.render(( - - Salad? - - ), node) - const a = node.getElementsByTagName('a')[0] - expect(a.className).not.toContain('active') - }) - - it('does not apply its passed activeClassName', () => { - ReactDOM.render(( - - Salad? - - ), node) - const a = node.getElementsByTagName('a')[0] - expect(a.className).not.toContain('active') - expect(a.className).not.toContain('selected') - }) - - it('does not apply its activeStyle', () => { - const defaultStyle = { color: 'black' } - const activeStyle = { color: 'red' } - - ReactDOM.render(( - - + , + node + ); + const a = node.getElementsByTagName("a")[0]; + expect(a.className).not.toContain("active"); + expect(a.className).toEqual("selected"); + }); + + it("applies its activeStyle", () => { + const defaultStyle = { color: "black" }; + const activeStyle = { color: "red" }; + + ReactDOM.render( + + + Pizza! + + , + node + ); + const a = node.getElementsByTagName("a")[0]; + expect(a.style.color).toBe(activeStyle.color); + }); + + it("applies aria-current of true if no override value is given", () => { + ReactDOM.render( + + + Pizza! + + , + node + ); + const a = node.getElementsByTagName("a")[0]; + expect(a.getAttribute("aria-current")).toEqual("true"); + }); + + it("applies the override aria-current value when given", () => { + ReactDOM.render( + + + Pizza! + + , + node + ); + const a = node.getElementsByTagName("a")[0]; + expect(a.getAttribute("aria-current")).toEqual("page"); + }); + + it("it properly escapes path-to-regexp special characters", () => { + ReactDOM.render( + + Pizza! + , + node + ); + + const href = node.querySelector("a").getAttribute("href"); + expect(href).toEqual("/pizza (1)"); + const a = node.getElementsByTagName("a")[0]; + expect(a.className).toEqual("active"); + }); + }); + + describe("When a is not active", () => { + it("does not apply its default activeClassName", () => { + ReactDOM.render( + + Salad? + , + node + ); + const a = node.getElementsByTagName("a")[0]; + expect(a.className).not.toContain("active"); + }); + + it("does not apply its passed activeClassName", () => { + ReactDOM.render( + + Salad? - - ), node) - const a = node.getElementsByTagName('a')[0] - expect(a.style.color).toBe(defaultStyle.color) - }) - - it('does not apply an aria-current value if no override value is given', () => { - ReactDOM.render(( - - Pizza! - - ), node) - const a = node.getElementsByTagName('a')[0] - expect(a.getAttribute('aria-current')).toBeNull() - }) - - it('does not apply an aria-current value if an override value is given', () => { - ReactDOM.render(( - - Pizza! - - ), node) - const a = node.getElementsByTagName('a')[0] - expect(a.getAttribute('aria-current')).toBeNull() - }) - }) - - describe('isActive', () => { - it('applies active default props when isActive returns true', () => { - ReactDOM.render(( - - true} - > + , + node + ); + const a = node.getElementsByTagName("a")[0]; + expect(a.className).not.toContain("active"); + expect(a.className).not.toContain("selected"); + }); + + it("does not apply its activeStyle", () => { + const defaultStyle = { color: "black" }; + const activeStyle = { color: "red" }; + + ReactDOM.render( + + + Salad? + + , + node + ); + const a = node.getElementsByTagName("a")[0]; + expect(a.style.color).toBe(defaultStyle.color); + }); + + it("does not apply an aria-current value if no override value is given", () => { + ReactDOM.render( + + Pizza! - - ), node) - const a = node.getElementsByTagName('a')[0] - expect(a.className).toEqual('active') - }) - - it('applies active passed props when isActive returns true', () => { - ReactDOM.render(( - - true} - > + , + node + ); + const a = node.getElementsByTagName("a")[0]; + expect(a.getAttribute("aria-current")).toBeNull(); + }); + + it("does not apply an aria-current value if an override value is given", () => { + ReactDOM.render( + + Pizza! - - ), node) - const a = node.getElementsByTagName('a')[0] - expect(a.className).not.toContain('active') - expect(a.className).toEqual('selected') - }) - - it('does not apply active default props when isActive returns false', () => { - ReactDOM.render(( - - false} - > + , + node + ); + const a = node.getElementsByTagName("a")[0]; + expect(a.getAttribute("aria-current")).toBeNull(); + }); + }); + + describe("isActive", () => { + it("applies active default props when isActive returns true", () => { + ReactDOM.render( + + true}> Pizza! - - ), node) - const a = node.getElementsByTagName('a')[0] - expect(a.className).not.toContain('active') - }) - - it('does not apply active passed props when isActive returns false', () => { - ReactDOM.render(( - + , + node + ); + const a = node.getElementsByTagName("a")[0]; + expect(a.className).toEqual("active"); + }); + + it("applies active passed props when isActive returns true", () => { + ReactDOM.render( + + true}> + Pizza! + + , + node + ); + const a = node.getElementsByTagName("a")[0]; + expect(a.className).not.toContain("active"); + expect(a.className).toEqual("selected"); + }); + + it("does not apply active default props when isActive returns false", () => { + ReactDOM.render( + + false}> + Pizza! + + , + node + ); + const a = node.getElementsByTagName("a")[0]; + expect(a.className).not.toContain("active"); + }); + + it("does not apply active passed props when isActive returns false", () => { + ReactDOM.render( + false} - > + > Pizza! - - ), node) - const a = node.getElementsByTagName('a')[0] - expect(a.className).not.toContain('active') - expect(a.className).not.toContain('selected') - }) - }) - - describe('exact', () => { - it('does not do exact matching by default', () => { - ReactDOM.render(( - - Pizza! - - ), node) - const a = node.getElementsByTagName('a')[0] - expect(a.className).toEqual('active') - }) - - it('sets active default value only for exact matches', () => { - ReactDOM.render(( - - Pizza! - - ), node) - const a = node.getElementsByTagName('a')[0] - expect(a.className).toEqual('active') - }) - - it('sets active passed value only for exact matches', () => { - ReactDOM.render(( - - Pizza! - - ), node) - const a = node.getElementsByTagName('a')[0] - expect(a.className).not.toContain('active') - expect(a.className).toEqual('selected') - }) - - it('does not set active default value for partial matches', () => { - ReactDOM.render(( - - Pizza! - - ), node) - const a = node.getElementsByTagName('a')[0] - expect(a.className).not.toContain('active') - }) - - it('does not set active passed value for partial matches', () => { - ReactDOM.render(( - - Pizza! - - ), node) - const a = node.getElementsByTagName('a')[0] - expect(a.className).not.toContain('active') - expect(a.className).not.toContain('selected') - }) - }) - - describe('strict (enforce path\'s trailing slash)', () => { - const PATH = '/pizza/' - it('does not do strict matching by default', () => { - ReactDOM.render(( - + , + node + ); + const a = node.getElementsByTagName("a")[0]; + expect(a.className).not.toContain("active"); + expect(a.className).not.toContain("selected"); + }); + }); + + describe("exact", () => { + it("does not do exact matching by default", () => { + ReactDOM.render( + + + Pizza! + + , + node + ); + const a = node.getElementsByTagName("a")[0]; + expect(a.className).toEqual("active"); + }); + + it("sets active default value only for exact matches", () => { + ReactDOM.render( + + + Pizza! + + , + node + ); + const a = node.getElementsByTagName("a")[0]; + expect(a.className).toEqual("active"); + }); + + it("sets active passed value only for exact matches", () => { + ReactDOM.render( + + + Pizza! + + , + node + ); + const a = node.getElementsByTagName("a")[0]; + expect(a.className).not.toContain("active"); + expect(a.className).toEqual("selected"); + }); + + it("does not set active default value for partial matches", () => { + ReactDOM.render( + + + Pizza! + + , + node + ); + const a = node.getElementsByTagName("a")[0]; + expect(a.className).not.toContain("active"); + }); + + it("does not set active passed value for partial matches", () => { + ReactDOM.render( + + + Pizza! + + , + node + ); + const a = node.getElementsByTagName("a")[0]; + expect(a.className).not.toContain("active"); + expect(a.className).not.toContain("selected"); + }); + }); + + describe("strict (enforce path's trailing slash)", () => { + const PATH = "/pizza/"; + it("does not do strict matching by default", () => { + ReactDOM.render( + Pizza! - - ), node) - const a = node.getElementsByTagName('a')[0] - expect(a.className).toEqual('active') - }) - - it('does not set active default value when location.pathname has no trailing slash', () => { - ReactDOM.render(( - - Pizza! - - ), node) - const a = node.getElementsByTagName('a')[0] - expect(a.className).not.toContain('active') - }) - - it('does not set active passed value when location.pathname has no trailing slash', () => { - ReactDOM.render(( - - Pizza! - - ), node) - const a = node.getElementsByTagName('a')[0] - expect(a.className).not.toContain('active') - expect(a.className).not.toContain('selected') - }) - - it('sets active default value when pathname has trailing slash', () => { - ReactDOM.render(( - - Pizza! - - ), node) - const a = node.getElementsByTagName('a')[0] - expect(a.className).toEqual('active') - }) - - it('sets active passed value when pathname has trailing slash', () => { - ReactDOM.render(( - - Pizza! - - ), node) - const a = node.getElementsByTagName('a')[0] - expect(a.className).not.toContain('active') - expect(a.className).toEqual('selected') - }) - }) - - describe('location property', () => { - it('overrides the current location', () => { - ReactDOM.render(( - - Pasta! - - ), node) - const a = node.getElementsByTagName('a')[0] - expect(a.className).not.toContain('active') - expect(a.className).toContain('selected') - }) - - it('is not overwritten by the current location', () => { - ReactDOM.render(( - - Pasta! - - ), node) - const a = node.getElementsByTagName('a')[0] - expect(a.className).not.toContain('active') - expect(a.className).not.toContain('selected') - }) - }) -}) + , + node + ); + const a = node.getElementsByTagName("a")[0]; + expect(a.className).toEqual("active"); + }); + + it("does not set active default value when location.pathname has no trailing slash", () => { + ReactDOM.render( + + + Pizza! + + , + node + ); + const a = node.getElementsByTagName("a")[0]; + expect(a.className).not.toContain("active"); + }); + + it("does not set active passed value when location.pathname has no trailing slash", () => { + ReactDOM.render( + + + Pizza! + + , + node + ); + const a = node.getElementsByTagName("a")[0]; + expect(a.className).not.toContain("active"); + expect(a.className).not.toContain("selected"); + }); + + it("sets active default value when pathname has trailing slash", () => { + ReactDOM.render( + + + Pizza! + + , + node + ); + const a = node.getElementsByTagName("a")[0]; + expect(a.className).toEqual("active"); + }); + + it("sets active passed value when pathname has trailing slash", () => { + ReactDOM.render( + + + Pizza! + + , + node + ); + const a = node.getElementsByTagName("a")[0]; + expect(a.className).not.toContain("active"); + expect(a.className).toEqual("selected"); + }); + }); + + describe("location property", () => { + it("overrides the current location", () => { + ReactDOM.render( + + + Pasta! + + , + node + ); + const a = node.getElementsByTagName("a")[0]; + expect(a.className).not.toContain("active"); + expect(a.className).toContain("selected"); + }); + + it("is not overwritten by the current location", () => { + ReactDOM.render( + + + Pasta! + + , + node + ); + const a = node.getElementsByTagName("a")[0]; + expect(a.className).not.toContain("active"); + expect(a.className).not.toContain("selected"); + }); + }); +}); diff --git a/packages/react-router-dom/modules/generatePath.js b/packages/react-router-dom/modules/generatePath.js index 790adaa90e..b4b3ee990e 100644 --- a/packages/react-router-dom/modules/generatePath.js +++ b/packages/react-router-dom/modules/generatePath.js @@ -1,3 +1,3 @@ // Written in this round about way for babel-transform-imports -import { generatePath } from 'react-router' -export default generatePath +import { generatePath } from "react-router"; +export default generatePath; diff --git a/packages/react-router-dom/modules/index.js b/packages/react-router-dom/modules/index.js index fb204e116b..789599ad00 100644 --- a/packages/react-router-dom/modules/index.js +++ b/packages/react-router-dom/modules/index.js @@ -1,14 +1,14 @@ -export BrowserRouter from './BrowserRouter' -export HashRouter from './HashRouter' -export Link from './Link' -export MemoryRouter from './MemoryRouter' -export NavLink from './NavLink' -export Prompt from './Prompt' -export Redirect from './Redirect' -export Route from './Route' -export Router from './Router' -export StaticRouter from './StaticRouter' -export Switch from './Switch' -export generatePath from './generatePath' -export matchPath from './matchPath' -export withRouter from './withRouter' +export BrowserRouter from "./BrowserRouter"; +export HashRouter from "./HashRouter"; +export Link from "./Link"; +export MemoryRouter from "./MemoryRouter"; +export NavLink from "./NavLink"; +export Prompt from "./Prompt"; +export Redirect from "./Redirect"; +export Route from "./Route"; +export Router from "./Router"; +export StaticRouter from "./StaticRouter"; +export Switch from "./Switch"; +export generatePath from "./generatePath"; +export matchPath from "./matchPath"; +export withRouter from "./withRouter"; diff --git a/packages/react-router-dom/modules/matchPath.js b/packages/react-router-dom/modules/matchPath.js index 8f4e4d7d98..854585ea8b 100644 --- a/packages/react-router-dom/modules/matchPath.js +++ b/packages/react-router-dom/modules/matchPath.js @@ -1,3 +1,3 @@ // Written in this round about way for babel-transform-imports -import { matchPath } from 'react-router' -export default matchPath +import { matchPath } from "react-router"; +export default matchPath; diff --git a/packages/react-router-dom/modules/withRouter.js b/packages/react-router-dom/modules/withRouter.js index d450f64339..5cf0b2f92d 100644 --- a/packages/react-router-dom/modules/withRouter.js +++ b/packages/react-router-dom/modules/withRouter.js @@ -1,3 +1,3 @@ // Written in this round about way for babel-transform-imports -import { withRouter } from 'react-router' -export default withRouter +import { withRouter } from "react-router"; +export default withRouter; diff --git a/packages/react-router-dom/rollup.config.js b/packages/react-router-dom/rollup.config.js index 1fc2c07084..00d4165d97 100644 --- a/packages/react-router-dom/rollup.config.js +++ b/packages/react-router-dom/rollup.config.js @@ -1,38 +1,36 @@ -import babel from 'rollup-plugin-babel' -import uglify from 'rollup-plugin-uglify' -import replace from 'rollup-plugin-replace' -import commonjs from 'rollup-plugin-commonjs' -import resolve from 'rollup-plugin-node-resolve' +import babel from "rollup-plugin-babel"; +import uglify from "rollup-plugin-uglify"; +import replace from "rollup-plugin-replace"; +import commonjs from "rollup-plugin-commonjs"; +import resolve from "rollup-plugin-node-resolve"; const config = { - input: 'modules/index.js', - name: 'ReactRouterDOM', + input: "modules/index.js", + name: "ReactRouterDOM", globals: { - react: 'React' + react: "React" }, - external: [ - 'react' - ], + external: ["react"], plugins: [ babel({ - exclude: 'node_modules/**' + exclude: "node_modules/**" }), resolve({ customResolveOptions: { - moduleDirectory: ['../../node_modules', '../'] + moduleDirectory: ["../../node_modules", "../"] } }), commonjs({ include: /node_modules/ }), replace({ - 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) + "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV) }) ] -} +}; -if (process.env.NODE_ENV === 'production') { - config.plugins.push(uglify()) +if (process.env.NODE_ENV === "production") { + config.plugins.push(uglify()); } -export default config +export default config; diff --git a/packages/react-router-native/BackButton.js b/packages/react-router-native/BackButton.js index f370343b2c..08250b5e06 100644 --- a/packages/react-router-native/BackButton.js +++ b/packages/react-router-native/BackButton.js @@ -1,6 +1,6 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { BackHandler } from 'react-native' +import React from "react"; +import PropTypes from "prop-types"; +import { BackHandler } from "react-native"; class BackButton extends React.Component { static contextTypes = { @@ -10,30 +10,30 @@ class BackButton extends React.Component { index: PropTypes.number.isRequired }).isRequired }).isRequired - } + }; componentDidMount() { - BackHandler.addEventListener('hardwareBackPress', this.handleBack) + BackHandler.addEventListener("hardwareBackPress", this.handleBack); } componentWillUnmount() { - BackHandler.removeEventListener('hardwareBackPress', this.handleBack) + BackHandler.removeEventListener("hardwareBackPress", this.handleBack); } handleBack = () => { - const { history } = this.context.router + const { history } = this.context.router; if (history.index === 0) { - return false // home screen + return false; // home screen } else { - history.goBack() - return true + history.goBack(); + return true; } - } + }; render() { - return this.props.children || null + return this.props.children || null; } } -export default BackButton +export default BackButton; diff --git a/packages/react-router-native/DeepLinking.js b/packages/react-router-native/DeepLinking.js index 2c620ca611..120650c055 100644 --- a/packages/react-router-native/DeepLinking.js +++ b/packages/react-router-native/DeepLinking.js @@ -1,8 +1,8 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import { Linking } from 'react-native' +import React, { Component } from "react"; +import PropTypes from "prop-types"; +import { Linking } from "react-native"; -const regex = /.*?:\/\//g +const regex = /.*?:\/\//g; class DeepLinking extends Component { static contextTypes = { @@ -11,31 +11,30 @@ class DeepLinking extends Component { push: PropTypes.func.isRequired }).isRequired }).isRequired - } + }; async componentDidMount() { - const url = await Linking.getInitialURL() - if (url) - this.push(url) - Linking.addEventListener('url', this.handleChange) + const url = await Linking.getInitialURL(); + if (url) this.push(url); + Linking.addEventListener("url", this.handleChange); } componentWillUnmount() { - Linking.removeEventListener('url', this.handleChange) + Linking.removeEventListener("url", this.handleChange); } - handleChange = (e) => { - this.push(e.url) - } + handleChange = e => { + this.push(e.url); + }; - push = (url) => { - const pathname = url.replace(regex, '') - this.context.router.history.push(pathname) - } + push = url => { + const pathname = url.replace(regex, ""); + this.context.router.history.push(pathname); + }; render() { return this.props.children || null; } } -export default DeepLinking +export default DeepLinking; diff --git a/packages/react-router-native/Link.js b/packages/react-router-native/Link.js index 8b21b34bf1..f36437b026 100644 --- a/packages/react-router-native/Link.js +++ b/packages/react-router-native/Link.js @@ -1,6 +1,6 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import { TouchableHighlight } from 'react-native' +import React, { Component } from "react"; +import PropTypes from "prop-types"; +import { TouchableHighlight } from "react-native"; class Link extends Component { static contextTypes = { @@ -10,43 +10,39 @@ class Link extends Component { replace: PropTypes.func.isRequired }).isRequired }).isRequired - } + }; static propTypes = { onPress: PropTypes.func, component: PropTypes.func, replace: PropTypes.bool, - to: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.object - ]) - } + to: PropTypes.oneOfType([PropTypes.string, PropTypes.object]) + }; static defaultProps = { component: TouchableHighlight, replace: false - } + }; - handlePress = (event) => { - if (this.props.onPress) - this.props.onPress(event) + handlePress = event => { + if (this.props.onPress) this.props.onPress(event); if (!event.defaultPrevented) { - const { history } = this.context.router - const { to, replace } = this.props + const { history } = this.context.router; + const { to, replace } = this.props; if (replace) { - history.replace(to) + history.replace(to); } else { - history.push(to) + history.push(to); } } - } + }; render() { - const { component: Component, to, replace, ...rest } = this.props - return + const { component: Component, to, replace, ...rest } = this.props; + return ; } } -export default Link +export default Link; diff --git a/packages/react-router-native/NativeRouter.js b/packages/react-router-native/NativeRouter.js index c2b3ad1312..927d20cd9d 100644 --- a/packages/react-router-native/NativeRouter.js +++ b/packages/react-router-native/NativeRouter.js @@ -1,15 +1,13 @@ -import React from 'react' -import PropTypes from 'prop-types' -import MemoryRouter from 'react-router/MemoryRouter' -import { Alert } from 'react-native' +import React from "react"; +import PropTypes from "prop-types"; +import MemoryRouter from "react-router/MemoryRouter"; +import { Alert } from "react-native"; /** * The public API for a designed for React Native. Gets * user confirmations via Alert by default. */ -const NativeRouter = (props) => ( - -) +const NativeRouter = props => ; NativeRouter.propTypes = { initialEntries: PropTypes.array, @@ -17,15 +15,15 @@ NativeRouter.propTypes = { getUserConfirmation: PropTypes.func, keyLength: PropTypes.number, children: PropTypes.node -} +}; NativeRouter.defaultProps = { getUserConfirmation: (message, callback) => { - Alert.alert('Confirm', message, [ - { text: 'Cancel', onPress: () => callback(false) }, - { text: 'OK', onPress: () => callback(true) } - ]) + Alert.alert("Confirm", message, [ + { text: "Cancel", onPress: () => callback(false) }, + { text: "OK", onPress: () => callback(true) } + ]); } -} +}; -export default NativeRouter +export default NativeRouter; diff --git a/packages/react-router-native/index.android.js b/packages/react-router-native/index.android.js index 2c8b0991a0..6594cbe7c4 100644 --- a/packages/react-router-native/index.android.js +++ b/packages/react-router-native/index.android.js @@ -1,65 +1,74 @@ -import React from 'react' -import { AppRegistry, StyleSheet, Text, View } from 'react-native' +import React from "react"; +import { AppRegistry, StyleSheet, Text, View } from "react-native"; -import { NativeRouter, Route, Link, DeepLinking, BackButton, Prompt } from './main' +import { + NativeRouter, + Route, + Link, + DeepLinking, + BackButton, + Prompt +} from "./main"; export default class ReactRouterNative extends React.Component { render() { return ( - - + + - ( - - - Welcome to React Router Native! - - - - Go to "/one" + ( + + + Welcome to React Router Native! - - - )}/> + + Go to "/one" + + + )} + /> - ( - - - - ONE! {match.url} - - - - Go Back - - - - )}/> + ( + + + ONE! {match.url} + + Go Back + + + )} + /> - ) + ); } } const styles = StyleSheet.create({ container: { flex: 1, - justifyContent: 'center', - alignItems: 'center', - backgroundColor: '#F5FCFF', + justifyContent: "center", + alignItems: "center", + backgroundColor: "#F5FCFF" }, welcome: { fontSize: 20, - textAlign: 'center', - margin: 10, + textAlign: "center", + margin: 10 }, instructions: { - textAlign: 'center', - color: '#333333', - marginBottom: 5, + textAlign: "center", + color: "#333333", + marginBottom: 5 } -}) +}); -AppRegistry.registerComponent('ReactRouterNative', () => ReactRouterNative) +AppRegistry.registerComponent("ReactRouterNative", () => ReactRouterNative); diff --git a/packages/react-router-native/index.ios.js b/packages/react-router-native/index.ios.js index 5805678c54..8aed3af6c1 100644 --- a/packages/react-router-native/index.ios.js +++ b/packages/react-router-native/index.ios.js @@ -1,8 +1,8 @@ -import { AppRegistry } from 'react-native' +import { AppRegistry } from "react-native"; -import ReactRouterNative from './examples/BasicExample' +import ReactRouterNative from "./examples/BasicExample"; //import ReactRouterNative from './examples/ExperimentalExample' -export default ReactRouterNative +export default ReactRouterNative; -AppRegistry.registerComponent('ReactRouterNative', () => ReactRouterNative) +AppRegistry.registerComponent("ReactRouterNative", () => ReactRouterNative); diff --git a/packages/react-router-native/main.js b/packages/react-router-native/main.js index 7a17cd003c..7cb6e99e42 100644 --- a/packages/react-router-native/main.js +++ b/packages/react-router-native/main.js @@ -1,9 +1,9 @@ -export * from 'react-router' +export * from "react-router"; -import BackButton from './BackButton' -import DeepLinking from './DeepLinking' -import Link from './Link' -import NativeRouter from './NativeRouter' +import BackButton from "./BackButton"; +import DeepLinking from "./DeepLinking"; +import Link from "./Link"; +import NativeRouter from "./NativeRouter"; export { BackButton, @@ -11,4 +11,4 @@ export { DeepLinking, Link, NativeRouter -} +}; diff --git a/packages/react-router-native/rn-cli.config.js b/packages/react-router-native/rn-cli.config.js index 9b3ac28157..13a895c301 100644 --- a/packages/react-router-native/rn-cli.config.js +++ b/packages/react-router-native/rn-cli.config.js @@ -1,13 +1,21 @@ -const path = require('path'); -const blacklist = require('react-native/packager/blacklist'); -const config = require('react-native/packager/rn-cli.config'); +const path = require("path"); +const blacklist = require("react-native/packager/blacklist"); +const config = require("react-native/packager/rn-cli.config"); -const rootPackagePath = path.join(__dirname, '..', '..'); +const rootPackagePath = path.join(__dirname, "..", ".."); config.getBlacklist = () => [ new RegExp(`^${escapeRegExp(rootPackagePath)}\/node_modules(.*)`), - new RegExp(`^${escapeRegExp(rootPackagePath)}\/packages\/(react-router-dom|react-router-website(-*)?)\/(.*)`), - new RegExp(`^${escapeRegExp(rootPackagePath)}\/packages\/react-router-native\/node_modules\/react-router(.*)`), + new RegExp( + `^${escapeRegExp( + rootPackagePath + )}\/packages\/(react-router-dom|react-router-website(-*)?)\/(.*)` + ), + new RegExp( + `^${escapeRegExp( + rootPackagePath + )}\/packages\/react-router-native\/node_modules\/react-router(.*)` + ) //new RegExp(`^${escapeRegExp(rootPackagePath)}\/packages\/react-router\/node_modules\/(.*)`), ]; @@ -17,13 +25,11 @@ config.getProjectRoots = () => getRoots(); config.getAssetRoots = () => getRoots(); function getRoots() { - return [ - path.join(__dirname, '../../'), - ]; + return [path.join(__dirname, "../../")]; } function escapeRegExp(s) { - return s.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&'); + return s.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&"); } module.exports = config; diff --git a/packages/react-router-redux/modules/ConnectedRouter.js b/packages/react-router-redux/modules/ConnectedRouter.js index 3020bcd21b..a525090d65 100644 --- a/packages/react-router-redux/modules/ConnectedRouter.js +++ b/packages/react-router-redux/modules/ConnectedRouter.js @@ -1,8 +1,8 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' -import { Router } from 'react-router' +import React, { Component } from "react"; +import PropTypes from "prop-types"; +import { Router } from "react-router"; -import { LOCATION_CHANGE } from './reducer' +import { LOCATION_CHANGE } from "./reducer"; class ConnectedRouter extends Component { static propTypes = { @@ -10,36 +10,36 @@ class ConnectedRouter extends Component { history: PropTypes.object.isRequired, children: PropTypes.node, isSSR: PropTypes.bool - } + }; static contextTypes = { store: PropTypes.object - } + }; handleLocationChange = location => { this.store.dispatch({ type: LOCATION_CHANGE, payload: location - }) - } + }); + }; componentWillMount() { - const { store:propsStore, history, isSSR } = this.props - this.store = propsStore || this.context.store + const { store: propsStore, history, isSSR } = this.props; + this.store = propsStore || this.context.store; if (!isSSR) - this.unsubscribeFromHistory = history.listen(this.handleLocationChange) + this.unsubscribeFromHistory = history.listen(this.handleLocationChange); - this.handleLocationChange(history.location) + this.handleLocationChange(history.location); } componentWillUnmount() { - if (this.unsubscribeFromHistory) this.unsubscribeFromHistory() + if (this.unsubscribeFromHistory) this.unsubscribeFromHistory(); } render() { - return + return ; } } -export default ConnectedRouter +export default ConnectedRouter; diff --git a/packages/react-router-redux/modules/__tests__/ConnectedRouter-test.js b/packages/react-router-redux/modules/__tests__/ConnectedRouter-test.js index 4222f6cab6..5d3be90d30 100644 --- a/packages/react-router-redux/modules/__tests__/ConnectedRouter-test.js +++ b/packages/react-router-redux/modules/__tests__/ConnectedRouter-test.js @@ -1,28 +1,30 @@ -import React from 'react' -import renderer from 'react-test-renderer' -import {Switch, Route, Redirect} from 'react-router' -import { applyMiddleware, createStore, combineReducers } from 'redux' -import { Provider } from 'react-redux' -import createHistory from 'history/createMemoryHistory' +import React from "react"; +import renderer from "react-test-renderer"; +import { Switch, Route, Redirect } from "react-router"; +import { applyMiddleware, createStore, combineReducers } from "redux"; +import { Provider } from "react-redux"; +import createHistory from "history/createMemoryHistory"; -import ConnectedRouter from '../ConnectedRouter' -import { LOCATION_CHANGE, routerReducer } from '../reducer' -import routerMiddleware from '../middleware' -import { push } from '../actions' +import ConnectedRouter from "../ConnectedRouter"; +import { LOCATION_CHANGE, routerReducer } from "../reducer"; +import routerMiddleware from "../middleware"; +import { push } from "../actions"; -describe('A ', () => { - let store, history +describe("A ", () => { + let store, history; beforeEach(() => { - store = createStore(combineReducers({ - router: routerReducer - })) + store = createStore( + combineReducers({ + router: routerReducer + }) + ); - history = createHistory() - }) + history = createHistory(); + }); - it('connects to a store via Provider', () => { - expect(store.getState()).toHaveProperty('router.location', null) + it("connects to a store via Provider", () => { + expect(store.getState()).toHaveProperty("router.location", null); renderer.create( @@ -30,61 +32,63 @@ describe('A ', () => {
Test
- ) + ); - expect(store.getState()).toHaveProperty('router.location.pathname') - }) + expect(store.getState()).toHaveProperty("router.location.pathname"); + }); - it('connects to a store via props', () => { - expect(store.getState()).toHaveProperty('router.location', null) + it("connects to a store via props", () => { + expect(store.getState()).toHaveProperty("router.location", null); renderer.create(
Test
- ) + ); - expect(store.getState()).toHaveProperty('router.location.pathname') - }) + expect(store.getState()).toHaveProperty("router.location.pathname"); + }); - it('updates the store with location changes', () => { + it("updates the store with location changes", () => { renderer.create(
Test
- ) + ); - expect(store.getState()).toHaveProperty('router.location.pathname', '/') + expect(store.getState()).toHaveProperty("router.location.pathname", "/"); - history.push('/foo') + history.push("/foo"); - expect(store.getState()).toHaveProperty('router.location.pathname', '/foo') - }) + expect(store.getState()).toHaveProperty("router.location.pathname", "/foo"); + }); - describe('with children', () => { - it('to render', () => { - const tree = renderer.create( - -
Test
-
- ).toJSON() - - expect(tree).toMatchSnapshot() - }) - }) - - describe('with no children', () => { - it('to render', () => { - const tree = renderer.create( - - ).toJSON() - - expect(tree).toMatchSnapshot() - }) - }) - - it('redirects properly', () => { - expect(store.getState()).toHaveProperty('router.location', null) + describe("with children", () => { + it("to render", () => { + const tree = renderer + .create( + +
Test
+
+ ) + .toJSON(); + + expect(tree).toMatchSnapshot(); + }); + }); + + describe("with no children", () => { + it("to render", () => { + const tree = renderer + .create() + .toJSON(); + + expect(tree).toMatchSnapshot(); + }); + }); + + it("redirects properly", () => { + expect(store.getState()).toHaveProperty("router.location", null); renderer.create( @@ -93,33 +97,39 @@ describe('A ', () => { - ) + ); - expect(store.getState()).toHaveProperty('router.location.pathname', '/test') - }) + expect(store.getState()).toHaveProperty( + "router.location.pathname", + "/test" + ); + }); - it('stays in sync if other middlewares dispatch routerActions as a reaction to the inital LOCATION_CHANGE', () => { - - let waitingForFirstLocationChange = true + it("stays in sync if other middlewares dispatch routerActions as a reaction to the inital LOCATION_CHANGE", () => { + let waitingForFirstLocationChange = true; const customMiddleware = st => next => action => { - const res = next(action) + const res = next(action); if (waitingForFirstLocationChange && action.type === LOCATION_CHANGE) { - waitingForFirstLocationChange = false - st.dispatch(push('/test')) + waitingForFirstLocationChange = false; + st.dispatch(push("/test")); } - return res - } - - store = createStore(combineReducers({ - router: routerReducer - }), applyMiddleware(routerMiddleware(history), customMiddleware)) - - expect(store.getState()).toHaveProperty('router.location', null) - - renderer.create( - - ) - - expect(store.getState()).toHaveProperty('router.location.pathname', '/test') - }) -}) + return res; + }; + + store = createStore( + combineReducers({ + router: routerReducer + }), + applyMiddleware(routerMiddleware(history), customMiddleware) + ); + + expect(store.getState()).toHaveProperty("router.location", null); + + renderer.create(); + + expect(store.getState()).toHaveProperty( + "router.location.pathname", + "/test" + ); + }); +}); diff --git a/packages/react-router-redux/modules/__tests__/actions-test.js b/packages/react-router-redux/modules/__tests__/actions-test.js index 8d377be009..086d8337c1 100644 --- a/packages/react-router-redux/modules/__tests__/actions-test.js +++ b/packages/react-router-redux/modules/__tests__/actions-test.js @@ -1,98 +1,104 @@ import { CALL_HISTORY_METHOD, - push, replace, go, goBack, goForward -} from '../actions' + push, + replace, + go, + goBack, + goForward +} from "../actions"; -describe('routerActions', () => { - - describe('push', () => { - it('creates actions', () => { - expect(push('/foo')).toEqual({ +describe("routerActions", () => { + describe("push", () => { + it("creates actions", () => { + expect(push("/foo")).toEqual({ type: CALL_HISTORY_METHOD, payload: { - method: 'push', - args: [ '/foo' ] + method: "push", + args: ["/foo"] } - }) + }); - expect(push({ pathname: '/foo', state: { the: 'state' } })).toEqual({ + expect(push({ pathname: "/foo", state: { the: "state" } })).toEqual({ type: CALL_HISTORY_METHOD, payload: { - method: 'push', - args: [ { - pathname: '/foo', - state: { the: 'state' } - } ] + method: "push", + args: [ + { + pathname: "/foo", + state: { the: "state" } + } + ] } - }) + }); - expect(push('/foo', 'baz', 123)).toEqual({ + expect(push("/foo", "baz", 123)).toEqual({ type: CALL_HISTORY_METHOD, payload: { - method: 'push', - args: [ '/foo' , 'baz', 123 ] + method: "push", + args: ["/foo", "baz", 123] } - }) - }) - }) + }); + }); + }); - describe('replace', () => { - it('creates actions', () => { - expect(replace('/foo')).toEqual({ + describe("replace", () => { + it("creates actions", () => { + expect(replace("/foo")).toEqual({ type: CALL_HISTORY_METHOD, payload: { - method: 'replace', - args: [ '/foo' ] + method: "replace", + args: ["/foo"] } - }) + }); - expect(replace({ pathname: '/foo', state: { the: 'state' } })).toEqual({ + expect(replace({ pathname: "/foo", state: { the: "state" } })).toEqual({ type: CALL_HISTORY_METHOD, payload: { - method: 'replace', - args: [ { - pathname: '/foo', - state: { the: 'state' } - } ] + method: "replace", + args: [ + { + pathname: "/foo", + state: { the: "state" } + } + ] } - }) - }) - }) + }); + }); + }); - describe('go', () => { - it('creates actions', () => { + describe("go", () => { + it("creates actions", () => { expect(go(1)).toEqual({ type: CALL_HISTORY_METHOD, payload: { - method: 'go', - args: [ 1 ] + method: "go", + args: [1] } - }) - }) - }) + }); + }); + }); - describe('goBack', () => { - it('creates actions', () => { + describe("goBack", () => { + it("creates actions", () => { expect(goBack()).toEqual({ type: CALL_HISTORY_METHOD, payload: { - method: 'goBack', + method: "goBack", args: [] } - }) - }) - }) + }); + }); + }); - describe('goForward', () => { - it('creates actions', () => { + describe("goForward", () => { + it("creates actions", () => { expect(goForward()).toEqual({ type: CALL_HISTORY_METHOD, payload: { - method: 'goForward', + method: "goForward", args: [] } - }) - }) - }) - -}) + }); + }); + }); +}); diff --git a/packages/react-router-redux/modules/__tests__/middleware-test.js b/packages/react-router-redux/modules/__tests__/middleware-test.js index 2aac8b88f2..96a54b6bc4 100644 --- a/packages/react-router-redux/modules/__tests__/middleware-test.js +++ b/packages/react-router-redux/modules/__tests__/middleware-test.js @@ -1,32 +1,31 @@ -import { push, replace } from '../actions' -import routerMiddleware from '../middleware' +import { push, replace } from "../actions"; +import routerMiddleware from "../middleware"; -describe('routerMiddleware', () => { - let history, next, dispatch +describe("routerMiddleware", () => { + let history, next, dispatch; beforeEach(() => { history = { push: jest.fn(), replace: jest.fn() - } - next = jest.fn() + }; + next = jest.fn(); - dispatch = routerMiddleware(history)()(next) - }) + dispatch = routerMiddleware(history)()(next); + }); + it("calls the appropriate history method", () => { + dispatch(push("/foo")); + expect(history.push).toHaveBeenCalled(); - it('calls the appropriate history method', () => { - dispatch(push('/foo')) - expect(history.push).toHaveBeenCalled() + dispatch(replace("/foo")); + expect(history.replace).toHaveBeenCalled(); - dispatch(replace('/foo')) - expect(history.replace).toHaveBeenCalled() + expect(next).toHaveBeenCalledTimes(0); + }); - expect(next).toHaveBeenCalledTimes(0) - }) - - it('ignores other actions', () => { - dispatch({ type: 'FOO' }) - expect(next).toHaveBeenCalled() - }) -}) + it("ignores other actions", () => { + dispatch({ type: "FOO" }); + expect(next).toHaveBeenCalled(); + }); +}); diff --git a/packages/react-router-redux/modules/__tests__/reducer-test.js b/packages/react-router-redux/modules/__tests__/reducer-test.js index f3b5f3af6f..4abdcbb85d 100644 --- a/packages/react-router-redux/modules/__tests__/reducer-test.js +++ b/packages/react-router-redux/modules/__tests__/reducer-test.js @@ -1,56 +1,61 @@ -import { LOCATION_CHANGE, routerReducer } from '../reducer' +import { LOCATION_CHANGE, routerReducer } from "../reducer"; -describe('routerReducer', () => { +describe("routerReducer", () => { const state = { location: { - pathname: '/foo', - action: 'POP' + pathname: "/foo", + action: "POP" } - } + }; - it('updates the path', () => { - expect(routerReducer(state, { - type: LOCATION_CHANGE, - payload: { - path: '/bar', - action: 'PUSH' - } - })).toEqual({ + it("updates the path", () => { + expect( + routerReducer(state, { + type: LOCATION_CHANGE, + payload: { + path: "/bar", + action: "PUSH" + } + }) + ).toEqual({ location: { - path: '/bar', - action: 'PUSH' + path: "/bar", + action: "PUSH" } - }) - }) + }); + }); - it('works with initialState', () => { - expect(routerReducer(undefined, { - type: LOCATION_CHANGE, - payload: { - path: '/bar', - action: 'PUSH' - } - })).toEqual({ + it("works with initialState", () => { + expect( + routerReducer(undefined, { + type: LOCATION_CHANGE, + payload: { + path: "/bar", + action: "PUSH" + } + }) + ).toEqual({ location: { - path: '/bar', - action: 'PUSH' + path: "/bar", + action: "PUSH" } - }) - }) + }); + }); - - it('respects replace', () => { - expect(routerReducer(state, { - type: LOCATION_CHANGE, - payload: { - path: '/bar', - action: 'REPLACE' - } - })).toEqual({ + it("respects replace", () => { + expect( + routerReducer(state, { + type: LOCATION_CHANGE, + payload: { + path: "/bar", + action: "REPLACE" + } + }) + ).toEqual({ location: { - path: '/bar', - action: 'REPLACE' + path: "/bar", + action: "REPLACE" } - }) - }) -}) + }); + }); +}); diff --git a/packages/react-router-redux/modules/__tests__/selectors-test.js b/packages/react-router-redux/modules/__tests__/selectors-test.js index 7c0300e34f..d34513f281 100644 --- a/packages/react-router-redux/modules/__tests__/selectors-test.js +++ b/packages/react-router-redux/modules/__tests__/selectors-test.js @@ -1,98 +1,98 @@ -import { getLocation, createMatchSelector } from '../selectors' -import { createStore, combineReducers } from 'redux' -import { routerReducer, LOCATION_CHANGE } from '../reducer' +import { getLocation, createMatchSelector } from "../selectors"; +import { createStore, combineReducers } from "redux"; +import { routerReducer, LOCATION_CHANGE } from "../reducer"; -describe('selectors', () => { - - let store +describe("selectors", () => { + let store; beforeEach(() => { - store = createStore(combineReducers({ - router: routerReducer - })) - }) + store = createStore( + combineReducers({ + router: routerReducer + }) + ); + }); - describe('getLocation', () => { - it('gets the location from the state', () => { - const location = { pathname: '/' } + describe("getLocation", () => { + it("gets the location from the state", () => { + const location = { pathname: "/" }; store.dispatch({ type: LOCATION_CHANGE, payload: location - }) - const state = store.getState() - expect(getLocation(state)).toBe(location) - }) - }) + }); + const state = store.getState(); + expect(getLocation(state)).toBe(location); + }); + }); - describe('createMatchSelector', () => { - it('matches correctly if the router is initialized', () => { - const matchSelector = createMatchSelector('/') + describe("createMatchSelector", () => { + it("matches correctly if the router is initialized", () => { + const matchSelector = createMatchSelector("/"); store.dispatch({ type: LOCATION_CHANGE, - payload: { pathname: '/test' } - }) - const state = store.getState() + payload: { pathname: "/test" } + }); + const state = store.getState(); expect(matchSelector(state)).toEqual({ isExact: false, params: {}, - path: '/', - url: '/' - }) - }) - - it('does not throw error if router has not yet initialized', () => { - const matchSelector = createMatchSelector('/') - const state = store.getState() - expect(() => matchSelector(state)).not.toThrow() - }) + path: "/", + url: "/" + }); + }); + + it("does not throw error if router has not yet initialized", () => { + const matchSelector = createMatchSelector("/"); + const state = store.getState(); + expect(() => matchSelector(state)).not.toThrow(); + }); - it('does not update if the match is the same', () => { - const matchSelector = createMatchSelector('/') + it("does not update if the match is the same", () => { + const matchSelector = createMatchSelector("/"); store.dispatch({ type: LOCATION_CHANGE, - payload: { pathname: '/test1' } - }) - const match1 = matchSelector(store.getState()) + payload: { pathname: "/test1" } + }); + const match1 = matchSelector(store.getState()); store.dispatch({ type: LOCATION_CHANGE, - payload: { pathname: '/test2' } - }) - const match2 = matchSelector(store.getState()) - expect(match1).toBe(match2) - }) + payload: { pathname: "/test2" } + }); + const match2 = matchSelector(store.getState()); + expect(match1).toBe(match2); + }); - it('updates if the match is different', () => { - const matchSelector = createMatchSelector('/sushi/:type') + it("updates if the match is different", () => { + const matchSelector = createMatchSelector("/sushi/:type"); store.dispatch({ type: LOCATION_CHANGE, - payload: { pathname: '/sushi/california' } - }) - const match1 = matchSelector(store.getState()) + payload: { pathname: "/sushi/california" } + }); + const match1 = matchSelector(store.getState()); store.dispatch({ type: LOCATION_CHANGE, - payload: { pathname: '/sushi/dynamite' } - }) - const match2 = matchSelector(store.getState()) - expect(match1).not.toBe(match2) - }) + payload: { pathname: "/sushi/dynamite" } + }); + const match2 = matchSelector(store.getState()); + expect(match1).not.toBe(match2); + }); - it('updates if the exact match is different', () => { + it("updates if the exact match is different", () => { const matchSelector = createMatchSelector({ - path: '/sushi', - exact: true, - }) + path: "/sushi", + exact: true + }); store.dispatch({ type: LOCATION_CHANGE, - payload: { pathname: '/sushi' } - }) - const match1 = matchSelector(store.getState()) + payload: { pathname: "/sushi" } + }); + const match1 = matchSelector(store.getState()); store.dispatch({ type: LOCATION_CHANGE, - payload: { pathname: '/sushi/dynamite' } - }) - const match2 = matchSelector(store.getState()) - expect(match1).not.toBe(match2) - }) - }) - -}) + payload: { pathname: "/sushi/dynamite" } + }); + const match2 = matchSelector(store.getState()); + expect(match1).not.toBe(match2); + }); + }); +}); diff --git a/packages/react-router-redux/modules/actions.js b/packages/react-router-redux/modules/actions.js index 771fbbbc9b..e505e8ec76 100644 --- a/packages/react-router-redux/modules/actions.js +++ b/packages/react-router-redux/modules/actions.js @@ -1,16 +1,15 @@ - /** * This action type will be dispatched by the history actions below. * If you're writing a middleware to watch for navigation events, be sure to * look for actions of this type. */ -export const CALL_HISTORY_METHOD = '@@router/CALL_HISTORY_METHOD' +export const CALL_HISTORY_METHOD = "@@router/CALL_HISTORY_METHOD"; function updateLocation(method) { return (...args) => ({ type: CALL_HISTORY_METHOD, payload: { method, args } - }) + }); } /** @@ -18,10 +17,10 @@ function updateLocation(method) { * The associated routerMiddleware will capture these events before they get to * your reducer and reissue them as the matching function on your history. */ -export const push = updateLocation('push') -export const replace = updateLocation('replace') -export const go = updateLocation('go') -export const goBack = updateLocation('goBack') -export const goForward = updateLocation('goForward') +export const push = updateLocation("push"); +export const replace = updateLocation("replace"); +export const go = updateLocation("go"); +export const goBack = updateLocation("goBack"); +export const goForward = updateLocation("goForward"); -export const routerActions = { push, replace, go, goBack, goForward } +export const routerActions = { push, replace, go, goBack, goForward }; diff --git a/packages/react-router-redux/modules/index.js b/packages/react-router-redux/modules/index.js index f556d3a638..bf0f07f09d 100644 --- a/packages/react-router-redux/modules/index.js +++ b/packages/react-router-redux/modules/index.js @@ -1,9 +1,13 @@ -export ConnectedRouter from './ConnectedRouter' -export { getLocation, createMatchSelector } from './selectors' -export { LOCATION_CHANGE, routerReducer } from './reducer' +export ConnectedRouter from "./ConnectedRouter"; +export { getLocation, createMatchSelector } from "./selectors"; +export { LOCATION_CHANGE, routerReducer } from "./reducer"; export { CALL_HISTORY_METHOD, - push, replace, go, goBack, goForward, + push, + replace, + go, + goBack, + goForward, routerActions -} from './actions' -export routerMiddleware from './middleware' +} from "./actions"; +export routerMiddleware from "./middleware"; diff --git a/packages/react-router-redux/modules/middleware.js b/packages/react-router-redux/modules/middleware.js index ad5d5ab51f..6a5766d2ec 100644 --- a/packages/react-router-redux/modules/middleware.js +++ b/packages/react-router-redux/modules/middleware.js @@ -1,4 +1,4 @@ -import { CALL_HISTORY_METHOD } from './actions' +import { CALL_HISTORY_METHOD } from "./actions"; /** * This middleware captures CALL_HISTORY_METHOD actions to redirect to the @@ -8,10 +8,10 @@ import { CALL_HISTORY_METHOD } from './actions' export default function routerMiddleware(history) { return () => next => action => { if (action.type !== CALL_HISTORY_METHOD) { - return next(action) + return next(action); } - const { payload: { method, args } } = action - history[method](...args) - } + const { payload: { method, args } } = action; + history[method](...args); + }; } diff --git a/packages/react-router-redux/modules/reducer.js b/packages/react-router-redux/modules/reducer.js index 05df5c65f1..6abee6c15e 100644 --- a/packages/react-router-redux/modules/reducer.js +++ b/packages/react-router-redux/modules/reducer.js @@ -2,11 +2,11 @@ * This action type will be dispatched when your history * receives a location change. */ -export const LOCATION_CHANGE = '@@router/LOCATION_CHANGE' +export const LOCATION_CHANGE = "@@router/LOCATION_CHANGE"; const initialState = { location: null -} +}; /** * This reducer will update the state with the most recent location history @@ -16,8 +16,8 @@ const initialState = { */ export function routerReducer(state = initialState, { type, payload } = {}) { if (type === LOCATION_CHANGE) { - return { ...state, location: payload } + return { ...state, location: payload }; } - return state + return state; } diff --git a/packages/react-router-redux/modules/selectors.js b/packages/react-router-redux/modules/selectors.js index e3f24fe85f..c5f5788337 100644 --- a/packages/react-router-redux/modules/selectors.js +++ b/packages/react-router-redux/modules/selectors.js @@ -1,20 +1,20 @@ -import { matchPath } from 'react-router' +import { matchPath } from "react-router"; -export const getLocation = state => state.router.location +export const getLocation = state => state.router.location; -export const createMatchSelector = (path) => { - let lastPathname = null - let lastMatch = null - return (state) => { - const { pathname } = getLocation(state) || {} +export const createMatchSelector = path => { + let lastPathname = null; + let lastMatch = null; + return state => { + const { pathname } = getLocation(state) || {}; if (pathname === lastPathname) { - return lastMatch + return lastMatch; } - lastPathname = pathname - const match = matchPath(pathname, path) + lastPathname = pathname; + const match = matchPath(pathname, path); if (!match || !lastMatch || match.url !== lastMatch.url) { - lastMatch = match + lastMatch = match; } - return lastMatch - } -} + return lastMatch; + }; +}; diff --git a/packages/react-router-redux/rollup.config.js b/packages/react-router-redux/rollup.config.js index 707b2baf48..48bbf9f643 100644 --- a/packages/react-router-redux/rollup.config.js +++ b/packages/react-router-redux/rollup.config.js @@ -1,29 +1,25 @@ -import babel from 'rollup-plugin-babel' -import uglify from 'rollup-plugin-uglify' +import babel from "rollup-plugin-babel"; +import uglify from "rollup-plugin-uglify"; var config = { output: { - format: 'umd', - name: 'ReactRouterRedux', + format: "umd", + name: "ReactRouterRedux" }, plugins: [ babel({ - exclude: 'node_modules/**' + exclude: "node_modules/**" }) ], - external: [ - 'react', - 'prop-types', - 'react-router' - ], + external: ["react", "prop-types", "react-router"], globals: { - react: 'React', - 'prop-types': 'PropTypes', - 'react-router': 'ReactRouter' + react: "React", + "prop-types": "PropTypes", + "react-router": "ReactRouter" } -} +}; -if (process.env.NODE_ENV === 'production') { +if (process.env.NODE_ENV === "production") { config.plugins.push( uglify({ compress: { @@ -33,7 +29,7 @@ if (process.env.NODE_ENV === 'production') { warnings: false } }) - ) + ); } -export default config +export default config; diff --git a/packages/react-router/modules/MemoryRouter.js b/packages/react-router/modules/MemoryRouter.js index 3e04c20495..3922857f2f 100644 --- a/packages/react-router/modules/MemoryRouter.js +++ b/packages/react-router/modules/MemoryRouter.js @@ -1,8 +1,8 @@ -import warning from 'warning' -import React from 'react' -import PropTypes from 'prop-types' -import {createMemoryHistory as createHistory} from 'history' -import Router from './Router' +import warning from "warning"; +import React from "react"; +import PropTypes from "prop-types"; +import { createMemoryHistory as createHistory } from "history"; +import Router from "./Router"; /** * The public API for a that stores location in memory. @@ -14,21 +14,21 @@ class MemoryRouter extends React.Component { getUserConfirmation: PropTypes.func, keyLength: PropTypes.number, children: PropTypes.node - } + }; - history = createHistory(this.props) + history = createHistory(this.props); componentWillMount() { warning( !this.props.history, - ' ignores the history prop. To use a custom history, ' + - 'use `import { Router }` instead of `import { MemoryRouter as Router }`.' - ) + " ignores the history prop. To use a custom history, " + + "use `import { Router }` instead of `import { MemoryRouter as Router }`." + ); } render() { - return + return ; } } -export default MemoryRouter +export default MemoryRouter; diff --git a/packages/react-router/modules/Prompt.js b/packages/react-router/modules/Prompt.js index b839fbef99..f2a2aac6c7 100644 --- a/packages/react-router/modules/Prompt.js +++ b/packages/react-router/modules/Prompt.js @@ -1,6 +1,6 @@ -import React from 'react' -import PropTypes from 'prop-types' -import invariant from 'invariant' +import React from "react"; +import PropTypes from "prop-types"; +import invariant from "invariant"; /** * The public API for prompting the user before navigating away @@ -9,15 +9,12 @@ import invariant from 'invariant' class Prompt extends React.Component { static propTypes = { when: PropTypes.bool, - message: PropTypes.oneOfType([ - PropTypes.func, - PropTypes.string - ]).isRequired - } + message: PropTypes.oneOfType([PropTypes.func, PropTypes.string]).isRequired + }; static defaultProps = { when: true - } + }; static contextTypes = { router: PropTypes.shape({ @@ -25,48 +22,46 @@ class Prompt extends React.Component { block: PropTypes.func.isRequired }).isRequired }).isRequired - } + }; enable(message) { - if (this.unblock) - this.unblock() + if (this.unblock) this.unblock(); - this.unblock = this.context.router.history.block(message) + this.unblock = this.context.router.history.block(message); } disable() { if (this.unblock) { - this.unblock() - this.unblock = null + this.unblock(); + this.unblock = null; } } componentWillMount() { invariant( this.context.router, - 'You should not use outside a ' - ) + "You should not use outside a " + ); - if (this.props.when) - this.enable(this.props.message) + if (this.props.when) this.enable(this.props.message); } componentWillReceiveProps(nextProps) { if (nextProps.when) { if (!this.props.when || this.props.message !== nextProps.message) - this.enable(nextProps.message) + this.enable(nextProps.message); } else { - this.disable() + this.disable(); } } componentWillUnmount() { - this.disable() + this.disable(); } render() { - return null + return null; } } -export default Prompt +export default Prompt; diff --git a/packages/react-router/modules/Redirect.js b/packages/react-router/modules/Redirect.js index e1c690001a..fb8984d3ae 100644 --- a/packages/react-router/modules/Redirect.js +++ b/packages/react-router/modules/Redirect.js @@ -1,9 +1,9 @@ -import React from 'react' -import PropTypes from 'prop-types' -import warning from 'warning' -import invariant from 'invariant' -import { createLocation, locationsAreEqual } from 'history' -import generatePath from './generatePath' +import React from "react"; +import PropTypes from "prop-types"; +import warning from "warning"; +import invariant from "invariant"; +import { createLocation, locationsAreEqual } from "history"; +import generatePath from "./generatePath"; /** * The public API for updating the location programmatically @@ -14,15 +14,12 @@ class Redirect extends React.Component { computedMatch: PropTypes.object, // private, from push: PropTypes.bool, from: PropTypes.string, - to: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.object - ]).isRequired - } + to: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).isRequired + }; static defaultProps = { push: false - } + }; static contextTypes = { router: PropTypes.shape({ @@ -32,70 +29,71 @@ class Redirect extends React.Component { }).isRequired, staticContext: PropTypes.object }).isRequired - } + }; isStatic() { - return this.context.router && this.context.router.staticContext + return this.context.router && this.context.router.staticContext; } componentWillMount() { invariant( this.context.router, - 'You should not use outside a ' - ) + "You should not use outside a " + ); - if (this.isStatic()) - this.perform() + if (this.isStatic()) this.perform(); } componentDidMount() { - if (!this.isStatic()) - this.perform() + if (!this.isStatic()) this.perform(); } componentDidUpdate(prevProps) { - const prevTo = createLocation(prevProps.to) - const nextTo = createLocation(this.props.to) + const prevTo = createLocation(prevProps.to); + const nextTo = createLocation(this.props.to); if (locationsAreEqual(prevTo, nextTo)) { - warning(false, `You tried to redirect to the same route you're currently on: ` + - `"${nextTo.pathname}${nextTo.search}"`) - return + warning( + false, + `You tried to redirect to the same route you're currently on: ` + + `"${nextTo.pathname}${nextTo.search}"` + ); + return; } - this.perform() + this.perform(); } computeTo({ computedMatch, to }) { if (computedMatch) { if (typeof to === "string") { - return generatePath(to, computedMatch.params) + return generatePath(to, computedMatch.params); } else { return { ...to, pathname: generatePath(to.pathname, computedMatch.params) - } + }; } } - return to + return to; } perform() { - const { history } = this.context.router - const { push } = this.props - const to = this.computeTo(this.props) + const { history } = this.context.router; + const { push } = this.props; + const to = this.computeTo(this.props); if (push) { - history.push(to) + history.push(to); } else { - history.replace(to) + history.replace(to); } } render() { - return null + return null; } } -export default Redirect +export default Redirect; diff --git a/packages/react-router/modules/Route.js b/packages/react-router/modules/Route.js index 98a569a57f..2795bd0b48 100644 --- a/packages/react-router/modules/Route.js +++ b/packages/react-router/modules/Route.js @@ -1,11 +1,10 @@ -import warning from 'warning' -import invariant from 'invariant' -import React from 'react' -import PropTypes from 'prop-types' -import matchPath from './matchPath' +import warning from "warning"; +import invariant from "invariant"; +import React from "react"; +import PropTypes from "prop-types"; +import matchPath from "./matchPath"; -const isEmptyChildren = (children) => - React.Children.count(children) === 0 +const isEmptyChildren = children => React.Children.count(children) === 0; /** * The public API for matching a single path and rendering. @@ -19,12 +18,9 @@ class Route extends React.Component { sensitive: PropTypes.bool, component: PropTypes.func, render: PropTypes.func, - children: PropTypes.oneOfType([ - PropTypes.func, - PropTypes.node - ]), + children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]), location: PropTypes.object - } + }; static contextTypes = { router: PropTypes.shape({ @@ -32,11 +28,11 @@ class Route extends React.Component { route: PropTypes.object.isRequired, staticContext: PropTypes.object }) - } + }; static childContextTypes = { router: PropTypes.object.isRequired - } + }; getChildContext() { return { @@ -47,82 +43,91 @@ class Route extends React.Component { match: this.state.match } } - } + }; } state = { match: this.computeMatch(this.props, this.context.router) - } + }; - computeMatch({ computedMatch, location, path, strict, exact, sensitive }, router) { - if (computedMatch) - return computedMatch // already computed the match for us + computeMatch( + { computedMatch, location, path, strict, exact, sensitive }, + router + ) { + if (computedMatch) return computedMatch; // already computed the match for us invariant( router, - 'You should not use or withRouter() outside a ' - ) + "You should not use or withRouter() outside a " + ); - const { route } = router - const pathname = (location || route.location).pathname + const { route } = router; + const pathname = (location || route.location).pathname; - return path ? matchPath(pathname, { path, strict, exact, sensitive }) : route.match + return path + ? matchPath(pathname, { path, strict, exact, sensitive }) + : route.match; } componentWillMount() { warning( !(this.props.component && this.props.render), - 'You should not use and in the same route; will be ignored' - ) + "You should not use and in the same route; will be ignored" + ); warning( - !(this.props.component && this.props.children && !isEmptyChildren(this.props.children)), - 'You should not use and in the same route; will be ignored' - ) + !( + this.props.component && + this.props.children && + !isEmptyChildren(this.props.children) + ), + "You should not use and in the same route; will be ignored" + ); warning( - !(this.props.render && this.props.children && !isEmptyChildren(this.props.children)), - 'You should not use and in the same route; will be ignored' - ) + !( + this.props.render && + this.props.children && + !isEmptyChildren(this.props.children) + ), + "You should not use and in the same route; will be ignored" + ); } componentWillReceiveProps(nextProps, nextContext) { warning( !(nextProps.location && !this.props.location), ' elements should not change from uncontrolled to controlled (or vice versa). You initially used no "location" prop and then provided one on a subsequent render.' - ) + ); warning( !(!nextProps.location && this.props.location), ' elements should not change from controlled to uncontrolled (or vice versa). You provided a "location" prop initially but omitted it on a subsequent render.' - ) + ); this.setState({ match: this.computeMatch(nextProps, nextContext.router) - }) + }); } render() { - const { match } = this.state - const { children, component, render } = this.props - const { history, route, staticContext } = this.context.router - const location = this.props.location || route.location - const props = { match, location, history, staticContext } + const { match } = this.state; + const { children, component, render } = this.props; + const { history, route, staticContext } = this.context.router; + const location = this.props.location || route.location; + const props = { match, location, history, staticContext }; - if (component) - return match ? React.createElement(component, props) : null + if (component) return match ? React.createElement(component, props) : null; - if (render) - return match ? render(props) : null + if (render) return match ? render(props) : null; - if (typeof children === 'function') - return children(props) + if (typeof children === "function") return children(props); if (children && !isEmptyChildren(children)) - return React.Children.only(children) + return React.Children.only(children); - return null + return null; } } -export default Route +export default Route; diff --git a/packages/react-router/modules/Router.js b/packages/react-router/modules/Router.js index 3959d19f89..a68b44d883 100644 --- a/packages/react-router/modules/Router.js +++ b/packages/react-router/modules/Router.js @@ -1,7 +1,7 @@ -import warning from 'warning' -import invariant from 'invariant' -import React from 'react' -import PropTypes from 'prop-types' +import warning from "warning"; +import invariant from "invariant"; +import React from "react"; +import PropTypes from "prop-types"; /** * The public API for putting history on context. @@ -10,15 +10,15 @@ class Router extends React.Component { static propTypes = { history: PropTypes.object.isRequired, children: PropTypes.node - } + }; static contextTypes = { router: PropTypes.object - } + }; static childContextTypes = { router: PropTypes.object.isRequired - } + }; getChildContext() { return { @@ -30,29 +30,29 @@ class Router extends React.Component { match: this.state.match } } - } + }; } state = { match: this.computeMatch(this.props.history.location.pathname) - } + }; computeMatch(pathname) { return { - path: '/', - url: '/', + path: "/", + url: "/", params: {}, - isExact: pathname === '/' - } + isExact: pathname === "/" + }; } componentWillMount() { - const { children, history } = this.props + const { children, history } = this.props; invariant( children == null || React.Children.count(children) === 1, - 'A may have only one child element' - ) + "A may have only one child element" + ); // Do this here so we can setState when a changes the // location in componentWillMount. This happens e.g. when doing @@ -60,25 +60,25 @@ class Router extends React.Component { this.unlisten = history.listen(() => { this.setState({ match: this.computeMatch(history.location.pathname) - }) - }) + }); + }); } componentWillReceiveProps(nextProps) { warning( this.props.history === nextProps.history, - 'You cannot change ' - ) + "You cannot change " + ); } componentWillUnmount() { - this.unlisten() + this.unlisten(); } render() { - const { children } = this.props - return children ? React.Children.only(children) : null + const { children } = this.props; + return children ? React.Children.only(children) : null; } } -export default Router +export default Router; diff --git a/packages/react-router/modules/StaticRouter.js b/packages/react-router/modules/StaticRouter.js index 3d12819115..d2ac53167c 100644 --- a/packages/react-router/modules/StaticRouter.js +++ b/packages/react-router/modules/StaticRouter.js @@ -1,64 +1,59 @@ -import warning from 'warning' -import invariant from 'invariant' -import React from 'react' -import PropTypes from 'prop-types' -import { createPath, parsePath } from 'history' -import Router from './Router' +import warning from "warning"; +import invariant from "invariant"; +import React from "react"; +import PropTypes from "prop-types"; +import { createPath, parsePath } from "history"; +import Router from "./Router"; -const normalizeLocation = (object) => { - const { pathname = '/', search = '', hash = '' } = object +const normalizeLocation = object => { + const { pathname = "/", search = "", hash = "" } = object; return { pathname, - search: search === '?' ? '' : search, - hash: hash === '#' ? '' : hash - } -} + search: search === "?" ? "" : search, + hash: hash === "#" ? "" : hash + }; +}; -const addLeadingSlash = (path) => { - return path.charAt(0) === '/' ? path : '/' + path; -} +const addLeadingSlash = path => { + return path.charAt(0) === "/" ? path : "/" + path; +}; const addBasename = (basename, location) => { - if (!basename) - return location + if (!basename) return location; return { ...location, pathname: addLeadingSlash(basename) + location.pathname - } -} + }; +}; const stripBasename = (basename, location) => { - if (!basename) - return location + if (!basename) return location; - const base = addLeadingSlash(basename) + const base = addLeadingSlash(basename); - if (location.pathname.indexOf(base) !== 0) - return location + if (location.pathname.indexOf(base) !== 0) return location; return { ...location, pathname: location.pathname.substr(base.length) - } -} + }; +}; -const createLocation = (location) => - typeof location === 'string' ? parsePath(location) : normalizeLocation(location) +const createLocation = location => + typeof location === "string" + ? parsePath(location) + : normalizeLocation(location); -const createURL = (location) => - typeof location === 'string' ? location : createPath(location) +const createURL = location => + typeof location === "string" ? location : createPath(location); -const staticHandler = (methodName) => () => { - invariant( - false, - 'You cannot %s with ', - methodName - ) -} +const staticHandler = methodName => () => { + invariant(false, "You cannot %s with ", methodName); +}; -const noop = () => {} +const noop = () => {}; /** * The public top-level API for a "static" , so-called because it @@ -70,78 +65,72 @@ class StaticRouter extends React.Component { static propTypes = { basename: PropTypes.string, context: PropTypes.object.isRequired, - location: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.object - ]) - } + location: PropTypes.oneOfType([PropTypes.string, PropTypes.object]) + }; static defaultProps = { - basename: '', - location: '/' - } + basename: "", + location: "/" + }; static childContextTypes = { router: PropTypes.object.isRequired - } + }; getChildContext() { return { router: { staticContext: this.props.context } - } + }; } - createHref = (path) => - addLeadingSlash(this.props.basename + createURL(path)) + createHref = path => addLeadingSlash(this.props.basename + createURL(path)); - handlePush = (location) => { - const { basename, context } = this.props - context.action = 'PUSH' - context.location = addBasename(basename, createLocation(location)) - context.url = createURL(context.location) - } + handlePush = location => { + const { basename, context } = this.props; + context.action = "PUSH"; + context.location = addBasename(basename, createLocation(location)); + context.url = createURL(context.location); + }; - handleReplace = (location) => { - const { basename, context } = this.props - context.action = 'REPLACE' - context.location = addBasename(basename, createLocation(location)) - context.url = createURL(context.location) - } + handleReplace = location => { + const { basename, context } = this.props; + context.action = "REPLACE"; + context.location = addBasename(basename, createLocation(location)); + context.url = createURL(context.location); + }; - handleListen = () => - noop + handleListen = () => noop; - handleBlock = () => - noop + handleBlock = () => noop; componentWillMount() { warning( !this.props.history, - ' ignores the history prop. To use a custom history, ' + - 'use `import { Router }` instead of `import { StaticRouter as Router }`.' - ) + " ignores the history prop. To use a custom history, " + + "use `import { Router }` instead of `import { StaticRouter as Router }`." + ); } render() { - const { basename, context, location, ...props } = this.props + const { basename, context, location, ...props } = this.props; const history = { createHref: this.createHref, - action: 'POP', + action: "POP", location: stripBasename(basename, createLocation(location)), push: this.handlePush, replace: this.handleReplace, - go: staticHandler('go'), - goBack: staticHandler('goBack'), - goForward: staticHandler('goForward'), + go: staticHandler("go"), + goBack: staticHandler("goBack"), + goForward: staticHandler("goForward"), listen: this.handleListen, block: this.handleBlock - } + }; - return + return ; } } -export default StaticRouter +export default StaticRouter; diff --git a/packages/react-router/modules/Switch.js b/packages/react-router/modules/Switch.js index c27ed1602f..f1de5f7fc9 100644 --- a/packages/react-router/modules/Switch.js +++ b/packages/react-router/modules/Switch.js @@ -1,8 +1,8 @@ -import React from 'react' -import PropTypes from 'prop-types' -import warning from 'warning' -import invariant from 'invariant' -import matchPath from './matchPath' +import React from "react"; +import PropTypes from "prop-types"; +import warning from "warning"; +import invariant from "invariant"; +import matchPath from "./matchPath"; /** * The public API for rendering the first that matches. @@ -12,50 +12,60 @@ class Switch extends React.Component { router: PropTypes.shape({ route: PropTypes.object.isRequired }).isRequired - } + }; static propTypes = { children: PropTypes.node, location: PropTypes.object - } + }; componentWillMount() { invariant( this.context.router, - 'You should not use outside a ' - ) + "You should not use outside a " + ); } componentWillReceiveProps(nextProps) { warning( !(nextProps.location && !this.props.location), ' elements should not change from uncontrolled to controlled (or vice versa). You initially used no "location" prop and then provided one on a subsequent render.' - ) + ); warning( !(!nextProps.location && this.props.location), ' elements should not change from controlled to uncontrolled (or vice versa). You provided a "location" prop initially but omitted it on a subsequent render.' - ) + ); } render() { - const { route } = this.context.router - const { children } = this.props - const location = this.props.location || route.location + const { route } = this.context.router; + const { children } = this.props; + const location = this.props.location || route.location; - let match, child + let match, child; React.Children.forEach(children, element => { if (match == null && React.isValidElement(element)) { - const { path: pathProp, exact, strict, sensitive, from } = element.props - const path = pathProp || from + const { + path: pathProp, + exact, + strict, + sensitive, + from + } = element.props; + const path = pathProp || from; - child = element - match = path ? matchPath(location.pathname, { path, exact, strict, sensitive }) : route.match + child = element; + match = path + ? matchPath(location.pathname, { path, exact, strict, sensitive }) + : route.match; } - }) + }); - return match ? React.cloneElement(child, { location, computedMatch: match }) : null + return match + ? React.cloneElement(child, { location, computedMatch: match }) + : null; } } -export default Switch +export default Switch; diff --git a/packages/react-router/modules/__tests__/MemoryRouter-test.js b/packages/react-router/modules/__tests__/MemoryRouter-test.js index f26cfe9589..9b160fcf76 100644 --- a/packages/react-router/modules/__tests__/MemoryRouter-test.js +++ b/packages/react-router/modules/__tests__/MemoryRouter-test.js @@ -1,44 +1,43 @@ -import React from 'react' -import ReactDOM from 'react-dom' -import PropTypes from 'prop-types' -import MemoryRouter from '../MemoryRouter' - -describe('A ', () => { - it('puts history on context.router', () => { - let history +import React from "react"; +import ReactDOM from "react-dom"; +import PropTypes from "prop-types"; +import MemoryRouter from "../MemoryRouter"; + +describe("A ", () => { + it("puts history on context.router", () => { + let history; const ContextChecker = (props, context) => { - history = context.router.history - return null - } + history = context.router.history; + return null; + }; ContextChecker.contextTypes = { router: PropTypes.object.isRequired - } + }; - const node = document.createElement('div') + const node = document.createElement("div"); - ReactDOM.render(( + ReactDOM.render( - - - ), node) + + , + node + ); - expect(typeof history).toBe('object') - }) + expect(typeof history).toBe("object"); + }); - it('warns when passed a history prop', () => { - const history = {} - const node = document.createElement('div') + it("warns when passed a history prop", () => { + const history = {}; + const node = document.createElement("div"); - spyOn(console, 'error') + spyOn(console, "error"); - ReactDOM.render(( - - ), node) + ReactDOM.render(, node); - expect(console.error).toHaveBeenCalledTimes(1) + expect(console.error).toHaveBeenCalledTimes(1); expect(console.error).toHaveBeenCalledWith( - expect.stringContaining(' ignores the history prop') - ) - }) -}) + expect.stringContaining(" ignores the history prop") + ); + }); +}); diff --git a/packages/react-router/modules/__tests__/Redirect-test.js b/packages/react-router/modules/__tests__/Redirect-test.js index 2b6ef76ae4..d29aa70e3d 100644 --- a/packages/react-router/modules/__tests__/Redirect-test.js +++ b/packages/react-router/modules/__tests__/Redirect-test.js @@ -1,36 +1,40 @@ -import React from 'react' -import ReactDOM from 'react-dom' -import MemoryRouter from '../MemoryRouter' -import Redirect from '../Redirect' -import Route from '../Route' -import Switch from '../Switch' +import React from "react"; +import ReactDOM from "react-dom"; +import MemoryRouter from "../MemoryRouter"; +import Redirect from "../Redirect"; +import Route from "../Route"; +import Switch from "../Switch"; -describe('A ', () => { - describe('inside a ', () => { - it('automatically interpolates params', () => { - const node = document.createElement('div') +describe("A ", () => { + describe("inside a ", () => { + it("automatically interpolates params", () => { + const node = document.createElement("div"); - let params + let params; - ReactDOM.render(( - + ReactDOM.render( + - { - params = match.params - return null - }}/> + { + params = match.params; + return null; + }} + /> - - ), node) + , + node + ); expect(params).toMatchObject({ - username: 'mjackson', - messageId: '123' - }) - }) - }) -}) + username: "mjackson", + messageId: "123" + }); + }); + }); +}); diff --git a/packages/react-router/modules/__tests__/Route-test.js b/packages/react-router/modules/__tests__/Route-test.js index f5943fef78..eabf2a6804 100644 --- a/packages/react-router/modules/__tests__/Route-test.js +++ b/packages/react-router/modules/__tests__/Route-test.js @@ -1,382 +1,390 @@ -import React from 'react' -import ReactDOM from 'react-dom' -import { createMemoryHistory } from 'history' -import MemoryRouter from '../MemoryRouter' -import Router from '../Router' -import Route from '../Route' - -describe('A ', () => { - it('renders at the root', () => { - const TEXT = 'Mrs. Kato' - const node = document.createElement('div') - - ReactDOM.render(( - - ( -

{TEXT}

- )}/> -
- ), node) - - expect(node.innerHTML).toContain(TEXT) - }) - - it('does not render when it does not match', () => { - const TEXT = 'bubblegum' - const node = document.createElement('div') - - ReactDOM.render(( - - ( -

{TEXT}

- )}/> -
- ), node) - - expect(node.innerHTML).not.toContain(TEXT) - }) - - it('can use a `location` prop instead of `context.router.route.location`', () => { - const TEXT = 'tamarind chutney' - const node = document.createElement('div') - - ReactDOM.render(( - +import React from "react"; +import ReactDOM from "react-dom"; +import { createMemoryHistory } from "history"; +import MemoryRouter from "../MemoryRouter"; +import Router from "../Router"; +import Route from "../Route"; + +describe("A ", () => { + it("renders at the root", () => { + const TEXT = "Mrs. Kato"; + const node = document.createElement("div"); + + ReactDOM.render( + +

{TEXT}

} /> +
, + node + ); + + expect(node.innerHTML).toContain(TEXT); + }); + + it("does not render when it does not match", () => { + const TEXT = "bubblegum"; + const node = document.createElement("div"); + + ReactDOM.render( + +

{TEXT}

} /> +
, + node + ); + + expect(node.innerHTML).not.toContain(TEXT); + }); + + it("can use a `location` prop instead of `context.router.route.location`", () => { + const TEXT = "tamarind chutney"; + const node = document.createElement("div"); + + ReactDOM.render( + ( -

{TEXT}

- )} + render={() =>

{TEXT}

} /> -
- ), node) +
, + node + ); - expect(node.innerHTML).toContain(TEXT) - }) + expect(node.innerHTML).toContain(TEXT); + }); - it('supports preact by nulling out children prop when empty array is passed', () => { - const TEXT = 'Mrs. Kato' - const node = document.createElement('div') + it("supports preact by nulling out children prop when empty array is passed", () => { + const TEXT = "Mrs. Kato"; + const node = document.createElement("div"); - ReactDOM.render(( - - ( -

{TEXT}

- )}> + ReactDOM.render( + +

{TEXT}

}> {[]}
-
- ), node) - - expect(node.innerHTML).toContain(TEXT) - }) - - it('matches using nextContext when updating', () => { - const node = document.createElement('div') - - let push - ReactDOM.render(( - - { - push = history.push - return
{match.url}
- }}/> -
- ), node) - push('/sushi/spicy-tuna') - expect(node.innerHTML).toContain('/sushi/spicy-tuna') - }) - - it('throws with no ', () => { - const node = document.createElement('div') - - spyOn(console, 'error') +
, + node + ); + + expect(node.innerHTML).toContain(TEXT); + }); + + it("matches using nextContext when updating", () => { + const node = document.createElement("div"); + + let push; + ReactDOM.render( + + { + push = history.push; + return
{match.url}
; + }} + /> +
, + node + ); + push("/sushi/spicy-tuna"); + expect(node.innerHTML).toContain("/sushi/spicy-tuna"); + }); + + it("throws with no ", () => { + const node = document.createElement("div"); + + spyOn(console, "error"); expect(() => { - ReactDOM.render(( - null} /> - ), node) - }).toThrow(/You should not use or withRouter\(\) outside a /) - }) -}) - -describe('A with dynamic segments in the path', () => { - it('decodes them', () => { - const node = document.createElement('div') - ReactDOM.render(( - -
{match.params.id}
} /> -
- ), node) - - expect(node.innerHTML).toContain('a dynamic segment') - }) -}) - -describe('A unicode ', () => { - it('is able to match', () => { - const node = document.createElement('div') - ReactDOM.render(( - + ReactDOM.render( null} />, node); + }).toThrow( + /You should not use or withRouter\(\) outside a / + ); + }); +}); + +describe("A with dynamic segments in the path", () => { + it("decodes them", () => { + const node = document.createElement("div"); + ReactDOM.render( + +
{match.params.id}
} + /> +
, + node + ); + + expect(node.innerHTML).toContain("a dynamic segment"); + }); +}); + +describe("A unicode ", () => { + it("is able to match", () => { + const node = document.createElement("div"); + ReactDOM.render( +
{match.url}
} /> -
- ), node) +
, + node + ); - expect(node.innerHTML).toContain('/パス名') - }) -}) + expect(node.innerHTML).toContain("/パス名"); + }); +}); -describe('', () => { - const history = createMemoryHistory() - const node = document.createElement('div') +describe("", () => { + const history = createMemoryHistory(); + const node = document.createElement("div"); afterEach(() => { - ReactDOM.unmountComponentAtNode(node) - }) - - it('renders its return value', () => { - const TEXT = 'Mrs. Kato' - const node = document.createElement('div') - ReactDOM.render(( - + ReactDOM.unmountComponentAtNode(node); + }); + + it("renders its return value", () => { + const TEXT = "Mrs. Kato"; + const node = document.createElement("div"); + ReactDOM.render( +
{TEXT}
} /> -
- ), node) +
, + node + ); - expect(node.innerHTML).toContain(TEXT) - }) + expect(node.innerHTML).toContain(TEXT); + }); - it('receives { match, location, history } props', () => { - let actual = null + it("receives { match, location, history } props", () => { + let actual = null; - ReactDOM.render(( + ReactDOM.render( - (actual = props) && null}/> - - ), node) + (actual = props) && null} /> +
, + node + ); - expect(actual.history).toBe(history) - expect(typeof actual.match).toBe('object') - expect(typeof actual.location).toBe('object') - }) -}) + expect(actual.history).toBe(history); + expect(typeof actual.match).toBe("object"); + expect(typeof actual.location).toBe("object"); + }); +}); -describe('', () => { - const history = createMemoryHistory() - const node = document.createElement('div') +describe("", () => { + const history = createMemoryHistory(); + const node = document.createElement("div"); afterEach(() => { - ReactDOM.unmountComponentAtNode(node) - }) - - it('renders the component', () => { - const TEXT = 'Mrs. Kato' - const node = document.createElement('div') - const Home = () =>
{TEXT}
- ReactDOM.render(( - + ReactDOM.unmountComponentAtNode(node); + }); + + it("renders the component", () => { + const TEXT = "Mrs. Kato"; + const node = document.createElement("div"); + const Home = () =>
{TEXT}
; + ReactDOM.render( + - - ), node) +
, + node + ); - expect(node.innerHTML).toContain(TEXT) - }) + expect(node.innerHTML).toContain(TEXT); + }); - it('receives { match, location, history } props', () => { - let actual = null - const Component = (props) => (actual = props) && null + it("receives { match, location, history } props", () => { + let actual = null; + const Component = props => (actual = props) && null; - ReactDOM.render(( + ReactDOM.render( - - - ), node) + +
, + node + ); - expect(actual.history).toBe(history) - expect(typeof actual.match).toBe('object') - expect(typeof actual.location).toBe('object') - }) -}) + expect(actual.history).toBe(history); + expect(typeof actual.match).toBe("object"); + expect(typeof actual.location).toBe("object"); + }); +}); -describe('', () => { - const history = createMemoryHistory() - const node = document.createElement('div') +describe("", () => { + const history = createMemoryHistory(); + const node = document.createElement("div"); afterEach(() => { - ReactDOM.unmountComponentAtNode(node) - }) - - it('renders a function', () => { - const TEXT = 'Mrs. Kato' - const node = document.createElement('div') - ReactDOM.render(( - + ReactDOM.unmountComponentAtNode(node); + }); + + it("renders a function", () => { + const TEXT = "Mrs. Kato"; + const node = document.createElement("div"); + ReactDOM.render( +
{TEXT}
} /> -
- ), node) - - expect(node.innerHTML).toContain(TEXT) - }) - - it('renders a child element', () => { - const TEXT = 'Mrs. Kato' - const node = document.createElement('div') - ReactDOM.render(( - + , + node + ); + + expect(node.innerHTML).toContain(TEXT); + }); + + it("renders a child element", () => { + const TEXT = "Mrs. Kato"; + const node = document.createElement("div"); + ReactDOM.render( +
{TEXT}
-
- ), node) +
, + node + ); - expect(node.innerHTML).toContain(TEXT) - }) + expect(node.innerHTML).toContain(TEXT); + }); - it('receives { match, location, history } props', () => { - let actual = null + it("receives { match, location, history } props", () => { + let actual = null; - ReactDOM.render(( + ReactDOM.render( - (actual = props) && null}/> - - ), node) - - expect(actual.history).toBe(history) - expect(typeof actual.match).toBe('object') - expect(typeof actual.location).toBe('object') - }) -}) - -describe('A ', () => { - it('renders when the URL does not have a trailing slash', () => { - const TEXT = 'bubblegum' - const node = document.createElement('div') - - ReactDOM.render(( - - ( -

{TEXT}

- )}/> -
- ), node) - - expect(node.innerHTML).toContain(TEXT) - }) - - it('renders when the URL has trailing slash', () => { - const TEXT = 'bubblegum' - const node = document.createElement('div') - - ReactDOM.render(( - - ( -

{TEXT}

- )}/> -
- ), node) - - expect(node.innerHTML).toContain(TEXT) - }) -}) - -describe('A ', () => { - it('does not render when the URL has a trailing slash', () => { - const TEXT = 'bubblegum' - const node = document.createElement('div') - - ReactDOM.render(( - - ( -

{TEXT}

- )}/> -
- ), node) - - expect(node.innerHTML).not.toContain(TEXT) - }) - - it('does not render when the URL does not have a trailing slash', () => { - const TEXT = 'bubblegum' - const node = document.createElement('div') - - ReactDOM.render(( - - ( -

{TEXT}

- )}/> -
- ), node) - - expect(node.innerHTML).not.toContain(TEXT) - }) -}) - -describe('A ', () => { - it('can use a `location` prop instead of `router.location`', () => { - const TEXT = 'tamarind chutney' - const node = document.createElement('div') - - ReactDOM.render(( - + (actual = props) && null} /> +
, + node + ); + + expect(actual.history).toBe(history); + expect(typeof actual.match).toBe("object"); + expect(typeof actual.location).toBe("object"); + }); +}); + +describe("A ", () => { + it("renders when the URL does not have a trailing slash", () => { + const TEXT = "bubblegum"; + const node = document.createElement("div"); + + ReactDOM.render( + +

{TEXT}

} /> +
, + node + ); + + expect(node.innerHTML).toContain(TEXT); + }); + + it("renders when the URL has trailing slash", () => { + const TEXT = "bubblegum"; + const node = document.createElement("div"); + + ReactDOM.render( + +

{TEXT}

} /> +
, + node + ); + + expect(node.innerHTML).toContain(TEXT); + }); +}); + +describe("A ", () => { + it("does not render when the URL has a trailing slash", () => { + const TEXT = "bubblegum"; + const node = document.createElement("div"); + + ReactDOM.render( + +

{TEXT}

} /> +
, + node + ); + + expect(node.innerHTML).not.toContain(TEXT); + }); + + it("does not render when the URL does not have a trailing slash", () => { + const TEXT = "bubblegum"; + const node = document.createElement("div"); + + ReactDOM.render( + +

{TEXT}

} /> +
, + node + ); + + expect(node.innerHTML).not.toContain(TEXT); + }); +}); + +describe("A ", () => { + it("can use a `location` prop instead of `router.location`", () => { + const TEXT = "tamarind chutney"; + const node = document.createElement("div"); + + ReactDOM.render( + ( -

{TEXT}

- )} + render={() =>

{TEXT}

} /> -
- ), node) +
, + node + ); - expect(node.innerHTML).toContain(TEXT) - }) + expect(node.innerHTML).toContain(TEXT); + }); - describe('children', () => { - it('uses parent\'s prop location', () => { - const TEXT = 'cheddar pretzel' - const node = document.createElement('div') + describe("children", () => { + it("uses parent's prop location", () => { + const TEXT = "cheddar pretzel"; + const node = document.createElement("div"); - ReactDOM.render(( - + ReactDOM.render( + ( - ( -

{TEXT}

- )} /> +

{TEXT}

} /> )} /> -
- ), node) - - expect(node.innerHTML).toContain(TEXT) - }) - - it('continues to use parent\'s prop location after navigation', () => { - const TEXT = 'cheddar pretzel' - const node = document.createElement('div') - let push - ReactDOM.render(( - + , + node + ); + + expect(node.innerHTML).toContain(TEXT); + }); + + it("continues to use parent's prop location after navigation", () => { + const TEXT = "cheddar pretzel"; + const node = document.createElement("div"); + let push; + ReactDOM.render( + { - push = history.push + push = history.push; return ( - ( -

{TEXT}

- )} /> - ) +

{TEXT}

} + /> + ); }} /> -
- ), node) - expect(node.innerHTML).toContain(TEXT) - push('/chips') - expect(node.innerHTML).toContain(TEXT) - }) - }) -}) +
, + node + ); + expect(node.innerHTML).toContain(TEXT); + push("/chips"); + expect(node.innerHTML).toContain(TEXT); + }); + }); +}); diff --git a/packages/react-router/modules/__tests__/Router-test.js b/packages/react-router/modules/__tests__/Router-test.js index 9b4a715f82..23ed306f2c 100644 --- a/packages/react-router/modules/__tests__/Router-test.js +++ b/packages/react-router/modules/__tests__/Router-test.js @@ -1,20 +1,20 @@ -import React from 'react' -import ReactDOM from 'react-dom' -import PropTypes from 'prop-types' -import Router from '../Router' -import { createMemoryHistory as createHistory } from 'history' +import React from "react"; +import ReactDOM from "react-dom"; +import PropTypes from "prop-types"; +import Router from "../Router"; +import { createMemoryHistory as createHistory } from "history"; -describe('A ', () => { - const node = document.createElement('div') +describe("A ", () => { + const node = document.createElement("div"); afterEach(() => { - ReactDOM.unmountComponentAtNode(node) - }) + ReactDOM.unmountComponentAtNode(node); + }); + + describe("when it has more than one child", () => { + it("throws an error explaining a Router may have only one child", () => { + spyOn(console, "error"); - describe('when it has more than one child', () => { - it('throws an error explaining a Router may have only one child', () => { - spyOn(console, 'error') - expect(() => { ReactDOM.render( @@ -22,117 +22,114 @@ describe('A ', () => {

Bar

, node - ) - }).toThrow(/A may have only one child element/) - }) - }) + ); + }).toThrow(/A may have only one child element/); + }); + }); - describe('with exactly one child', () => { - it('does not throw an error', () => { + describe("with exactly one child", () => { + it("does not throw an error", () => { expect(() => { ReactDOM.render(

Bar

, node - ) - }).not.toThrow() - }) - }) + ); + }).not.toThrow(); + }); + }); - describe('with no children', () => { - it('does not throw an error', () => { + describe("with no children", () => { + it("does not throw an error", () => { expect(() => { - ReactDOM.render( - , - node - ) - }).not.toThrow() - }) - }) + ReactDOM.render(, node); + }).not.toThrow(); + }); + }); - describe('context', () => { - let rootContext + describe("context", () => { + let rootContext; const ContextChecker = (props, context) => { - rootContext = context - return null - } + rootContext = context; + return null; + }; ContextChecker.contextTypes = { router: PropTypes.shape({ history: PropTypes.object, route: PropTypes.object }) - } + }; afterEach(() => { - rootContext = undefined - }) + rootContext = undefined; + }); - it('puts history on context.history', () => { - const history = createHistory() + it("puts history on context.history", () => { + const history = createHistory(); ReactDOM.render( , node - ) + ); - expect(rootContext.router.history).toBe(history) - }) + expect(rootContext.router.history).toBe(history); + }); - it('sets context.router.route at the root', () => { + it("sets context.router.route at the root", () => { const history = createHistory({ - initialEntries: ['/'] - }) + initialEntries: ["/"] + }); ReactDOM.render( - + , node - ) + ); - expect(rootContext.router.route.match.path).toEqual('/') - expect(rootContext.router.route.match.url).toEqual('/') - expect(rootContext.router.route.match.params).toEqual({}) - expect(rootContext.router.route.match.isExact).toEqual(true) - expect(rootContext.router.route.location).toEqual(history.location) - }) + expect(rootContext.router.route.match.path).toEqual("/"); + expect(rootContext.router.route.match.url).toEqual("/"); + expect(rootContext.router.route.match.params).toEqual({}); + expect(rootContext.router.route.match.isExact).toEqual(true); + expect(rootContext.router.route.location).toEqual(history.location); + }); - it('updates context.router.route upon navigation', () => { + it("updates context.router.route upon navigation", () => { const history = createHistory({ - initialEntries: [ '/' ] - }) + initialEntries: ["/"] + }); ReactDOM.render( , node - ) + ); - expect(rootContext.router.route.match.isExact).toBe(true) + expect(rootContext.router.route.match.isExact).toBe(true); - const newLocation = { pathname: '/new' } - history.push(newLocation) + const newLocation = { pathname: "/new" }; + history.push(newLocation); - expect(rootContext.router.route.match.isExact).toBe(false) - }) + expect(rootContext.router.route.match.isExact).toBe(false); + }); - it('does not contain context.router.staticContext by default', () => { + it("does not contain context.router.staticContext by default", () => { const history = createHistory({ - initialEntries: [ '/' ] - }) + initialEntries: ["/"] + }); ReactDOM.render( , node - ) + ); - expect(rootContext.router.staticContext).toBe(undefined) - }) - }) -}) + expect(rootContext.router.staticContext).toBe(undefined); + }); + }); +}); diff --git a/packages/react-router/modules/__tests__/StaticRouter-test.js b/packages/react-router/modules/__tests__/StaticRouter-test.js index 952b57541b..ad6f7b6bed 100644 --- a/packages/react-router/modules/__tests__/StaticRouter-test.js +++ b/packages/react-router/modules/__tests__/StaticRouter-test.js @@ -1,231 +1,236 @@ -import React from 'react' -import ReactDOM from 'react-dom' -import ReactDOMServer from 'react-dom/server' -import PropTypes from 'prop-types' -import StaticRouter from '../StaticRouter' -import Redirect from '../Redirect' -import Route from '../Route' -import Prompt from '../Prompt' - -describe('A ', () => { - it('provides context.router.staticContext in props.staticContext', () => { +import React from "react"; +import ReactDOM from "react-dom"; +import ReactDOMServer from "react-dom/server"; +import PropTypes from "prop-types"; +import StaticRouter from "../StaticRouter"; +import Redirect from "../Redirect"; +import Route from "../Route"; +import Prompt from "../Prompt"; + +describe("A ", () => { + it("provides context.router.staticContext in props.staticContext", () => { const ContextChecker = (props, reactContext) => { - expect(typeof reactContext.router).toBe('object') - expect(reactContext.router.staticContext).toBe(props.staticContext) - return null - } + expect(typeof reactContext.router).toBe("object"); + expect(reactContext.router.staticContext).toBe(props.staticContext); + return null; + }; ContextChecker.contextTypes = { router: PropTypes.object.isRequired - } + }; - const context = {} + const context = {}; ReactDOMServer.renderToStaticMarkup( - + - ) - }) + ); + }); - it('context.router.staticContext persists inside of a ', () => { + it("context.router.staticContext persists inside of a ", () => { const ContextChecker = (props, reactContext) => { - expect(typeof reactContext.router).toBe('object') - expect(reactContext.router.staticContext).toBe(context) - return null - } + expect(typeof reactContext.router).toBe("object"); + expect(reactContext.router.staticContext).toBe(context); + return null; + }; ContextChecker.contextTypes = { router: PropTypes.object.isRequired - } + }; - const context = {} + const context = {}; ReactDOMServer.renderToStaticMarkup( - + - ) - }) + ); + }); - it('provides context.router.history', () => { + it("provides context.router.history", () => { const ContextChecker = (props, reactContext) => { - expect(typeof reactContext.router.history).toBe('object') - return null - } + expect(typeof reactContext.router.history).toBe("object"); + return null; + }; ContextChecker.contextTypes = { router: PropTypes.object.isRequired - } + }; - const context = {} + const context = {}; ReactDOMServer.renderToStaticMarkup( - + - ) - }) + ); + }); - it('warns when passed a history prop', () => { - const context = {} - const history = {} - const node = document.createElement('div') + it("warns when passed a history prop", () => { + const context = {}; + const history = {}; + const node = document.createElement("div"); - spyOn(console, 'error') + spyOn(console, "error"); - ReactDOM.render(( - - ), node) + ReactDOM.render(, node); - expect(console.error).toHaveBeenCalledTimes(1) + expect(console.error).toHaveBeenCalledTimes(1); expect(console.error).toHaveBeenCalledWith( - expect.stringContaining(' ignores the history prop') - ) - }) + expect.stringContaining(" ignores the history prop") + ); + }); - it('reports PUSH actions on the context object', () => { - const context = {} + it("reports PUSH actions on the context object", () => { + const context = {}; ReactDOMServer.renderToStaticMarkup( - + - ) + ); - expect(context.action).toBe('PUSH') - expect(context.url).toBe('/somewhere-else') - }) + expect(context.action).toBe("PUSH"); + expect(context.url).toBe("/somewhere-else"); + }); - it('reports REPLACE actions on the context object', () => { - const context = {} + it("reports REPLACE actions on the context object", () => { + const context = {}; ReactDOMServer.renderToStaticMarkup( - + - ) + ); - expect(context.action).toBe('REPLACE') - expect(context.url).toBe('/somewhere-else') - }) + expect(context.action).toBe("REPLACE"); + expect(context.url).toBe("/somewhere-else"); + }); - it('knows how to serialize location objects', () => { - const context = {} + it("knows how to serialize location objects", () => { + const context = {}; ReactDOMServer.renderToStaticMarkup( - + - ) + ); - expect(context.action).toBe('REPLACE') - expect(context.location.pathname).toBe('/somewhere-else') - expect(context.location.search).toBe('') - expect(context.location.hash).toBe('') - expect(context.url).toBe('/somewhere-else') - }) + expect(context.action).toBe("REPLACE"); + expect(context.location.pathname).toBe("/somewhere-else"); + expect(context.location.search).toBe(""); + expect(context.location.hash).toBe(""); + expect(context.url).toBe("/somewhere-else"); + }); - it('knows how to parse raw URLs', () => { - const LocationChecker = (props) => { + it("knows how to parse raw URLs", () => { + const LocationChecker = props => { expect(props.location).toMatchObject({ - pathname: '/the/path', - search: '?the=query', - hash: '#the-hash' - }) - return null - } + pathname: "/the/path", + search: "?the=query", + hash: "#the-hash" + }); + return null; + }; - const context = {} + const context = {}; ReactDOMServer.renderToStaticMarkup( - + - ) - }) + ); + }); - describe('with a basename', () => { - it('strips the basename from location pathnames', () => { - const LocationChecker = (props) => { + describe("with a basename", () => { + it("strips the basename from location pathnames", () => { + const LocationChecker = props => { expect(props.location).toMatchObject({ - pathname: '/path' - }) - return null - } + pathname: "/path" + }); + return null; + }; - const context = {} + const context = {}; ReactDOMServer.renderToStaticMarkup( - - + + - ) - }) + ); + }); - it('reports PUSH actions on the context object', () => { - const context = {} + it("reports PUSH actions on the context object", () => { + const context = {}; ReactDOMServer.renderToStaticMarkup( - + - ) + ); - expect(context.action).toBe('PUSH') - expect(context.url).toBe('/the-base/somewhere-else') - }) + expect(context.action).toBe("PUSH"); + expect(context.url).toBe("/the-base/somewhere-else"); + }); - it('reports REPLACE actions on the context object', () => { - const context = {} + it("reports REPLACE actions on the context object", () => { + const context = {}; ReactDOMServer.renderToStaticMarkup( - + - ) + ); - expect(context.action).toBe('REPLACE') - expect(context.url).toBe('/the-base/somewhere-else') - }) - }) + expect(context.action).toBe("REPLACE"); + expect(context.url).toBe("/the-base/somewhere-else"); + }); + }); - describe('no basename', () => { - it('createHref does not append extra leading slash', () => { - const context = {} - const node = document.createElement('div') - const pathname = '/test-path-please-ignore' + describe("no basename", () => { + it("createHref does not append extra leading slash", () => { + const context = {}; + const node = document.createElement("div"); + const pathname = "/test-path-please-ignore"; const Link = ({ to, children }) => ( - ( -
{children} - )} /> - ) - - ReactDOM.render(( + ( + {children} + )} + /> + ); + + ReactDOM.render( - - ), node) +
, + node + ); - const a = node.getElementsByTagName('a')[0] - expect(a.getAttribute('href')).toEqual(pathname) - }) - }) + const a = node.getElementsByTagName("a")[0]; + expect(a.getAttribute("href")).toEqual(pathname); + }); + }); - describe('render a ', () => { - it('does nothing', () => { - const context = {} - const node = document.createElement('div') + describe("render a ", () => { + it("does nothing", () => { + const context = {}; + const node = document.createElement("div"); expect(() => { - ReactDOM.render(( + ReactDOM.render( - - - ), node) - }).not.toThrow() - }) - }) - -}) + +
, + node + ); + }).not.toThrow(); + }); + }); +}); diff --git a/packages/react-router/modules/__tests__/Switch-test.js b/packages/react-router/modules/__tests__/Switch-test.js index 13406cbc2b..4c45ff466a 100644 --- a/packages/react-router/modules/__tests__/Switch-test.js +++ b/packages/react-router/modules/__tests__/Switch-test.js @@ -1,341 +1,347 @@ -import React from 'react' -import ReactDOM from 'react-dom' -import MemoryRouter from '../MemoryRouter' -import Switch from '../Switch' -import Route from '../Route' -import Redirect from '../Redirect' - -describe('A ', () => { - it('renders the first that matches the URL', () => { - const node = document.createElement('div') - - ReactDOM.render(( - +import React from "react"; +import ReactDOM from "react-dom"; +import MemoryRouter from "../MemoryRouter"; +import Switch from "../Switch"; +import Route from "../Route"; +import Redirect from "../Redirect"; + +describe("A ", () => { + it("renders the first that matches the URL", () => { + const node = document.createElement("div"); + + ReactDOM.render( + - ( -

one

- )}/> - ( -

two

- )}/> +

one

} /> +

two

} />
-
- ), node) +
, + node + ); - expect(node.innerHTML).toMatch(/one/) - }) + expect(node.innerHTML).toMatch(/one/); + }); - it('renders the first that matches the URL', () => { - const node = document.createElement('div') + it("renders the first that matches the URL", () => { + const node = document.createElement("div"); - ReactDOM.render(( - + ReactDOM.render( + - ( -

one

- )}/> - - - ( -

two

- )}/> +

one

} /> + + +

two

} />
-
- ), node) +
, + node + ); - expect(node.innerHTML).toMatch(/two/) - }) + expect(node.innerHTML).toMatch(/two/); + }); - it('does not render a second or that also matches the URL', () => { - const node = document.createElement('div') + it("does not render a second or that also matches the URL", () => { + const node = document.createElement("div"); - ReactDOM.render(( - + ReactDOM.render( + - ( -

one

- )}/> - - ( -

two

- )}/> - ( -

two

- )}/> +

one

} /> + +

two

} /> +

two

} />
-
- ), node) +
, + node + ); - expect(node.innerHTML).not.toMatch(/two/) - }) + expect(node.innerHTML).not.toMatch(/two/); + }); - it('renders pathless Routes', () => { - const node = document.createElement('div') + it("renders pathless Routes", () => { + const node = document.createElement("div"); - ReactDOM.render(( - + ReactDOM.render( + -
one
}/> -
two
}/> +
one
} /> +
two
} />
-
- ), node) +
, + node + ); - expect(node.innerHTML).not.toContain('one') - expect(node.innerHTML).toContain('two') - }) + expect(node.innerHTML).not.toContain("one"); + expect(node.innerHTML).toContain("two"); + }); - it('handles from-less Redirects', () => { - const node = document.createElement('div') + it("handles from-less Redirects", () => { + const node = document.createElement("div"); - ReactDOM.render(( - + ReactDOM.render( + -
bub
}/> - -
cup
}/> +
bub
} /> + +
cup
} />
-
- ), node) +
, + node + ); - expect(node.innerHTML).not.toContain('cup') - expect(node.innerHTML).toContain('bub') - }) + expect(node.innerHTML).not.toContain("cup"); + expect(node.innerHTML).toContain("bub"); + }); - it('handles subsequent redirects', () => { - const node = document.createElement('div') + it("handles subsequent redirects", () => { + const node = document.createElement("div"); - ReactDOM.render(( - + ReactDOM.render( + - - + + -
three
}/> +
three
} />
-
- ), node) +
, + node + ); - expect(node.innerHTML).toContain('three') - }) + expect(node.innerHTML).toContain("three"); + }); - it('warns when redirecting to same route, both strings', () => { - const node = document.createElement('div') - let redirected = false - let done = false + it("warns when redirecting to same route, both strings", () => { + const node = document.createElement("div"); + let redirected = false; + let done = false; - spyOn(console, 'error') + spyOn(console, "error"); - ReactDOM.render(( - + ReactDOM.render( + - { - if (done) - return

done

- - if (!redirected) { - return - } - done = true - - return - }}/> + { + if (done) return

done

; + + if (!redirected) { + return ; + } + done = true; + + return ; + }} + />
-
- ), node) +
, + node + ); - expect(node.innerHTML).not.toContain('done') - expect(console.error.calls.count()).toBe(1) - expect(console.error.calls.argsFor(0)[0]).toMatch(/Warning:.*"\/one"/) - }) + expect(node.innerHTML).not.toContain("done"); + expect(console.error.calls.count()).toBe(1); + expect(console.error.calls.argsFor(0)[0]).toMatch(/Warning:.*"\/one"/); + }); - it('warns when redirecting to same route, mixed types', () => { - const node = document.createElement('div') - let redirected = false - let done = false + it("warns when redirecting to same route, mixed types", () => { + const node = document.createElement("div"); + let redirected = false; + let done = false; - spyOn(console, 'error') + spyOn(console, "error"); - ReactDOM.render(( - + ReactDOM.render( + - { - if (done) - return

done

- - if (!redirected) { - redirected = true - return - } - done = true - - return - }}/> + { + if (done) return

done

; + + if (!redirected) { + redirected = true; + return ; + } + done = true; + + return ; + }} + />
-
- ), node) +
, + node + ); - expect(node.innerHTML).not.toContain('done') - expect(console.error.calls.count()).toBe(1) - expect(console.error.calls.argsFor(0)[0]).toMatch(/Warning:.*"\/one"/) - }) + expect(node.innerHTML).not.toContain("done"); + expect(console.error.calls.count()).toBe(1); + expect(console.error.calls.argsFor(0)[0]).toMatch(/Warning:.*"\/one"/); + }); - it('warns when redirecting to same route, mixed types, string with query', () => { - const node = document.createElement('div') - let redirected = false - let done = false + it("warns when redirecting to same route, mixed types, string with query", () => { + const node = document.createElement("div"); + let redirected = false; + let done = false; - spyOn(console, 'error') + spyOn(console, "error"); - ReactDOM.render(( - + ReactDOM.render( + - { - if (done) - return

done

- - if (!redirected) { - redirected = true - return - } - done = true - - return - }}/> + { + if (done) return

done

; + + if (!redirected) { + redirected = true; + return ; + } + done = true; + + return ; + }} + />
-
- ), node) - - expect(node.innerHTML).not.toContain('done') - expect(console.error.calls.count()).toBe(1) - expect(console.error.calls.argsFor(0)[0]).toMatch(/Warning:.*"\/one\?utm=1"/) - }) - - it('does NOT warn when redirecting to same route with different `search`', () => { - const node = document.createElement('div') - let redirected = false - let done = false - - spyOn(console, 'error') - - ReactDOM.render(( - + , + node + ); + + expect(node.innerHTML).not.toContain("done"); + expect(console.error.calls.count()).toBe(1); + expect(console.error.calls.argsFor(0)[0]).toMatch( + /Warning:.*"\/one\?utm=1"/ + ); + }); + + it("does NOT warn when redirecting to same route with different `search`", () => { + const node = document.createElement("div"); + let redirected = false; + let done = false; + + spyOn(console, "error"); + + ReactDOM.render( + - { - if (done) - return

done

- - if (!redirected) { - redirected = true - return - } - done = true - - return - }}/> + { + if (done) return

done

; + + if (!redirected) { + redirected = true; + return ; + } + done = true; + + return ; + }} + />
-
- ), node) +
, + node + ); - expect(node.innerHTML).toContain('done') - expect(console.error.calls.count()).toBe(0) - }) + expect(node.innerHTML).toContain("done"); + expect(console.error.calls.count()).toBe(0); + }); - it('handles comments', () => { - const node = document.createElement('div') + it("handles comments", () => { + const node = document.createElement("div"); - ReactDOM.render(( - + ReactDOM.render( + -
bub
}/> +
bub
} /> {/* this is a comment */} -
cup
}/> +
cup
} />
-
- ), node) +
, + node + ); - expect(node.innerHTML).not.toContain('bub') - expect(node.innerHTML).toContain('cup') - }) + expect(node.innerHTML).not.toContain("bub"); + expect(node.innerHTML).toContain("cup"); + }); - it('renders with non-element children', () => { - const node = document.createElement('div') + it("renders with non-element children", () => { + const node = document.createElement("div"); - ReactDOM.render(( - + ReactDOM.render( + - (

one

)}/> +

one

} /> {false} {undefined}
-
- ), node) +
, + node + ); - expect(node.innerHTML).toMatch(/one/) - }) + expect(node.innerHTML).toMatch(/one/); + }); - it('throws with no ', () => { - const node = document.createElement('div') + it("throws with no ", () => { + const node = document.createElement("div"); - spyOn(console, 'error') + spyOn(console, "error"); expect(() => { - ReactDOM.render(( + ReactDOM.render( - ( -

one

- )}/> - ( -

two

- )}/> -
- ), node) - }).toThrow(/You should not use outside a /) - - expect(console.error.calls.count()).toBe(2) +

one

} /> +

two

} /> +
, + node + ); + }).toThrow(/You should not use outside a /); + + expect(console.error.calls.count()).toBe(2); expect(console.error.calls.argsFor(0)[0]).toContain( - 'The context `router` is marked as required in `Switch`' - ) - }) -}) - - -describe('A ', () => { - it('can use a `location` prop instead of `router.location`', () => { - const node = document.createElement('div') - - ReactDOM.render(( - - -

one

}/> -

two

}/> + "The context `router` is marked as required in `Switch`" + ); + }); +}); + +describe("A ", () => { + it("can use a `location` prop instead of `router.location`", () => { + const node = document.createElement("div"); + + ReactDOM.render( + + +

one

} /> +

two

} />
-
- ), node) - - expect(node.innerHTML).toMatch(/two/) - }) - - describe('children', () => { - it('passes location prop to matched ', () => { - const node = document.createElement('div') - - let propLocation - const RouteHoneytrap = (props) => { - propLocation = props.location - return - } - - const switchLocation = { pathname: '/two' } - ReactDOM.render(( - + , + node + ); + + expect(node.innerHTML).toMatch(/two/); + }); + + describe("children", () => { + it("passes location prop to matched ", () => { + const node = document.createElement("div"); + + let propLocation; + const RouteHoneytrap = props => { + propLocation = props.location; + return ; + }; + + const switchLocation = { pathname: "/two" }; + ReactDOM.render( + -

one

}/> -

two

}/> +

one

} /> +

two

} />
-
- ), node) - expect(propLocation).toEqual(switchLocation) - }) - }) -}) +
, + node + ); + expect(propLocation).toEqual(switchLocation); + }); + }); +}); diff --git a/packages/react-router/modules/__tests__/SwitchMount-test.js b/packages/react-router/modules/__tests__/SwitchMount-test.js index 1e4cba2ad6..fa19bcf806 100644 --- a/packages/react-router/modules/__tests__/SwitchMount-test.js +++ b/packages/react-router/modules/__tests__/SwitchMount-test.js @@ -1,45 +1,46 @@ -import React from 'react' -import ReactDOM from 'react-dom' -import { createMemoryHistory as createHistory } from 'history' -import Router from '../Router' -import Switch from '../Switch' -import Route from '../Route' +import React from "react"; +import ReactDOM from "react-dom"; +import { createMemoryHistory as createHistory } from "history"; +import Router from "../Router"; +import Switch from "../Switch"; +import Route from "../Route"; -describe('A ', () => { - it('does not remount a ', () => { - const node = document.createElement('div') +describe("A ", () => { + it("does not remount a ", () => { + const node = document.createElement("div"); - let mountCount = 0 + let mountCount = 0; class App extends React.Component { componentWillMount() { - mountCount++ + mountCount++; } render() { - return
+ return
; } } const history = createHistory({ - initialEntries: [ '/one' ] - }) + initialEntries: ["/one"] + }); - ReactDOM.render(( + ReactDOM.render( - - + + - - ), node) + , + node + ); - expect(mountCount).toBe(1) - history.push('/two') + expect(mountCount).toBe(1); + history.push("/two"); - expect(mountCount).toBe(1) - history.push('/one') + expect(mountCount).toBe(1); + history.push("/one"); - expect(mountCount).toBe(1) - }) -}) + expect(mountCount).toBe(1); + }); +}); diff --git a/packages/react-router/modules/__tests__/generatePath-test.js b/packages/react-router/modules/__tests__/generatePath-test.js index ed7b300696..3f84a78eca 100644 --- a/packages/react-router/modules/__tests__/generatePath-test.js +++ b/packages/react-router/modules/__tests__/generatePath-test.js @@ -1,56 +1,56 @@ -import generatePath from '../generatePath' +import generatePath from "../generatePath"; -describe('generatePath', () => { +describe("generatePath", () => { describe('with pattern="/"', () => { - it('returns correct url with no params', () => { - const pattern = '/' - const generated = generatePath(pattern) - expect(generated).toBe('/') - }) + it("returns correct url with no params", () => { + const pattern = "/"; + const generated = generatePath(pattern); + expect(generated).toBe("/"); + }); - it('returns correct url with params', () => { - const pattern = '/' - const params = { foo: "tobi", bar: 123 } - const generated = generatePath(pattern, params) - expect(generated).toBe('/') - }) - }) + it("returns correct url with params", () => { + const pattern = "/"; + const params = { foo: "tobi", bar: 123 }; + const generated = generatePath(pattern, params); + expect(generated).toBe("/"); + }); + }); describe('with pattern="/:foo/somewhere/:bar"', () => { - it('throws with no params', () => { - const pattern = '/:foo/somewhere/:bar' + it("throws with no params", () => { + const pattern = "/:foo/somewhere/:bar"; expect(() => { - generatePath(pattern) - }).toThrow() - }) + generatePath(pattern); + }).toThrow(); + }); - it('throws with some params', () => { - const pattern = '/:foo/somewhere/:bar' - const params = { foo: "tobi", quux: 999 } + it("throws with some params", () => { + const pattern = "/:foo/somewhere/:bar"; + const params = { foo: "tobi", quux: 999 }; expect(() => { - generatePath(pattern, params) - }).toThrow() - }) + generatePath(pattern, params); + }).toThrow(); + }); - it('returns correct url with params', () => { - const pattern = '/:foo/somewhere/:bar' - const params = { foo: "tobi", bar: 123 } - const generated = generatePath(pattern, params) - expect(generated).toBe('/tobi/somewhere/123') - }) + it("returns correct url with params", () => { + const pattern = "/:foo/somewhere/:bar"; + const params = { foo: "tobi", bar: 123 }; + const generated = generatePath(pattern, params); + expect(generated).toBe("/tobi/somewhere/123"); + }); - it('returns correct url with additional params', () => { - const pattern = '/:foo/somewhere/:bar' - const params = { foo: "tobi", bar: 123, quux: 999 } - const generated = generatePath(pattern, params) - expect(generated).toBe('/tobi/somewhere/123') - }) - }) + it("returns correct url with additional params", () => { + const pattern = "/:foo/somewhere/:bar"; + const params = { foo: "tobi", bar: 123, quux: 999 }; + const generated = generatePath(pattern, params); + expect(generated).toBe("/tobi/somewhere/123"); + }); + }); - describe('with no path', () => { - it('matches the root URL', () => { - const generated = generatePath() - expect(generated).toBe('/') - }) - }) -}) + describe("with no path", () => { + it("matches the root URL", () => { + const generated = generatePath(); + expect(generated).toBe("/"); + }); + }); +}); diff --git a/packages/react-router/modules/__tests__/integration-test.js b/packages/react-router/modules/__tests__/integration-test.js index c8a03b3fa3..3296d9d573 100644 --- a/packages/react-router/modules/__tests__/integration-test.js +++ b/packages/react-router/modules/__tests__/integration-test.js @@ -1,70 +1,71 @@ -import React from 'react' -import ReactDOM from 'react-dom' -import MemoryRouter from '../MemoryRouter' -import Route from '../Route' +import React from "react"; +import ReactDOM from "react-dom"; +import MemoryRouter from "../MemoryRouter"; +import Route from "../Route"; -describe('Integration Tests', () => { - it('renders nested matches', () => { - const node = document.createElement('div') - const TEXT1 = 'Ms. Tripp' - const TEXT2 = 'Mrs. Schiffman' - ReactDOM.render(( - - ( -
-

{TEXT1}

- ( -

{TEXT2}

- )}/> -
- )}/> -
- ), node) - expect(node.innerHTML).toContain(TEXT1) - expect(node.innerHTML).toContain(TEXT2) - }) +describe("Integration Tests", () => { + it("renders nested matches", () => { + const node = document.createElement("div"); + const TEXT1 = "Ms. Tripp"; + const TEXT2 = "Mrs. Schiffman"; + ReactDOM.render( + + ( +
+

{TEXT1}

+

{TEXT2}

} /> +
+ )} + /> +
, + node + ); + expect(node.innerHTML).toContain(TEXT1); + expect(node.innerHTML).toContain(TEXT2); + }); - it('renders only as deep as the matching Route', () => { - const node = document.createElement('div') - const TEXT1 = 'Ms. Tripp' - const TEXT2 = 'Mrs. Schiffman' - ReactDOM.render(( - - ( -
-

{TEXT1}

- ( -

{TEXT2}

- )}/> -
- )}/> -
- ), node) - expect(node.innerHTML).toContain(TEXT1) - expect(node.innerHTML).not.toContain(TEXT2) - }) + it("renders only as deep as the matching Route", () => { + const node = document.createElement("div"); + const TEXT1 = "Ms. Tripp"; + const TEXT2 = "Mrs. Schiffman"; + ReactDOM.render( + + ( +
+

{TEXT1}

+

{TEXT2}

} /> +
+ )} + /> +
, + node + ); + expect(node.innerHTML).toContain(TEXT1); + expect(node.innerHTML).not.toContain(TEXT2); + }); - it('renders multiple matching routes', () => { - const node = document.createElement('div') - const TEXT1 = 'Mrs. Schiffman' - const TEXT2 = 'Mrs. Burton' - ReactDOM.render(( - + it("renders multiple matching routes", () => { + const node = document.createElement("div"); + const TEXT1 = "Mrs. Schiffman"; + const TEXT2 = "Mrs. Burton"; + ReactDOM.render( +
- ( -

{TEXT2}

- )}/> +

{TEXT2}

} />
-
- ), node) - expect(node.innerHTML).toContain(TEXT1) - expect(node.innerHTML).toContain(TEXT2) - }) -}) +
, + node + ); + expect(node.innerHTML).toContain(TEXT1); + expect(node.innerHTML).toContain(TEXT2); + }); +}); diff --git a/packages/react-router/modules/__tests__/matchPath-test.js b/packages/react-router/modules/__tests__/matchPath-test.js index 8da53eec60..8ee6f661e2 100644 --- a/packages/react-router/modules/__tests__/matchPath-test.js +++ b/packages/react-router/modules/__tests__/matchPath-test.js @@ -1,84 +1,86 @@ -import matchPath from '../matchPath' +import matchPath from "../matchPath"; -describe('matchPath', () => { +describe("matchPath", () => { describe('with path="/"', () => { it('returns correct url at "/"', () => { - const path = '/' - const pathname = '/' - const match = matchPath(pathname, path) - expect(match.url).toBe('/') - }) + const path = "/"; + const pathname = "/"; + const match = matchPath(pathname, path); + expect(match.url).toBe("/"); + }); it('returns correct url at "/somewhere/else"', () => { - const path = '/' - const pathname = '/somewhere/else' - const match = matchPath(pathname, path) - expect(match.url).toBe('/') - }) - }) + const path = "/"; + const pathname = "/somewhere/else"; + const match = matchPath(pathname, path); + expect(match.url).toBe("/"); + }); + }); describe('with path="/somewhere"', () => { it('returns correct url at "/somewhere"', () => { - const path = '/somewhere' - const pathname = '/somewhere' - const match = matchPath(pathname, path) - expect(match.url).toBe('/somewhere') - }) + const path = "/somewhere"; + const pathname = "/somewhere"; + const match = matchPath(pathname, path); + expect(match.url).toBe("/somewhere"); + }); it('returns correct url at "/somewhere/else"', () => { - const path = '/somewhere' - const pathname = '/somewhere/else' - const match = matchPath(pathname, path) - expect(match.url).toBe('/somewhere') - }) - }) + const path = "/somewhere"; + const pathname = "/somewhere/else"; + const match = matchPath(pathname, path); + expect(match.url).toBe("/somewhere"); + }); + }); - describe('with sensitive path', () => { - it('returns non-sensitive url', () => { + describe("with sensitive path", () => { + it("returns non-sensitive url", () => { const options = { - path: '/SomeWhere', - } - const pathname = '/somewhere' - const match = matchPath(pathname, options) - expect(match.url).toBe('/somewhere') - }) + path: "/SomeWhere" + }; + const pathname = "/somewhere"; + const match = matchPath(pathname, options); + expect(match.url).toBe("/somewhere"); + }); - it('returns sensitive url', () => { + it("returns sensitive url", () => { const options = { - path: '/SomeWhere', + path: "/SomeWhere", sensitive: true - } - const pathname = '/somewhere' - const match = matchPath(pathname, options) - expect(match).toBe(null) - }) - }) + }; + const pathname = "/somewhere"; + const match = matchPath(pathname, options); + expect(match).toBe(null); + }); + }); - describe('with no path', () => { - it('matches the root URL', () => { - const match = matchPath('/test-location/7', {}) + describe("with no path", () => { + it("matches the root URL", () => { + const match = matchPath("/test-location/7", {}); expect(match).toMatchObject({ - url: '/', - path: '/', + url: "/", + path: "/", params: {}, isExact: false - }) - }) - }) + }); + }); + }); - describe('cache', () => { - it('creates a cache entry for each exact/strict pair', () => { + describe("cache", () => { + it("creates a cache entry for each exact/strict pair", () => { // true/false and false/true will collide when adding booleans - const trueFalse = matchPath( - '/one/two', - { path: '/one/two/', exact : true, strict: false } - ) - const falseTrue = matchPath( - '/one/two', - { path: '/one/two/', exact : false, strict: true } - ) - expect(!!trueFalse).toBe(true) - expect(!!falseTrue).toBe(false) - }) - }) -}) + const trueFalse = matchPath("/one/two", { + path: "/one/two/", + exact: true, + strict: false + }); + const falseTrue = matchPath("/one/two", { + path: "/one/two/", + exact: false, + strict: true + }); + expect(!!trueFalse).toBe(true); + expect(!!falseTrue).toBe(false); + }); + }); +}); diff --git a/packages/react-router/modules/__tests__/withRouter-test.js b/packages/react-router/modules/__tests__/withRouter-test.js index e9d53e76b8..9114852fc6 100644 --- a/packages/react-router/modules/__tests__/withRouter-test.js +++ b/packages/react-router/modules/__tests__/withRouter-test.js @@ -1,111 +1,117 @@ -import React from 'react' -import ReactDOM from 'react-dom' -import MemoryRouter from '../MemoryRouter' -import StaticRouter from '../StaticRouter' -import Route from '../Route' -import withRouter from '../withRouter' +import React from "react"; +import ReactDOM from "react-dom"; +import MemoryRouter from "../MemoryRouter"; +import StaticRouter from "../StaticRouter"; +import Route from "../Route"; +import withRouter from "../withRouter"; -describe('withRouter', () => { - const node = document.createElement('div') +describe("withRouter", () => { + const node = document.createElement("div"); afterEach(() => { - ReactDOM.unmountComponentAtNode(node) - }) + ReactDOM.unmountComponentAtNode(node); + }); - it('provides { match, location, history } props', () => { + it("provides { match, location, history } props", () => { const PropsChecker = withRouter(props => { - expect(typeof props.match).toBe('object') - expect(typeof props.location).toBe('object') - expect(typeof props.history).toBe('object') - return null - }) - - ReactDOM.render(( - - ( - - )}/> - - ), node) - }) - - it('provides the parent match as a prop to the wrapped component', () => { - let parentMatch + expect(typeof props.match).toBe("object"); + expect(typeof props.location).toBe("object"); + expect(typeof props.history).toBe("object"); + return null; + }); + + ReactDOM.render( + + } /> + , + node + ); + }); + + it("provides the parent match as a prop to the wrapped component", () => { + let parentMatch; const PropsChecker = withRouter(props => { - expect(props.match).toEqual(parentMatch) - return null - }) - - ReactDOM.render(( - - { - parentMatch = match - return - }}/> - - ), node) - }) - - describe('inside a ', () => { - it('provides the staticContext prop', () => { + expect(props.match).toEqual(parentMatch); + return null; + }); + + ReactDOM.render( + + { + parentMatch = match; + return ; + }} + /> + , + node + ); + }); + + describe("inside a ", () => { + it("provides the staticContext prop", () => { const PropsChecker = withRouter(props => { - expect(typeof props.staticContext).toBe('object') - expect(props.staticContext).toBe(context) - return null - }) + expect(typeof props.staticContext).toBe("object"); + expect(props.staticContext).toBe(context); + return null; + }); - const context = {} + const context = {}; - ReactDOM.render(( + ReactDOM.render( - - - ), node) - }) - }) - - it('exposes the wrapped component as WrappedComponent', () => { - const Component = () =>
- const decorated = withRouter(Component) - expect(decorated.WrappedComponent).toBe(Component) - }) - - it('exposes the instance of the wrapped component via wrappedComponentRef', () => { + + , + node + ); + }); + }); + + it("exposes the wrapped component as WrappedComponent", () => { + const Component = () =>
; + const decorated = withRouter(Component); + expect(decorated.WrappedComponent).toBe(Component); + }); + + it("exposes the instance of the wrapped component via wrappedComponentRef", () => { class WrappedComponent extends React.Component { render() { - return null + return null; } } - const Component = withRouter(WrappedComponent) - - let ref - ReactDOM.render(( - - ( - ref = r}/> - )}/> - - ), node) - - expect(ref instanceof WrappedComponent).toBe(true) - }) - - it('hoists non-react statics from the wrapped component', () => { + const Component = withRouter(WrappedComponent); + + let ref; + ReactDOM.render( + + (ref = r)} />} + /> + , + node + ); + + expect(ref instanceof WrappedComponent).toBe(true); + }); + + it("hoists non-react statics from the wrapped component", () => { class Component extends React.Component { static foo() { - return 'bar' + return "bar"; } render() { - return null + return null; } } - Component.hello = 'world' + Component.hello = "world"; - const decorated = withRouter(Component) + const decorated = withRouter(Component); - expect(decorated.hello).toBe('world') - expect(typeof decorated.foo).toBe('function') - expect(decorated.foo()).toBe('bar') - }) -}) + expect(decorated.hello).toBe("world"); + expect(typeof decorated.foo).toBe("function"); + expect(decorated.foo()).toBe("bar"); + }); +}); diff --git a/packages/react-router/modules/generatePath.js b/packages/react-router/modules/generatePath.js index 2bd296f537..5022df4a08 100644 --- a/packages/react-router/modules/generatePath.js +++ b/packages/react-router/modules/generatePath.js @@ -1,35 +1,34 @@ -import pathToRegexp from 'path-to-regexp' +import pathToRegexp from "path-to-regexp"; -const patternCache = {} -const cacheLimit = 10000 -let cacheCount = 0 +const patternCache = {}; +const cacheLimit = 10000; +let cacheCount = 0; -const compileGenerator = (pattern) => { - const cacheKey = pattern - const cache = patternCache[cacheKey] || (patternCache[cacheKey] = {}) +const compileGenerator = pattern => { + const cacheKey = pattern; + const cache = patternCache[cacheKey] || (patternCache[cacheKey] = {}); - if (cache[pattern]) - return cache[pattern] + if (cache[pattern]) return cache[pattern]; - const compiledGenerator = pathToRegexp.compile(pattern) + const compiledGenerator = pathToRegexp.compile(pattern); if (cacheCount < cacheLimit) { - cache[pattern] = compiledGenerator - cacheCount++ + cache[pattern] = compiledGenerator; + cacheCount++; } - return compiledGenerator -} + return compiledGenerator; +}; /** * Public API for generating a URL pathname from a pattern and parameters. */ -const generatePath = (pattern = '/', params = {}) => { - if (pattern === '/') { - return pattern +const generatePath = (pattern = "/", params = {}) => { + if (pattern === "/") { + return pattern; } - const generator = compileGenerator(pattern) - return generator(params) -} + const generator = compileGenerator(pattern); + return generator(params); +}; -export default generatePath +export default generatePath; diff --git a/packages/react-router/modules/index.js b/packages/react-router/modules/index.js index e702e51b6c..f511875493 100644 --- a/packages/react-router/modules/index.js +++ b/packages/react-router/modules/index.js @@ -1,10 +1,10 @@ -export MemoryRouter from './MemoryRouter' -export Prompt from './Prompt' -export Redirect from './Redirect' -export Route from './Route' -export Router from './Router' -export StaticRouter from './StaticRouter' -export Switch from './Switch' -export generatePath from './generatePath' -export matchPath from './matchPath' -export withRouter from './withRouter' +export MemoryRouter from "./MemoryRouter"; +export Prompt from "./Prompt"; +export Redirect from "./Redirect"; +export Route from "./Route"; +export Router from "./Router"; +export StaticRouter from "./StaticRouter"; +export Switch from "./Switch"; +export generatePath from "./generatePath"; +export matchPath from "./matchPath"; +export withRouter from "./withRouter"; diff --git a/packages/react-router/modules/matchPath.js b/packages/react-router/modules/matchPath.js index 4646477512..c83d943874 100644 --- a/packages/react-router/modules/matchPath.js +++ b/packages/react-router/modules/matchPath.js @@ -1,57 +1,58 @@ -import pathToRegexp from 'path-to-regexp' +import pathToRegexp from "path-to-regexp"; -const patternCache = {} -const cacheLimit = 10000 -let cacheCount = 0 +const patternCache = {}; +const cacheLimit = 10000; +let cacheCount = 0; const compilePath = (pattern, options) => { - const cacheKey = `${options.end}${options.strict}${options.sensitive}` - const cache = patternCache[cacheKey] || (patternCache[cacheKey] = {}) + const cacheKey = `${options.end}${options.strict}${options.sensitive}`; + const cache = patternCache[cacheKey] || (patternCache[cacheKey] = {}); - if (cache[pattern]) - return cache[pattern] + if (cache[pattern]) return cache[pattern]; - const keys = [] - const re = pathToRegexp(pattern, keys, options) - const compiledPattern = { re, keys } + const keys = []; + const re = pathToRegexp(pattern, keys, options); + const compiledPattern = { re, keys }; if (cacheCount < cacheLimit) { - cache[pattern] = compiledPattern - cacheCount++ + cache[pattern] = compiledPattern; + cacheCount++; } - return compiledPattern -} + return compiledPattern; +}; /** * Public API for matching a URL pathname to a path pattern. */ const matchPath = (pathname, options = {}) => { - if (typeof options === 'string') - options = { path: options } + if (typeof options === "string") options = { path: options }; - const { path = '/', exact = false, strict = false, sensitive = false } = options - const { re, keys } = compilePath(path, { end: exact, strict, sensitive }) - const match = re.exec(pathname) + const { + path = "/", + exact = false, + strict = false, + sensitive = false + } = options; + const { re, keys } = compilePath(path, { end: exact, strict, sensitive }); + const match = re.exec(pathname); - if (!match) - return null + if (!match) return null; - const [ url, ...values ] = match - const isExact = pathname === url + const [url, ...values] = match; + const isExact = pathname === url; - if (exact && !isExact) - return null + if (exact && !isExact) return null; return { path, // the path pattern used to match - url: path === '/' && url === '' ? '/' : url, // the matched portion of the URL + url: path === "/" && url === "" ? "/" : url, // the matched portion of the URL isExact, // whether or not we matched exactly params: keys.reduce((memo, key, index) => { - memo[key.name] = values[index] - return memo + memo[key.name] = values[index]; + return memo; }, {}) - } -} + }; +}; -export default matchPath +export default matchPath; diff --git a/packages/react-router/modules/withRouter.js b/packages/react-router/modules/withRouter.js index 0ac3718361..d895eaf8ad 100644 --- a/packages/react-router/modules/withRouter.js +++ b/packages/react-router/modules/withRouter.js @@ -1,28 +1,34 @@ -import React from 'react' -import PropTypes from 'prop-types' -import hoistStatics from 'hoist-non-react-statics' -import Route from './Route' +import React from "react"; +import PropTypes from "prop-types"; +import hoistStatics from "hoist-non-react-statics"; +import Route from "./Route"; /** * A public higher-order component to access the imperative API */ -const withRouter = (Component) => { - const C = (props) => { - const { wrappedComponentRef, ...remainingProps } = props +const withRouter = Component => { + const C = props => { + const { wrappedComponentRef, ...remainingProps } = props; return ( - ( - - )}/> - ) - } + ( + + )} + /> + ); + }; - C.displayName = `withRouter(${Component.displayName || Component.name})` - C.WrappedComponent = Component + C.displayName = `withRouter(${Component.displayName || Component.name})`; + C.WrappedComponent = Component; C.propTypes = { wrappedComponentRef: PropTypes.func - } + }; - return hoistStatics(C, Component) -} + return hoistStatics(C, Component); +}; -export default withRouter +export default withRouter; diff --git a/packages/react-router/rollup.config.js b/packages/react-router/rollup.config.js index cbfafb3a76..75ad23bcd6 100644 --- a/packages/react-router/rollup.config.js +++ b/packages/react-router/rollup.config.js @@ -1,34 +1,32 @@ -import babel from 'rollup-plugin-babel' -import uglify from 'rollup-plugin-uglify' -import replace from 'rollup-plugin-replace' -import commonjs from 'rollup-plugin-commonjs' -import resolve from 'rollup-plugin-node-resolve' +import babel from "rollup-plugin-babel"; +import uglify from "rollup-plugin-uglify"; +import replace from "rollup-plugin-replace"; +import commonjs from "rollup-plugin-commonjs"; +import resolve from "rollup-plugin-node-resolve"; const config = { - input: 'modules/index.js', - name: 'ReactRouter', + input: "modules/index.js", + name: "ReactRouter", globals: { - react: 'React' + react: "React" }, - external: [ - 'react' - ], + external: ["react"], plugins: [ babel({ - exclude: 'node_modules/**' + exclude: "node_modules/**" }), resolve(), commonjs({ include: /node_modules/ }), replace({ - 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) + "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV) }) ] -} +}; -if (process.env.NODE_ENV === 'production') { - config.plugins.push(uglify()) +if (process.env.NODE_ENV === "production") { + config.plugins.push(uglify()); } -export default config +export default config;