Permalink
Please sign in to comment.
Showing
with
639 additions
and 1,805 deletions.
- +0 −4 .eslintignore
- +2 −36 .eslintrc
- +4 −4 CONTRIBUTING.md
- +13 −107 README.md
- BIN assets/thumbnail.png
- +11 −9 karma.conf.js
- +41 −39 package.json
- +0 −70 scripts/bower-prepare.js
- +0 −20 src/ButtonLink.js
- +11 −0 src/IndexLinkContainer.js
- +53 −0 src/LinkContainer.js
- +0 −83 src/LinkMixin.js
- +0 −20 src/ListGroupItemLink.js
- +0 −23 src/MenuItemLink.js
- +0 −20 src/NavItemLink.js
- +0 −20 src/PageItemLink.js
- +0 −7 src/RouterOverlayTrigger.js
- +0 −20 src/ThumbnailLink.js
- +2 −7 src/index.js
- +2 −8 tests/.eslintrc
- +0 −166 tests/ButtonLink.spec.js
- +56 −0 tests/IndexLinkContainer.spec.js
- +223 −0 tests/LinkContainer.spec.js
- +0 −164 tests/ListGroupItemLink.spec.js
- +0 −168 tests/MenuItemLink.spec.js
- +0 −190 tests/NavItemLink.spec.js
- +0 −103 tests/PageItemLink.spec.js
- +0 −13 tests/RouterOverlayTrigger.spec.js
- +0 −31 tests/TestHandlers.js
- +0 −103 tests/ThumbnailLink.spec.js
- +0 −21 tests/bower-imports-module.spec.js
- +3 −18 tests/index.js
- +0 −31 tests/phantom-shims.js
- +0 −2 tests/visual.js
- +40 −31 tests/visual/ButtonVisual.js
- +72 −36 tests/visual/ListGroupItemVisual.js
- +0 −42 tests/visual/MenuItemVisual.js
- +28 −28 tests/visual/NavItemVisual.js
- +0 −28 tests/visual/PageItemVisual.js
- +0 −21 tests/visual/ThumbnailVisual.js
- +0 −29 tests/visual/app.js
- +10 −19 tests/visual/home.js
- +35 −0 tests/visual/index.js
- +11 −39 webpack.config.babel.js
- +5 −18 webpack.test.config.babel.js
- +17 −0 webpack.visual.config.babel.js
- +0 −7 webpack/bower-imports-loader.js
4
.eslintignore
| @@ -1,4 +0,0 @@ | ||
| -node_modules/ | ||
| -lib/ | ||
| -amd/ | ||
| -karma.conf.js |
38
.eslintrc
| @@ -1,41 +1,7 @@ | ||
| { | ||
| - "extends": ["eslint-config-airbnb"], | ||
| - "env": { | ||
| - "browser": true, | ||
| - "node": true | ||
| - }, | ||
| - "ecmaFeatures": { | ||
| - "jsx": true | ||
| - }, | ||
| - "parser": "babel-eslint", | ||
| - "plugins": [ | ||
| - "react", | ||
| - "babel" | ||
| - ], | ||
| + "extends": "airbnb", | ||
| "rules": { | ||
| "comma-dangle": 0, | ||
| - "comma-spacing": 1, | ||
| - "key-spacing": 0, | ||
| - "no-eq-null": 0, | ||
| - "no-param-reassign": 0, | ||
| - "no-underscore-dangle": 0, | ||
| - "no-undef": 2, | ||
| - "no-unused-vars": [2, { "vars": "all", "args": "none" }], | ||
| - "no-var": 2, | ||
| - "babel/object-shorthand": 2, | ||
| - "quotes": [1, "single", "avoid-escape"], | ||
| - "react/display-name": 0, | ||
| - "react/jsx-no-undef": 2, | ||
| - "react/jsx-quotes": 0, | ||
| - "react/jsx-uses-react": 2, | ||
| - "react/no-did-mount-set-state": 2, | ||
| - "react/no-did-update-set-state": 2, | ||
| - "react/no-multi-comp": 2, | ||
| - "react/prop-types": [1, { "ignore": ["children", "className"] }], | ||
| - "react/react-in-jsx-scope": 2, | ||
| - "react/self-closing-comp": 1, | ||
| - "react/wrap-multilines": 2, | ||
| - "react/jsx-uses-vars": 1, | ||
| - "strict": 0 | ||
| + "no-eq-null": 0 | ||
| } | ||
| } |
8
CONTRIBUTING.md
| @@ -1,7 +1,7 @@ | ||
| # Contributing | ||
| -As part of the react-bootstrap organization all contributing guidelines can be | ||
| -found at: | ||
| -https://github.com/react-bootstrap/react-bootstrap/blob/master/CONTRIBUTING.md | ||
| +As part of the react-bootstrap organization all contributing guidelines can be found at: https://github.com/react-bootstrap/react-bootstrap/blob/master/CONTRIBUTING.md. | ||
| -Note that automated changelog generation has not been setup on this repo yet. | ||
| +Use `npm run visual-test` to check the appearance of components in your browser. The page will load at [http://localhost:8080/](http://localhost:8080/). | ||
| + | ||
| +Note that automated changelog generation has not been set up on this repo yet. |
120
README.md
| @@ -1,127 +1,33 @@ | ||
| # react-router-bootstrap | ||
| +Integration between [React Router](https://github.com/rackt/react-router) and [React-Bootstrap](https://github.com/react-bootstrap/react-bootstrap). | ||
| [](https://travis-ci.org/react-bootstrap/react-router-bootstrap) | ||
| +[](http://badge.fury.io/js/react-router-bootstrap) | ||
| -Intregation between [react-router](https://github.com/rackt/react-router) and [react-bootstrap](https://github.com/react-bootstrap/react-bootstrap) | ||
| - | ||
| -This package gives you react-router compatible substitutes for: | ||
| - | ||
| -- `NavItem` -> `NavItemLink` | ||
| -- `Button` -> `ButtonLink` | ||
| -- `MenuItem` -> `MenuItemLink` | ||
| -- `ListGroupItem` -> `ListGroupItemLink` | ||
| -- `PageItem` -> `PageItemLink` | ||
| -- `Thumbnail` -> `ThumbnailLink` | ||
| - | ||
| -Turning this: | ||
| +## Usage | ||
| -```jsx | ||
| -React.createClass({ | ||
| - mixins: [State, Navigation], | ||
| +Wrap your React-Bootstrap element in a `LinkContainer` to make it behave like a React Router `Link`: | ||
| - render: function() { | ||
| - var href = this.makeHref('destination', {some: 'params'}, {some: 'query param'}); | ||
| - var isActive = this.isActive('destination', {some: 'params'}, {some: 'query param'}); | ||
| - return <Button href={href} active={isActive}>; | ||
| - } | ||
| -}); | ||
| +```js | ||
| +<LinkContainer to="/foo" query={{bar: "baz"}}> | ||
| + <Button>Foo</Button> | ||
| +</LinkContainer> | ||
| ``` | ||
| -Into this | ||
| - | ||
| -```jsx | ||
| -React.createClass({ | ||
| - render: function() { | ||
| - return <ButtonLink to="destination" params={{ some: 'params' }} query={{some: 'query param'}}>; | ||
| - } | ||
| -}); | ||
| -``` | ||
| +To disable the element and the link, set the `disabled` prop on the `LinkContainer`. For the equivalent of `IndexLink`, use `IndexLinkContainer`. | ||
| ## Installation | ||
| ``` | ||
| -npm install --save react-router-bootstrap | ||
| +npm install react-router-bootstrap | ||
| ``` | ||
| -You will also (if you haven't already) want to install `react-router` and `react-bootstrap` | ||
| +You will also want to have React Router and React-Bootstrap. | ||
| ``` | ||
| -npm install --save react-router react-bootstrap | ||
| -``` | ||
| - | ||
| -## Usage | ||
| - | ||
| -A simple example | ||
| - | ||
| -```jsx | ||
| -var Router = require('react-router') | ||
| - , RouteHandler = Router.RouteHandler | ||
| - , Route = Router.Route; | ||
| - | ||
| -var ReactBootstrap = require('react-bootstrap') | ||
| - , Nav = ReactBootstrap.Nav | ||
| - , ListGroup = ReactBootstrap.ListGroup; | ||
| - | ||
| -var ReactRouterBootstrap = require('react-router-bootstrap') | ||
| - , NavItemLink = ReactRouterBootstrap.NavItemLink | ||
| - , ButtonLink = ReactRouterBootstrap.ButtonLink | ||
| - , ListGroupItemLink = ReactRouterBootstrap.ListGroupItemLink; | ||
| - | ||
| -var App = React.createClass({ | ||
| - render: function() { | ||
| - return ( | ||
| - <div> | ||
| - NavItemLink<br /> | ||
| - <Nav> | ||
| - <NavItemLink | ||
| - to="destination" | ||
| - params={{ someparam: 'hello' }}> | ||
| - Linky! | ||
| - </NavItemLink> | ||
| - </Nav> | ||
| - <br /> | ||
| - ButtonLink<br /> | ||
| - <ButtonLink | ||
| - to="destination" | ||
| - params={{ someparam: 'hello' }}> | ||
| - Linky! | ||
| - </ButtonLink> | ||
| - <br /> | ||
| - <ListGroup> | ||
| - <ListGroupItemLink | ||
| - to="destination" | ||
| - params={{ someparam: 'hello' }}> | ||
| - Linky! | ||
| - </ListGroupItemLink> | ||
| - </ListGroup> | ||
| - <RouteHandler /> | ||
| - </div> | ||
| - ); | ||
| - } | ||
| -}); | ||
| - | ||
| -var Destination = React.createClass({ | ||
| - render: function() { | ||
| - return <div>You made it!</div>; | ||
| - } | ||
| -}); | ||
| - | ||
| -var routes = ( | ||
| - <Route handler={App} path="/"> | ||
| - <Route name="destination" path="destination/:someparam" handler={Destination} /> | ||
| - </Route> | ||
| -); | ||
| - | ||
| -Router.run(routes, function (Handler) { | ||
| - React.render(<Handler/>, document.body); | ||
| -}); | ||
| - | ||
| +npm install react-router react-bootstrap | ||
| ``` | ||
| ## Contributing | ||
| -See [CONTRIBUTING](CONTRIBUTING.md) | ||
| - | ||
| -Use `npm run visual-test` command to check components appearance in browser. It will open browser with a blank page. Then after `webpack-server` finishes its bundling, the browser automatically will refresh the page. | ||
| - | ||
| -URL for it: http://localhost:8080/public/visual#/ | ||
| +See [CONTRIBUTING](CONTRIBUTING.md). |
BIN
assets/thumbnail.png
Deleted file not rendered
20
karma.conf.js
80
package.json
70
scripts/bower-prepare.js
| @@ -1,70 +0,0 @@ | ||
| -/* globals cat, config, cp, mkdir, rm, test */ | ||
| -/* eslint curly: 0, no-console: 0 */ | ||
| -import 'colors'; | ||
| -import 'shelljs/global'; | ||
| -import path from 'path'; | ||
| -import _ from 'lodash'; | ||
| -import yargs from 'yargs'; | ||
| - | ||
| -// do not die on errors | ||
| -config.fatal = false; | ||
| - | ||
| -//------------------------------------------------------------------------------ | ||
| -// constants | ||
| -const repoRoot = path.resolve(__dirname, '../'); | ||
| -const libFolder = path.join(repoRoot, 'lib'); | ||
| -const bowerRoot = path.join(repoRoot, 'amd'); | ||
| -const bowerTemplate = path.join(repoRoot, 'bower.template.json'); | ||
| -const license = path.join(repoRoot, 'LICENSE'); | ||
| - | ||
| - | ||
| -//------------------------------------------------------------------------------ | ||
| -// command line options | ||
| -const argv = yargs | ||
| - .usage('Usage: $0 [--verbose]') | ||
| - .example('$0', 'Prepare bower package for releasing') | ||
| - .option('verbose', { | ||
| - demand: false, | ||
| - default: false, | ||
| - describe: 'Increased debug output' | ||
| - }) | ||
| - .argv; | ||
| - | ||
| -if (argv.dryRun) console.log('DRY RUN'.magenta); | ||
| - | ||
| -config.silent = !argv.verbose; | ||
| - | ||
| - | ||
| -//------------------------------------------------------------------------------ | ||
| -// functions | ||
| -function bower() { | ||
| - console.log('Creating: '.cyan + 'bower package'.green); | ||
| - | ||
| - rm('-rf', bowerRoot); | ||
| - mkdir('-p', bowerRoot); | ||
| - | ||
| - // generate bower.json from template | ||
| - const pkg = JSON.parse(cat(path.join(repoRoot, 'package.json'))); | ||
| - const template = _.template(cat(bowerTemplate)); | ||
| - const bowerConfigObject = template({ pkg }); | ||
| - const json = JSON.stringify(JSON.parse(bowerConfigObject), null, 2); // proper formatting hack | ||
| - json.to(path.join(bowerRoot, 'bower.json')); | ||
| - | ||
| - // copy readme and license | ||
| - const readmeBower = path.join(repoRoot, 'README.bower.md'); | ||
| - const readme = path.join(repoRoot, 'README.md'); | ||
| - if (test('-e', readmeBower)) { | ||
| - cp(readmeBower, path.join(bowerRoot, 'README.md')); | ||
| - } else { | ||
| - cp(readme, bowerRoot); | ||
| - } | ||
| - if (test('-e', license)) cp(license, bowerRoot); | ||
| - | ||
| - // copy distr files | ||
| - cp('-r', libFolder, bowerRoot); | ||
| - | ||
| - console.log('Created: '.cyan + 'bower package'.green); | ||
| -} | ||
| - | ||
| -//------------------------------------------------------------------------------ | ||
| -bower(); |
20
src/ButtonLink.js
| @@ -1,20 +0,0 @@ | ||
| -import React from 'react'; | ||
| - | ||
| -import Button from 'react-bootstrap/lib/Button'; | ||
| -import LinkMixin from './LinkMixin'; | ||
| - | ||
| -const ButtonLink = React.createClass({ | ||
| - mixins: [ | ||
| - LinkMixin | ||
| - ], | ||
| - | ||
| - render() { | ||
| - return ( | ||
| - <Button {...this.getLinkProps()} ref='button'> | ||
| - {this.props.children} | ||
| - </Button> | ||
| - ); | ||
| - } | ||
| -}); | ||
| - | ||
| -export default ButtonLink; |
11
src/IndexLinkContainer.js
| @@ -0,0 +1,11 @@ | ||
| +import React from 'react'; | ||
| + | ||
| +import LinkContainer from './LinkContainer'; | ||
| + | ||
| +export default class IndexLinkContainer extends React.Component { | ||
| + render() { | ||
| + return ( | ||
| + <LinkContainer {...this.props} onlyActiveOnIndex /> | ||
| + ); | ||
| + } | ||
| +} |
53
src/LinkContainer.js
| @@ -0,0 +1,53 @@ | ||
| +// This is largely taken from react-router/lib/Link. | ||
| + | ||
| +import React from 'react'; | ||
| +import {Link} from 'react-router'; | ||
| + | ||
| +export default class LinkContainer extends React.Component { | ||
| + constructor(props, context) { | ||
| + super(props, context); | ||
| + | ||
| + this.onClick = this.onClick.bind(this); | ||
| + } | ||
| + | ||
| + onClick(event) { | ||
| + if (this.props.disabled) { | ||
| + event.preventDefault(); | ||
| + return; | ||
| + } | ||
| + | ||
| + Link.prototype.handleClick.call(this, event); | ||
| + } | ||
| + | ||
| + render() { | ||
| + const {history} = this.context; | ||
| + const {onlyActiveOnIndex, to, query, children, ...props} = this.props; | ||
| + | ||
| + delete props.state; | ||
| + delete props.onClick; | ||
| + props.onClick = this.onClick; | ||
| + props.href = history.createHref(to, query); | ||
| + props.active = history.isActive(to, query, onlyActiveOnIndex); | ||
| + | ||
| + return React.cloneElement(React.Children.only(children), props); | ||
| + } | ||
| +} | ||
| + | ||
| +LinkContainer.propTypes = { | ||
| + onlyActiveOnIndex: React.PropTypes.bool.isRequired, | ||
| + to: React.PropTypes.string.isRequired, | ||
| + query: React.PropTypes.object, | ||
| + state: React.PropTypes.object, | ||
| + onClick: React.PropTypes.func, | ||
| + disabled: React.PropTypes.bool.isRequired, | ||
| + children: React.PropTypes.node.isRequired | ||
| +}; | ||
| + | ||
| +LinkContainer.contextTypes = { | ||
| + history: React.PropTypes.object.isRequired | ||
| +}; | ||
| + | ||
| +LinkContainer.defaultProps = { | ||
| + onlyActiveOnIndex: false, | ||
| + disabled: false | ||
| +}; |
83
src/LinkMixin.js
| @@ -1,83 +0,0 @@ | ||
| -import React from 'react'; | ||
| - | ||
| -function isLeftClickEvent(event) { | ||
| - return event.button === 0; | ||
| -} | ||
| - | ||
| -function isModifiedEvent(event) { | ||
| - return !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey); | ||
| -} | ||
| - | ||
| -export default { | ||
| - propTypes: { | ||
| - active: React.PropTypes.bool, | ||
| - activeClassName: React.PropTypes.string.isRequired, | ||
| - disabled: React.PropTypes.bool, | ||
| - to: React.PropTypes.string.isRequired, | ||
| - params: React.PropTypes.object, | ||
| - query: React.PropTypes.object, | ||
| - onClick: React.PropTypes.func | ||
| - }, | ||
| - contextTypes: { | ||
| - router: React.PropTypes.func.isRequired | ||
| - }, | ||
| - | ||
| - getDefaultProps() { | ||
| - return { | ||
| - activeClassName: 'active' | ||
| - }; | ||
| - }, | ||
| - | ||
| - /** | ||
| - * Returns props except those used by this Mixin | ||
| - * Gets "active" from router if needed. | ||
| - * Gets the value of the "href" attribute to use on the DOM element. | ||
| - * Sets "onClick" to "handleRouteTo". | ||
| - */ | ||
| - getLinkProps() { | ||
| - const { | ||
| - to, | ||
| - params, | ||
| - query, | ||
| - ...props | ||
| - } = this.props; | ||
| - | ||
| - if (this.props.active === undefined) { | ||
| - props.active = this.context.router.isActive(to, params, query); | ||
| - } | ||
| - | ||
| - props.href = this.context.router.makeHref(to, params, query); | ||
| - | ||
| - props.onClick = this.handleRouteTo; | ||
| - | ||
| - return props; | ||
| - }, | ||
| - | ||
| - handleRouteTo(event) { | ||
| - let allowTransition = true; | ||
| - let clickResult; | ||
| - | ||
| - if (this.props.disabled) { | ||
| - event.preventDefault(); | ||
| - return; | ||
| - } | ||
| - | ||
| - if (this.props.onClick) { | ||
| - clickResult = this.props.onClick(event); | ||
| - } | ||
| - | ||
| - if (isModifiedEvent(event) || !isLeftClickEvent(event)) { | ||
| - return; | ||
| - } | ||
| - | ||
| - if (clickResult === false || event.defaultPrevented === true) { | ||
| - allowTransition = false; | ||
| - } | ||
| - | ||
| - event.preventDefault(); | ||
| - | ||
| - if (allowTransition) { | ||
| - this.context.router.transitionTo(this.props.to, this.props.params, this.props.query); | ||
| - } | ||
| - } | ||
| -}; |
20
src/ListGroupItemLink.js
| @@ -1,20 +0,0 @@ | ||
| -import React from 'react'; | ||
| - | ||
| -import ListGroupItem from 'react-bootstrap/lib/ListGroupItem'; | ||
| -import LinkMixin from './LinkMixin'; | ||
| - | ||
| -const LinkGroupItemLink = React.createClass({ | ||
| - mixins: [ | ||
| - LinkMixin | ||
| - ], | ||
| - | ||
| - render() { | ||
| - return ( | ||
| - <ListGroupItem {...this.getLinkProps()} ref='listGroupItem'> | ||
| - {this.props.children} | ||
| - </ListGroupItem> | ||
| - ); | ||
| - } | ||
| -}); | ||
| - | ||
| -export default LinkGroupItemLink; |
23
src/MenuItemLink.js
| @@ -1,23 +0,0 @@ | ||
| -import React from 'react'; | ||
| - | ||
| -import MenuItem from 'react-bootstrap/lib/MenuItem'; | ||
| -import LinkMixin from './LinkMixin'; | ||
| - | ||
| -const MenuItemLink = React.createClass({ | ||
| - mixins: [ | ||
| - LinkMixin | ||
| - ], | ||
| - | ||
| - render() { | ||
| - const props = this.getLinkProps(); | ||
| - delete props.onSelect; // this is done on the copy of this.props | ||
| - | ||
| - return ( | ||
| - <MenuItem {...props} ref="menuItem"> | ||
| - {this.props.children} | ||
| - </MenuItem> | ||
| - ); | ||
| - } | ||
| -}); | ||
| - | ||
| -export default MenuItemLink; |
20
src/NavItemLink.js
| @@ -1,20 +0,0 @@ | ||
| -import React from 'react'; | ||
| - | ||
| -import NavItem from 'react-bootstrap/lib/NavItem'; | ||
| -import LinkMixin from './LinkMixin'; | ||
| - | ||
| -const NavItemLink = React.createClass({ | ||
| - mixins: [ | ||
| - LinkMixin | ||
| - ], | ||
| - | ||
| - render() { | ||
| - return ( | ||
| - <NavItem {...this.getLinkProps()} ref="navItem"> | ||
| - {this.props.children} | ||
| - </NavItem> | ||
| - ); | ||
| - } | ||
| -}); | ||
| - | ||
| -export default NavItemLink; |
20
src/PageItemLink.js
| @@ -1,20 +0,0 @@ | ||
| -import React from 'react'; | ||
| - | ||
| -import PageItem from 'react-bootstrap/lib/PageItem'; | ||
| -import LinkMixin from './LinkMixin'; | ||
| - | ||
| -const PageItemLink = React.createClass({ | ||
| - mixins: [ | ||
| - LinkMixin | ||
| - ], | ||
| - | ||
| - render() { | ||
| - return ( | ||
| - <PageItem {...this.getLinkProps()} ref='pageItem'> | ||
| - {this.props.children} | ||
| - </PageItem> | ||
| - ); | ||
| - } | ||
| -}); | ||
| - | ||
| -export default PageItemLink; |
7
src/RouterOverlayTrigger.js
| @@ -1,7 +0,0 @@ | ||
| -import React from 'react'; | ||
| - | ||
| -import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger'; | ||
| - | ||
| -export default OverlayTrigger.withContext({ | ||
| - router: React.PropTypes.func | ||
| -}); |
20
src/ThumbnailLink.js
| @@ -1,20 +0,0 @@ | ||
| -import React from 'react'; | ||
| - | ||
| -import Thumbnail from 'react-bootstrap/lib/Thumbnail'; | ||
| -import LinkMixin from './LinkMixin'; | ||
| - | ||
| -const ThumbnailLink = React.createClass({ | ||
| - mixins: [ | ||
| - LinkMixin | ||
| - ], | ||
| - | ||
| - render() { | ||
| - return ( | ||
| - <Thumbnail {...this.getLinkProps()} ref='thumbnail'> | ||
| - {this.props.children} | ||
| - </Thumbnail> | ||
| - ); | ||
| - } | ||
| -}); | ||
| - | ||
| -export default ThumbnailLink; |
9
src/index.js
| @@ -1,7 +1,2 @@ | ||
| -export ButtonLink from './ButtonLink'; | ||
| -export ListGroupItemLink from './ListGroupItemLink'; | ||
| -export MenuItemLink from './MenuItemLink'; | ||
| -export NavItemLink from './NavItemLink'; | ||
| -export PageItemLink from './PageItemLink'; | ||
| -export RouterOverlayTrigger from './RouterOverlayTrigger'; | ||
| -export ThumbnailLink from './ThumbnailLink'; | ||
| +export IndexLinkContainer from './IndexLinkContainer'; | ||
| +export LinkContainer from './LinkContainer'; |
10
tests/.eslintrc
166
tests/ButtonLink.spec.js
| @@ -1,166 +0,0 @@ | ||
| -/* globals describe, it, assert, expect */ | ||
| - | ||
| -import React from 'react/addons'; | ||
| -import ButtonLink from '../src/ButtonLink'; | ||
| -import Router, { Route, RouteHandler } from 'react-router'; | ||
| -import { Foo, Bar } from './TestHandlers'; | ||
| -import TestLocation from 'react-router/lib/locations/TestLocation'; | ||
| -const { click } = React.addons.TestUtils.Simulate; | ||
| - | ||
| -describe('A ButtonLink', function() { | ||
| - describe('with params and a query', function() { | ||
| - it('knows how to make its href', function() { | ||
| - const ButtonLinkHandler = React.createClass({ | ||
| - render() { | ||
| - return <ButtonLink to="foo" params={{bar: 'baz'}} query={{qux: 'quux'}}>ButtonLink</ButtonLink>; | ||
| - } | ||
| - }); | ||
| - | ||
| - const routes = [ | ||
| - <Route name="foo" path="foo/:bar" handler={Foo} />, | ||
| - <Route name="link" handler={ButtonLinkHandler} /> | ||
| - ]; | ||
| - | ||
| - const div = document.createElement('div'); | ||
| - const testLocation = new TestLocation(); | ||
| - testLocation.history = ['/link']; | ||
| - | ||
| - Router.run(routes, testLocation, function(Handler) { | ||
| - React.render(<Handler/>, div, function() { | ||
| - const a = div.querySelector('a'); | ||
| - expect(a.getAttribute('href')).to.equal('/foo/baz?qux=quux'); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| - | ||
| - describe('when its route is active', function() { | ||
| - it('has an active class name', function(done) { | ||
| - const ButtonLinkHandler = React.createClass({ | ||
| - render() { | ||
| - return ( | ||
| - <div> | ||
| - <ButtonLink | ||
| - to='foo' | ||
| - className='dontKillMe' | ||
| - bsStyle='primary' | ||
| - bsSize='small' | ||
| - >ButtonLink</ButtonLink> | ||
| - <RouteHandler/> | ||
| - </div> | ||
| - ); | ||
| - } | ||
| - }); | ||
| - | ||
| - const routes = ( | ||
| - <Route path="/" handler={ButtonLinkHandler}> | ||
| - <Route name="foo" handler={Foo} /> | ||
| - <Route name="bar" handler={Bar} /> | ||
| - </Route> | ||
| - ); | ||
| - | ||
| - const div = document.createElement('div'); | ||
| - const testLocation = new TestLocation(); | ||
| - testLocation.history = ['/foo']; | ||
| - const steps = []; | ||
| - | ||
| - function assertActive() { | ||
| - const a = div.querySelector('a'); | ||
| - expect(a.className.split(' ').sort().join(' ')).to.equal('active btn btn-primary btn-sm dontKillMe'); | ||
| - } | ||
| - | ||
| - function assertInactive() { | ||
| - const a = div.querySelector('a'); | ||
| - expect(a.className.split(' ').sort().join(' ')).to.equal('btn btn-primary btn-sm dontKillMe'); | ||
| - } | ||
| - | ||
| - steps.push(() => { | ||
| - assertActive(); | ||
| - testLocation.push('/bar'); | ||
| - }); | ||
| - | ||
| - steps.push(() => { | ||
| - assertInactive(); | ||
| - testLocation.push('/foo'); | ||
| - }); | ||
| - | ||
| - steps.push(() => { | ||
| - assertActive(); | ||
| - done(); | ||
| - }); | ||
| - | ||
| - Router.run(routes, testLocation, function(Handler) { | ||
| - React.render(<Handler/>, div, () => { | ||
| - steps.shift()(); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| - | ||
| - describe('when clicked', function() { | ||
| - it('calls a user defined click handler', function(done) { | ||
| - const ButtonLinkHandler = React.createClass({ | ||
| - handleClick(event) { | ||
| - assert.ok(true); | ||
| - done(); | ||
| - }, | ||
| - | ||
| - render() { | ||
| - return <ButtonLink to="foo" onClick={this.handleClick}>ButtonLink</ButtonLink>; | ||
| - } | ||
| - }); | ||
| - | ||
| - const routes = [ | ||
| - <Route name="foo" handler={Foo} />, | ||
| - <Route name="link" handler={ButtonLinkHandler} /> | ||
| - ]; | ||
| - const div = document.createElement('div'); | ||
| - const testLocation = new TestLocation(); | ||
| - testLocation.history = ['/link']; | ||
| - | ||
| - Router.run(routes, testLocation, function(Handler) { | ||
| - React.render(<Handler/>, div, function() { | ||
| - click(div.querySelector('a')); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| - | ||
| - it('transitions to the correct route', function(done) { | ||
| - const div = document.createElement('div'); | ||
| - const testLocation = new TestLocation(); | ||
| - testLocation.history = ['/link']; | ||
| - | ||
| - const ButtonLinkHandler = React.createClass({ | ||
| - handleClick() { | ||
| - // just here to make sure click handlers don't prevent it from happening | ||
| - }, | ||
| - | ||
| - render() { | ||
| - return <ButtonLink to="foo" onClick={this.handleClick}>ButtonLink</ButtonLink>; | ||
| - } | ||
| - }); | ||
| - | ||
| - const routes = [ | ||
| - <Route name="foo" handler={Foo} />, | ||
| - <Route name="link" handler={ButtonLinkHandler} /> | ||
| - ]; | ||
| - | ||
| - const steps = []; | ||
| - | ||
| - steps.push(function() { | ||
| - click(div.querySelector('a'), {button: 0}); | ||
| - }); | ||
| - | ||
| - steps.push(function() { | ||
| - expect(div.innerHTML).to.match(/Foo/); | ||
| - done(); | ||
| - }); | ||
| - | ||
| - Router.run(routes, testLocation, function(Handler) { | ||
| - React.render(<Handler/>, div, function() { | ||
| - steps.shift()(); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| -}); |
56
tests/IndexLinkContainer.spec.js
| @@ -0,0 +1,56 @@ | ||
| +import createMemoryHistory from 'history/lib/createMemoryHistory'; | ||
| +import React from 'react'; | ||
| +import ReactTestUtils from 'react/lib/ReactTestUtils'; | ||
| +import * as ReactBootstrap from 'react-bootstrap'; | ||
| +import ReactDOM from 'react-dom'; | ||
| +import {IndexRoute, Route, Router} from 'react-router'; | ||
| + | ||
| +import IndexLinkContainer from '../src/IndexLinkContainer'; | ||
| + | ||
| +describe('IndexLinkContainer', () => { | ||
| + [ | ||
| + 'Button', | ||
| + 'NavItem', | ||
| + 'ListGroupItem' | ||
| + ].forEach(name => { | ||
| + describe(name, () => { | ||
| + const Component = ReactBootstrap[name]; | ||
| + | ||
| + describe('active state', () => { | ||
| + function renderComponent(location) { | ||
| + class LinkWrapper extends React.Component { | ||
| + render() { | ||
| + return ( | ||
| + <IndexLinkContainer to="/"> | ||
| + <Component>Root</Component> | ||
| + </IndexLinkContainer> | ||
| + ); | ||
| + } | ||
| + } | ||
| + | ||
| + const router = ReactTestUtils.renderIntoDocument( | ||
| + <Router history={createMemoryHistory(location)}> | ||
| + <Route path="/" component={LinkWrapper}> | ||
| + <IndexRoute /> | ||
| + <Route path="foo" /> | ||
| + </Route> | ||
| + </Router> | ||
| + ); | ||
| + | ||
| + const component = ReactTestUtils.findRenderedComponentWithType( | ||
| + router, Component | ||
| + ); | ||
| + return ReactDOM.findDOMNode(component); | ||
| + } | ||
| + | ||
| + it('should be active on the index route', () => { | ||
| + expect(renderComponent('/').className).to.match(/\bactive\b/); | ||
| + }); | ||
| + | ||
| + it('should not be active on a child route', () => { | ||
| + expect(renderComponent('/foo').className).to.not.match(/\bactive\b/); | ||
| + }); | ||
| + }); | ||
| + }); | ||
| + }); | ||
| +}); |
223
tests/LinkContainer.spec.js
| @@ -0,0 +1,223 @@ | ||
| +import createMemoryHistory from 'history/lib/createMemoryHistory'; | ||
| +import React from 'react'; | ||
| +import ReactTestUtils from 'react/lib/ReactTestUtils'; | ||
| +import * as ReactBootstrap from 'react-bootstrap'; | ||
| +import ReactDOM from 'react-dom'; | ||
| +import {Route, Router} from 'react-router'; | ||
| + | ||
| +import LinkContainer from '../src/LinkContainer'; | ||
| + | ||
| +describe('LinkContainer', () => { | ||
| + ['Button', | ||
| + 'NavItem', | ||
| + 'ListGroupItem' | ||
| + ].forEach(name => { | ||
| + describe(name, () => { | ||
| + const Component = ReactBootstrap[name]; | ||
| + | ||
| + it('should make the correct href', () => { | ||
| + class LinkWrapper extends React.Component { | ||
| + render() { | ||
| + return ( | ||
| + <LinkContainer to="/foo" query={{bar: 'baz'}}> | ||
| + <Component>Foo</Component> | ||
| + </LinkContainer> | ||
| + ); | ||
| + } | ||
| + } | ||
| + | ||
| + const router = ReactTestUtils.renderIntoDocument( | ||
| + <Router history={createMemoryHistory('/')}> | ||
| + <Route path="/" component={LinkWrapper} /> | ||
| + </Router> | ||
| + ); | ||
| + | ||
| + const anchor = ReactTestUtils.findRenderedDOMComponentWithTag( | ||
| + router, 'A' | ||
| + ); | ||
| + expect(anchor.getAttribute('href')).to.equal('/foo?bar=baz'); | ||
| + }); | ||
| + | ||
| + it('should not add extra DOM nodes', () => { | ||
| + class LinkWrapper extends React.Component { | ||
| + render() { | ||
| + return ( | ||
| + <LinkContainer to="/foo" query={{bar: 'baz'}}> | ||
| + <Component>Foo</Component> | ||
| + </LinkContainer> | ||
| + ); | ||
| + } | ||
| + } | ||
| + | ||
| + const router = ReactTestUtils.renderIntoDocument( | ||
| + <Router history={createMemoryHistory('/')}> | ||
| + <Route path="/" component={LinkWrapper} /> | ||
| + </Router> | ||
| + ); | ||
| + | ||
| + const container = ReactTestUtils.findRenderedComponentWithType( | ||
| + router, LinkContainer | ||
| + ); | ||
| + const component = ReactTestUtils.findRenderedComponentWithType( | ||
| + router, Component | ||
| + ); | ||
| + | ||
| + expect(ReactDOM.findDOMNode(container)) | ||
| + .to.equal(ReactDOM.findDOMNode(component)); | ||
| + }); | ||
| + | ||
| + describe('when clicked', () => { | ||
| + it('should transition to the correct route', () => { | ||
| + class LinkWrapper extends React.Component { | ||
| + render() { | ||
| + return ( | ||
| + <LinkContainer to="/target"> | ||
| + <Component>Target</Component> | ||
| + </LinkContainer> | ||
| + ); | ||
| + } | ||
| + } | ||
| + | ||
| + class Target extends React.Component { | ||
| + render() { | ||
| + return <div className="target" />; | ||
| + } | ||
| + } | ||
| + | ||
| + const router = ReactTestUtils.renderIntoDocument( | ||
| + <Router history={createMemoryHistory('/')}> | ||
| + <Route path="/" component={LinkWrapper} /> | ||
| + <Route path="/target" component={Target} /> | ||
| + </Router> | ||
| + ); | ||
| + | ||
| + const component = ReactTestUtils.findRenderedComponentWithType( | ||
| + router, Component | ||
| + ); | ||
| + ReactTestUtils.Simulate.click(ReactDOM.findDOMNode(component), | ||
| + {button: 0} | ||
| + ); | ||
| + | ||
| + const target = ReactTestUtils.findRenderedDOMComponentWithClass( | ||
| + router, 'target' | ||
| + ); | ||
| + expect(target).to.exist; | ||
| + }); | ||
| + | ||
| + it('should call a user defined click handler', () => { | ||
| + const onClick = sinon.spy(); | ||
| + | ||
| + class LinkWrapper extends React.Component { | ||
| + render() { | ||
| + return ( | ||
| + <LinkContainer to="/foo" onClick={onClick}> | ||
| + <Component>Foo</Component> | ||
| + </LinkContainer> | ||
| + ); | ||
| + } | ||
| + } | ||
| + | ||
| + const router = ReactTestUtils.renderIntoDocument( | ||
| + <Router history={createMemoryHistory('/')}> | ||
| + <Route path="/" component={LinkWrapper} /> | ||
| + </Router> | ||
| + ); | ||
| + | ||
| + const component = ReactTestUtils.findRenderedComponentWithType( | ||
| + router, Component | ||
| + ); | ||
| + ReactTestUtils.Simulate.click(ReactDOM.findDOMNode(component)); | ||
| + | ||
| + expect(onClick).to.have.been.called; | ||
| + }); | ||
| + }); | ||
| + | ||
| + describe('active state', () => { | ||
| + function renderComponent(location) { | ||
| + class LinkWrapper extends React.Component { | ||
| + render() { | ||
| + return ( | ||
| + <LinkContainer to="/foo"> | ||
| + <Component>Foo</Component> | ||
| + </LinkContainer> | ||
| + ); | ||
| + } | ||
| + } | ||
| + | ||
| + const router = ReactTestUtils.renderIntoDocument( | ||
| + <Router history={createMemoryHistory(location)}> | ||
| + <Route component={LinkWrapper}> | ||
| + <Route path="/foo" /> | ||
| + <Route path="/bar" /> | ||
| + </Route> | ||
| + </Router> | ||
| + ); | ||
| + | ||
| + const component = ReactTestUtils.findRenderedComponentWithType( | ||
| + router, Component | ||
| + ); | ||
| + return ReactDOM.findDOMNode(component); | ||
| + } | ||
| + | ||
| + it('should be active when on the target route', () => { | ||
| + expect(renderComponent('/foo').className).to.match(/\bactive\b/); | ||
| + }); | ||
| + | ||
| + it('should not be active when on a different route', () => { | ||
| + expect(renderComponent('/bar').className).to.not.match(/\bactive\b/); | ||
| + }); | ||
| + }); | ||
| + | ||
| + describe('disabled state', () => { | ||
| + let router; | ||
| + | ||
| + beforeEach(() => { | ||
| + class LinkWrapper extends React.Component { | ||
| + render() { | ||
| + return ( | ||
| + <LinkContainer to="/target" disabled> | ||
| + <Component>Target</Component> | ||
| + </LinkContainer> | ||
| + ); | ||
| + } | ||
| + } | ||
| + | ||
| + class Target extends React.Component { | ||
| + render() { | ||
| + return <div className="target" />; | ||
| + } | ||
| + } | ||
| + | ||
| + router = ReactTestUtils.renderIntoDocument( | ||
| + <Router history={createMemoryHistory('/')}> | ||
| + <Route path="/" component={LinkWrapper} /> | ||
| + <Route path="/target" component={Target} /> | ||
| + </Router> | ||
| + ); | ||
| + }); | ||
| + | ||
| + it('should not transition on click', () => { | ||
| + const component = ReactTestUtils.findRenderedComponentWithType( | ||
| + router, Component | ||
| + ); | ||
| + ReactTestUtils.Simulate.click(ReactDOM.findDOMNode(component), | ||
| + {button: 0} | ||
| + ); | ||
| + | ||
| + const target = ReactTestUtils.scryRenderedDOMComponentsWithClass( | ||
| + router, 'target' | ||
| + ); | ||
| + expect(target).to.be.empty; | ||
| + }); | ||
| + | ||
| + it('should render with disabled class', () => { | ||
| + const component = ReactTestUtils.findRenderedComponentWithType( | ||
| + router, Component | ||
| + ); | ||
| + expect(ReactDOM.findDOMNode(component).className) | ||
| + .to.match(/\bdisabled\b/); | ||
| + }); | ||
| + }); | ||
| + }); | ||
| + }); | ||
| +}); |
164
tests/ListGroupItemLink.spec.js
| @@ -1,164 +0,0 @@ | ||
| -/* globals describe, it, assert, expect */ | ||
| - | ||
| -import React from 'react/addons'; | ||
| -import ListGroupItemLink from '../src/ListGroupItemLink'; | ||
| -import Router, { Route, RouteHandler } from 'react-router'; | ||
| -import { Foo, Bar } from './TestHandlers'; | ||
| -import TestLocation from 'react-router/lib/locations/TestLocation'; | ||
| -const { click } = React.addons.TestUtils.Simulate; | ||
| - | ||
| -describe('A ListGroupItemLink', function() { | ||
| - describe('with params and a query', function() { | ||
| - it('knows how to make its href', function() { | ||
| - const ListGroupItemLinkHandler = React.createClass({ | ||
| - render() { | ||
| - return <ListGroupItemLink to="foo" params={{bar: 'baz'}} query={{qux: 'quux'}}>ListGroupItemLink</ListGroupItemLink>; | ||
| - } | ||
| - }); | ||
| - | ||
| - const routes = [ | ||
| - <Route name="foo" path="foo/:bar" handler={Foo} />, | ||
| - <Route name="link" handler={ListGroupItemLinkHandler} /> | ||
| - ]; | ||
| - | ||
| - const div = document.createElement('div'); | ||
| - const testLocation = new TestLocation(); | ||
| - testLocation.history = ['/link']; | ||
| - | ||
| - Router.run(routes, testLocation, function(Handler) { | ||
| - React.render(<Handler/>, div, function() { | ||
| - const a = div.querySelector('a'); | ||
| - expect(a.getAttribute('href')).to.equal('/foo/baz?qux=quux'); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| - | ||
| - describe('when its route is active', function() { | ||
| - it('has an active class name', function(done) { | ||
| - const ListGroupItemLinkHandler = React.createClass({ | ||
| - render() { | ||
| - return ( | ||
| - <div> | ||
| - <ListGroupItemLink | ||
| - to="foo" | ||
| - className="dontKillMe" | ||
| - >ListGroupItemLink</ListGroupItemLink> | ||
| - <RouteHandler/> | ||
| - </div> | ||
| - ); | ||
| - } | ||
| - }); | ||
| - | ||
| - const routes = ( | ||
| - <Route path="/" handler={ListGroupItemLinkHandler}> | ||
| - <Route name="foo" handler={Foo} /> | ||
| - <Route name="bar" handler={Bar} /> | ||
| - </Route> | ||
| - ); | ||
| - | ||
| - const div = document.createElement('div'); | ||
| - const testLocation = new TestLocation(); | ||
| - testLocation.history = ['/foo']; | ||
| - const steps = []; | ||
| - | ||
| - function assertActive() { | ||
| - const a = div.querySelector('a'); | ||
| - expect(a.className.split(' ').sort().join(' ')).to.equal('active dontKillMe list-group-item'); | ||
| - } | ||
| - | ||
| - function assertInactive() { | ||
| - const a = div.querySelector('a'); | ||
| - expect(a.className).to.equal('dontKillMe list-group-item'); | ||
| - } | ||
| - | ||
| - steps.push(() => { | ||
| - assertActive(); | ||
| - testLocation.push('/bar'); | ||
| - }); | ||
| - | ||
| - steps.push(() => { | ||
| - assertInactive(); | ||
| - testLocation.push('/foo'); | ||
| - }); | ||
| - | ||
| - steps.push(() => { | ||
| - assertActive(); | ||
| - done(); | ||
| - }); | ||
| - | ||
| - Router.run(routes, testLocation, function(Handler) { | ||
| - React.render(<Handler/>, div, () => { | ||
| - steps.shift()(); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| - | ||
| - describe('when clicked', function() { | ||
| - it('calls a user defined click handler', function(done) { | ||
| - const ListGroupItemLinkHandler = React.createClass({ | ||
| - handleClick(event) { | ||
| - assert.ok(true); | ||
| - done(); | ||
| - }, | ||
| - | ||
| - render() { | ||
| - return <ListGroupItemLink to="foo" onClick={this.handleClick}>ListGroupItemLink</ListGroupItemLink>; | ||
| - } | ||
| - }); | ||
| - | ||
| - const routes = [ | ||
| - <Route name="foo" handler={Foo} />, | ||
| - <Route name="link" handler={ListGroupItemLinkHandler} /> | ||
| - ]; | ||
| - const div = document.createElement('div'); | ||
| - const testLocation = new TestLocation(); | ||
| - testLocation.history = ['/link']; | ||
| - | ||
| - Router.run(routes, testLocation, function(Handler) { | ||
| - React.render(<Handler/>, div, function() { | ||
| - click(div.querySelector('a')); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| - | ||
| - it('transitions to the correct route', function(done) { | ||
| - const div = document.createElement('div'); | ||
| - const testLocation = new TestLocation(); | ||
| - testLocation.history = ['/link']; | ||
| - | ||
| - const ListGroupItemLinkHandler = React.createClass({ | ||
| - handleClick() { | ||
| - // just here to make sure click handlers don't prevent it from happening | ||
| - }, | ||
| - | ||
| - render() { | ||
| - return <ListGroupItemLink to="foo" onClick={this.handleClick}>ListGroupItemLink</ListGroupItemLink>; | ||
| - } | ||
| - }); | ||
| - | ||
| - const routes = [ | ||
| - <Route name="foo" handler={Foo} />, | ||
| - <Route name="link" handler={ListGroupItemLinkHandler} /> | ||
| - ]; | ||
| - | ||
| - const steps = []; | ||
| - | ||
| - steps.push(function() { | ||
| - click(div.querySelector('a'), {button: 0}); | ||
| - }); | ||
| - | ||
| - steps.push(function() { | ||
| - expect(div.innerHTML).to.match(/Foo/); | ||
| - done(); | ||
| - }); | ||
| - | ||
| - Router.run(routes, testLocation, function(Handler) { | ||
| - React.render(<Handler/>, div, function() { | ||
| - steps.shift()(); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| -}); |
168
tests/MenuItemLink.spec.js
| @@ -1,168 +0,0 @@ | ||
| -/* globals describe, it, assert, expect */ | ||
| - | ||
| -import React from 'react/addons'; | ||
| -import MenuItemLink from '../src/MenuItemLink'; | ||
| -import Router, { Route, RouteHandler } from 'react-router'; | ||
| -import { Foo, Bar } from './TestHandlers'; | ||
| -import TestLocation from 'react-router/lib/locations/TestLocation'; | ||
| -const { click } = React.addons.TestUtils.Simulate; | ||
| - | ||
| -describe('A MenuItemLink', function() { | ||
| - describe('with params and a query', function() { | ||
| - it('knows how to make its href', function() { | ||
| - const MenuItemLinkHandler = React.createClass({ | ||
| - render() { | ||
| - return <MenuItemLink to="foo" params={{bar: 'baz'}} query={{qux: 'quux'}}>MenuItemLink</MenuItemLink>; | ||
| - } | ||
| - }); | ||
| - | ||
| - const routes = [ | ||
| - <Route name="foo" path="foo/:bar" handler={Foo} />, | ||
| - <Route name="link" handler={MenuItemLinkHandler} /> | ||
| - ]; | ||
| - | ||
| - const div = document.createElement('div'); | ||
| - const testLocation = new TestLocation(); | ||
| - testLocation.history = ['/link']; | ||
| - | ||
| - Router.run(routes, testLocation, function(Handler) { | ||
| - React.render(<Handler/>, div, function() { | ||
| - const a = div.querySelector('a'); | ||
| - expect(a.getAttribute('href')).to.equal('/foo/baz?qux=quux'); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| - | ||
| - describe('when its route is active', function() { | ||
| - it('has an active class name', function(done) { | ||
| - const MenuItemLinkHandler = React.createClass({ | ||
| - render() { | ||
| - return ( | ||
| - <div> | ||
| - <MenuItemLink | ||
| - to="foo" | ||
| - className="dontKillMe" | ||
| - >MenuItemLink</MenuItemLink> | ||
| - <RouteHandler/> | ||
| - </div> | ||
| - ); | ||
| - } | ||
| - }); | ||
| - | ||
| - const routes = ( | ||
| - <Route path="/" handler={MenuItemLinkHandler}> | ||
| - <Route name="foo" handler={Foo} /> | ||
| - <Route name="bar" handler={Bar} /> | ||
| - </Route> | ||
| - ); | ||
| - | ||
| - const div = document.createElement('div'); | ||
| - const testLocation = new TestLocation(); | ||
| - testLocation.history = ['/foo']; | ||
| - const steps = []; | ||
| - | ||
| - function assertActive() { | ||
| - const li = div.querySelector('li'); | ||
| - expect(li.className.split(' ').sort().join(' ')).to.equal('active dontKillMe'); | ||
| - const a = div.querySelector('a'); | ||
| - expect(a.className.split(' ').sort().join(' ')).to.equal(''); | ||
| - } | ||
| - | ||
| - function assertInactive() { | ||
| - const li = div.querySelector('li'); | ||
| - expect(li.className.split(' ').sort().join(' ')).to.equal('dontKillMe'); | ||
| - const a = div.querySelector('a'); | ||
| - expect(a.className.split(' ').sort().join(' ')).to.equal(''); | ||
| - } | ||
| - | ||
| - steps.push(() => { | ||
| - assertActive(); | ||
| - testLocation.push('/bar'); | ||
| - }); | ||
| - | ||
| - steps.push(() => { | ||
| - assertInactive(); | ||
| - testLocation.push('/foo'); | ||
| - }); | ||
| - | ||
| - steps.push(() => { | ||
| - assertActive(); | ||
| - done(); | ||
| - }); | ||
| - | ||
| - Router.run(routes, testLocation, function(Handler) { | ||
| - React.render(<Handler/>, div, () => { | ||
| - steps.shift()(); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| - | ||
| - describe('when clicked', function() { | ||
| - it('calls a user defined click handler', function(done) { | ||
| - const MenuItemLinkHandler = React.createClass({ | ||
| - handleClick(event) { | ||
| - assert.ok(true); | ||
| - done(); | ||
| - }, | ||
| - | ||
| - render() { | ||
| - return <MenuItemLink to="foo" onClick={this.handleClick}>MenuItemLink</MenuItemLink>; | ||
| - } | ||
| - }); | ||
| - | ||
| - const routes = [ | ||
| - <Route name="foo" handler={Foo} />, | ||
| - <Route name="link" handler={MenuItemLinkHandler} /> | ||
| - ]; | ||
| - const div = document.createElement('div'); | ||
| - const testLocation = new TestLocation(); | ||
| - testLocation.history = ['/link']; | ||
| - | ||
| - Router.run(routes, testLocation, function(Handler) { | ||
| - React.render(<Handler/>, div, function() { | ||
| - click(div.querySelector('a')); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| - | ||
| - it('transitions to the correct route', function(done) { | ||
| - const div = document.createElement('div'); | ||
| - const testLocation = new TestLocation(); | ||
| - testLocation.history = ['/link']; | ||
| - | ||
| - const MenuItemLinkHandler = React.createClass({ | ||
| - handleClick() { | ||
| - // just here to make sure click handlers don't prevent it from happening | ||
| - }, | ||
| - | ||
| - render() { | ||
| - return <MenuItemLink to="foo" onClick={this.handleClick}>MenuItemLink</MenuItemLink>; | ||
| - } | ||
| - }); | ||
| - | ||
| - const routes = [ | ||
| - <Route name="foo" handler={Foo} />, | ||
| - <Route name="link" handler={MenuItemLinkHandler} /> | ||
| - ]; | ||
| - | ||
| - const steps = []; | ||
| - | ||
| - steps.push(function() { | ||
| - click(div.querySelector('a'), {button: 0}); | ||
| - }); | ||
| - | ||
| - steps.push(function() { | ||
| - expect(div.innerHTML).to.match(/Foo/); | ||
| - done(); | ||
| - }); | ||
| - | ||
| - Router.run(routes, testLocation, function(Handler) { | ||
| - React.render(<Handler/>, div, function() { | ||
| - steps.shift()(); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| -}); |
190
tests/NavItemLink.spec.js
| @@ -1,190 +0,0 @@ | ||
| -/* globals describe, it, assert, expect */ | ||
| - | ||
| -import React from 'react/addons'; | ||
| -import NavItemLink from '../src/NavItemLink'; | ||
| -import Router, { Route, RouteHandler } from 'react-router'; | ||
| -import { Foo, Bar } from './TestHandlers'; | ||
| -import TestLocation from 'react-router/lib/locations/TestLocation'; | ||
| -const { click } = React.addons.TestUtils.Simulate; | ||
| - | ||
| -describe('A NavItemLink', function() { | ||
| - describe('with params and a query', function() { | ||
| - it('knows how to make its href', function() { | ||
| - const NavItemLinkHandler = React.createClass({ | ||
| - render() { | ||
| - return <NavItemLink to="foo" params={{bar: 'baz'}} query={{qux: 'quux'}}>NavItemLink</NavItemLink>; | ||
| - } | ||
| - }); | ||
| - | ||
| - const routes = [ | ||
| - <Route name="foo" path="foo/:bar" handler={Foo} />, | ||
| - <Route name="link" handler={NavItemLinkHandler} /> | ||
| - ]; | ||
| - | ||
| - const div = document.createElement('div'); | ||
| - const testLocation = new TestLocation(); | ||
| - testLocation.history = ['/link']; | ||
| - | ||
| - Router.run(routes, testLocation, function(Handler) { | ||
| - React.render(<Handler/>, div, function() { | ||
| - const a = div.querySelector('a'); | ||
| - expect(a.getAttribute('href')).to.equal('/foo/baz?qux=quux'); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| - | ||
| - describe('when its route is active', function() { | ||
| - it('has an active class name', function(done) { | ||
| - const NavItemLinkHandler = React.createClass({ | ||
| - render() { | ||
| - return ( | ||
| - <div> | ||
| - <NavItemLink | ||
| - to="foo" | ||
| - className="dontKillMe" | ||
| - >NavItemLink</NavItemLink> | ||
| - <RouteHandler/> | ||
| - </div> | ||
| - ); | ||
| - } | ||
| - }); | ||
| - | ||
| - const routes = ( | ||
| - <Route path="/" handler={NavItemLinkHandler}> | ||
| - <Route name="foo" handler={Foo} /> | ||
| - <Route name="bar" handler={Bar} /> | ||
| - </Route> | ||
| - ); | ||
| - | ||
| - const div = document.createElement('div'); | ||
| - const testLocation = new TestLocation(); | ||
| - testLocation.history = ['/foo']; | ||
| - const steps = []; | ||
| - | ||
| - function assertActive() { | ||
| - const a = div.querySelector('li'); | ||
| - expect(a.className.split(' ').sort().join(' ')).to.equal('active dontKillMe'); | ||
| - } | ||
| - | ||
| - function assertInactive() { | ||
| - const a = div.querySelector('li'); | ||
| - expect(a.className).to.equal('dontKillMe'); | ||
| - } | ||
| - | ||
| - steps.push(() => { | ||
| - assertActive(); | ||
| - testLocation.push('/bar'); | ||
| - }); | ||
| - | ||
| - steps.push(() => { | ||
| - assertInactive(); | ||
| - testLocation.push('/foo'); | ||
| - }); | ||
| - | ||
| - steps.push(() => { | ||
| - assertActive(); | ||
| - done(); | ||
| - }); | ||
| - | ||
| - Router.run(routes, testLocation, function(Handler) { | ||
| - React.render(<Handler/>, div, () => { | ||
| - steps.shift()(); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| - | ||
| - describe('when clicked', function() { | ||
| - it('calls a user defined click handler', function(done) { | ||
| - const NavItemLinkHandler = React.createClass({ | ||
| - handleClick(event) { | ||
| - assert.ok(true); | ||
| - done(); | ||
| - }, | ||
| - | ||
| - render() { | ||
| - return <NavItemLink to="foo" onClick={this.handleClick}>NavItemLink</NavItemLink>; | ||
| - } | ||
| - }); | ||
| - | ||
| - const routes = [ | ||
| - <Route name="foo" handler={Foo} />, | ||
| - <Route name="link" handler={NavItemLinkHandler} /> | ||
| - ]; | ||
| - const div = document.createElement('div'); | ||
| - const testLocation = new TestLocation(); | ||
| - testLocation.history = ['/link']; | ||
| - | ||
| - Router.run(routes, testLocation, function(Handler) { | ||
| - React.render(<Handler/>, div, function() { | ||
| - click(div.querySelector('a')); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| - | ||
| - it('when disabled does not proceed', function() { | ||
| - const NavItemLinkHandler = React.createClass({ | ||
| - handleClick(event) { | ||
| - throw new Error('click should not be called'); | ||
| - }, | ||
| - | ||
| - render() { | ||
| - return <NavItemLink to="foo" disabled onClick={this.handleClick}>NavItemLink</NavItemLink>; | ||
| - } | ||
| - }); | ||
| - | ||
| - const routes = [ | ||
| - <Route name="foo" handler={Foo} />, | ||
| - <Route name="link" handler={NavItemLinkHandler} /> | ||
| - ]; | ||
| - const div = document.createElement('div'); | ||
| - const testLocation = new TestLocation(); | ||
| - testLocation.history = ['/link']; | ||
| - | ||
| - Router.run(routes, testLocation, function(Handler) { | ||
| - React.render(<Handler/>, div, function() { | ||
| - click(div.querySelector('a')); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| - | ||
| - it('transitions to the correct route', function(done) { | ||
| - const div = document.createElement('div'); | ||
| - const testLocation = new TestLocation(); | ||
| - testLocation.history = ['/link']; | ||
| - | ||
| - const NavItemLinkHandler = React.createClass({ | ||
| - handleClick() { | ||
| - // just here to make sure click handlers don't prevent it from happening | ||
| - }, | ||
| - | ||
| - render() { | ||
| - return <NavItemLink to="foo" onClick={this.handleClick}>NavItemLink</NavItemLink>; | ||
| - } | ||
| - }); | ||
| - | ||
| - const routes = [ | ||
| - <Route name="foo" handler={Foo} />, | ||
| - <Route name="link" handler={NavItemLinkHandler} /> | ||
| - ]; | ||
| - | ||
| - const steps = []; | ||
| - | ||
| - steps.push(function() { | ||
| - click(div.querySelector('a'), {button: 0}); | ||
| - }); | ||
| - | ||
| - steps.push(function() { | ||
| - expect(div.innerHTML).to.match(/Foo/); | ||
| - done(); | ||
| - }); | ||
| - | ||
| - Router.run(routes, testLocation, function(Handler) { | ||
| - React.render(<Handler/>, div, function() { | ||
| - steps.shift()(); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| -}); |
103
tests/PageItemLink.spec.js
| @@ -1,103 +0,0 @@ | ||
| -/* globals describe, it, assert, expect */ | ||
| - | ||
| -import React from 'react/addons'; | ||
| -import PageItemLink from '../src/PageItemLink'; | ||
| -import Router, { Route } from 'react-router'; | ||
| -import { Foo } from './TestHandlers'; | ||
| -import TestLocation from 'react-router/lib/locations/TestLocation'; | ||
| -const { click } = React.addons.TestUtils.Simulate; | ||
| - | ||
| -describe('A PageItemLink', function() { | ||
| - describe('with params and a query', function() { | ||
| - it('knows how to make its href', function() { | ||
| - const PageItemLinkHandler = React.createClass({ | ||
| - render() { | ||
| - return <PageItemLink to="foo" params={{bar: 'baz'}} query={{qux: 'quux'}}>PageItemLink</PageItemLink>; | ||
| - } | ||
| - }); | ||
| - | ||
| - const routes = [ | ||
| - <Route name="foo" path="foo/:bar" handler={Foo} />, | ||
| - <Route name="link" handler={PageItemLinkHandler} /> | ||
| - ]; | ||
| - | ||
| - const div = document.createElement('div'); | ||
| - const testLocation = new TestLocation(); | ||
| - testLocation.history = ['/link']; | ||
| - | ||
| - Router.run(routes, testLocation, function(Handler) { | ||
| - React.render(<Handler/>, div, function() { | ||
| - const a = div.querySelector('a'); | ||
| - expect(a.getAttribute('href')).to.equal('/foo/baz?qux=quux'); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| - | ||
| - describe('when clicked', function() { | ||
| - it('calls a user defined click handler', function(done) { | ||
| - const PageItemLinkHandler = React.createClass({ | ||
| - handleClick(event) { | ||
| - assert.ok(true); | ||
| - done(); | ||
| - }, | ||
| - | ||
| - render() { | ||
| - return <PageItemLink to="foo" onClick={this.handleClick}>PageItemLink</PageItemLink>; | ||
| - } | ||
| - }); | ||
| - | ||
| - const routes = [ | ||
| - <Route name="foo" handler={Foo} />, | ||
| - <Route name="link" handler={PageItemLinkHandler} /> | ||
| - ]; | ||
| - const div = document.createElement('div'); | ||
| - const testLocation = new TestLocation(); | ||
| - testLocation.history = ['/link']; | ||
| - | ||
| - Router.run(routes, testLocation, function(Handler) { | ||
| - React.render(<Handler/>, div, function() { | ||
| - click(div.querySelector('a')); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| - | ||
| - it('transitions to the correct route', function(done) { | ||
| - const div = document.createElement('div'); | ||
| - const testLocation = new TestLocation(); | ||
| - testLocation.history = ['/link']; | ||
| - | ||
| - const PageItemLinkHandler = React.createClass({ | ||
| - handleClick() { | ||
| - // just here to make sure click handlers don't prevent it from happening | ||
| - }, | ||
| - | ||
| - render() { | ||
| - return <PageItemLink to="foo" onClick={this.handleClick}>PageItemLink</PageItemLink>; | ||
| - } | ||
| - }); | ||
| - | ||
| - const routes = [ | ||
| - <Route name="foo" handler={Foo} />, | ||
| - <Route name="link" handler={PageItemLinkHandler} /> | ||
| - ]; | ||
| - | ||
| - const steps = []; | ||
| - | ||
| - steps.push(function() { | ||
| - click(div.querySelector('a'), {button: 0}); | ||
| - }); | ||
| - | ||
| - steps.push(function() { | ||
| - expect(div.innerHTML).to.match(/Foo/); | ||
| - done(); | ||
| - }); | ||
| - | ||
| - Router.run(routes, testLocation, function(Handler) { | ||
| - React.render(<Handler/>, div, function() { | ||
| - steps.shift()(); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| -}); |
13
tests/RouterOverlayTrigger.spec.js
| @@ -1,13 +0,0 @@ | ||
| -/* globals describe, it, expect */ | ||
| - | ||
| -import React from 'react'; | ||
| - | ||
| -import RouterOverlayTrigger from '../src/RouterOverlayTrigger'; | ||
| - | ||
| -describe('A RouterOverlayTrigger', function() { | ||
| - it('has the right contextTypes', function() { | ||
| - expect(RouterOverlayTrigger.contextTypes).to.eql({ | ||
| - router: React.PropTypes.func | ||
| - }); | ||
| - }); | ||
| -}); |
31
tests/TestHandlers.js
| @@ -1,31 +0,0 @@ | ||
| -import React from 'react'; | ||
| -import { RouteHandler } from 'react-router'; | ||
| - | ||
| -exports.Nested = React.createClass({ | ||
| - render() { | ||
| - return ( | ||
| - <div> | ||
| - <h1 className="Nested">Nested</h1> | ||
| - <RouteHandler /> | ||
| - </div> | ||
| - ); | ||
| - } | ||
| -}); | ||
| - | ||
| -exports.Foo = React.createClass({ | ||
| - render() { | ||
| - return <div className="Foo">Foo</div>; | ||
| - } | ||
| -}); | ||
| - | ||
| -exports.Bar = React.createClass({ | ||
| - render() { | ||
| - return <div className="Bar">Bar</div>; | ||
| - } | ||
| -}); | ||
| - | ||
| -exports.Baz = React.createClass({ | ||
| - render() { | ||
| - return <div className="Baz">Baz</div>; | ||
| - } | ||
| -}); |
103
tests/ThumbnailLink.spec.js
| @@ -1,103 +0,0 @@ | ||
| -/* globals describe, it, assert, expect */ | ||
| - | ||
| -import React from 'react/addons'; | ||
| -import ThumbnailLink from '../src/ThumbnailLink'; | ||
| -import Router, { Route } from 'react-router'; | ||
| -import { Foo } from './TestHandlers'; | ||
| -import TestLocation from 'react-router/lib/locations/TestLocation'; | ||
| -const { click } = React.addons.TestUtils.Simulate; | ||
| - | ||
| -describe('A ThumbnailLink', function() { | ||
| - describe('with params and a query', function() { | ||
| - it('knows how to make its href', function() { | ||
| - const ThumbnailLinkHandler = React.createClass({ | ||
| - render() { | ||
| - return <ThumbnailLink to="foo" params={{bar: 'baz'}} query={{qux: 'quux'}} />; | ||
| - } | ||
| - }); | ||
| - | ||
| - const routes = [ | ||
| - <Route name="foo" path="foo/:bar" handler={Foo} />, | ||
| - <Route name="link" handler={ThumbnailLinkHandler} /> | ||
| - ]; | ||
| - | ||
| - const div = document.createElement('div'); | ||
| - const testLocation = new TestLocation(); | ||
| - testLocation.history = ['/link']; | ||
| - | ||
| - Router.run(routes, testLocation, function(Handler) { | ||
| - React.render(<Handler/>, div, function() { | ||
| - const a = div.querySelector('a'); | ||
| - expect(a.getAttribute('href')).to.equal('/foo/baz?qux=quux'); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| - | ||
| - describe('when clicked', function() { | ||
| - it('calls a user defined click handler', function(done) { | ||
| - const ThumbnailLinkHandler = React.createClass({ | ||
| - handleClick(event) { | ||
| - assert.ok(true); | ||
| - done(); | ||
| - }, | ||
| - | ||
| - render() { | ||
| - return <ThumbnailLink to="foo" onClick={this.handleClick} />; | ||
| - } | ||
| - }); | ||
| - | ||
| - const routes = [ | ||
| - <Route name="foo" handler={Foo} />, | ||
| - <Route name="link" handler={ThumbnailLinkHandler} /> | ||
| - ]; | ||
| - const div = document.createElement('div'); | ||
| - const testLocation = new TestLocation(); | ||
| - testLocation.history = ['/link']; | ||
| - | ||
| - Router.run(routes, testLocation, function(Handler) { | ||
| - React.render(<Handler/>, div, function() { | ||
| - click(div.querySelector('a')); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| - | ||
| - it('transitions to the correct route', function(done) { | ||
| - const div = document.createElement('div'); | ||
| - const testLocation = new TestLocation(); | ||
| - testLocation.history = ['/link']; | ||
| - | ||
| - const ThumbnailLinkHandler = React.createClass({ | ||
| - handleClick() { | ||
| - // just here to make sure click handlers don't prevent it from happening | ||
| - }, | ||
| - | ||
| - render() { | ||
| - return <ThumbnailLink to="foo" onClick={this.handleClick} />; | ||
| - } | ||
| - }); | ||
| - | ||
| - const routes = [ | ||
| - <Route name="foo" handler={Foo} />, | ||
| - <Route name="link" handler={ThumbnailLinkHandler} /> | ||
| - ]; | ||
| - | ||
| - const steps = []; | ||
| - | ||
| - steps.push(function() { | ||
| - click(div.querySelector('a'), {button: 0}); | ||
| - }); | ||
| - | ||
| - steps.push(function() { | ||
| - expect(div.innerHTML).to.match(/Foo/); | ||
| - done(); | ||
| - }); | ||
| - | ||
| - Router.run(routes, testLocation, function(Handler) { | ||
| - React.render(<Handler/>, div, function() { | ||
| - steps.shift()(); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| - }); | ||
| -}); |
21
tests/bower-imports-module.spec.js
| @@ -1,21 +0,0 @@ | ||
| -import loader from '../webpack/bower-imports-loader'; | ||
| - | ||
| -describe('bower-imports-loader', function() { | ||
| - it('replaces react-bootstrap/lib/* imports to work with bower dependency', function() { | ||
| - const input = `import React from 'react'; | ||
| - | ||
| -import Button from 'react-bootstrap/lib/Button'; | ||
| -import LinkMixin from './LinkMixin'; | ||
| - | ||
| -const ButtonLink = React.createClass({`; | ||
| - | ||
| - const expected = `import React from 'react'; | ||
| - | ||
| -import {Button} from 'react-bootstrap'; | ||
| -import LinkMixin from './LinkMixin'; | ||
| - | ||
| -const ButtonLink = React.createClass({`; | ||
| - | ||
| - loader(input).should.equal(expected); | ||
| - }); | ||
| -}); |
21
tests/index.js
| @@ -1,19 +1,4 @@ | ||
| -import './phantom-shims'; | ||
| -import 'mocha'; | ||
| +import 'es5-shim'; | ||
| -const chai = require('chai'); | ||
| -chai.should(); | ||
| - | ||
| -global.expect = chai.expect; | ||
| -global.assert = chai.assert; | ||
| - | ||
| -global.TestUtils = require('react/addons').addons.TestUtils; | ||
| - | ||
| -import './ButtonLink.spec.js'; | ||
| -import './ListGroupItemLink.spec.js'; | ||
| -import './MenuItemLink.spec.js'; | ||
| -import './NavItemLink.spec.js'; | ||
| -import './PageItemLink.spec.js'; | ||
| -import './RouterOverlayTrigger.spec.js'; | ||
| -import './ThumbnailLink.spec.js'; | ||
| -import './bower-imports-module.spec.js'; | ||
| +const testsContext = require.context('.', true, /\.spec\.js$/); | ||
| +testsContext.keys().forEach(testsContext); |
31
tests/phantom-shims.js
| @@ -1,31 +0,0 @@ | ||
| -const Ap = Array.prototype; | ||
| -const slice = Ap.slice; | ||
| -const Fp = Function.prototype; | ||
| - | ||
| -if (!Fp.bind) { | ||
| - // PhantomJS doesn't support Function.prototype.bind natively, so | ||
| - // polyfill it whenever this module is required. | ||
| - Fp.bind = function(context) { | ||
| - const func = this; | ||
| - const args = slice.call(arguments, 1); | ||
| - | ||
| - function bound() { | ||
| - const invokedAsConstructor = func.prototype && (this instanceof func); | ||
| - return func.apply( | ||
| - // Ignore the context parameter when invoking the bound function | ||
| - // as a constructor. Note that this includes not only constructor | ||
| - // invocations using the new keyword but also calls to base class | ||
| - // constructors such as BaseClass.call(this, ...) or super(...). | ||
| - !invokedAsConstructor && context || this, | ||
| - args.concat(slice.call(arguments)) | ||
| - ); | ||
| - } | ||
| - | ||
| - // The bound function must share the .prototype of the unbound | ||
| - // function so that any object created by one constructor will count | ||
| - // as an instance of both constructors. | ||
| - bound.prototype = func.prototype; | ||
| - | ||
| - return bound; | ||
| - }; | ||
| -} |
2
tests/visual.js
| @@ -1,2 +0,0 @@ | ||
| -import 'bootstrap/less/bootstrap.less'; | ||
| -import './visual/app'; |
71
tests/visual/ButtonVisual.js
| @@ -1,36 +1,45 @@ | ||
| import React from 'react'; | ||
| -import {Link} from 'react-router'; | ||
| import ButtonToolbar from 'react-bootstrap/lib/ButtonToolbar'; | ||
| import Button from 'react-bootstrap/lib/Button'; | ||
| -import ButtonLink from '../../src/ButtonLink'; | ||
| +import {Link} from 'react-router'; | ||
| + | ||
| +import LinkContainer from '../../src/LinkContainer'; | ||
| + | ||
| +export default () => ( | ||
| + <div> | ||
| + <Link to="home">Back to Index</Link> | ||
| + <h2>Button</h2> | ||
| -const ButtonVisual = React.createClass({ | ||
| - render() { | ||
| - return ( | ||
| - <div> | ||
| - <Link to='home'><-- Back to Index</Link> | ||
| - <h2>ButtonLink</h2> | ||
| - <h3>Baseline (Raw React-Bootstrap)</h3> | ||
| - <ButtonToolbar> | ||
| - <Button>Default</Button> | ||
| - <Button bsStyle="success">Success</Button> | ||
| - <Button bsStyle="info">Info</Button> | ||
| - <Button bsStyle="warning">Warning</Button> | ||
| - <Button bsStyle="danger">Danger</Button> | ||
| - <Button bsStyle="link">Link</Button> | ||
| - </ButtonToolbar> | ||
| - <h3>ButtonLink</h3> | ||
| - <ButtonToolbar> | ||
| - <ButtonLink to='home'>Default</ButtonLink> | ||
| - <ButtonLink to='home' bsStyle="success">Success</ButtonLink> | ||
| - <ButtonLink to='home' bsStyle="info">Info</ButtonLink> | ||
| - <ButtonLink to='home' bsStyle="warning">Warning</ButtonLink> | ||
| - <ButtonLink to='home' bsStyle="danger">Danger</ButtonLink> | ||
| - <ButtonLink to='home' bsStyle="link">Link</ButtonLink> | ||
| - </ButtonToolbar> | ||
| - </div> | ||
| - ); | ||
| - } | ||
| -}); | ||
| + <h3>Baseline</h3> | ||
| + <ButtonToolbar> | ||
| + <Button>Default</Button> | ||
| + <Button bsStyle="success">Success</Button> | ||
| + <Button bsStyle="info">Info</Button> | ||
| + <Button bsStyle="warning">Warning</Button> | ||
| + <Button bsStyle="danger">Danger</Button> | ||
| + <Button bsStyle="link">Link</Button> | ||
| + </ButtonToolbar> | ||
| -export default ButtonVisual; | ||
| + <h3>LinkContainer</h3> | ||
| + <ButtonToolbar> | ||
| + <LinkContainer to="/home"> | ||
| + <Button>Default</Button> | ||
| + </LinkContainer> | ||
| + <LinkContainer to="/home"> | ||
| + <Button bsStyle="success">Success</Button> | ||
| + </LinkContainer> | ||
| + <LinkContainer to="/home"> | ||
| + <Button bsStyle="info">Info</Button> | ||
| + </LinkContainer> | ||
| + <LinkContainer to="/home"> | ||
| + <Button bsStyle="warning">Warning</Button> | ||
| + </LinkContainer> | ||
| + <LinkContainer to="/home"> | ||
| + <Button bsStyle="danger">Danger</Button> | ||
| + </LinkContainer> | ||
| + <LinkContainer to="/home"> | ||
| + <Button bsStyle="link">Link</Button> | ||
| + </LinkContainer> | ||
| + </ButtonToolbar> | ||
| + </div> | ||
| +); |
108
tests/visual/ListGroupItemVisual.js
| @@ -1,41 +1,77 @@ | ||
| import React from 'react'; | ||
| -import {Link} from 'react-router'; | ||
| import ListGroup from 'react-bootstrap/lib/ListGroup'; | ||
| import ListGroupItem from 'react-bootstrap/lib/ListGroupItem'; | ||
| -import ListGroupItemLink from '../../src/ListGroupItemLink'; | ||
| +import {Link} from 'react-router'; | ||
| + | ||
| +import LinkContainer from '../../src/LinkContainer'; | ||
| + | ||
| +export default () => ( | ||
| + <div> | ||
| + <Link to="/home">Back to Index</Link> | ||
| + <h2>ListGroupItem</h2> | ||
| -const NavItemVisual = React.createClass({ | ||
| - handleSelect(selectedKey) { | ||
| - window.alert('selected ' + selectedKey); | ||
| - }, | ||
| - render() { | ||
| - return ( | ||
| - <div> | ||
| - <Link to='home'><-- Back to Index</Link> | ||
| - <h2>ListGroupItemLink</h2> | ||
| - <h3>Baseline (Raw React-Bootstrap)</h3> | ||
| - <ListGroup> | ||
| - <ListGroupItem eventKey={1} href="/home" header="ListGroupItem 1 Heading">ListGroupItem 1 content</ListGroupItem> | ||
| - <ListGroupItem eventKey={2} header="ListGroupItem 2 Heading">ListGroupItem 2 content</ListGroupItem> | ||
| - <ListGroupItem eventKey={3} disabled={true}>ListGroupItem 3 content disabled</ListGroupItem> | ||
| - <ListGroupItem eventKey={4} bsStyle="success">ListGroupItem 4 content success</ListGroupItem> | ||
| - <ListGroupItem eventKey={5} bsStyle="info">ListGroupItem 5 content info</ListGroupItem> | ||
| - <ListGroupItem eventKey={6} bsStyle="warning">ListGroupItem 6 content warning</ListGroupItem> | ||
| - <ListGroupItem eventKey={7} bsStyle="danger">ListGroupItem 7 content danger</ListGroupItem> | ||
| - </ListGroup> | ||
| - <h3>ListGroupItemLink</h3> | ||
| - <ListGroup> | ||
| - <ListGroupItemLink to="list-group-item" header="ListGroupItemLink 1 Heading">ListGroupItemLink 1 content</ListGroupItemLink> | ||
| - <ListGroupItemLink to="home" header="ListGroupItemLink 2 Heading">ListGroupItemLink 2 content</ListGroupItemLink> | ||
| - <ListGroupItemLink to="home" disabled={true}>ListGroupItemLink 3 content disabled</ListGroupItemLink> | ||
| - <ListGroupItemLink to="home" bsStyle="success">ListGroupItemLink 4 content success</ListGroupItemLink> | ||
| - <ListGroupItemLink to="home" bsStyle="info">ListGroupItemLink 5 content info</ListGroupItemLink> | ||
| - <ListGroupItemLink to="home" bsStyle="warning">ListGroupItemLink 6 content warning</ListGroupItemLink> | ||
| - <ListGroupItemLink to="home" bsStyle="danger">ListGroupItemLink 7 content danger</ListGroupItemLink> | ||
| - </ListGroup> | ||
| - </div> | ||
| - ); | ||
| - } | ||
| -}); | ||
| + <h3>Baseline</h3> | ||
| + <ListGroup> | ||
| + <ListGroupItem href="#/home" active header="ListGroupItem 1 Heading"> | ||
| + ListGroupItem 1 content | ||
| + </ListGroupItem> | ||
| + <ListGroupItem header="ListGroupItem 2 Heading"> | ||
| + ListGroupItem 2 content | ||
| + </ListGroupItem> | ||
| + <ListGroupItem disabled> | ||
| + ListGroupItem 3 content disabled | ||
| + </ListGroupItem> | ||
| + <ListGroupItem bsStyle="success"> | ||
| + ListGroupItem 4 content success | ||
| + </ListGroupItem> | ||
| + <ListGroupItem bsStyle="info"> | ||
| + ListGroupItem 5 content info | ||
| + </ListGroupItem> | ||
| + <ListGroupItem bsStyle="warning"> | ||
| + ListGroupItem 6 content warning | ||
| + </ListGroupItem> | ||
| + <ListGroupItem bsStyle="danger"> | ||
| + ListGroupItem 7 content danger | ||
| + </ListGroupItem> | ||
| + </ListGroup> | ||
| -export default NavItemVisual; | ||
| + <h3>LinkContainer</h3> | ||
| + <ListGroup> | ||
| + <LinkContainer to="/list-group-item"> | ||
| + <ListGroupItem header="ListGroupItem 1 Heading"> | ||
| + ListGroupItem 1 content | ||
| + </ListGroupItem> | ||
| + </LinkContainer> | ||
| + <LinkContainer to="/home"> | ||
| + <ListGroupItem header="ListGroupItem 2 Heading"> | ||
| + ListGroupItem 2 content | ||
| + </ListGroupItem> | ||
| + </LinkContainer> | ||
| + <LinkContainer to="/home" disabled> | ||
| + <ListGroupItem> | ||
| + ListGroupItem 3 content disabled | ||
| + </ListGroupItem> | ||
| + </LinkContainer> | ||
| + <LinkContainer to="/home"> | ||
| + <ListGroupItem bsStyle="success"> | ||
| + ListGroupItem 4 content success | ||
| + </ListGroupItem> | ||
| + </LinkContainer> | ||
| + <LinkContainer to="/home"> | ||
| + <ListGroupItem bsStyle="info"> | ||
| + ListGroupItem 5 content info | ||
| + </ListGroupItem> | ||
| + </LinkContainer> | ||
| + <LinkContainer to="/home"> | ||
| + <ListGroupItem bsStyle="warning"> | ||
| + ListGroupItem 6 content warning | ||
| + </ListGroupItem> | ||
| + </LinkContainer> | ||
| + <LinkContainer to="/home"> | ||
| + <ListGroupItem bsStyle="danger"> | ||
| + ListGroupItem 7 content danger | ||
| + </ListGroupItem> | ||
| + </LinkContainer> | ||
| + </ListGroup> | ||
| + </div> | ||
| +); |
42
tests/visual/MenuItemVisual.js
| @@ -1,42 +0,0 @@ | ||
| -import React from 'react'; | ||
| -import {Link} from 'react-router'; | ||
| -import ButtonToolbar from 'react-bootstrap/lib/ButtonToolbar'; | ||
| -import SplitButton from 'react-bootstrap/lib/SplitButton'; | ||
| -import MenuItem from 'react-bootstrap/lib/MenuItem'; | ||
| -import MenuItemLink from '../../src/MenuItemLink'; | ||
| - | ||
| -const MenuItemVisual = React.createClass({ | ||
| - handleSelect(selectedKey) { | ||
| - window.alert('selected ' + selectedKey); | ||
| - }, | ||
| - render() { | ||
| - return ( | ||
| - <div> | ||
| - <Link to='home'><-- Back to Index</Link> | ||
| - <h2>MenuItemLink</h2> | ||
| - <h3>Baseline (Raw React-Bootstrap)</h3> | ||
| - <ButtonToolbar> | ||
| - <SplitButton title="Dropdown"> | ||
| - <MenuItem eventKey="1">Action</MenuItem> | ||
| - <MenuItem eventKey="2">Another action</MenuItem> | ||
| - <MenuItem eventKey="3">Something else here</MenuItem> | ||
| - <MenuItem divider /> | ||
| - <MenuItem eventKey="4">Separated link</MenuItem> | ||
| - </SplitButton> | ||
| - </ButtonToolbar> | ||
| - <h3>MenuItemLink</h3> | ||
| - <ButtonToolbar> | ||
| - <SplitButton title="Dropdown"> | ||
| - <MenuItemLink to='menu-item'>Action</MenuItemLink> | ||
| - <MenuItemLink to='home'>Another action</MenuItemLink> | ||
| - <MenuItemLink to='home'>Something else here</MenuItemLink> | ||
| - <MenuItem divider /> | ||
| - <MenuItemLink to='home'>Separated link</MenuItemLink> | ||
| - </SplitButton> | ||
| - </ButtonToolbar> | ||
| - </div> | ||
| - ); | ||
| - } | ||
| -}); | ||
| - | ||
| -export default MenuItemVisual; |
56
tests/visual/NavItemVisual.js
| @@ -1,33 +1,33 @@ | ||
| import React from 'react'; | ||
| -import {Link} from 'react-router'; | ||
| import Nav from 'react-bootstrap/lib/Nav'; | ||
| import NavItem from 'react-bootstrap/lib/NavItem'; | ||
| -import NavItemLink from '../../src/NavItemLink'; | ||
| +import {Link} from 'react-router'; | ||
| + | ||
| +import LinkContainer from '../../src/LinkContainer'; | ||
| + | ||
| +export default () => ( | ||
| + <div> | ||
| + <Link to="/home">Back to Index</Link> | ||
| + <h2>NavItem</h2> | ||
| -const NavItemVisual = React.createClass({ | ||
| - handleSelect(selectedKey) { | ||
| - window.alert('selected ' + selectedKey); | ||
| - }, | ||
| - render() { | ||
| - return ( | ||
| - <div> | ||
| - <Link to='home'><-- Back to Index</Link> | ||
| - <h2>NavItemLink</h2> | ||
| - <h3>Baseline (Raw React-Bootstrap)</h3> | ||
| - <Nav bsStyle="pills" activeKey={1} onSelect={this.handleSelect}> | ||
| - <NavItem eventKey={1} href="/home">NavItem 1 content</NavItem> | ||
| - <NavItem eventKey={2} title="Item">NavItem 2 content</NavItem> | ||
| - <NavItem eventKey={3} disabled={true}>NavItem 3 content</NavItem> | ||
| - </Nav> | ||
| - <h3>NavItemLink</h3> | ||
| - <Nav bsStyle="pills"> | ||
| - <NavItemLink to='nav-item'>NavItemLink 1 content</NavItemLink> | ||
| - <NavItemLink to='home'>NavItemLink 2 content</NavItemLink> | ||
| - <NavItemLink to='home' disabled={true}>NavItemLink 3 content</NavItemLink> | ||
| - </Nav> | ||
| - </div> | ||
| - ); | ||
| - } | ||
| -}); | ||
| + <h3>Baseline</h3> | ||
| + <Nav bsStyle="pills" activeKey={1}> | ||
| + <NavItem eventKey={1}>NavItem 1 content</NavItem> | ||
| + <NavItem eventKey={2}>NavItem 2 content</NavItem> | ||
| + <NavItem eventKey={3} disabled>NavItem 3 content</NavItem> | ||
| + </Nav> | ||
| -export default NavItemVisual; | ||
| + <h3>LinkContainer</h3> | ||
| + <Nav bsStyle="pills"> | ||
| + <LinkContainer to="/nav-item"> | ||
| + <NavItem>NavItem 1 content</NavItem> | ||
| + </LinkContainer> | ||
| + <LinkContainer to="/home"> | ||
| + <NavItem>NavItem 2 content</NavItem> | ||
| + </LinkContainer> | ||
| + <LinkContainer to="/home" disabled> | ||
| + <NavItem>NavItem 3 content</NavItem> | ||
| + </LinkContainer> | ||
| + </Nav> | ||
| + </div> | ||
| +); |
28
tests/visual/PageItemVisual.js
| @@ -1,28 +0,0 @@ | ||
| -import React from 'react'; | ||
| -import {Link} from 'react-router'; | ||
| -import Pager from 'react-bootstrap/lib/Pager'; | ||
| -import PageItem from 'react-bootstrap/lib/PageItem'; | ||
| -import PageItemLink from '../../src/PageItemLink'; | ||
| - | ||
| -const PageItemVisual = React.createClass({ | ||
| - render() { | ||
| - return ( | ||
| - <div> | ||
| - <Link to='home'><-- Back to Index</Link> | ||
| - <h2>PageItemLink</h2> | ||
| - <h3>Baseline (Raw React-Bootstrap)</h3> | ||
| - <Pager> | ||
| - <PageItem previous>← Previous Page</PageItem> | ||
| - <PageItem next>Next Page →</PageItem> | ||
| - </Pager> | ||
| - <h3>PageItemLink</h3> | ||
| - <Pager> | ||
| - <PageItemLink previous to='home'>← Previous Page</PageItemLink> | ||
| - <PageItemLink next to='home'>Next Page →</PageItemLink> | ||
| - </Pager> | ||
| - </div> | ||
| - ); | ||
| - } | ||
| -}); | ||
| - | ||
| -export default PageItemVisual; |
21
tests/visual/ThumbnailVisual.js
| @@ -1,21 +0,0 @@ | ||
| -import React from 'react'; | ||
| -import {Link} from 'react-router'; | ||
| -import Thumbnail from 'react-bootstrap/lib/Thumbnail'; | ||
| -import ThumbnailLink from '../../src/ThumbnailLink'; | ||
| - | ||
| -const ThumbnailVisual = React.createClass({ | ||
| - render() { | ||
| - return ( | ||
| - <div> | ||
| - <Link to='home'><-- Back to Index</Link> | ||
| - <h2>Thumbnailink</h2> | ||
| - <h3>Baseline (Raw React-Bootstrap)</h3> | ||
| - <Thumbnail alt='171x180' src='/assets/thumbnail.png' /> | ||
| - <h3>ThumbnailLink</h3> | ||
| - <ThumbnailLink to='home' alt='171x180' src='/assets/thumbnail.png' /> | ||
| - </div> | ||
| - ); | ||
| - } | ||
| -}); | ||
| - | ||
| -export default ThumbnailVisual; |
29
tests/visual/app.js
| @@ -1,29 +0,0 @@ | ||
| -import React from 'react'; | ||
| -import Router, { Route, RouteHandler } from 'react-router'; | ||
| - | ||
| -const App = React.createClass({ | ||
| - render() { | ||
| - return ( | ||
| - <div> | ||
| - <h1>React-Router-Bootstrap Module Visual Test</h1> | ||
| - <RouteHandler /> | ||
| - </div> | ||
| - ); | ||
| - } | ||
| -}); | ||
| - | ||
| -const routes = ( | ||
| - <Route handler={App} path="/"> | ||
| - <Route name='home' path='/' handler={require('./home')} /> | ||
| - <Route name='button' handler={require('./ButtonVisual')} /> | ||
| - <Route name='nav-item' handler={require('./NavItemVisual')} /> | ||
| - <Route name='menu-item' handler={require('./MenuItemVisual')} /> | ||
| - <Route name='list-group-item' handler={require('./ListGroupItemVisual')} /> | ||
| - <Route name='page-item' handler={require('./PageItemVisual')} /> | ||
| - <Route name='thumbnail' handler={require('./ThumbnailVisual')} /> | ||
| - </Route> | ||
| -); | ||
| - | ||
| -Router.run(routes, function(Handler) { | ||
| - React.render(<Handler/>, document.body); | ||
| -}); |
29
tests/visual/home.js
| @@ -1,22 +1,13 @@ | ||
| import React from 'react'; | ||
| import {Link} from 'react-router'; | ||
| -const Home = React.createClass({ | ||
| - render() { | ||
| - return ( | ||
| - <div> | ||
| - <h2>Index</h2> | ||
| - <ul> | ||
| - <li><Link to='button'>ButtonLink</Link></li> | ||
| - <li><Link to='nav-item'>NavItemLink</Link></li> | ||
| - <li><Link to='menu-item'>MenuItemLink</Link></li> | ||
| - <li><Link to='list-group-item'>ListGroupItemLink</Link></li> | ||
| - <li><Link to='page-item'>PageItemLink</Link></li> | ||
| - <li><Link to='thumbnail'>ThumbnailLink</Link></li> | ||
| - </ul> | ||
| - </div> | ||
| - ); | ||
| - } | ||
| -}); | ||
| - | ||
| -export default Home; | ||
| +export default () => ( | ||
| + <div> | ||
| + <h2>Index</h2> | ||
| + <ul> | ||
| + <li><Link to="/button">Button</Link></li> | ||
| + <li><Link to="/nav-item">NavItem</Link></li> | ||
| + <li><Link to="/list-group-item">ListGroupItem</Link></li> | ||
| + </ul> | ||
| + </div> | ||
| +); |
35
tests/visual/index.js
| @@ -0,0 +1,35 @@ | ||
| +import React from 'react'; | ||
| +import Grid from 'react-bootstrap/lib/Grid'; | ||
| +import ReactDOM from 'react-dom'; | ||
| +import {IndexRoute, Route, Router} from 'react-router'; | ||
| + | ||
| +import ButtonVisual from './ButtonVisual'; | ||
| +import Home from './Home'; | ||
| +import ListGroupItemVisual from './ListGroupItemVisual'; | ||
| +import NavItemVisual from './NavItemVisual'; | ||
| + | ||
| +import 'bootstrap/less/bootstrap.less'; | ||
| + | ||
| +const App = ({children}) => ( | ||
| + <Grid> | ||
| + <h1>React-Router-Bootstrap Module Visual Test</h1> | ||
| + {children} | ||
| + </Grid> | ||
| +); | ||
| + | ||
| +const mountNode = document.createElement('div'); | ||
| +document.body.appendChild(mountNode); | ||
| + | ||
| +ReactDOM.render( | ||
| + <Router> | ||
| + <Route path="/" component={App}> | ||
| + <IndexRoute onEnter={(_, replaceWith) => replaceWith(null, '/home')} /> | ||
| + <Route path="home" component={Home} /> | ||
| + | ||
| + <Route path="button" component={ButtonVisual} /> | ||
| + <Route path="nav-item" component={NavItemVisual} /> | ||
| + <Route path="list-group-item" component={ListGroupItemVisual} /> | ||
| + </Route> | ||
| + </Router>, | ||
| + mountNode | ||
| +); |
50
webpack.config.babel.js
23
webpack.test.config.babel.js
| @@ -1,24 +1,11 @@ | ||
| -import path from 'path'; | ||
| - | ||
| -module.exports = { | ||
| - entry: { | ||
| - visual: ['./tests/visual.js'] | ||
| - }, | ||
| - | ||
| - devtool: 'inline-source-map', | ||
| - | ||
| +export default { | ||
| output: { | ||
| - path: path.join(__dirname, 'tests-served/'), | ||
| - publicPath: '/public/', | ||
| - filename: '[name].js' | ||
| + pathinfo: true | ||
| }, | ||
| - | ||
| module: { | ||
| loaders: [ | ||
| - {test: /\.js/, loader: 'babel', exclude: /node_modules/}, | ||
| - {test: /\.less$/, loader: 'style!css!less'}, | ||
| - {test:/\.woff|\.woff2$/, loader: 'url?prefix=font/&limit=5000'}, | ||
| - {test:/\.eot$|\.ttf$|\.svg$/, loader: 'file?prefix=font/'} | ||
| + {test: /\.js/, loader: 'babel', exclude: /node_modules/} | ||
| ] | ||
| - } | ||
| + }, | ||
| + devtool: 'inline-source-map' | ||
| }; |
17
webpack.visual.config.babel.js
| @@ -0,0 +1,17 @@ | ||
| +import HtmlWebpackPlugin from 'html-webpack-plugin'; | ||
| + | ||
| +export default { | ||
| + entry: './tests/visual', | ||
| + module: { | ||
| + loaders: [ | ||
| + {test: /\.js/, loader: 'babel', exclude: /node_modules/}, | ||
| + {test: /\.less$/, loader: 'style!css!less'}, | ||
| + {test: /\.woff|\.woff2$/, loader: 'url?prefix=font/&limit=5000'}, | ||
| + {test: /\.eot$|\.ttf$|\.svg$/, loader: 'file?prefix=font/'} | ||
| + ] | ||
| + }, | ||
| + plugins: [ | ||
| + new HtmlWebpackPlugin() | ||
| + ], | ||
| + devtool: 'eval-source-map' | ||
| +}; |
7
webpack/bower-imports-loader.js
| @@ -1,7 +0,0 @@ | ||
| -export default function bowerImportsLoader(source) { | ||
| - const rgx = /^import (.*) from 'react-bootstrap\/lib\/.*';/; | ||
| - | ||
| - return source.split('\n') | ||
| - .map(line => line.replace(rgx, "import {$1} from 'react-bootstrap';")) | ||
| - .join('\n'); | ||
| -} |
0 comments on commit
ac500c8