Remove global state, return rules directly

This breaks backwards compatibility.

This removes .routes because it's not intuitive what the result value
of that must be, and users are free to .map over .route themselves.

Also, .routes was never tested.

Fixes #14.
pull/18/head
Denis Sokolov 9 years ago
parent d9ab1242b4
commit 824d69fd08

@ -72,46 +72,34 @@ function which parses
}
```
### `docuri.route(route, name)`
Create a single route. The `route` argument must be a routing string. The
`name` argument will be the identifier for the resulting function:
`docuri[name]`. Routes added later may override previously declared routes.
### `docuri.route(route)`
Create a single route. The `route` argument must be a routing string.
```js
// parses 'page/home' as { id: 'home' }:
docuri.route('page/:id', 'page');
var page = docuri.route('page/:id');
```
### `docuri.routes(map)`
Install a routes hash which maps DocURIs with parameters to functions:
```js
docuri.routes({
'movie/:id': 'movie',
'movie/:movie_id/:type/*path': 'movieAsset'
'movie/:movie_id/gallery-image/:id(/:version)': 'galleryImage',
});
```
### `docuri[name](strOrObj, [obj])`
### `route(strOrObj, [obj])`
The functions generated by DocURI can have a different behaviour, depending on
the type and number of the supplied arguments:
* `name(str)`: parse DocURI string to object
* `name(obj)`: generate DocURI string from object
* `name(str, obj)`: change DocURI string parts with values provided by object returning a string
* `route(str)`: parse DocURI string to object
* `route(obj)`: generate DocURI string from object
* `route(str, obj)`: change DocURI string parts with values provided by object returning a string
The function returns `false` if a string can not be parsed, enabling type
checks.
#### Example
```js
docuri.movie('movie/blade-runner');
movie('movie/blade-runner');
// { id: 'blade-runner' }
docuri.movieAsset('movie/blade-runner');
movieAsset('movie/blade-runner');
// false
docuri.galleryImage({ movie_id: 'blade-runner', id: 12 });
galleryImage({ movie_id: 'blade-runner', id: 12 });
// 'movie/blade-runner/gallery-image/12'
docuri.galleryImage('movie/blade-runner/gallery-image/12', { version: 'large' });
galleryImage('movie/blade-runner/gallery-image/12', { version: 'large' });
// 'movie/blade-runner/gallery-image/12/large'
```

@ -9,8 +9,6 @@
var docuri = module.exports = exports = {};
var reservedNames = ['routes', 'route'];
// Cached regular expressions for matching named param parts and splatted parts
// of route strings.
// http://backbonejs.org/docs/backbone.html#section-158
@ -65,7 +63,7 @@ function extractParameters(route, fragment) {
}
params = params.slice(1);
return Object.keys(route.keys).reduce(function(memo, key, i) {
var param = params[i];
@ -103,22 +101,10 @@ function insertParameters(route, obj) {
}
// Map routes
docuri.routes = function(map) {
Object.keys(map).forEach(function(route) {
docuri.route(route, map[route]);
});
};
// Manually bind a single named route
docuri.route = function(route, name) {
if (reservedNames.indexOf(name) > -1) {
throw('Reserved name "' + name + '" cannot be used.');
}
docuri.route = function(route) {
route = routeToRegExp(route);
docuri[name] = function(source, target) {
return function(source, target) {
source = source || {};
if (target) {

@ -2,11 +2,11 @@ var test = require('tap').test;
var docuri = require('..');
test('simple route', function(t) {
docuri.route('page', 'page');
var page = docuri.route('page');
t.deepEqual(docuri.page('page'), {}, 'parsed page returns empty object');
t.equal(docuri.page('image'), false, 'parsed image returns false');
t.equal(docuri.page(), 'page', 'generate page url');
t.deepEqual(page('page'), {}, 'parsed page returns empty object');
t.equal(page('image'), false, 'parsed image returns false');
t.equal(page(), 'page', 'generate page url');
t.end();
});

@ -2,26 +2,26 @@ var test = require('tap').test;
var docuri = require('..');
test('named parameter', function(t) {
docuri.route('page/:id', 'page');
var page = docuri.route('page/:id');
t.equal(docuri.page('page/mypage', { id: 'otherpage' }), 'page/otherpage', 'merged page has "id" set to "otherpage"');
t.equal(page('page/mypage', { id: 'otherpage' }), 'page/otherpage', 'merged page has "id" set to "otherpage"');
t.end();
});
test('optional parameter', function(t) {
docuri.route('page(/:id)', 'page');
var page = docuri.route('page(/:id)');
t.deepEqual(docuri.page('page/mypage'), { id: 'mypage' }, 'parsed page has "id" set to "mypage"');
t.equal(docuri.page('page/mypage', { id: 'otherpage' }), 'page/otherpage', 'merged page has "id" set to "otherpage"');
t.deepEqual(page('page/mypage'), { id: 'mypage' }, 'parsed page has "id" set to "mypage"');
t.equal(page('page/mypage', { id: 'otherpage' }), 'page/otherpage', 'merged page has "id" set to "otherpage"');
t.end();
});
test('two named parameters', function(t) {
docuri.route('page/:page_id/content/:id', 'content');
var content = docuri.route('page/:page_id/content/:id');
t.equal(docuri.content('page/mypage/content/mycontent', { id: 'othercontent' }), 'page/mypage/content/othercontent', 'merged content has "id" set to "othercontent"');
t.equal(content('page/mypage/content/mycontent', { id: 'othercontent' }), 'page/mypage/content/othercontent', 'merged content has "id" set to "othercontent"');
t.end();
});

@ -2,28 +2,28 @@ var test = require('tap').test;
var docuri = require('..');
test('named parameter', function(t) {
docuri.route('page/:id', 'page');
var page = docuri.route('page/:id');
t.deepEqual(docuri.page('page/mypage'), { id: 'mypage' }, 'parsed page has "id" set to "mypage"');
t.equal(docuri.page({ id: 'mypage' }), 'page/mypage', 'stringified page results in "page/mypage"');
t.deepEqual(page('page/mypage'), { id: 'mypage' }, 'parsed page has "id" set to "mypage"');
t.equal(page({ id: 'mypage' }), 'page/mypage', 'stringified page results in "page/mypage"');
t.end();
});
test('two named parameters', function(t) {
docuri.route('page/:page_id/content/:id', 'content');
var content = docuri.route('page/:page_id/content/:id');
t.deepEqual(docuri.content('page/mypage/content/mycontent'), { page_id: 'mypage', id: 'mycontent' }, 'parsed content has "page_id" set to "mypage" and "id" set to "mycontent"');
t.equal(docuri.content({ page_id: 'mypage', id: 'mycontent' }), 'page/mypage/content/mycontent', 'stringified content results in "page/mypage/content/mycontent"');
t.deepEqual(content('page/mypage/content/mycontent'), { page_id: 'mypage', id: 'mycontent' }, 'parsed content has "page_id" set to "mypage" and "id" set to "mycontent"');
t.equal(content({ page_id: 'mypage', id: 'mycontent' }), 'page/mypage/content/mycontent', 'stringified content results in "page/mypage/content/mycontent"');
t.end();
});
test('named parameter followed by optional parameter', function(t) {
docuri.route('page/:id(/:optional)', 'page');
var page = docuri.route('page/:id(/:optional)');
t.deepEqual(docuri.page('page/mypage'), { id: 'mypage' }, 'parsed page has "id" set to "mypage"');
t.equal(docuri.page({ id: 'mypage', optional: 'number' }), 'page/mypage/number', 'stringified page results in "page/mypage/number"');
t.deepEqual(page('page/mypage'), { id: 'mypage' }, 'parsed page has "id" set to "mypage"');
t.equal(page({ id: 'mypage', optional: 'number' }), 'page/mypage/number', 'stringified page results in "page/mypage/number"');
t.end();
});

@ -2,23 +2,23 @@ var test = require('tap').test;
var docuri = require('..');
test('optional parameter', function(t) {
docuri.route('page(/:id)', 'page');
var page = docuri.route('page(/:id)');
t.deepEqual(docuri.page('page'), {}, 'parsed page returns empty object');
t.deepEqual(docuri.page('page/mypage'), { id: 'mypage' }, 'parsed page has "id" set to "mypage"');
t.equal(docuri.page(), 'page', 'stringified empty page results in "page"');
t.equal(docuri.page({ id: 'mypage' }), 'page/mypage', 'stringified page results in "page/mypage"');
t.deepEqual(page('page'), {}, 'parsed page returns empty object');
t.deepEqual(page('page/mypage'), { id: 'mypage' }, 'parsed page has "id" set to "mypage"');
t.equal(page(), 'page', 'stringified empty page results in "page"');
t.equal(page({ id: 'mypage' }), 'page/mypage', 'stringified page results in "page/mypage"');
t.end();
});
test('surrounded optional parameter', function(t) {
docuri.route('page(/:id)/suffix', 'page');
var page = docuri.route('page(/:id)/suffix');
t.deepEqual(docuri.page('page/suffix'), {}, 'parsed page returns empty object');
t.deepEqual(docuri.page('page/mypage/suffix'), { id: 'mypage' }, 'parsed page has "id" set to "mypage"');
t.equal(docuri.page(), 'page/suffix', 'stringified empty page results in "page"');
t.equal(docuri.page({ id: 'mypage' }), 'page/mypage/suffix', 'stringified page results in "page/mypage"');
t.deepEqual(page('page/suffix'), {}, 'parsed page returns empty object');
t.deepEqual(page('page/mypage/suffix'), { id: 'mypage' }, 'parsed page has "id" set to "mypage"');
t.equal(page(), 'page/suffix', 'stringified empty page results in "page"');
t.equal(page({ id: 'mypage' }), 'page/mypage/suffix', 'stringified page results in "page/mypage"');
t.end();
});

@ -1,26 +0,0 @@
var test = require('tap').test;
var docuri = require('..');
test('reserved name route', function(t) {
t.plan(1);
try {
docuri.route('page', 'route');
} catch(e) {
t.equal(e, 'Reserved name "route" cannot be used.', 'reserved name "route" should throw error');
}
t.end();
});
test('reserved name routes', function(t) {
t.plan(1);
try {
docuri.route('page', 'routes');
} catch(e) {
t.equal(e, 'Reserved name "routes" cannot be used.', 'reserved name "routes" should throw error');
}
t.end();
});

@ -2,10 +2,10 @@ var test = require('tap').test;
var docuri = require('..');
test('splat and named parameter', function(t) {
docuri.route('*splat/page/:named', 'page');
var page = docuri.route('*splat/page/:named');
t.deepEqual(docuri.page('splat/page/named'), { splat: [ 'splat' ], named: 'named' }, 'splat and named parameter parsed correctly');
t.equal(docuri.page({ splat: [ 'splat' ], named: 'named' }), 'splat/page/named', 'stringified result is in right order');
t.deepEqual(page('splat/page/named'), { splat: [ 'splat' ], named: 'named' }, 'splat and named parameter parsed correctly');
t.equal(page({ splat: [ 'splat' ], named: 'named' }), 'splat/page/named', 'stringified result is in right order');
t.end();
});

@ -2,10 +2,10 @@ var test = require('tap').test;
var docuri = require('..');
test('splat parameter', function(t) {
docuri.route('page/*path', 'page');
var page = docuri.route('page/*path');
t.deepEqual(docuri.page('page/mypage/otherpage'), { path: ['mypage', 'otherpage'] }, 'parsed page has "parts" set to ["mypage","otherpage"]');
t.equal(docuri.page({ path: ['mypage', 'otherpage'] }), 'page/mypage/otherpage', 'stringified page results in "page/mypage/otherpage"');
t.deepEqual(page('page/mypage/otherpage'), { path: ['mypage', 'otherpage'] }, 'parsed page has "parts" set to ["mypage","otherpage"]');
t.equal(page({ path: ['mypage', 'otherpage'] }), 'page/mypage/otherpage', 'stringified page results in "page/mypage/otherpage"');
t.end();
});

Loading…
Cancel
Save