diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..43c97e7 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +package-lock=false diff --git a/.travis.yml b/.travis.yml index c92003f..6d760ea 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,17 +1,8 @@ language: node_js node_js: - - "0.10" - - "0.12" - - "1.8" - - "2.5" - - "3.3" - - "4.9" - - "5.12" - - "6.14" - - "7.10" - - "8.11" - - "9.11" - "10.6" + - "12.14" + - "13.5" sudo: false cache: directories: diff --git a/HISTORY.md b/HISTORY.md index 72ac292..da1a190 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,18 @@ +unreleased +========== + + * deps: mocha@7.0.0 + * deps: supertest@4.0.2 + * deps: nyc@15.0.0 + * deps: setprototypeof@1.2.0 + * deps: path-to-regexp@3.0.0 + * deps: eslint@6.8.0 + * deps: eslint-plugin-markdown@1.0.1 + * Deprecate arity based error middleware + - Added `.error` instead of 4 argument functions + - Added deprecation warning when relying on arity based inference + - Added Stack & FlatStack + 2.0.0-alpha.1 / 2018-07-27 ========================== diff --git a/README.md b/README.md index 6c5bddf..72fd283 100644 --- a/README.md +++ b/README.md @@ -175,14 +175,14 @@ rather than responding. ```js router.route('/') -.all(function (req, res, next) { - next() -}) -.all(check_something) -.get(function (req, res) { - res.setHeader('Content-Type', 'text/plain; charset=utf-8') - res.end('Hello World!') -}) + .all(function (req, res, next) { + next() + }) + .all(check_something) + .get(function (req, res) { + res.setHeader('Content-Type', 'text/plain; charset=utf-8') + res.end('Hello World!') + }) ``` ## Middleware @@ -200,12 +200,35 @@ is returned from the function, the router will attach an `onRejected` callback using `.then`. If the promise is rejected, `next` will be called with the rejected value, or an error if the value is falsy. +### Error Middleware + +Error middleware are special functions which take an `error` argument as the first +argument instead of the `request`. You can add error middleware by calling `.error()`. +These can be used for handling errors that occurred in previous handlers +(E.g. from calling `next(err)`). This is most used when you want to define shared +handling or rendering of errors. + +```js +router.get('/error_route', (req, res, next) => { + next(new Error('Bad Request')) +}) + +router.error((err, req, res) => { + res.end(err.message) //=> "Bad Request" +}) +``` + +Error handling middleware will **only** be invoked when an error was given. As +long as the error is in the pipeline, normal middleware and handlers will be +bypassed - only error handling middleware will be invoked with an error. + +**Deprecated behavior:** + +*Deprecated in `router@2.0.0`* + Middleware and method handlers can also be defined with four arguments. When the function has four parameters defined, the first argument is an error and -subsequent arguments remain, becoming - "err", "req", "res", "next". These -functions are "error handling middleware", and can be used for handling -errors that occurred in previous handlers (E.g. from calling `next(err)`). -This is most used when you want to define arbitrary rendering of errors. +subsequent arguments remain, becoming - "err", "req", "res", "next". ```js router.get('/error_route', function (req, res, next) { @@ -217,10 +240,6 @@ router.use(function (err, req, res, next) { }) ``` -Error handling middleware will **only** be invoked when an error was given. As -long as the error is in the pipeline, normal middleware and handlers will be -bypassed - only error handling middleware will be invoked with an error. - ## Examples ```js @@ -382,6 +401,98 @@ router.route('/pet/:id') server.listen(8080) ``` +## Migrating to 2.x from 1.x + +#### Deprecation of arity based error middleware + +In previous versions of `router`, the arity of a function was used to determine +if a middleware was a normal middleware or an error handling middleware. In `router@2.0` +this behavior still works, but is deprecated. The new api is as follows: + +```javascript +router.error(...errorMiddleware) + +// Create a reusable stack of mw +const mw = new Router.Stack() + +// Register normal middleware +mw.use(() => {}, () => {}) + +// Add an error middleware +mw.error((err, req, res) => { + // notice no more `next` required! + res.statusCode = 500 + res.end(err.message) +}) + +// to explicitly opt back into the old behavior you can use `stack.infer` +mw.infer((req, res) => { + next(new Error()) +}, (err, req, res, next) => { + // This sill be inferred from the arity like Express did in the past + // Notice that in this example all four arguments are required even + // if you never call next +}) +``` + +### Update `path-to-regexp` to `3.x` + +The update to `path-to-regexp@3.0.0` has a few breaking changes: + +#### No longer a direct conversion to a RegExp with sugar on top. + +It's a path matcher with named and unnamed matching groups. It's unlikely you previously abused this feature, +it's rare and you could always use a RegExp instead. An example of this would be: + +```javascript +// Used to work +router.get('/\\d+') + +// Now requires matching group +router.get('/(\\d+)') +``` + +#### All matching RegExp special characters can be used in a matching group. + +Other RegExp features are not supported - no nested matching groups, non-capturing groups or look aheads +There is really only one common change is needing replacing any routes with `*` to `(.*)`. Some examples: + +- `/:user(*)` becomes `/:user(.*)` +- `/:user/*` becomes `/:user/(.*)` +- `/foo/*/bar` becomes `/foo/(.*)/bar` + +#### Parameters have suffixes that augment meaning - `*`, `+` and `?`. E.g. `/:user*` + +Needs more info. + +#### Named params with regex no longer define positionally. + +One other small change (hopefully low impact), is that named parameters with regular expressions no longer result in positional +values in the `params` object. An example is: + +```javascript +router.get('/:foo(.*)') + +// old GET /bar +console.log(req.params) // {0: 'bar', 'foo': 'bar'} + +// new GET /bar +console.log(req.params) // {'foo': 'bar'} +``` + +#### Partial matching, prefer escaping delimiter + +The update to `path-to-regexp@3` includes a change to how partial matches are handled, +now you should escape the delimiter before a partial match segment. For example: + +```javascript +// old +router.get('/user(s)?/:user/:op') + +// new +router.get('\\/user(s)?/:user/:op') +``` + ## License [MIT](LICENSE) diff --git a/index.js b/index.js index 7c68516..5aa73ae 100644 --- a/index.js +++ b/index.js @@ -13,6 +13,7 @@ */ var debug = require('debug')('router') +var deprecate = require('depd')('router') var flatten = require('array-flatten') var Layer = require('./lib/layer') var methods = require('methods') @@ -20,6 +21,7 @@ var mixin = require('utils-merge') var parseUrl = require('parseurl') var Route = require('./lib/route') var setPrototypeOf = require('setprototypeof') +var mwStack = require('mwstack') /** * Module variables. @@ -40,6 +42,18 @@ module.exports = Router module.exports.Route = Route +/** + * Expose `Stack`. + */ + +module.exports.Stack = mwStack.Stack + +/** + * Expose `FlatStack`. + */ + +module.exports.FlatStack = mwStack.FlatStack + /** * Initialize a new `Router` with the given `options`. * @@ -66,7 +80,7 @@ function Router(options) { router.mergeParams = opts.mergeParams router.params = {} router.strict = opts.strict - router.stack = [] + router.stack = new mwStack.Stack() return router } @@ -439,52 +453,29 @@ Router.prototype.process_params = function process_params(layer, called, req, re * @public */ -Router.prototype.use = function use(handler) { - var offset = 0 - var path = '/' - - // default path to '/' - // disambiguate router.use([handler]) - if (typeof handler !== 'function') { - var arg = handler - - while (Array.isArray(arg) && arg.length !== 0) { - arg = arg[0] - } - - // first arg is the path - if (typeof arg !== 'function') { - offset = 1 - path = handler - } - } - - var callbacks = flatten(slice.call(arguments, offset)) - - if (callbacks.length === 0) { - throw new TypeError('argument handler is required') - } - - for (var i = 0; i < callbacks.length; i++) { - var fn = callbacks[i] +Router.prototype.use = function use() { + var args = processUseArgs(arguments) + this.stack = this.stack.concat(createLayers(args[0], args[1], { + caseSensitive: this.caseSensitive + })) - if (typeof fn !== 'function') { - throw new TypeError('argument handler must be a function') - } - - // add the middleware - debug('use %o %s', path, fn.name || '') - - var layer = new Layer(path, { - sensitive: this.caseSensitive, - strict: false, - end: false - }, fn) + return this +} - layer.route = undefined +/** + * Use the given error handling middleware function + * + * See .use for usage + * + * @public + */ - this.stack.push(layer) - } +Router.prototype.error = function error (handler) { + var args = processUseArgs(arguments) + this.stack = this.stack.concat(createLayers(args[0], args[1], { + caseSensitive: this.caseSensitive, + error: true + })) return this } @@ -530,6 +521,77 @@ methods.concat('all').forEach(function(method){ } }) +/** + * Process args for a call to use or error + * + * @param {array} args + * @private + */ + +function processUseArgs (args) { + var offset = 0 + var path = '/' + + // default path to '/' + // disambiguate router.use([handler]) + if (typeof args[0] !== 'function') { + var arg = args[0] + + while (Array.isArray(arg) && arg.length !== 0) { + arg = arg[0] + } + + // first arg is the path + if (typeof arg !== 'function') { + offset = 1 + path = args[0] + } + } + + return [path, flatten(slice.call(args, offset))] +} + +/** + * Create layers for a call to use or error + * + * @param {string} path + * @param {array} callbacks + * @param {object} opts + * @private + */ + +function createLayers (path, callbacks, opts) { + if (callbacks.length === 0) { + throw new TypeError('argument handler is required') + } + + return callbacks.map(function createLayers (fn) { + if (typeof fn !== 'function') { + throw new TypeError('argument handler must be a function') + } + + if ((!opts.error && !mwStack.isError(fn)) && fn.length === 4) { + // not a standard error handler + deprecate('registering error handlers with .use is deprecated, use .error or Stack.error instead') + opts.error = true + } + + // add the middleware + debug('use %o %s', path, fn.name || '') + + var layer = new Layer(path, { + sensitive: opts.caseSensitive, + error: opts.error || mwStack.isError(fn), + strict: false, + end: false + }, fn) + + layer.route = undefined + + return layer + }) +} + /** * Generate a callback that will make an OPTIONS response. * diff --git a/lib/layer.js b/lib/layer.js index c012165..dc32024 100644 --- a/lib/layer.js +++ b/lib/layer.js @@ -28,19 +28,34 @@ var hasOwnProperty = Object.prototype.hasOwnProperty module.exports = Layer -function Layer(path, options, fn) { +function Layer(p, options, fn) { if (!(this instanceof Layer)) { - return new Layer(path, options, fn) + return new Layer(p, options, fn) } debug('new %o', path) var opts = options || {} + // If not in strict allow both with or without trailing slash + var path = p + if (!opts.strict) { + if (!Array.isArray(path) && path !== '/' && path[path.length - 1] === '/') { + path = path.substr(0, path.length - 1) + } else { + for (var i = 0; i < path.length; i++) { + if (path[i] !== '/' && path[i][path[i].length - 1] === '/') { + path[i] = path[i].substr(0, path[i].length - 1) + } + } + } + } + this.handle = fn this.name = fn.name || '' this.params = undefined this.path = undefined this.regexp = pathRegexp(path, this.keys = [], opts) + this.error = !!opts.error // set fast path flags this.regexp.fast_star = path === '*' @@ -60,7 +75,7 @@ function Layer(path, options, fn) { Layer.prototype.handle_error = function handle_error(error, req, res, next) { var fn = this.handle - if (fn.length !== 4) { + if (!this.error) { // not a standard error handler return next(error) } @@ -92,7 +107,7 @@ Layer.prototype.handle_error = function handle_error(error, req, res, next) { Layer.prototype.handle_request = function handle(req, res, next) { var fn = this.handle - if (fn.length > 3) { + if (this.error) { // not a standard request handler return next() } diff --git a/lib/route.js b/lib/route.js index c501b08..605f2dc 100644 --- a/lib/route.js +++ b/lib/route.js @@ -13,9 +13,11 @@ */ var debug = require('debug')('router:route') +var deprecate = require('depd')('router') var flatten = require('array-flatten') var Layer = require('./layer') var methods = require('methods') +var mwStack = require('mwstack') /** * Module variables. @@ -174,32 +176,15 @@ Route.prototype.dispatch = function dispatch(req, res, done) { * @api public */ -Route.prototype.all = function all(handler) { - var callbacks = flatten(slice.call(arguments)) - - if (callbacks.length === 0) { - throw new TypeError('argument handler is required') - } - - for (var i = 0; i < callbacks.length; i++) { - var fn = callbacks[i] - - if (typeof fn !== 'function') { - throw new TypeError('argument handler must be a function') - } - - var layer = Layer('/', {}, fn) - layer.method = undefined - - this.methods._all = true - this.stack.push(layer) - } - - return this -} - +Route.prototype.all = handleMethod('_all', false) +Route.prototype.error = handleMethod('_all', true) methods.forEach(function (method) { - Route.prototype[method] = function (handler) { + Route.prototype[method] = handleMethod(method, false) + Route.prototype[method + 'Error'] = handleMethod(method, true) +}) + +function handleMethod (method, isError) { + return function (handler) { var callbacks = flatten(slice.call(arguments)) if (callbacks.length === 0) { @@ -215,8 +200,17 @@ methods.forEach(function (method) { debug('%s %s', method, this.path) - var layer = Layer('/', {}, fn) - layer.method = method + // check for error handler + var error = !!isError + if ((!error && !mwStack.isError(fn)) && fn.length === 4) { + deprecate('registering error handlers with .all is deprecated, use .error instead') + error = true + } + + var layer = Layer('/', { + error: error + }, fn) + layer.method = method === '_all' ? undefined : method this.methods[method] = true this.stack.push(layer) @@ -224,4 +218,4 @@ methods.forEach(function (method) { return this } -}) +} diff --git a/package.json b/package.json index 41328ab..9bafa3a 100644 --- a/package.json +++ b/package.json @@ -11,20 +11,22 @@ "dependencies": { "array-flatten": "2.1.1", "debug": "3.1.0", + "depd": "1.1.1", "methods": "~1.1.2", + "mwstack": "0.0.2", "parseurl": "~1.3.2", - "path-to-regexp": "0.1.7", - "setprototypeof": "1.1.0", + "path-to-regexp": "^3.0.0", + "setprototypeof": "1.2.0", "utils-merge": "1.0.1" }, "devDependencies": { "after": "0.8.2", - "eslint": "3.19.0", - "eslint-plugin-markdown": "1.0.0-beta.6", + "eslint": "6.8.0", + "eslint-plugin-markdown": "1.0.1", "finalhandler": "1.1.1", - "mocha": "3.5.3", - "nyc": "10.3.2", - "supertest": "1.2.0" + "mocha": "7.0.0", + "nyc": "15.0.0", + "supertest": "4.0.2" }, "files": [ "lib/", @@ -38,6 +40,7 @@ }, "scripts": { "lint": "eslint --plugin markdown --ext js,md .", + "lint-fix": "eslint --plugin markdown --ext js,md . --fix", "test": "mocha --reporter spec --bail --check-leaks test/", "test-cov": "nyc --reporter=text npm test", "test-travis": "nyc --reporter=html --reporter=text npm test" diff --git a/test/auto-head.js b/test/auto-head.js index f64a0fa..bb63145 100644 --- a/test/auto-head.js +++ b/test/auto-head.js @@ -13,10 +13,10 @@ describe('HEAD', function () { router.get('/users', sethit(1), saw) request(server) - .head('/users') - .expect('Content-Type', 'text/plain') - .expect('x-fn-1', 'hit') - .expect(200, done) + .head('/users') + .expect('Content-Type', 'text/plain') + .expect('x-fn-1', 'hit') + .expect(200, done) }) it('should invoke head if prior to get', function (done) { @@ -27,10 +27,10 @@ describe('HEAD', function () { router.get('/users', sethit(2), saw) request(server) - .head('/users') - .expect('Content-Type', 'text/plain') - .expect('x-fn-1', 'hit') - .expect(200, done) + .head('/users') + .expect('Content-Type', 'text/plain') + .expect('x-fn-1', 'hit') + .expect(200, done) }) }) diff --git a/test/auto-options.js b/test/auto-options.js index cd7a0b4..ac90959 100644 --- a/test/auto-options.js +++ b/test/auto-options.js @@ -16,9 +16,9 @@ describe('OPTIONS', function () { router.put('/users', saw) request(server) - .options('/users') - .expect('Allow', 'GET, HEAD, POST, PUT') - .expect(200, 'GET, HEAD, POST, PUT', done) + .options('/users') + .expect('Allow', 'GET, HEAD, POST, PUT') + .expect(200, 'GET, HEAD, POST, PUT', done) }) it('should not contain methods multiple times', function (done) { @@ -31,9 +31,9 @@ describe('OPTIONS', function () { router.get('/users', saw) request(server) - .options('/users') - .expect('GET, HEAD, PUT') - .expect('Allow', 'GET, HEAD, PUT', done) + .options('/users') + .expect('GET, HEAD, PUT') + .expect('Allow', 'GET, HEAD, PUT', done) }) it('should not include "all" routes', function (done) { @@ -46,10 +46,10 @@ describe('OPTIONS', function () { router.all('/users', sethit(1)) request(server) - .options('/users') - .expect('x-fn-1', 'hit') - .expect('Allow', 'GET, HEAD, PUT') - .expect(200, 'GET, HEAD, PUT', done) + .options('/users') + .expect('x-fn-1', 'hit') + .expect('Allow', 'GET, HEAD, PUT') + .expect(200, 'GET, HEAD, PUT', done) }) it('should not respond if no matching path', function (done) { @@ -59,8 +59,8 @@ describe('OPTIONS', function () { router.get('/users', saw) request(server) - .options('/') - .expect(404, done) + .options('/') + .expect(404, done) }) it('should do nothing with explicit options route', function (done) { @@ -71,8 +71,8 @@ describe('OPTIONS', function () { router.options('/users', saw) request(server) - .options('/users') - .expect(200, 'saw OPTIONS /users', done) + .options('/users') + .expect(200, 'saw OPTIONS /users', done) }) describe('when error occurs in respone handler', function () { @@ -88,8 +88,8 @@ describe('OPTIONS', function () { router.get('/users', saw) request(server) - .options('/users') - .expect(200, 'true', done) + .options('/users') + .expect(200, 'true', done) }) }) }) diff --git a/test/fqdn-url.js b/test/fqdn-url.js index 5411500..7fc0b71 100644 --- a/test/fqdn-url.js +++ b/test/fqdn-url.js @@ -13,8 +13,8 @@ describe('FQDN url', function () { router.use(saw) rawrequest(server) - .get('http://example.com/foo') - .expect(200, 'saw GET http://example.com/foo', done) + .get('http://example.com/foo') + .expect(200, 'saw GET http://example.com/foo', done) }) it('should strip/restore FQDN req.url', function (done) { @@ -25,9 +25,9 @@ describe('FQDN url', function () { router.use(saw) rawrequest(server) - .get('http://example.com/blog/post/1') - .expect('x-saw-1', 'GET http://example.com/post/1') - .expect(200, 'saw GET http://example.com/blog/post/1', done) + .get('http://example.com/blog/post/1') + .expect('x-saw-1', 'GET http://example.com/post/1') + .expect(200, 'saw GET http://example.com/blog/post/1', done) }) it('should ignore FQDN in search', function (done) { @@ -38,9 +38,9 @@ describe('FQDN url', function () { router.use(saw) rawrequest(server) - .get('/proxy?url=http://example.com/blog/post/1') - .expect('x-saw-1', 'GET /?url=http://example.com/blog/post/1') - .expect(200, 'saw GET /proxy?url=http://example.com/blog/post/1', done) + .get('/proxy?url=http://example.com/blog/post/1') + .expect('x-saw-1', 'GET /?url=http://example.com/blog/post/1') + .expect(200, 'saw GET /proxy?url=http://example.com/blog/post/1', done) }) it('should ignore FQDN in path', function (done) { @@ -51,9 +51,9 @@ describe('FQDN url', function () { router.use(saw) rawrequest(server) - .get('/proxy/http://example.com/blog/post/1') - .expect('x-saw-1', 'GET /http://example.com/blog/post/1') - .expect(200, 'saw GET /proxy/http://example.com/blog/post/1', done) + .get('/proxy/http://example.com/blog/post/1') + .expect('x-saw-1', 'GET /http://example.com/blog/post/1') + .expect(200, 'saw GET /proxy/http://example.com/blog/post/1', done) }) }) diff --git a/test/param.js b/test/param.js index e2a5aad..7a31a3c 100644 --- a/test/param.js +++ b/test/param.js @@ -48,12 +48,12 @@ describe('Router', function () { }) request(server) - .get('/user/2') - .expect(200, 'get user 2', cb) + .get('/user/2') + .expect(200, 'get user 2', cb) request(server) - .get('/user/bob') - .expect(200, 'get user NaN', cb) + .get('/user/bob') + .expect(200, 'get user NaN', cb) }) it('should allow chaining', function (done) { @@ -76,8 +76,8 @@ describe('Router', function () { }) request(server) - .get('/user/2') - .expect(200, 'get user 2 (2)', done) + .get('/user/2') + .expect(200, 'get user 2 (2)', done) }) it('should automatically decode path value', function (done) { @@ -95,8 +95,8 @@ describe('Router', function () { }) request(server) - .get('/user/%22bob%2Frobert%22') - .expect('get user "bob/robert"', done) + .get('/user/%22bob%2Frobert%22') + .expect('get user "bob/robert"', done) }) it('should 400 on invalid path value', function (done) { @@ -114,8 +114,8 @@ describe('Router', function () { }) request(server) - .get('/user/%bob') - .expect(400, /URIError: Failed to decode param/, done) + .get('/user/%bob') + .expect(400, /URIError: Failed to decode param/, done) }) it('should only invoke fn when necessary', function (done) { @@ -136,13 +136,13 @@ describe('Router', function () { router.put('/user/:id', saw) request(server) - .get('/user/bob') - .expect(500, /Error: boom/, cb) + .get('/user/bob') + .expect(500, /Error: boom/, cb) request(server) - .put('/user/bob') - .expect('x-id', 'bob') - .expect(200, 'saw PUT /user/bob', cb) + .put('/user/bob') + .expect('x-id', 'bob') + .expect(200, 'saw PUT /user/bob', cb) }) it('should only invoke fn once per request', function (done) { @@ -163,8 +163,8 @@ describe('Router', function () { }) request(server) - .get('/user/bob') - .expect('get user bob 1 times', done) + .get('/user/bob') + .expect('get user bob 1 times', done) }) it('should keep changes to req.params value', function (done) { @@ -187,8 +187,8 @@ describe('Router', function () { }) request(server) - .get('/user/01') - .expect('get user 1 1 times', done) + .get('/user/01') + .expect('get user 1 1 times', done) }) it('should invoke fn if path value differs', function (done) { @@ -210,8 +210,8 @@ describe('Router', function () { }) request(server) - .get('/user/bob') - .expect('get user bob 2 times: user, bob', done) + .get('/user/bob') + .expect('get user bob 2 times: user, bob', done) }) it('should catch exception in fn', function (done) { @@ -228,8 +228,8 @@ describe('Router', function () { }) request(server) - .get('/user/bob') - .expect(500, /Error: boom/, done) + .get('/user/bob') + .expect(500, /Error: boom/, done) }) it('should catch exception in chained fn', function (done) { @@ -250,8 +250,8 @@ describe('Router', function () { }) request(server) - .get('/user/bob') - .expect(500, /Error: boom/, done) + .get('/user/bob') + .expect(500, /Error: boom/, done) }) describe('next("route")', function () { @@ -283,16 +283,16 @@ describe('Router', function () { }) request(server) - .get('/user/2') - .expect(200, 'get user 2', cb) + .get('/user/2') + .expect(200, 'get user 2', cb) request(server) - .get('/user/bob') - .expect(404, cb) + .get('/user/bob') + .expect(404, cb) request(server) - .get('/user/new') - .expect(400, 'cannot get a new user', cb) + .get('/user/new') + .expect(400, 'cannot get a new user', cb) }) it('should invoke fn if path value differs', function (done) { @@ -314,10 +314,10 @@ describe('Router', function () { }) request(server) - .get('/user/bob') - .expect(shouldNotHitHandle(1)) - .expect(shouldHitHandle(2)) - .expect('get user bob 2 times: user, bob', done) + .get('/user/bob') + .expect(shouldNotHitHandle(1)) + .expect(shouldHitHandle(2)) + .expect('get user bob 2 times: user, bob', done) }) }) }) diff --git a/test/req.params.js b/test/req.params.js index c7dbba2..9a8ade9 100644 --- a/test/req.params.js +++ b/test/req.params.js @@ -13,8 +13,8 @@ describe('req.params', function () { router.get('/', sawParams) request(server) - .get('/') - .expect(200, '{}', done) + .get('/') + .expect(200, '{}', done) }) it('should not exist outside the router', function (done) { @@ -29,9 +29,9 @@ describe('req.params', function () { router.get('/', hitParams(1)) request(server) - .get('/') - .expect('x-params-1', '{}') - .expect(200, '', done) + .get('/') + .expect('x-params-1', '{}') + .expect(200, '', done) }) it('should overwrite value outside the router', function (done) { @@ -44,8 +44,8 @@ describe('req.params', function () { router.get('/', sawParams) request(server) - .get('/') - .expect(200, '{}', done) + .get('/') + .expect(200, '{}', done) }) it('should restore previous value outside the router', function (done) { @@ -62,9 +62,9 @@ describe('req.params', function () { router.get('/', hitParams(1)) request(server) - .get('/') - .expect('x-params-1', '{}') - .expect(200, '{"foo":"bar"}', done) + .get('/') + .expect('x-params-1', '{}') + .expect(200, '{"foo":"bar"}', done) }) describe('when "mergeParams: true"', function () { @@ -82,9 +82,9 @@ describe('req.params', function () { router.get('/:fizz', hitParams(1)) request(server) - .get('/buzz') - .expect('x-params-1', '{"foo":"bar","fizz":"buzz"}') - .expect(200, '{"foo":"bar"}', done) + .get('/buzz') + .expect('x-params-1', '{"foo":"bar","fizz":"buzz"}') + .expect(200, '{"foo":"bar"}', done) }) it('should ignore non-object outsite object', function (done) { @@ -101,9 +101,9 @@ describe('req.params', function () { router.get('/:fizz', hitParams(1)) request(server) - .get('/buzz') - .expect('x-params-1', '{"fizz":"buzz"}') - .expect(200, '42', done) + .get('/buzz') + .expect('x-params-1', '{"fizz":"buzz"}') + .expect(200, '42', done) }) it('should overwrite outside keys that are the same', function (done) { @@ -120,9 +120,9 @@ describe('req.params', function () { router.get('/:foo', hitParams(1)) request(server) - .get('/buzz') - .expect('x-params-1', '{"foo":"buzz"}') - .expect(200, '{"foo":"bar"}', done) + .get('/buzz') + .expect('x-params-1', '{"foo":"buzz"}') + .expect(200, '{"foo":"bar"}', done) }) describe('with numeric properties in req.params', function () { @@ -137,12 +137,12 @@ describe('req.params', function () { }) }) - router.get('/*', hitParams(1)) + router.get('/(.*)', hitParams(1)) request(server) - .get('/buzz') - .expect('x-params-1', '{"0":"foo","1":"bar","2":"buzz"}') - .expect(200, '{"0":"foo","1":"bar"}', done) + .get('/buzz') + .expect('x-params-1', '{"0":"foo","1":"bar","2":"buzz"}') + .expect(200, '{"0":"foo","1":"bar"}', done) }) it('should merge with same numeric properties', function (done) { @@ -156,12 +156,12 @@ describe('req.params', function () { }) }) - router.get('/*', hitParams(1)) + router.get('/(.*)', hitParams(1)) request(server) - .get('/bar') - .expect('x-params-1', '{"0":"foo","1":"bar"}') - .expect(200, '{"0":"foo"}', done) + .get('/bar') + .expect('x-params-1', '{"0":"foo","1":"bar"}') + .expect(200, '{"0":"foo"}', done) }) }) }) diff --git a/test/route.js b/test/route.js index d680272..9ee9821 100644 --- a/test/route.js +++ b/test/route.js @@ -31,16 +31,16 @@ describe('Router', function () { route.post(saw) request(server) - .get('/foo') - .expect(200, 'saw GET /foo', cb) + .get('/foo') + .expect(200, 'saw GET /foo', cb) request(server) - .post('/foo') - .expect(200, 'saw POST /foo', cb) + .post('/foo') + .expect(200, 'saw POST /foo', cb) request(server) - .put('/foo') - .expect(404, cb) + .put('/foo') + .expect(404, cb) }) it('should stack', function (done) { @@ -56,21 +56,21 @@ describe('Router', function () { router.use(saw) request(server) - .get('/foo') - .expect('x-fn-2', 'hit') - .expect('x-fn-3', 'hit') - .expect(200, 'saw GET /foo', cb) + .get('/foo') + .expect('x-fn-2', 'hit') + .expect('x-fn-3', 'hit') + .expect(200, 'saw GET /foo', cb) request(server) - .post('/foo') - .expect('x-fn-1', 'hit') - .expect('x-fn-2', 'hit') - .expect(200, 'saw POST /foo', cb) + .post('/foo') + .expect('x-fn-1', 'hit') + .expect('x-fn-2', 'hit') + .expect(200, 'saw POST /foo', cb) request(server) - .put('/foo') - .expect('x-fn-2', 'hit') - .expect(200, 'saw PUT /foo', cb) + .put('/foo') + .expect('x-fn-2', 'hit') + .expect(200, 'saw PUT /foo', cb) }) it('should not error on empty route', function (done) { @@ -80,12 +80,12 @@ describe('Router', function () { var server = createServer(router) request(server) - .get('/foo') - .expect(404, cb) + .get('/foo') + .expect(404, cb) request(server) - .head('/foo') - .expect(404, cb) + .head('/foo') + .expect(404, cb) }) it('should not invoke singular error route', function (done) { @@ -93,13 +93,13 @@ describe('Router', function () { var route = router.route('/foo') var server = createServer(router) - route.all(function handleError(err, req, res, next) { + route.error(function handleError(err, req, res, next) { throw new Error('boom!') }) request(server) - .get('/foo') - .expect(404, done) + .get('/foo') + .expect(404, done) }) describe('.all(...fn)', function () { @@ -130,16 +130,16 @@ describe('Router', function () { route.all(saw) request(server) - .get('/foo') - .expect(200, 'saw GET /foo', cb) + .get('/foo') + .expect(200, 'saw GET /foo', cb) request(server) - .post('/foo') - .expect(200, 'saw POST /foo', cb) + .post('/foo') + .expect(200, 'saw POST /foo', cb) request(server) - .put('/foo') - .expect(200, 'saw PUT /foo', cb) + .put('/foo') + .expect(200, 'saw PUT /foo', cb) }) it('should accept multiple arguments', function (done) { @@ -150,10 +150,10 @@ describe('Router', function () { route.all(createHitHandle(1), createHitHandle(2), helloWorld) request(server) - .get('/foo') - .expect('x-fn-1', 'hit') - .expect('x-fn-2', 'hit') - .expect(200, 'hello, world', done) + .get('/foo') + .expect('x-fn-1', 'hit') + .expect('x-fn-2', 'hit') + .expect(200, 'hello, world', done) }) it('should accept single array of handlers', function (done) { @@ -164,10 +164,10 @@ describe('Router', function () { route.all([createHitHandle(1), createHitHandle(2), helloWorld]) request(server) - .get('/foo') - .expect('x-fn-1', 'hit') - .expect('x-fn-2', 'hit') - .expect(200, 'hello, world', done) + .get('/foo') + .expect('x-fn-1', 'hit') + .expect('x-fn-2', 'hit') + .expect(200, 'hello, world', done) }) it('should accept nested arrays of handlers', function (done) { @@ -178,11 +178,11 @@ describe('Router', function () { route.all([[createHitHandle(1), createHitHandle(2)], createHitHandle(3)], helloWorld) request(server) - .get('/foo') - .expect('x-fn-1', 'hit') - .expect('x-fn-2', 'hit') - .expect('x-fn-3', 'hit') - .expect(200, 'hello, world', done) + .get('/foo') + .expect('x-fn-1', 'hit') + .expect('x-fn-2', 'hit') + .expect('x-fn-3', 'hit') + .expect(200, 'hello, world', done) }) }) @@ -194,7 +194,7 @@ describe('Router', function () { var body = method !== 'head' ? 'hello, world' - : '' + : undefined describe('.' + method + '(...fn)', function () { it('should respond to a ' + method.toUpperCase() + ' request', function (done) { @@ -205,8 +205,8 @@ describe('Router', function () { route[method](helloWorld) request(server) - [method]('/') - .expect(200, body, done) + [method]('/') + .expect(200, body, done) }) it('should reject no arguments', function () { @@ -235,10 +235,10 @@ describe('Router', function () { route[method](createHitHandle(1), createHitHandle(2), helloWorld) request(server) - [method]('/foo') - .expect('x-fn-1', 'hit') - .expect('x-fn-2', 'hit') - .expect(200, body, done) + [method]('/foo') + .expect('x-fn-1', 'hit') + .expect('x-fn-2', 'hit') + .expect(200, body, done) }) it('should accept single array of handlers', function (done) { @@ -249,10 +249,10 @@ describe('Router', function () { route[method]([createHitHandle(1), createHitHandle(2), helloWorld]) request(server) - [method]('/foo') - .expect('x-fn-1', 'hit') - .expect('x-fn-2', 'hit') - .expect(200, body, done) + [method]('/foo') + .expect('x-fn-1', 'hit') + .expect('x-fn-2', 'hit') + .expect(200, body, done) }) it('should accept nested arrays of handlers', function (done) { @@ -263,11 +263,11 @@ describe('Router', function () { route[method]([[createHitHandle(1), createHitHandle(2)], createHitHandle(3)], helloWorld) request(server) - [method]('/foo') - .expect('x-fn-1', 'hit') - .expect('x-fn-2', 'hit') - .expect('x-fn-3', 'hit') - .expect(200, body, done) + [method]('/foo') + .expect('x-fn-1', 'hit') + .expect('x-fn-2', 'hit') + .expect('x-fn-3', 'hit') + .expect(200, body, done) }) }) }) @@ -284,14 +284,14 @@ describe('Router', function () { route.all(helloWorld) - route.all(function handleError(err, req, res, next) { + route.error(function handleError(err, req, res, next) { res.statusCode = 500 res.end('caught: ' + err.message) }) request(server) - .get('/foo') - .expect(500, 'caught: boom!', done) + .get('/foo') + .expect(500, 'caught: boom!', done) }) it('should handle errors thrown', function (done) { @@ -305,14 +305,14 @@ describe('Router', function () { route.all(helloWorld) - route.all(function handleError(err, req, res, next) { + route.error(function handleError(err, req, res, next) { res.statusCode = 500 res.end('caught: ' + err.message) }) request(server) - .get('/foo') - .expect(500, 'caught: boom!', done) + .get('/foo') + .expect(500, 'caught: boom!', done) }) it('should handle errors thrown in error handlers', function (done) { @@ -324,18 +324,18 @@ describe('Router', function () { throw new Error('boom!') }) - route.all(function handleError(err, req, res, next) { + route.error(function handleError(err, req, res, next) { throw new Error('oh, no!') }) - route.all(function handleError(err, req, res, next) { + route.error(function handleError(err, req, res, next) { res.statusCode = 500 res.end('caught: ' + err.message) }) request(server) - .get('/foo') - .expect(500, 'caught: oh, no!', done) + .get('/foo') + .expect(500, 'caught: oh, no!', done) }) }) @@ -353,9 +353,9 @@ describe('Router', function () { router.use(saw) request(server) - .get('/foo') - .expect('x-next', 'route') - .expect(200, 'saw GET /foo', done) + .get('/foo') + .expect('x-next', 'route') + .expect(200, 'saw GET /foo', done) }) it('should invoke next route', function (done) { @@ -371,9 +371,9 @@ describe('Router', function () { router.route('/foo').all(saw) request(server) - .get('/foo') - .expect('x-next', 'route') - .expect(200, 'saw GET /foo', done) + .get('/foo') + .expect('x-next', 'route') + .expect(200, 'saw GET /foo', done) }) it('should skip next handlers in route', function (done) { @@ -391,11 +391,11 @@ describe('Router', function () { router.use(saw) request(server) - .get('/foo') - .expect(shouldHitHandle(1)) - .expect('x-next', 'route') - .expect(shouldNotHitHandle(2)) - .expect(200, 'saw GET /foo', done) + .get('/foo') + .expect(shouldHitHandle(1)) + .expect('x-next', 'route') + .expect(shouldNotHitHandle(2)) + .expect(200, 'saw GET /foo', done) }) it('should not invoke error handlers', function (done) { @@ -408,15 +408,15 @@ describe('Router', function () { next('route') }) - route.all(function handleError(err, req, res, next) { + route.error(function handleError(err, req, res, next) { res.statusCode = 500 res.end('caught: ' + err.message) }) request(server) - .get('/foo') - .expect('x-next', 'route') - .expect(404, done) + .get('/foo') + .expect('x-next', 'route') + .expect(404, done) }) }) @@ -436,10 +436,10 @@ describe('Router', function () { router.use(saw) request(server) - .get('/foo') - .expect('x-next', 'router') - .expect(shouldNotHitHandle(1)) - .expect(404, done) + .get('/foo') + .expect('x-next', 'router') + .expect(shouldNotHitHandle(1)) + .expect(404, done) }) it('should not invoke error handlers', function (done) { @@ -452,20 +452,20 @@ describe('Router', function () { next('router') }) - route.all(function handleError (err, req, res, next) { + route.error(function handleError (err, req, res, next) { res.statusCode = 500 res.end('caught: ' + err.message) }) - router.use(function handleError (err, req, res, next) { + router.error(function handleError (err, req, res, next) { res.statusCode = 500 res.end('caught: ' + err.message) }) request(server) - .get('/foo') - .expect('x-next', 'router') - .expect(404, done) + .get('/foo') + .expect('x-next', 'router') + .expect(404, done) }) }) @@ -481,14 +481,14 @@ describe('Router', function () { route.all(helloWorld) - route.all(function handleError (err, req, res, next) { + route.error(function handleError (err, req, res, next) { res.statusCode = 500 res.end('caught: ' + err.message) }) request(server) - .get('/foo') - .expect(500, 'caught: boom!', done) + .get('/foo') + .expect(500, 'caught: boom!', done) }) it('should pass rejected promise without value', function (done) { @@ -502,14 +502,14 @@ describe('Router', function () { route.all(helloWorld) - route.all(function handleError (err, req, res, next) { + route.error(function handleError (err, req, res, next) { res.statusCode = 500 res.end('caught: ' + err.message) }) request(server) - .get('/foo') - .expect(500, 'caught: Rejected promise', done) + .get('/foo') + .expect(500, 'caught: Rejected promise', done) }) it('should ignore resolved promise', function (done) { @@ -527,8 +527,8 @@ describe('Router', function () { }) request(server) - .get('/foo') - .expect(200, 'saw GET /foo', done) + .get('/foo') + .expect(200, 'saw GET /foo', done) }) describe('error handling', function () { @@ -541,18 +541,18 @@ describe('Router', function () { return Promise.reject(new Error('boom!')) }) - route.all(function handleError (err, req, res, next) { + route.error(function handleError (err, req, res, next) { return Promise.reject(new Error('caught: ' + err.message)) }) - route.all(function handleError (err, req, res, next) { + route.error(function handleError (err, req, res, next) { res.statusCode = 500 res.end('caught again: ' + err.message) }) request(server) - .get('/foo') - .expect(500, 'caught again: caught: boom!', done) + .get('/foo') + .expect(500, 'caught again: caught: boom!', done) }) it('should pass rejected promise without value', function (done) { @@ -564,18 +564,18 @@ describe('Router', function () { return Promise.reject(new Error('boom!')) }) - route.all(function handleError (err, req, res, next) { + route.error(function handleError (err, req, res, next) { return Promise.reject() }) - route.all(function handleError (err, req, res, next) { + route.error(function handleError (err, req, res, next) { res.statusCode = 500 res.end('caught again: ' + err.message) }) request(server) - .get('/foo') - .expect(500, 'caught again: Rejected promise', done) + .get('/foo') + .expect(500, 'caught again: Rejected promise', done) }) it('should ignore resolved promise', function (done) { @@ -587,7 +587,7 @@ describe('Router', function () { return Promise.reject(new Error('boom!')) }) - route.all(function handleError (err, req, res, next) { + route.error(function handleError (err, req, res, next) { res.statusCode = 500 res.end('caught: ' + err.message) return Promise.resolve('foo') @@ -598,8 +598,8 @@ describe('Router', function () { }) request(server) - .get('/foo') - .expect(500, 'caught: boom!', done) + .get('/foo') + .expect(500, 'caught: boom!', done) }) }) }) @@ -614,8 +614,8 @@ describe('Router', function () { route.all(sendParams) request(server) - .get('/bar') - .expect(200, {'foo': 'bar'}, done) + .get('/bar') + .expect(200, {'foo': 'bar'}, done) }) it('should match single path segment', function (done) { @@ -626,8 +626,8 @@ describe('Router', function () { route.all(sendParams) request(server) - .get('/bar/bar') - .expect(404, done) + .get('/bar/bar') + .expect(404, done) }) it('should work multiple times', function (done) { @@ -638,25 +638,25 @@ describe('Router', function () { route.all(sendParams) request(server) - .get('/fizz/buzz') - .expect(200, {'foo': 'fizz', 'bar': 'buzz'}, done) + .get('/fizz/buzz') + .expect(200, {'foo': 'fizz', 'bar': 'buzz'}, done) }) it('should work following a partial capture group', function (done) { var cb = after(2, done) var router = new Router() - var route = router.route('/user(s)?/:user/:op') + var route = router.route('\\/user(s)?/:user/:op') var server = createServer(router) route.all(sendParams) request(server) - .get('/user/tj/edit') - .expect(200, {'user': 'tj', 'op': 'edit'}, cb) + .get('/user/tj/edit') + .expect(200, {'user': 'tj', 'op': 'edit'}, cb) request(server) - .get('/users/tj/edit') - .expect(200, {'0': 's', 'user': 'tj', 'op': 'edit'}, cb) + .get('/users/tj/edit') + .expect(200, {'0': 's', 'user': 'tj', 'op': 'edit'}, cb) }) it('should work inside literal paranthesis', function (done) { @@ -667,8 +667,8 @@ describe('Router', function () { route.all(sendParams) request(server) - .get('/tj(edit)') - .expect(200, {'user': 'tj', 'op': 'edit'}, done) + .get('/tj(edit)') + .expect(200, {'user': 'tj', 'op': 'edit'}, done) }) it('should work within arrays', function (done) { @@ -680,12 +680,12 @@ describe('Router', function () { route.all(sendParams) request(server) - .get('/user/tj/poke') - .expect(200, {'user': 'tj'}, cb) + .get('/user/tj/poke') + .expect(200, {'user': 'tj'}, cb) request(server) - .get('/user/tj/pokes') - .expect(200, {'user': 'tj'}, cb) + .get('/user/tj/pokes') + .expect(200, {'user': 'tj'}, cb) }) }) @@ -698,8 +698,8 @@ describe('Router', function () { route.all(sendParams) request(server) - .get('/foo/bar/baz') - .expect(200, {'0': '/foo/bar/baz'}, done) + .get('/foo/bar/baz') + .expect(200, {'0': '/foo/bar/baz'}, done) }) it('should decode the capture', function (done) { @@ -710,111 +710,111 @@ describe('Router', function () { route.all(sendParams) request(server) - .get('/foo/%20/baz') - .expect(200, {'0': '/foo/ /baz'}, done) + .get('/foo/%20/baz') + .expect(200, {'0': '/foo/ /baz'}, done) }) it('should capture everything with pre- and post-fixes', function (done) { var router = new Router() - var route = router.route('/foo/*/bar') + var route = router.route('/foo/(.*)/bar') var server = createServer(router) route.all(sendParams) request(server) - .get('/foo/1/2/3/bar') - .expect(200, {'0': '1/2/3'}, done) + .get('/foo/1/2/3/bar') + .expect(200, {'0': '1/2/3'}, done) }) it('should capture greedly', function (done) { var router = new Router() - var route = router.route('/foo/*/bar') + var route = router.route('/foo/(.*)/bar') var server = createServer(router) route.all(sendParams) request(server) - .get('/foo/bar/bar/bar') - .expect(200, {'0': 'bar/bar'}, done) + .get('/foo/bar/bar/bar') + .expect(200, {'0': 'bar/bar'}, done) }) it('should be an optional capture', function (done) { var router = new Router() - var route = router.route('/foo*') + var route = router.route('/foo(.*)') var server = createServer(router) route.all(sendParams) request(server) - .get('/foo') - .expect(200, {'0': ''}, done) + .get('/foo') + .expect(200, {'0': ''}, done) }) it('should require preceeding /', function (done) { var cb = after(2, done) var router = new Router() - var route = router.route('/foo/*') + var route = router.route('/foo/(.*)') var server = createServer(router) route.all(sendParams) request(server) - .get('/foo') - .expect(404, cb) + .get('/foo') + .expect(404, cb) request(server) - .get('/foo/') - .expect(200, cb) + .get('/foo/') + .expect(200, cb) }) it('should work in a named parameter', function (done) { var cb = after(2, done) var router = new Router() - var route = router.route('/:foo(*)') + var route = router.route('/:foo(.*)') var server = createServer(router) route.all(sendParams) request(server) - .get('/bar') - .expect(200, {'0': 'bar', 'foo': 'bar'}, cb) + .get('/bar') + .expect(200, {'foo': 'bar'}, cb) request(server) - .get('/fizz/buzz') - .expect(200, {'0': 'fizz/buzz', 'foo': 'fizz/buzz'}, cb) + .get('/fizz/buzz') + .expect(200, {'foo': 'fizz/buzz'}, cb) }) it('should work before a named parameter', function (done) { var router = new Router() - var route = router.route('/*/user/:id') + var route = router.route('/(.*)/user/:id') var server = createServer(router) route.all(sendParams) request(server) - .get('/poke/user/42') - .expect(200, {'0': 'poke', 'id': '42'}, done) + .get('/poke/user/42') + .expect(200, {'0': 'poke', 'id': '42'}, done) }) it('should work within arrays', function (done) { var cb = after(3, done) var router = new Router() - var route = router.route(['/user/:id', '/foo/*', '/:action']) + var route = router.route(['/user/:id', '/foo/(.*)', '/:action']) var server = createServer(router) route.all(sendParams) request(server) - .get('/user/42') - .expect(200, {'id': '42'}, cb) + .get('/user/42') + .expect(200, {'id': '42'}, cb) request(server) - .get('/foo/bar') - .expect(200, {'0': 'bar'}, cb) + .get('/foo/bar') + .expect(200, {'0': 'bar'}, cb) request(server) - .get('/poke') - .expect(200, {'action': 'poke'}, cb) + .get('/poke') + .expect(200, {'action': 'poke'}, cb) }) }) }) diff --git a/test/router.js b/test/router.js index 0bb89a4..c2c7314 100644 --- a/test/router.js +++ b/test/router.js @@ -54,11 +54,11 @@ describe('Router', function () { var body = method !== 'head' ? 'hello, world' - : '' + : undefined request(server) - [method]('/') - .expect(200, body, cb) + [method]('/') + .expect(200, body, cb) }) }) @@ -70,16 +70,16 @@ describe('Router', function () { router.all(['/foo', '/bar'], saw) request(server) - .get('/') - .expect(404, cb) + .get('/') + .expect(404, cb) request(server) - .get('/foo') - .expect(200, 'saw GET /foo', cb) + .get('/foo') + .expect(200, 'saw GET /foo', cb) request(server) - .get('/bar') - .expect(200, 'saw GET /bar', cb) + .get('/bar') + .expect(200, 'saw GET /bar', cb) }) it('should support regexp path', function (done) { @@ -90,16 +90,16 @@ describe('Router', function () { router.all(/^\/[a-z]oo$/, saw) request(server) - .get('/') - .expect(404, cb) + .get('/') + .expect(404, cb) request(server) - .get('/foo') - .expect(200, 'saw GET /foo', cb) + .get('/foo') + .expect(200, 'saw GET /foo', cb) request(server) - .get('/zoo') - .expect(200, 'saw GET /zoo', cb) + .get('/zoo') + .expect(200, 'saw GET /zoo', cb) }) it('should support parameterized path', function (done) { @@ -110,23 +110,26 @@ describe('Router', function () { router.all('/:thing', saw) request(server) - .get('/') - .expect(404, cb) + .get('/') + .expect(404, cb) request(server) - .get('/foo') - .expect(200, 'saw GET /foo', cb) + .get('/foo') + .expect(200, 'saw GET /foo', cb) request(server) - .get('/bar') - .expect(200, 'saw GET /bar', cb) + .get('/bar') + .expect(200, 'saw GET /bar', cb) request(server) - .get('/foo/bar') - .expect(404, cb) + .get('/foo/bar') + .expect(404, cb) }) it('should not stack overflow with many registered routes', function (done) { + // This test might take longer on slow machines. + this.timeout(4000) + var router = new Router() var server = createServer(router) @@ -137,8 +140,8 @@ describe('Router', function () { router.get('/', helloWorld) request(server) - .get('/') - .expect(200, 'hello, world', done) + .get('/') + .expect(200, 'hello, world', done) }) describe('with "caseSensitive" option', function () { @@ -150,16 +153,16 @@ describe('Router', function () { router.all('/foo/bar', saw) request(server) - .get('/foo/bar') - .expect(200, 'saw GET /foo/bar', cb) + .get('/foo/bar') + .expect(200, 'saw GET /foo/bar', cb) request(server) - .get('/FOO/bar') - .expect(200, 'saw GET /FOO/bar', cb) + .get('/FOO/bar') + .expect(200, 'saw GET /FOO/bar', cb) request(server) - .get('/FOO/BAR') - .expect(200, 'saw GET /FOO/BAR', cb) + .get('/FOO/BAR') + .expect(200, 'saw GET /FOO/BAR', cb) }) it('should not match paths case-sensitively when false', function (done) { @@ -170,16 +173,16 @@ describe('Router', function () { router.all('/foo/bar', saw) request(server) - .get('/foo/bar') - .expect(200, 'saw GET /foo/bar', cb) + .get('/foo/bar') + .expect(200, 'saw GET /foo/bar', cb) request(server) - .get('/FOO/bar') - .expect(200, 'saw GET /FOO/bar', cb) + .get('/FOO/bar') + .expect(200, 'saw GET /FOO/bar', cb) request(server) - .get('/FOO/BAR') - .expect(200, 'saw GET /FOO/BAR', cb) + .get('/FOO/BAR') + .expect(200, 'saw GET /FOO/BAR', cb) }) it('should match paths case-sensitively when true', function (done) { @@ -190,16 +193,16 @@ describe('Router', function () { router.all('/foo/bar', saw) request(server) - .get('/foo/bar') - .expect(200, 'saw GET /foo/bar', cb) + .get('/foo/bar') + .expect(200, 'saw GET /foo/bar', cb) request(server) - .get('/FOO/bar') - .expect(404, cb) + .get('/FOO/bar') + .expect(404, cb) request(server) - .get('/FOO/BAR') - .expect(404, cb) + .get('/FOO/BAR') + .expect(404, cb) }) }) @@ -212,12 +215,12 @@ describe('Router', function () { router.all('/foo', saw) request(server) - .get('/foo') - .expect(200, 'saw GET /foo', cb) + .get('/foo') + .expect(200, 'saw GET /foo', cb) request(server) - .get('/foo/') - .expect(200, 'saw GET /foo/', cb) + .get('/foo/') + .expect(200, 'saw GET /foo/', cb) }) it('should accept optional trailing slashes when false', function (done) { @@ -228,12 +231,12 @@ describe('Router', function () { router.all('/foo', saw) request(server) - .get('/foo') - .expect(200, 'saw GET /foo', cb) + .get('/foo') + .expect(200, 'saw GET /foo', cb) request(server) - .get('/foo/') - .expect(200, 'saw GET /foo/', cb) + .get('/foo/') + .expect(200, 'saw GET /foo/', cb) }) it('should not accept optional trailing slashes when true', function (done) { @@ -244,12 +247,12 @@ describe('Router', function () { router.all('/foo', saw) request(server) - .get('/foo') - .expect(200, 'saw GET /foo', cb) + .get('/foo') + .expect(200, 'saw GET /foo', cb) request(server) - .get('/foo/') - .expect(404, cb) + .get('/foo/') + .expect(404, cb) }) }) }) @@ -262,7 +265,7 @@ describe('Router', function () { var body = method !== 'head' ? 'hello, world' - : '' + : undefined describe('.' + method + '(path, ...fn)', function () { it('should be chainable', function () { @@ -277,8 +280,8 @@ describe('Router', function () { router[method]('/', helloWorld) request(server) - [method]('/') - .expect(200, body, done) + [method]('/') + .expect(200, body, done) }) it('should reject invalid fn', function () { @@ -294,19 +297,19 @@ describe('Router', function () { router[method](['/foo', '/bar'], createHitHandle(1), helloWorld) request(server) - [method]('/') - .expect(shouldNotHitHandle(1)) - .expect(404, cb) + [method]('/') + .expect(shouldNotHitHandle(1)) + .expect(404, cb) request(server) - [method]('/foo') - .expect(shouldHitHandle(1)) - .expect(200, body, cb) + [method]('/foo') + .expect(shouldHitHandle(1)) + .expect(200, body, cb) request(server) - [method]('/bar') - .expect(shouldHitHandle(1)) - .expect(200, body, cb) + [method]('/bar') + .expect(shouldHitHandle(1)) + .expect(200, body, cb) }) it('should support regexp path', function (done) { @@ -317,19 +320,19 @@ describe('Router', function () { router[method](/^\/[a-z]oo$/, createHitHandle(1), helloWorld) request(server) - [method]('/') - .expect(shouldNotHitHandle(1)) - .expect(404, cb) + [method]('/') + .expect(shouldNotHitHandle(1)) + .expect(404, cb) request(server) - [method]('/foo') - .expect(shouldHitHandle(1)) - .expect(200, body, cb) + [method]('/foo') + .expect(shouldHitHandle(1)) + .expect(200, body, cb) request(server) - [method]('/zoo') - .expect(shouldHitHandle(1)) - .expect(200, body, cb) + [method]('/zoo') + .expect(shouldHitHandle(1)) + .expect(200, body, cb) }) it('should support parameterized path', function (done) { @@ -340,24 +343,24 @@ describe('Router', function () { router[method]('/:thing', createHitHandle(1), helloWorld) request(server) - [method]('/') - .expect(shouldNotHitHandle(1)) - .expect(404, cb) + [method]('/') + .expect(shouldNotHitHandle(1)) + .expect(404, cb) request(server) - [method]('/foo') - .expect(shouldHitHandle(1)) - .expect(200, body, cb) + [method]('/foo') + .expect(shouldHitHandle(1)) + .expect(200, body, cb) request(server) - [method]('/bar') - .expect(shouldHitHandle(1)) - .expect(200, body, cb) + [method]('/bar') + .expect(shouldHitHandle(1)) + .expect(200, body, cb) request(server) - [method]('/foo/bar') - .expect(shouldNotHitHandle(1)) - .expect(404, cb) + [method]('/foo/bar') + .expect(shouldNotHitHandle(1)) + .expect(404, cb) }) it('should accept multiple arguments', function (done) { @@ -367,10 +370,10 @@ describe('Router', function () { router[method]('/', createHitHandle(1), createHitHandle(2), helloWorld) request(server) - [method]('/') - .expect(shouldHitHandle(1)) - .expect(shouldHitHandle(2)) - .expect(200, body, done) + [method]('/') + .expect(shouldHitHandle(1)) + .expect(shouldHitHandle(2)) + .expect(200, body, done) }) describe('req.baseUrl', function () { @@ -384,9 +387,9 @@ describe('Router', function () { }) request(server) - [method]('/foo') - .expect('x-url-base', '""') - .expect(200, done) + [method]('/foo') + .expect('x-url-base', '""') + .expect(200, done) }) }) @@ -401,9 +404,9 @@ describe('Router', function () { }) request(server) - [method]('/foo') - .expect('x-is-route', 'true') - .expect(200, done) + [method]('/foo') + .expect('x-is-route', 'true') + .expect(200, done) }) it('should be the matched route', function (done) { @@ -416,9 +419,9 @@ describe('Router', function () { }) request(server) - [method]('/foo') - .expect('x-is-route', 'true') - .expect(200, done) + [method]('/foo') + .expect('x-is-route', 'true') + .expect(200, done) }) }) }) @@ -456,20 +459,20 @@ describe('Router', function () { router.use(saw) request(server) - .get('/') - .expect(200, 'saw GET /', cb) + .get('/') + .expect(200, 'saw GET /', cb) request(server) - .put('/') - .expect(200, 'saw PUT /', cb) + .put('/') + .expect(200, 'saw PUT /', cb) request(server) - .post('/foo') - .expect(200, 'saw POST /foo', cb) + .post('/foo') + .expect(200, 'saw POST /foo', cb) rawrequest(server) - .options('*') - .expect(200, 'saw OPTIONS *', cb) + .options('*') + .expect(200, 'saw OPTIONS *', cb) }) it('should not invoke for blank URLs', function (done) { @@ -482,8 +485,8 @@ describe('Router', function () { router.use(saw) request(server) - .get('/') - .expect(404, done) + .get('/') + .expect(404, done) }) it('should support another router', function (done) { @@ -495,8 +498,8 @@ describe('Router', function () { router.use(inner) request(server) - .get('/') - .expect(200, 'saw GET /', done) + .get('/') + .expect(200, 'saw GET /', done) }) it('should accept multiple arguments', function (done) { @@ -506,10 +509,10 @@ describe('Router', function () { router.use(createHitHandle(1), createHitHandle(2), helloWorld) request(server) - .get('/') - .expect(shouldHitHandle(1)) - .expect(shouldHitHandle(2)) - .expect(200, 'hello, world', done) + .get('/') + .expect(shouldHitHandle(1)) + .expect(shouldHitHandle(2)) + .expect(200, 'hello, world', done) }) it('should accept single array of middleware', function (done) { @@ -519,10 +522,10 @@ describe('Router', function () { router.use([createHitHandle(1), createHitHandle(2), helloWorld]) request(server) - .get('/') - .expect(shouldHitHandle(1)) - .expect(shouldHitHandle(2)) - .expect(200, 'hello, world', done) + .get('/') + .expect(shouldHitHandle(1)) + .expect(shouldHitHandle(2)) + .expect(200, 'hello, world', done) }) it('should accept nested arrays of middleware', function (done) { @@ -532,24 +535,24 @@ describe('Router', function () { router.use([[createHitHandle(1), createHitHandle(2)], createHitHandle(3)], helloWorld) request(server) - .get('/') - .expect(shouldHitHandle(1)) - .expect(shouldHitHandle(2)) - .expect(shouldHitHandle(3)) - .expect(200, 'hello, world', done) + .get('/') + .expect(shouldHitHandle(1)) + .expect(shouldHitHandle(2)) + .expect(shouldHitHandle(3)) + .expect(200, 'hello, world', done) }) it('should not invoke singular error function', function (done) { var router = new Router() var server = createServer(router) - router.use(function handleError(err, req, res, next) { + router.error(function handleError(err, req, res, next) { throw new Error('boom!') }) request(server) - .get('/') - .expect(404, done) + .get('/') + .expect(404, done) }) describe('error handling', function () { @@ -561,11 +564,11 @@ describe('Router', function () { next(new Error('boom!')) }) - router.use(sawError) + router.error(sawError) request(server) - .get('/') - .expect(200, 'saw Error: boom!', done) + .get('/') + .expect(200, 'saw Error: boom!', done) }) it('should invoke error function after throw err', function (done) { @@ -576,25 +579,43 @@ describe('Router', function () { throw new Error('boom!') }) - router.use(sawError) + router.error(sawError) request(server) - .get('/') - .expect(200, 'saw Error: boom!', done) + .get('/') + .expect(200, 'saw Error: boom!', done) }) it('should not invoke error functions above function', function (done) { var router = new Router() var server = createServer(router) - router.use(sawError) + router.error(sawError) router.use(function handle(req, res, next) { throw new Error('boom!') }) + request(server) + .get('/') + .expect(500, done) + }) + + it('should support error functions mixed with non-error functions in a Stack', function (done) { + var router = new Router() + var server = createServer(router) + + var stack = new Router.Stack() + stack.use(createHitHandle(1)) + stack.error(sawError) + stack.use(function (req, res, next) { + throw new Error('boom!') + }) + router.use(stack) + request(server) .get('/') + .expect(shouldHitHandle(1)) .expect(500, done) }) }) @@ -612,9 +633,9 @@ describe('Router', function () { router.use(saw) request(server) - .get('/') - .expect('x-next', 'route') - .expect(200, 'saw GET /', done) + .get('/') + .expect('x-next', 'route') + .expect(200, 'saw GET /', done) }) it('should invoke next function', function (done) { @@ -629,11 +650,11 @@ describe('Router', function () { router.use(createHitHandle(1), goNext, createHitHandle(2), saw) request(server) - .get('/') - .expect(shouldHitHandle(1)) - .expect('x-next', 'route') - .expect(shouldHitHandle(2)) - .expect(200, 'saw GET /', done) + .get('/') + .expect(shouldHitHandle(1)) + .expect('x-next', 'route') + .expect(shouldHitHandle(2)) + .expect(200, 'saw GET /', done) }) it('should not invoke error handlers', function (done) { @@ -645,12 +666,12 @@ describe('Router', function () { next('route') }) - router.use(sawError) + router.error(sawError) request(server) - .get('/') - .expect('x-next', 'route') - .expect(404, done) + .get('/') + .expect('x-next', 'route') + .expect(404, done) }) }) @@ -668,10 +689,10 @@ describe('Router', function () { router.use(saw) request(server) - .get('/') - .expect('x-next', 'router') - .expect(shouldNotHitHandle(1)) - .expect(404, done) + .get('/') + .expect('x-next', 'router') + .expect(shouldNotHitHandle(1)) + .expect(404, done) }) it('should not invoke error handlers', function (done) { @@ -683,12 +704,12 @@ describe('Router', function () { next('route') }) - router.use(sawError) + router.error(sawError) request(server) - .get('/') - .expect('x-next', 'router') - .expect(404, done) + .get('/') + .expect('x-next', 'router') + .expect(404, done) }) }) @@ -701,11 +722,11 @@ describe('Router', function () { return Promise.reject(new Error('boom!')) }) - router.use(sawError) + router.error(sawError) request(server) - .get('/') - .expect(200, 'saw Error: boom!', done) + .get('/') + .expect(200, 'saw Error: boom!', done) }) it('should pass rejected promise without value', function (done) { @@ -716,11 +737,11 @@ describe('Router', function () { return Promise.reject() }) - router.use(sawError) + router.error(sawError) request(server) - .get('/') - .expect(200, 'saw Error: Rejected promise', done) + .get('/') + .expect(200, 'saw Error: Rejected promise', done) }) it('should ignore resolved promise', function (done) { @@ -737,8 +758,8 @@ describe('Router', function () { }) request(server) - .get('/foo') - .expect(200, 'saw GET /foo', done) + .get('/foo') + .expect(200, 'saw GET /foo', done) }) describe('error handling', function () { @@ -750,15 +771,15 @@ describe('Router', function () { return Promise.reject(new Error('boom!')) }) - router.use(function handleError (err, req, res, next) { + router.error(function handleError (err, req, res, next) { return Promise.reject(new Error('caught: ' + err.message)) }) - router.use(sawError) + router.error(sawError) request(server) - .get('/') - .expect(200, 'saw Error: caught: boom!', done) + .get('/') + .expect(200, 'saw Error: caught: boom!', done) }) it('should pass rejected promise without value', function (done) { @@ -769,15 +790,15 @@ describe('Router', function () { return Promise.reject() }) - router.use(function handleError (err, req, res, next) { + router.error(function handleError (err, req, res, next) { return Promise.reject(new Error('caught: ' + err.message)) }) - router.use(sawError) + router.error(sawError) request(server) - .get('/') - .expect(200, 'saw Error: caught: Rejected promise', done) + .get('/') + .expect(200, 'saw Error: caught: Rejected promise', done) }) it('should ignore resolved promise', function (done) { @@ -788,7 +809,7 @@ describe('Router', function () { return Promise.reject(new Error('boom!')) }) - router.use(function handleError (err, req, res, next) { + router.error(function handleError (err, req, res, next) { sawError(err, req, res, next) return Promise.resolve('foo') }) @@ -798,8 +819,8 @@ describe('Router', function () { }) request(server) - .get('/foo') - .expect(200, 'saw Error: boom!', done) + .get('/foo') + .expect(200, 'saw Error: boom!', done) }) }) }) @@ -812,8 +833,8 @@ describe('Router', function () { router.use(sawBase) request(server) - .get('/foo/bar') - .expect(200, 'saw ', done) + .get('/foo/bar') + .expect(200, 'saw ', done) }) }) }) @@ -832,16 +853,16 @@ describe('Router', function () { router.use('/foo', saw) request(server) - .get('/') - .expect(404, cb) + .get('/') + .expect(404, cb) request(server) - .post('/foo') - .expect(200, 'saw POST /', cb) + .post('/foo') + .expect(200, 'saw POST /', cb) request(server) - .post('/foo/bar') - .expect(200, 'saw POST /bar', cb) + .post('/foo/bar') + .expect(200, 'saw POST /bar', cb) }) it('should match if path has trailing slash', function (done) { @@ -852,16 +873,16 @@ describe('Router', function () { router.use('/foo/', saw) request(server) - .get('/') - .expect(404, cb) + .get('/') + .expect(404, cb) request(server) - .post('/foo') - .expect(200, 'saw POST /', cb) + .post('/foo') + .expect(200, 'saw POST /', cb) request(server) - .post('/foo/bar') - .expect(200, 'saw POST /bar', cb) + .post('/foo/bar') + .expect(200, 'saw POST /bar', cb) }) it('should support array of paths', function (done) { @@ -872,16 +893,16 @@ describe('Router', function () { router.use(['/foo/', '/bar'], saw) request(server) - .get('/') - .expect(404, cb) + .get('/') + .expect(404, cb) request(server) - .get('/foo') - .expect(200, 'saw GET /', cb) + .get('/foo') + .expect(200, 'saw GET /', cb) request(server) - .get('/bar') - .expect(200, 'saw GET /', cb) + .get('/bar') + .expect(200, 'saw GET /', cb) }) it('should support regexp path', function (done) { @@ -892,24 +913,24 @@ describe('Router', function () { router.use(/^\/[a-z]oo/, saw) request(server) - .get('/') - .expect(404, cb) + .get('/') + .expect(404, cb) request(server) - .get('/foo') - .expect(200, 'saw GET /', cb) + .get('/foo') + .expect(200, 'saw GET /', cb) request(server) - .get('/fooo') - .expect(404, cb) + .get('/fooo') + .expect(404, cb) request(server) - .get('/zoo/bear') - .expect(200, 'saw GET /bear', cb) + .get('/zoo/bear') + .expect(200, 'saw GET /bear', cb) request(server) - .get('/get/zoo') - .expect(404, cb) + .get('/get/zoo') + .expect(404, cb) }) it('should support parameterized path', function (done) { @@ -920,20 +941,20 @@ describe('Router', function () { router.use('/:thing', saw) request(server) - .get('/') - .expect(404, cb) + .get('/') + .expect(404, cb) request(server) - .get('/foo') - .expect(200, 'saw GET /', cb) + .get('/foo') + .expect(200, 'saw GET /', cb) request(server) - .get('/bar') - .expect(200, 'saw GET /', cb) + .get('/bar') + .expect(200, 'saw GET /', cb) request(server) - .get('/foo/bar') - .expect(200, 'saw GET /bar', cb) + .get('/foo/bar') + .expect(200, 'saw GET /bar', cb) }) it('should accept multiple arguments', function (done) { @@ -943,10 +964,10 @@ describe('Router', function () { router.use('/foo', createHitHandle(1), createHitHandle(2), helloWorld) request(server) - .get('/foo') - .expect(shouldHitHandle(1)) - .expect(shouldHitHandle(2)) - .expect(200, 'hello, world', done) + .get('/foo') + .expect(shouldHitHandle(1)) + .expect(shouldHitHandle(2)) + .expect(200, 'hello, world', done) }) describe('with "caseSensitive" option', function () { @@ -958,16 +979,16 @@ describe('Router', function () { router.use('/foo', saw) request(server) - .get('/foo/bar') - .expect(200, 'saw GET /bar', cb) + .get('/foo/bar') + .expect(200, 'saw GET /bar', cb) request(server) - .get('/FOO/bar') - .expect(200, 'saw GET /bar', cb) + .get('/FOO/bar') + .expect(200, 'saw GET /bar', cb) request(server) - .get('/FOO/BAR') - .expect(200, 'saw GET /BAR', cb) + .get('/FOO/BAR') + .expect(200, 'saw GET /BAR', cb) }) it('should not match paths case-sensitively when false', function (done) { @@ -978,16 +999,16 @@ describe('Router', function () { router.use('/foo', saw) request(server) - .get('/foo/bar') - .expect(200, 'saw GET /bar', cb) + .get('/foo/bar') + .expect(200, 'saw GET /bar', cb) request(server) - .get('/FOO/bar') - .expect(200, 'saw GET /bar', cb) + .get('/FOO/bar') + .expect(200, 'saw GET /bar', cb) request(server) - .get('/FOO/BAR') - .expect(200, 'saw GET /BAR', cb) + .get('/FOO/BAR') + .expect(200, 'saw GET /BAR', cb) }) it('should match paths case-sensitively when true', function (done) { @@ -998,16 +1019,16 @@ describe('Router', function () { router.use('/foo', saw) request(server) - .get('/foo/bar') - .expect(200, 'saw GET /bar', cb) + .get('/foo/bar') + .expect(200, 'saw GET /bar', cb) request(server) - .get('/FOO/bar') - .expect(404, cb) + .get('/FOO/bar') + .expect(404, cb) request(server) - .get('/FOO/BAR') - .expect(404, cb) + .get('/FOO/BAR') + .expect(404, cb) }) }) @@ -1020,12 +1041,12 @@ describe('Router', function () { router.use('/foo', saw) request(server) - .get('/foo') - .expect(200, 'saw GET /', cb) + .get('/foo') + .expect(200, 'saw GET /', cb) request(server) - .get('/foo/') - .expect(200, 'saw GET /', cb) + .get('/foo/') + .expect(200, 'saw GET /', cb) }) it('should accept optional trailing slashes when false', function (done) { @@ -1036,12 +1057,12 @@ describe('Router', function () { router.use('/foo', saw) request(server) - .get('/foo') - .expect(200, 'saw GET /', cb) + .get('/foo') + .expect(200, 'saw GET /', cb) request(server) - .get('/foo/') - .expect(200, 'saw GET /', cb) + .get('/foo/') + .expect(200, 'saw GET /', cb) }) it('should accept optional trailing slashes when true', function (done) { @@ -1052,12 +1073,12 @@ describe('Router', function () { router.use('/foo', saw) request(server) - .get('/foo') - .expect(200, 'saw GET /', cb) + .get('/foo') + .expect(200, 'saw GET /', cb) request(server) - .get('/foo/') - .expect(200, 'saw GET /', cb) + .get('/foo/') + .expect(200, 'saw GET /', cb) }) }) @@ -1074,9 +1095,9 @@ describe('Router', function () { router.use('/foo', saw) request(server) - .get('/foo') - .expect('x-next', 'route') - .expect(200, 'saw GET /', done) + .get('/foo') + .expect('x-next', 'route') + .expect(200, 'saw GET /', done) }) it('should invoke next function', function (done) { @@ -1091,11 +1112,11 @@ describe('Router', function () { router.use('/foo', createHitHandle(1), goNext, createHitHandle(2), saw) request(server) - .get('/foo') - .expect(shouldHitHandle(1)) - .expect('x-next', 'route') - .expect(shouldHitHandle(2)) - .expect(200, 'saw GET /', done) + .get('/foo') + .expect(shouldHitHandle(1)) + .expect('x-next', 'route') + .expect(shouldHitHandle(2)) + .expect(200, 'saw GET /', done) }) }) @@ -1107,8 +1128,8 @@ describe('Router', function () { router.use('/foo', sawBase) request(server) - .get('/foo/bar') - .expect(200, 'saw /foo', done) + .get('/foo/bar') + .expect(200, 'saw /foo', done) }) it('should contain the stripped path for multiple levels', function (done) { @@ -1120,8 +1141,8 @@ describe('Router', function () { router2.use('/bar', sawBase) request(server) - .get('/foo/bar/baz') - .expect(200, 'saw /foo/bar', done) + .get('/foo/bar/baz') + .expect(200, 'saw /foo/bar', done) }) it('should be altered correctly', function(done){ @@ -1146,13 +1167,13 @@ describe('Router', function () { router.use(helloWorld) request(server) - .get('/foo/bar/baz/zed') - .expect('x-saw-base-1', '/foo/bar/baz') - .expect('x-saw-base-2', '/foo') - .expect('x-saw-base-3', '/foo/bar') - .expect('x-saw-base-4', '') - .expect('x-saw-base-5', '') - .expect(200, done) + .get('/foo/bar/baz/zed') + .expect('x-saw-base-1', '/foo/bar/baz') + .expect('x-saw-base-2', '/foo') + .expect('x-saw-base-3', '/foo/bar') + .expect('x-saw-base-4', '') + .expect('x-saw-base-5', '') + .expect(200, done) }) }) @@ -1164,8 +1185,8 @@ describe('Router', function () { router.use('/foo', saw) request(server) - .get('/foo/bar') - .expect(200, 'saw GET /bar', done) + .get('/foo/bar') + .expect(200, 'saw GET /bar', done) }) it('should restore req.url after stripping', function (done) { @@ -1176,9 +1197,9 @@ describe('Router', function () { router.use(saw) request(server) - .get('/foo/bar') - .expect('x-saw-1', 'GET /bar') - .expect(200, 'saw GET /foo/bar', done) + .get('/foo/bar') + .expect('x-saw-1', 'GET /bar') + .expect(200, 'saw GET /foo/bar', done) }) it('should strip/restore with trailing stash', function (done) { @@ -1189,9 +1210,9 @@ describe('Router', function () { router.use(saw) request(server) - .get('/foo/') - .expect('x-saw-1', 'GET /') - .expect(200, 'saw GET /foo/', done) + .get('/foo/') + .expect('x-saw-1', 'GET /') + .expect(200, 'saw GET /foo/', done) }) }) }) @@ -1212,12 +1233,12 @@ describe('Router', function () { router.use(saw) request(server) - .post('/foo') - .expect(shouldNotHitHandle(1)) - .expect(shouldHitHandle(2)) - .expect(shouldNotHitHandle(3)) - .expect(shouldHitHandle(4)) - .expect(200, 'saw PUT /foo', done) + .post('/foo') + .expect(shouldNotHitHandle(1)) + .expect(shouldHitHandle(2)) + .expect(shouldNotHitHandle(3)) + .expect(shouldHitHandle(4)) + .expect(200, 'saw PUT /foo', done) }) it('should support altering req.url', function (done) { @@ -1235,12 +1256,12 @@ describe('Router', function () { router.use(saw) request(server) - .get('/foo') - .expect(shouldNotHitHandle(1)) - .expect(shouldHitHandle(2)) - .expect(shouldNotHitHandle(3)) - .expect(shouldHitHandle(4)) - .expect(200, 'saw GET /bar', done) + .get('/foo') + .expect(shouldNotHitHandle(1)) + .expect(shouldHitHandle(2)) + .expect(shouldNotHitHandle(3)) + .expect(shouldHitHandle(4)) + .expect(200, 'saw GET /bar', done) }) }) })