Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
# react-minimal-router [![Build Status](https://travis-ci.org/skidding/react-minimal-router.svg?branch=master)](https://travis-ci.org/skidding/react-minimal-router) [![Coverage Status](https://coveralls.io/repos/skidding/react-minimal-router/badge.svg?branch=master)](https://coveralls.io/r/skidding/react-minimal-router?branch=master)
# react-querystring-router [![Build Status](https://travis-ci.org/skidding/react-querystring-router.svg?branch=master)](https://travis-ci.org/skidding/react-querystring-router) [![Coverage Status](https://coveralls.io/repos/skidding/react-querystring-router/badge.svg?branch=master)](https://coveralls.io/r/skidding/react-querystring-router?branch=master)
Bare router for React components, using query string as props.

```
http://mysite.com/?component=Father&eyes=blue&mood=happy
```

This route would render the Father component (see `getComponentClass` option),
This route will render the component class returned by `getComponentClass`
using the following props:

```js
{
component: 'Father',
eyes: 'blue',
mood: 'happy'
}
Expand All @@ -18,7 +19,7 @@ using the following props:
#### Options

```js
var Router = require('react-minimal-router').Router;
var Router = require('react-querystring-router').Router;

var myRouter = new Router({
// These props will be sent to all components loaded, and will be overridden
Expand All @@ -27,15 +28,15 @@ var myRouter = new Router({
fries: true
},
// This is how the router maps component names to corresponding classes
getComponentClass: function(name) {
return require('components/' + name + '.jsx');
getComponentClass: function(props) {
return require('components/' + props.component + '.jsx');
},
// Tell React where to render in the DOM
container: document.getElementById('content'),
// Called whenever the route changes (also initially), receiving the parsed
// params as the first argument
onChange: function(params) {
// E.g. Use the params to set a custom document.title
// props as the first argument
onChange: function(props) {
// E.g. Use the props to set a custom document.title
}
});
```
Expand All @@ -46,7 +47,7 @@ the `router` prop.
#### Changing the route

```jsx
var stringifyParams = require('react-minimal-router').uri.stringifyParams;
var stringifyParams = require('react-querystring-router').uri.stringifyParams;

//...

Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"name": "react-minimal-router",
"version": "0.1.3",
"name": "react-querystring-router",
"version": "0.2.0",
"description": "Bare router for React components, using props as query string",
"main": "src/main.js",
"repository": {
"type": "git",
"url": "https://github.com/skidding/react-minimal-router.git"
"url": "https://github.com/skidding/react-querystring-router.git"
},
"devDependencies": {
"chai": "^2.2.0",
Expand Down
6 changes: 3 additions & 3 deletions src/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,17 @@ Router.prototype = {
// possible for a component to change the page through the router and
// not have to rely on any sort of globals
router: this
}, this._options.defaultProps, _.omit(params, 'component'));
}, this._options.defaultProps, params);

var ComponentClass = this._options.getComponentClass(params.component),
var ComponentClass = this._options.getComponentClass(props),
componentElement = React.createElement(ComponentClass, props);

// The router exposes the instance of the currently rendered component
this.rootComponent = React.render(componentElement,
this._options.container);

if (_.isFunction(this._options.onChange)) {
this._options.onChange.call(this, params);
this._options.onChange.call(this, props);
}
},

Expand Down
9 changes: 7 additions & 2 deletions src/uri.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
module.exports = {
parseLocation: function(location) {
var queryString = location.split('?').pop(),
params = {};
var params = {};

if (location.indexOf('?') === -1) {
return params;
}

var queryString = location.split('?').pop();

if (!queryString.length) {
return params;
Expand Down
24 changes: 16 additions & 8 deletions tests/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,16 @@ describe('Router class', function() {
expect(uri.parseLocation.lastCall.args[0]).to.equal(uriLocation);
});

it('should call getComponentClass with name', function() {
expect(routerOptions.getComponentClass.lastCall.args[0])
.to.equal(uriParams.component);
it('should call getComponentClass with params', function() {
var propsSent = routerOptions.getComponentClass.lastCall.args[0];
expect(propsSent.component).to.equal(uriParams.component);
expect(propsSent.dataUrl).to.equal(uriParams.dataUrl);
});

it('should call getComponentClass with default props', function() {
var propsSent = routerOptions.getComponentClass.lastCall.args[0];
expect(propsSent.defaultProp)
.to.equal(routerOptions.defaultProps.defaultProp);
});

it('should call createElement with returned class', function() {
Expand All @@ -48,11 +55,6 @@ describe('Router class', function() {
expect(propsSent.dataUrl).to.equal(uriParams.dataUrl);
});

it('should omit component param in props', function() {
var propsSent = React.createElement.lastCall.args[1];
expect(propsSent.component).to.be.undefined;
});

it('should attach router reference to props', function() {
expect(React.createElement.lastCall.args[1].router)
.to.equal(routerInstance);
Expand All @@ -77,6 +79,12 @@ describe('Router class', function() {
expect(params.component).to.equal(uriParams.component);
expect(params.dataUrl).to.equal(uriParams.dataUrl);
});

it('should call onChange callback with default props', function() {
var params = routerOptions.onChange.lastCall.args[0];
expect(params.defaultProp)
.to.equal(routerOptions.defaultProps.defaultProp);
});
};

var currentLocationTests = function() {
Expand Down
17 changes: 16 additions & 1 deletion tests/uri.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
var uri = require('../src/uri.js');
var _ = require('lodash'),
uri = require('../src/uri.js');

describe('uri lib', function() {
it('should return empty object when querystring is missing', function() {
var uriLocation = 'mypage.com';
params = uri.parseLocation(uriLocation);

expect(_.keys(params).length).to.equal(0);
});

it('should return empty object when querystring is empty', function() {
var uriLocation = 'mypage.com?';
params = uri.parseLocation(uriLocation);

expect(_.keys(params).length).to.equal(0);
});

it('should parse stringified and encoded props from location', function() {
var uriLocation = 'mypage.com?name=Jack&info=%7B%22age%22%3A25%7D';
params = uri.parseLocation(uriLocation);
Expand Down