From f623660a3bae2a0ef02a59166d00aaf3bef0d915 Mon Sep 17 00:00:00 2001 From: visualfanatic Date: Sun, 28 Aug 2016 16:37:41 +0200 Subject: [PATCH 1/4] Allow to pass name/options as third arguments in standalone mode --- README.md | 12 ++++-------- router.js | 28 +++++++++++++--------------- test/test.js | 25 ++++++------------------- 3 files changed, 23 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 3c3ab84..0d44272 100644 --- a/README.md +++ b/README.md @@ -73,10 +73,8 @@ information, see https://github.com/alubbe/named-routes/issues/13. var Router = require('named-routes')(); var router = new Router(); -router.add('get', '/admin/user/:id', function(req, res, next) { +router.add('get', '/admin/user/:id', 'admin.user.edit', function(req, res, next) { var url = router.build('admin.user.edit', {id: 2}); // /admin/user/2 -}, { - name: 'admin.user.edit' }); //... in a request handler @@ -110,8 +108,8 @@ app.namedRoutes.build('todo.user.list.id', {user: 'foo', list: 93}) // Throws er As a standalone: ```js -router.add('get', '/about', function(req, res, next) {...}, {name:'about'}) -router.add('get', '/todo/:user/:list/:id', function(req, res, next) {...}, {name:'todo.user.list.id'}) +router.add('get', '/about', 'about', function(req, res, next) {...}) +router.add('get', '/todo/:user/:list/:id', 'todo.user.list.id', function(req, res, next) {...}) router.build('about') // '/about' router.build('todo.user.list.id', {user: 'foo', list: 93, id: 1337}) // '/todo/foo/93/1337' @@ -195,10 +193,8 @@ url('admin.user.edit', {id:2, _masked: ['any','thing']}) ### Converting the trailing `*` anonymous parameter to multiple `name:value` parameters ```js -router.add('get', '/admin/*/user/*/:id/albums/*', 'admin.user.edit', function(req, res, next) { +router.add('get', '/admin/*/user/*/:id/albums/*', {name: 'admin.user.edit', wildcardInPairs: true}, function(req, res, next) { console.log(req.params) -}, { - wildcardInPairs: true }); ``` Requesting: `/admin/any/user/thing/2/albums/sort/name/order/desc` will output: diff --git a/router.js b/router.js index 8bb0328..d7e0e38 100644 --- a/router.js +++ b/router.js @@ -65,22 +65,20 @@ Router.prototype.match = function (req) { * @param options */ Router.prototype.add = function (method, path, callbacks, options) { - function flatten(arr, ret) { - var ret = ret || [] - , len = arr.length; - for (var i = 0; i < len; ++i) { - if (Array.isArray(arr[i])) { - flatten(arr[i], ret); - } else { - ret.push(arr[i]); - } - } - return ret; - } + var hasOptions = (typeof callback !== 'function' && !Array.isArray(callback)); + var callbacks = [].slice.call(arguments, 2); + var options = {}; - callbacks = [callbacks] method = method.toLowerCase(); - options = options || {}; + + if (hasOptions) { + if (typeof callback === 'string') { + options['name'] = callback; + } else { + options = callback; + } + callbacks.shift(); + } this.routesByMethodAndPath[method] = this.routesByMethodAndPath[method] || {}; options.caseSensitive = options.caseSensitive == undefined ? this.caseSensitive : options.caseSensitive; @@ -311,7 +309,7 @@ Router.prototype.extendExpress = function (app) { next(); }; } - this.namedRoutes.add(method, path, [], {name: name}); + this.namedRoutes.add(method, path, name, []); return originalMethod.apply(this, args); } }); diff --git a/test/test.js b/test/test.js index d8e9c10..172c6c6 100644 --- a/test/test.js +++ b/test/test.js @@ -92,9 +92,7 @@ module.exports = { params: {} }; - self.router.add('get', '/admin/user/:id', routeSpy, { - name: 'admin.user.edit' - }); + self.router.add('get', '/admin/user/:id', 'admin.user.edit', routeSpy); self.router.dispatch(req, {}, function(){ }); @@ -151,9 +149,7 @@ module.exports = { this.router.build('invalid route Name'); }).to.throwError(); - self.router.add('post', '(/:controller(/:action(/:id)))', spy, { - 'name': 'reversed' - }); + self.router.add('post', '(/:controller(/:action(/:id)))', 'reversed', spy); expect(self.router.build('reversed', { 'controller': 'Home', @@ -167,9 +163,7 @@ module.exports = { expect(spy.called).to.equal(true); - self.router.add('post', '/todo/:user/:list/:id', spy, { - 'name': 'ajax' - }); + self.router.add('post', '/todo/:user/:list/:id', 'ajax', spy); expect(self.router.build('ajax', { 'user': 'foo', @@ -177,9 +171,7 @@ module.exports = { 'id': null })).to.equal('/todo/foo'); - self.router.add('get', '/admin/(user/(edit/:id/)(album/:albumId/):session/)test', spy, { - name: 'optionals' - }); + self.router.add('get', '/admin/(user/(edit/:id/)(album/:albumId/):session/)test', 'optionals', spy); expect(self.router.build('optionals', { id: 4, @@ -211,9 +203,7 @@ module.exports = { next = sinon.spy(), spy = sinon.spy(); - self.router.add('get', '/admin/*/user/*/:id', spy, { - name: 'admin.user.edit' - }); + self.router.add('get', '/admin/*/user/*/:id', 'admin.user.edit', spy); req = { method: 'get', @@ -228,10 +218,7 @@ module.exports = { id:2, _masked: ['any','thing'] })).to.equal('/admin/any/user/thing/2'); - self.router.add('get', '/admin/*/user/*/:id/albums/*', spy, { - wildcardInPairs: true, - name: 'admin.user.edit2' - }); + self.router.add('get', '/admin/*/user/*/:id/albums/*', {wildcardInPairs: true, name: 'admin.user.edit2'}, spy); req = { method: 'get', From 977704c8705a8da5b48f01c8241521ac62a6deb4 Mon Sep 17 00:00:00 2001 From: visualfanatic Date: Sun, 28 Aug 2016 16:43:33 +0200 Subject: [PATCH 2/4] Update args --- router.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/router.js b/router.js index d7e0e38..d69e08a 100644 --- a/router.js +++ b/router.js @@ -61,10 +61,9 @@ Router.prototype.match = function (req) { * Registers new route * @param method * @param path - * @param callbacks - * @param options + * @param callback */ -Router.prototype.add = function (method, path, callbacks, options) { +Router.prototype.add = function (method, path, callback) { var hasOptions = (typeof callback !== 'function' && !Array.isArray(callback)); var callbacks = [].slice.call(arguments, 2); var options = {}; From d24b2538213279cca0437224e8afbc30d36c1338 Mon Sep 17 00:00:00 2001 From: visualfanatic Date: Sun, 28 Aug 2016 16:56:59 +0200 Subject: [PATCH 3/4] Missing `flatten` function --- router.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/router.js b/router.js index d69e08a..d8ff4c6 100644 --- a/router.js +++ b/router.js @@ -57,6 +57,18 @@ Router.prototype.match = function (req) { return false; } +var flatten = function (arr, ret) { + var ret = ret || []; + for (var i = 0, len = arr.length; i < len; ++i) { + if (Array.isArray(arr[i])) { + flatten(arr[i], ret); + } else { + ret.push(arr[i]); + } + } + return ret; +} + /** * Registers new route * @param method From 266fa001bc610c1a3541f28b447380b95f7d19d4 Mon Sep 17 00:00:00 2001 From: visualfanatic Date: Fri, 30 Sep 2016 10:04:32 +0000 Subject: [PATCH 4/4] Added missing tests --- test/test.js | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/test/test.js b/test/test.js index 172c6c6..fc7511b 100644 --- a/test/test.js +++ b/test/test.js @@ -106,6 +106,35 @@ module.exports = { expect(routeSpy.callCount).to.equal(1); expect(dispatchSpy.called).to.equal(true); }, + 'matches (multiple callbacks)': function(){ + var + self = this, + dispatchSpy = sinon.spy(), + middlewareSpy = sinon.stub(), + routeSpy = sinon.spy(), + path = '/admin/user/:id', + req = { + method: 'get', + path: '/admin/user/1', + params: {} + }; + + // Call `next` arg inside the spy middleware + middlewareSpy.callsArg(2); + + self.router.add('get', path, 'admin.user.edit', [middlewareSpy, routeSpy]); + + self.router.dispatch(req, {}, function(){ }); + + // Route should have 2 callbacks + expect(self.router.callbacksByPathAndMethod[path].get).to.have.length(2); + + expect(middlewareSpy.calledOnce).to.equal(true); + expect(routeSpy.calledOnce).to.equal(true); + + expect(middlewareSpy.calledWith(req, sinon.match.any, sinon.match.any)).to.equal(true); + expect(routeSpy.calledWith(req, sinon.match.any, sinon.match.any)).to.equal(true); + }, 'optionals': function(){ var self = this,