diff --git a/README.md b/README.md index ee8d214..d7d1193 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ Route = require('route-parser'); var route = new Route('/my/fancy/route/page/:page'); route.match('/my/fancy/route/page/7') // { page: 7 } route.reverse({page: 3}) // -> '/my/fancy/route/page/3' +route.asRegExp() // new RegExp(/^\/my\/fancy\/route\/page\/([^/\?]+))?(?=\?|$)/) ``` ## What can I use in my routes? diff --git a/lib/route.js b/lib/route.js index 6acdb77..cfd8263 100644 --- a/lib/route.js +++ b/lib/route.js @@ -68,5 +68,16 @@ Route.prototype.reverse = function (params) { return ReverseVisitor.visit(this.ast, params); }; +/** + * Returns a regular expression for matching the route + * @example + * var route = new Route('/route/:one/(:two)') + * route.asRegExp() // -> /\/route\/([^\\/\\?]+)\/(?:([^\\/\\?]+))?/ + * @return {RegExp} The route expressed as a regular expression + */ +Route.prototype.asRegExp = function () { + var matcher = RegexpVisitor.visit(this.ast); + return matcher.re; +}; module.exports = Route; diff --git a/test/test.js b/test/test.js index 446787e..e1de066 100644 --- a/test/test.js +++ b/test/test.js @@ -171,4 +171,47 @@ describe('Route', function () { ); }); }); + + describe('asRegExp', function () { + it('returns regexp for route without params', function () { + var route = RouteParser('/foo'); + var regexp = route.asRegExp(); + assert.typeOf(regexp, 'regexp'); + assert.match('/foo', regexp); + assert.match('/foo?', regexp); + assert.notMatch('/foo/', regexp); + }); + + it('returns regexp for route with simple params', function () { + var route = RouteParser('/:foo/:bar'); + var regexp = route.asRegExp(); + assert.typeOf(regexp, 'regexp'); + assert.match('/red/green', regexp); + }); + + it('returns regexp for route with optional params', function () { + var route = RouteParser('/things/(option/:first)'); + var regexp = route.asRegExp(); + assert.typeOf(regexp, 'regexp'); + assert.match('/things/', regexp); + assert.notMatch('/things/option/', regexp); + assert.match('/things/option/blue', regexp); + }); + + it('returns regexp for route with nested optional params', function () { + var route = RouteParser('/things/(option/:first(/second/:second))'); + var regexp = route.asRegExp(); + assert.typeOf(regexp, 'regexp'); + assert.match('/things/', regexp); + assert.match('/things/option/blue', regexp); + assert.match('/things/option/blue/second/red', regexp); + }); + + it('returns regexp for route with splat', function () { + var route = RouteParser('/*a/foo/*b'); + var regexp = route.asRegExp(); + assert.typeOf(regexp, 'regexp'); + assert.match('/zoo/woo/foo/bar/baz', regexp); + }); + }); });