Skip to content

Commit

Permalink
Handle null same way as undefined (#51)
Browse files Browse the repository at this point in the history
- Handle `null` same way as `undefined`
- Return `null` instead of `undefined` to signal no match (BREAKING CHANGE)
  • Loading branch information
langpavel authored and koistya committed Oct 9, 2016
1 parent fb4821f commit 9740ad0
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 16 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ All notable changes to this project will be documented in this file.

- Add `context.redirect(path)` method to be used from inside route actions (PLANNED)

### [v1.3.0] - [unreleased]

- Handle `null` same way as `undefined`
- Return `null` instead of `undefined` to signal no match. (BREAKING CHANGE)

### [v1.2.2] - 2016-05-31

- Update UMD build to include missing dependencies ([#33](/~https://github.com/kriasoft/universal-router/pull/33))
Expand Down
2 changes: 1 addition & 1 deletion docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ title: API ∙ Universal Router
### `resolve(routes, { path, ...context })``any`

Traverses the list of routes in the order they are defined until it finds the first route that
matches provided URL path string and whose action method returns anything other than `undefined`.
matches provided URL path string and whose action method returns anything other than `null` or `undefined`.

```js
import { resolve } from 'universal-router';
Expand Down
2 changes: 1 addition & 1 deletion docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ $ npm install universal-router --save

This module contains a `resolve` function that responsible for traversing the list of routes, until it
finds the first route matching the provided URL path string and whose action method returns anything
other than `undefined`. Each route is just a plain JavaScript object having `path`, `action`, and
other than `null` or `undefined`. Each route is just a plain JavaScript object having `path`, `action`, and
`children` (optional) properties.

```js
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"private": true,
"name": "universal-router",
"version": "1.2.2",
"version": "1.3.0",
"description": "Isomorphic router for JavaScript web applications",
"homepage": "https://www.kriasoft.com/universal-router/",
"repository": "kriasoft/universal-router",
Expand Down
8 changes: 4 additions & 4 deletions src/resolve.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ async function resolve(routes, pathOrContext) {
? { path: pathOrContext }
: pathOrContext;
const root = Array.isArray(routes) ? { path: '/', children: routes } : routes;
let result;
let result = null;
let value;
let done = false;

Expand Down Expand Up @@ -42,7 +42,7 @@ async function resolve(routes, pathOrContext) {
}
}

return undefined;
return null;
}

context.next = next;
Expand All @@ -51,12 +51,12 @@ async function resolve(routes, pathOrContext) {
while (!done) {
result = await next();

if (result !== undefined) {
if (result !== null && result !== undefined) {
break;
}
}

if (result === undefined && errorRoute) {
if ((result === null || result === undefined) && errorRoute) {
context.error = new Error('Not found');
context.error.status = 404;
return await errorRoute.action(context, {});
Expand Down
21 changes: 12 additions & 9 deletions test/resolve.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ import { resolve } from '../src/main';

describe('resolve(routes, { path, ...context })', () => {

it('should return [undefined] if a route wasn\'t not found', async () => {
it('should return null if a route wasn\'t not found', async () => {
const routes = [];
const result = await resolve(routes, '/');
expect(result).to.be.undefined;
expect(result).to.be.null;
});

it('should execute the matching route\'s action method and return its result', async () => {
Expand All @@ -30,20 +30,23 @@ describe('resolve(routes, { path, ...context })', () => {
expect(result).to.be.equal('b');
});

it('should find the first route whose action method !== [undefined]', async () => {
it('should find the first route whose action method !== undefined or null', async () => {
const action1 = sinon.spy(() => undefined);
const action2 = sinon.spy(() => 'b');
const action3 = sinon.spy(() => 'b');
const action2 = sinon.spy(() => null);
const action3 = sinon.spy(() => 'c');
const action4 = sinon.spy(() => 'd');
const routes = [
{ path: '/a', action: action1 },
{ path: '/a', action: action2 },
{ path: '/a', action: action2 },
{ path: '/a', action: action3 },
{ path: '/a', action: action4 },
];
const result = await resolve(routes, '/a');
expect(result).to.be.equal('b');
expect(action1.calledOnce).to.be.true;
expect(result).to.be.equal('c');
expect(action1.calledOnce).to.be.true;
expect(action3.called).to.be.false;
expect(action2.calledOnce).to.be.true;
expect(action3.calledOnce).to.be.true;
expect(action4.called).to.be.false;
});

it('should be able to pass context variables to action methods', async () => {
Expand Down

0 comments on commit 9740ad0

Please sign in to comment.