From d3de352d4577c0f144c56dbca202df3bbb85c459 Mon Sep 17 00:00:00 2001 From: Wes Todd Date: Sun, 1 Sep 2024 12:38:53 -0500 Subject: [PATCH] fix(ci): replace after with run-series to address flaky superagent behavior --- package.json | 2 +- test/param.js | 73 +++-- test/route.js | 395 ++++++++++++++----------- test/router.js | 787 ++++++++++++++++++++++++++++--------------------- 4 files changed, 720 insertions(+), 537 deletions(-) diff --git a/package.json b/package.json index 1016e69..66ba5af 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,6 @@ "utils-merge": "1.0.1" }, "devDependencies": { - "after": "0.8.2", "eslint": "8.34.0", "eslint-config-standard": "14.1.1", "eslint-plugin-import": "2.26.0", @@ -29,6 +28,7 @@ "finalhandler": "1.2.0", "mocha": "10.2.0", "nyc": "15.1.0", + "run-series": "^1.1.9", "safe-buffer": "5.2.1", "supertest": "6.3.3" }, diff --git a/test/param.js b/test/param.js index e2ca379..0b02b5c 100644 --- a/test/param.js +++ b/test/param.js @@ -1,5 +1,5 @@ -var after = require('after') +var series = require('run-series') var Router = require('..') var utils = require('./support/utils') @@ -35,7 +35,6 @@ describe('Router', function () { }) it('should map logic for a path param', function (done) { - var cb = after(2, done) var router = new Router() var server = createServer(router) @@ -49,13 +48,18 @@ describe('Router', function () { res.end('get user ' + req.params.id) }) - request(server) - .get('/user/2') - .expect(200, 'get user 2', cb) - - request(server) - .get('/user/bob') - .expect(200, 'get user NaN', cb) + series([ + function (cb) { + request(server) + .get('/user/2') + .expect(200, 'get user 2', cb) + }, + function (cb) { + request(server) + .get('/user/bob') + .expect(200, 'get user NaN', cb) + } + ], done) }) it('should allow chaining', function (done) { @@ -121,7 +125,6 @@ describe('Router', function () { }) it('should only invoke fn when necessary', function (done) { - var cb = after(2, done) var router = new Router() var server = createServer(router) @@ -137,14 +140,19 @@ describe('Router', function () { router.get('/user/:user', saw) router.put('/user/:id', saw) - request(server) - .get('/user/bob') - .expect(500, /Error: boom/, cb) - - request(server) - .put('/user/bob') - .expect('x-id', 'bob') - .expect(200, 'saw PUT /user/bob', cb) + series([ + function (cb) { + request(server) + .get('/user/bob') + .expect(500, /Error: boom/, cb) + }, + function (cb) { + request(server) + .put('/user/bob') + .expect('x-id', 'bob') + .expect(200, 'saw PUT /user/bob', cb) + } + ], done) }) it('should only invoke fn once per request', function (done) { @@ -300,7 +308,6 @@ describe('Router', function () { describe('next("route")', function () { it('should cause route with param to be skipped', function (done) { - var cb = after(3, done) var router = new Router() var server = createServer(router) @@ -326,17 +333,23 @@ describe('Router', function () { res.end('cannot get a new user') }) - request(server) - .get('/user/2') - .expect(200, 'get user 2', cb) - - request(server) - .get('/user/bob') - .expect(404, cb) - - request(server) - .get('/user/new') - .expect(400, 'cannot get a new user', cb) + series([ + function (cb) { + request(server) + .get('/user/2') + .expect(200, 'get user 2', cb) + }, + function (cb) { + request(server) + .get('/user/bob') + .expect(404, cb) + }, + function (cb) { + request(server) + .get('/user/new') + .expect(400, 'cannot get a new user', cb) + } + ], done) }) it('should invoke fn if path value differs', function (done) { diff --git a/test/route.js b/test/route.js index fcd6f8b..724f5d5 100644 --- a/test/route.js +++ b/test/route.js @@ -1,7 +1,7 @@ -var after = require('after') var Buffer = require('safe-buffer').Buffer var methods = require('methods') +var series = require('run-series') var Router = require('..') var utils = require('./support/utils') @@ -25,7 +25,6 @@ describe('Router', function () { }) it('should respond to multiple methods', function (done) { - var cb = after(3, done) var router = new Router() var route = router.route('/foo') var server = createServer(router) @@ -33,17 +32,23 @@ describe('Router', function () { route.get(saw) route.post(saw) - request(server) - .get('/foo') - .expect(200, 'saw GET /foo', cb) - - request(server) - .post('/foo') - .expect(200, 'saw POST /foo', cb) - - request(server) - .put('/foo') - .expect(404, cb) + series([ + function (cb) { + request(server) + .get('/foo') + .expect(200, 'saw GET /foo', cb) + }, + function (cb) { + request(server) + .post('/foo') + .expect(200, 'saw POST /foo', cb) + }, + function (cb) { + request(server) + .put('/foo') + .expect(404, cb) + } + ], done) }) it('should route without method', function (done) { @@ -71,7 +76,6 @@ describe('Router', function () { }) it('should stack', function (done) { - var cb = after(3, done) var router = new Router() var route = router.route('/foo') var server = createServer(router) @@ -82,39 +86,49 @@ 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) - - request(server) - .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) + series([ + function (cb) { + request(server) + .get('/foo') + .expect('x-fn-2', 'hit') + .expect('x-fn-3', 'hit') + .expect(200, 'saw GET /foo', cb) + }, + function (cb) { + request(server) + .post('/foo') + .expect('x-fn-1', 'hit') + .expect('x-fn-2', 'hit') + .expect(200, 'saw POST /foo', cb) + }, + function (cb) { + request(server) + .put('/foo') + .expect('x-fn-2', 'hit') + .expect(200, 'saw PUT /foo', cb) + } + ], done) }) it('should not error on empty route', function (done) { - var cb = after(2, done) var router = new Router() var route = router.route('/foo') var server = createServer(router) assert.ok(route) - request(server) - .get('/foo') - .expect(404, cb) - - request(server) - .head('/foo') - .expect(404, cb) + series([ + function (cb) { + request(server) + .get('/foo') + .expect(404, cb) + }, + function (cb) { + request(server) + .head('/foo') + .expect(404, cb) + } + ], done) }) it('should not invoke singular error route', function (done) { @@ -169,24 +183,29 @@ describe('Router', function () { }) it('should respond to all methods', function (done) { - var cb = after(3, done) var router = new Router() var route = router.route('/foo') var server = createServer(router) route.all(saw) - request(server) - .get('/foo') - .expect(200, 'saw GET /foo', cb) - - request(server) - .post('/foo') - .expect(200, 'saw POST /foo', cb) - - request(server) - .put('/foo') - .expect(200, 'saw PUT /foo', cb) + series([ + function (cb) { + request(server) + .get('/foo') + .expect(200, 'saw GET /foo', cb) + }, + function (cb) { + request(server) + .post('/foo') + .expect(200, 'saw POST /foo', cb) + }, + function (cb) { + request(server) + .put('/foo') + .expect(200, 'saw PUT /foo', cb) + } + ], done) }) it('should accept multiple arguments', function (done) { @@ -238,6 +257,9 @@ describe('Router', function () { // CONNECT is tricky and supertest doesn't support it return } + if (method === 'query' && process.version.startsWith('v21')) { + return + } var body = method !== 'head' ? shouldHaveBody(Buffer.from('hello, world')) @@ -695,20 +717,24 @@ describe('Router', function () { }) 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 server = createServer(router) route.all(sendParams) - request(server) - .get('/user/tj/edit') - .expect(200, { 0: '', user: 'tj', op: 'edit' }, cb) - - request(server) - .get('/users/tj/edit') - .expect(200, { 0: 's', user: 'tj', op: 'edit' }, cb) + series([ + function (cb) { + request(server) + .get('/user/tj/edit') + .expect(200, { 0: '', user: 'tj', op: 'edit' }, cb) + }, + function (cb) { + request(server) + .get('/users/tj/edit') + .expect(200, { 0: 's', user: 'tj', op: 'edit' }, cb) + } + ], done) }) it('should work inside literal paranthesis', function (done) { @@ -724,203 +750,240 @@ describe('Router', function () { }) it('should work within arrays', function (done) { - var cb = after(2, done) var router = new Router() var route = router.route(['/user/:user/poke', '/user/:user/pokes']) var server = createServer(router) route.all(sendParams) - - request(server) - .get('/user/tj/poke') - .expect(200, { user: 'tj' }, cb) - - request(server) - .get('/user/tj/pokes') - .expect(200, { user: 'tj' }, cb) + series([ + function (cb) { + request(server) + .get('/user/tj/poke') + .expect(200, { user: 'tj' }, cb) + }, + function (cb) { + request(server) + .get('/user/tj/pokes') + .expect(200, { user: 'tj' }, cb) + } + ], done) }) }) describe('using ":name?"', function () { it('should name an optional parameter', function (done) { - var cb = after(2, done) var router = new Router() var route = router.route('/:foo?') var server = createServer(router) route.all(sendParams) - - request(server) - .get('/bar') - .expect(200, { foo: 'bar' }, cb) - - request(server) - .get('/') - .expect(200, {}, cb) + series([ + function (cb) { + request(server) + .get('/bar') + .expect(200, { foo: 'bar' }, cb) + }, + function (cb) { + request(server) + .get('/') + .expect(200, {}, cb) + } + ], done) }) it('should work in any segment', function (done) { - var cb = after(2, done) var router = new Router() var route = router.route('/user/:foo?/delete') var server = createServer(router) route.all(sendParams) - - request(server) - .get('/user/bar/delete') - .expect(200, { foo: 'bar' }, cb) - - request(server) - .get('/user/delete') - .expect(200, {}, cb) + series([ + function (cb) { + request(server) + .get('/user/bar/delete') + .expect(200, { foo: 'bar' }, cb) + }, + function (cb) { + request(server) + .get('/user/delete') + .expect(200, {}, cb) + } + ], done) }) }) describe('using ":name*"', function () { it('should name a zero-or-more repeated parameter', function (done) { - var cb = after(3, done) var router = new Router() var route = router.route('/:foo*') var server = createServer(router) route.all(sendParams) - - request(server) - .get('/') - .expect(200, {}, cb) - - request(server) - .get('/bar') - .expect(200, { foo: 'bar' }, cb) - - request(server) - .get('/fizz/buzz') - .expect(200, { foo: 'fizz/buzz' }, cb) + series([ + function (cb) { + request(server) + .get('/') + .expect(200, {}, cb) + }, + function (cb) { + request(server) + .get('/bar') + .expect(200, { foo: 'bar' }, cb) + }, + function (cb) { + request(server) + .get('/fizz/buzz') + .expect(200, { foo: 'fizz/buzz' }, cb) + } + ], done) }) it('should work in any segment', function (done) { - var cb = after(3, done) var router = new Router() var route = router.route('/user/:foo*/delete') var server = createServer(router) route.all(sendParams) - - request(server) - .get('/user/delete') - .expect(200, {}, cb) - - request(server) - .get('/user/bar/delete') - .expect(200, { foo: 'bar' }, cb) - - request(server) - .get('/user/fizz/buzz/delete') - .expect(200, { foo: 'fizz/buzz' }, cb) + series([ + function (cb) { + request(server) + .get('/user/delete') + .expect(200, {}, cb) + }, + function (cb) { + request(server) + .get('/user/bar/delete') + .expect(200, { foo: 'bar' }, cb) + }, + function (cb) { + request(server) + .get('/user/fizz/buzz/delete') + .expect(200, { foo: 'fizz/buzz' }, cb) + } + ], done) }) }) describe('using ":name+"', function () { it('should name a one-or-more repeated parameter', function (done) { - var cb = after(3, done) var router = new Router() var route = router.route('/:foo+') var server = createServer(router) route.all(sendParams) - request(server) - .get('/') - .expect(404, cb) - - request(server) - .get('/bar') - .expect(200, { foo: 'bar' }, cb) - - request(server) - .get('/fizz/buzz') - .expect(200, { foo: 'fizz/buzz' }, cb) + series([ + function (cb) { + request(server) + .get('/') + .expect(404, cb) + }, + function (cb) { + request(server) + .get('/bar') + .expect(200, { foo: 'bar' }, cb) + }, + function (cb) { + request(server) + .get('/fizz/buzz') + .expect(200, { foo: 'fizz/buzz' }, cb) + } + ], done) }) it('should work in any segment', function (done) { - var cb = after(3, done) var router = new Router() var route = router.route('/user/:foo+/delete') var server = createServer(router) route.all(sendParams) - - request(server) - .get('/user/delete') - .expect(404, cb) - - request(server) - .get('/user/bar/delete') - .expect(200, { foo: 'bar' }, cb) - - request(server) - .get('/user/fizz/buzz/delete') - .expect(200, { foo: 'fizz/buzz' }, cb) + series([ + function (cb) { + request(server) + .get('/user/delete') + .expect(404, cb) + }, + function (cb) { + request(server) + .get('/user/bar/delete') + .expect(200, { foo: 'bar' }, cb) + }, + function (cb) { + request(server) + .get('/user/fizz/buzz/delete') + .expect(200, { foo: 'fizz/buzz' }, cb) + } + ], done) }) }) describe('using ":name(regexp)"', function () { it('should limit capture group to regexp match', function (done) { - var cb = after(2, done) var router = new Router() var route = router.route('/:foo([0-9]+)') var server = createServer(router) route.all(sendParams) - request(server) - .get('/foo') - .expect(404, cb) - - request(server) - .get('/42') - .expect(200, { foo: '42' }, cb) + series([ + function (cb) { + request(server) + .get('/foo') + .expect(404, cb) + }, + function (cb) { + request(server) + .get('/42') + .expect(200, { foo: '42' }, cb) + } + ], done) }) }) describe('using "(regexp)"', function () { it('should add capture group using regexp', function (done) { - var cb = after(2, done) var router = new Router() var route = router.route('/page_([0-9]+)') var server = createServer(router) route.all(sendParams) - - request(server) - .get('/page_foo') - .expect(404, cb) - - request(server) - .get('/page_42') - .expect(200, { 0: '42' }, cb) + series([ + function (cb) { + request(server) + .get('/page_foo') + .expect(404, cb) + }, + function (cb) { + request(server) + .get('/page_42') + .expect(200, { 0: '42' }, cb) + } + ], done) }) it('should treat regexp as literal regexp', function (done) { - var cb = after(3, done) var router = new Router() var route = router.route('/([a-z]+:n[0-9]+)') var server = createServer(router) route.all(sendParams) - - request(server) - .get('/foo:bar') - .expect(404, cb) - - request(server) - .get('/foo:n') - .expect(404, cb) - - request(server) - .get('/foo:n42') - .expect(200, { 0: 'foo:n42' }, cb) + series([ + function (cb) { + request(server) + .get('/foo:bar') + .expect(404, cb) + }, + function (cb) { + request(server) + .get('/foo:n') + .expect(404, cb) + }, + function (cb) { + request(server) + .get('/foo:n42') + .expect(200, { 0: 'foo:n42' }, cb) + } + ], done) }) }) }) diff --git a/test/router.js b/test/router.js index 7af8186..433634f 100644 --- a/test/router.js +++ b/test/router.js @@ -1,7 +1,7 @@ -var after = require('after') var Buffer = require('safe-buffer').Buffer var methods = require('methods') +var series = require('run-series') var Router = require('..') var utils = require('./support/utils') @@ -44,90 +44,107 @@ describe('Router', function () { }) it('should respond to all methods', function (done) { - var cb = after(methods.length, done) var router = new Router() var server = createServer(router) router.all('/', helloWorld) - methods.forEach(function (method) { - if (method === 'connect') { - // CONNECT is tricky and supertest doesn't support it - return cb() + series(methods.map(function (method) { + return function (cb) { + if (method === 'connect') { + // CONNECT is tricky and supertest doesn't support it + return cb() + } + if (method === 'query' && process.version.startsWith('v21')) { + return cb() + } + + var body = method !== 'head' + ? shouldHaveBody(Buffer.from('hello, world')) + : shouldNotHaveBody() + + request(server)[method]('/') + .expect(200) + .expect(body) + .end(cb) } - - var body = method !== 'head' - ? shouldHaveBody(Buffer.from('hello, world')) - : shouldNotHaveBody() - - request(server)[method]('/') - .expect(200) - .expect(body) - .end(cb) - }) + }), done) }) it('should support array of paths', function (done) { - var cb = after(3, done) var router = new Router() var server = createServer(router) router.all(['/foo', '/bar'], saw) - - request(server) - .get('/') - .expect(404, cb) - - request(server) - .get('/foo') - .expect(200, 'saw GET /foo', cb) - - request(server) - .get('/bar') - .expect(200, 'saw GET /bar', cb) + series([ + function (cb) { + request(server) + .get('/') + .expect(404, cb) + }, + function (cb) { + request(server) + .get('/foo') + .expect(200, 'saw GET /foo', cb) + }, + function (cb) { + request(server) + .get('/bar') + .expect(200, 'saw GET /bar', cb) + } + ], done) }) it('should support regexp path', function (done) { - var cb = after(3, done) var router = new Router() var server = createServer(router) router.all(/^\/[a-z]oo$/, saw) - - request(server) - .get('/') - .expect(404, cb) - - request(server) - .get('/foo') - .expect(200, 'saw GET /foo', cb) - - request(server) - .get('/zoo') - .expect(200, 'saw GET /zoo', cb) + series([ + function (cb) { + request(server) + .get('/') + .expect(404, cb) + }, + function (cb) { + request(server) + .get('/foo') + .expect(200, 'saw GET /foo', cb) + }, + function (cb) { + request(server) + .get('/zoo') + .expect(200, 'saw GET /zoo', cb) + } + ], done) }) it('should support parameterized path', function (done) { - var cb = after(4, done) var router = new Router() var server = createServer(router) router.all('/:thing', saw) - - request(server) - .get('/') - .expect(404, cb) - - request(server) - .get('/foo') - .expect(200, 'saw GET /foo', cb) - - request(server) - .get('/bar') - .expect(200, 'saw GET /bar', cb) - - request(server) - .get('/foo/bar') - .expect(404, cb) + series([ + function (cb) { + request(server) + .get('/') + .expect(404, cb) + }, + function (cb) { + request(server) + .get('/foo') + .expect(200, 'saw GET /foo', cb) + }, + function (cb) { + request(server) + .get('/bar') + .expect(200, 'saw GET /bar', cb) + }, + function (cb) { + request(server) + .get('/foo/bar') + .expect(404, cb) + } + ], done) }) it('should not stack overflow with many registered routes', function (done) { @@ -166,113 +183,134 @@ describe('Router', function () { describe('with "caseSensitive" option', function () { it('should not match paths case-sensitively by default', function (done) { - var cb = after(3, done) var router = new Router() var server = createServer(router) router.all('/foo/bar', saw) - - request(server) - .get('/foo/bar') - .expect(200, 'saw GET /foo/bar', cb) - - request(server) - .get('/FOO/bar') - .expect(200, 'saw GET /FOO/bar', cb) - - request(server) - .get('/FOO/BAR') - .expect(200, 'saw GET /FOO/BAR', cb) + series([ + function (cb) { + request(server) + .get('/foo/bar') + .expect(200, 'saw GET /foo/bar', cb) + }, + function (cb) { + request(server) + .get('/FOO/bar') + .expect(200, 'saw GET /FOO/bar', cb) + }, + function (cb) { + request(server) + .get('/FOO/BAR') + .expect(200, 'saw GET /FOO/BAR', cb) + } + ], done) }) it('should not match paths case-sensitively when false', function (done) { - var cb = after(3, done) var router = new Router({ caseSensitive: false }) var server = createServer(router) router.all('/foo/bar', saw) - - request(server) - .get('/foo/bar') - .expect(200, 'saw GET /foo/bar', cb) - - request(server) - .get('/FOO/bar') - .expect(200, 'saw GET /FOO/bar', cb) - - request(server) - .get('/FOO/BAR') - .expect(200, 'saw GET /FOO/BAR', cb) + series([ + function (cb) { + request(server) + .get('/foo/bar') + .expect(200, 'saw GET /foo/bar', cb) + }, + function (cb) { + request(server) + .get('/FOO/bar') + .expect(200, 'saw GET /FOO/bar', cb) + }, + function (cb) { + request(server) + .get('/FOO/BAR') + .expect(200, 'saw GET /FOO/BAR', cb) + } + ], done) }) it('should match paths case-sensitively when true', function (done) { - var cb = after(3, done) var router = new Router({ caseSensitive: true }) var server = createServer(router) router.all('/foo/bar', saw) - - request(server) - .get('/foo/bar') - .expect(200, 'saw GET /foo/bar', cb) - - request(server) - .get('/FOO/bar') - .expect(404, cb) - - request(server) - .get('/FOO/BAR') - .expect(404, cb) + series([ + function (cb) { + request(server) + .get('/foo/bar') + .expect(200, 'saw GET /foo/bar', cb) + }, + function (cb) { + request(server) + .get('/FOO/bar') + .expect(404, cb) + }, + function (cb) { + request(server) + .get('/FOO/BAR') + .expect(404, cb) + } + ], done) }) }) describe('with "strict" option', function () { it('should accept optional trailing slashes by default', function (done) { - var cb = after(2, done) var router = new Router() var server = createServer(router) router.all('/foo', saw) - - request(server) - .get('/foo') - .expect(200, 'saw GET /foo', cb) - - request(server) - .get('/foo/') - .expect(200, 'saw GET /foo/', cb) + series([ + function (cb) { + request(server) + .get('/foo') + .expect(200, 'saw GET /foo', cb) + }, + function (cb) { + request(server) + .get('/foo/') + .expect(200, 'saw GET /foo/', cb) + } + ], done) }) it('should accept optional trailing slashes when false', function (done) { - var cb = after(2, done) var router = new Router({ strict: false }) var server = createServer(router) router.all('/foo', saw) - - request(server) - .get('/foo') - .expect(200, 'saw GET /foo', cb) - - request(server) - .get('/foo/') - .expect(200, 'saw GET /foo/', cb) + series([ + function (cb) { + request(server) + .get('/foo') + .expect(200, 'saw GET /foo', cb) + }, + function (cb) { + request(server) + .get('/foo/') + .expect(200, 'saw GET /foo/', cb) + } + ], done) }) it('should not accept optional trailing slashes when true', function (done) { - var cb = after(2, done) var router = new Router({ strict: true }) var server = createServer(router) router.all('/foo', saw) - - request(server) - .get('/foo') - .expect(200, 'saw GET /foo', cb) - - request(server) - .get('/foo/') - .expect(404, cb) + series([ + function (cb) { + request(server) + .get('/foo') + .expect(200, 'saw GET /foo', cb) + }, + function (cb) { + request(server) + .get('/foo/') + .expect(404, cb) + } + ], done) }) }) }) @@ -282,6 +320,9 @@ describe('Router', function () { // CONNECT is tricky and supertest doesn't support it return } + if (method === 'query' && process.version.startsWith('v21')) { + return + } var body = method !== 'head' ? shouldHaveBody(Buffer.from('hello, world')) @@ -311,83 +352,97 @@ describe('Router', function () { }) it('should support array of paths', function (done) { - var cb = after(3, done) var router = new Router() var server = createServer(router) router[method](['/foo', '/bar'], createHitHandle(1), helloWorld) - - request(server)[method]('/') - .expect(404) - .expect(shouldNotHitHandle(1)) - .end(cb) - - request(server)[method]('/foo') - .expect(200) - .expect(shouldHitHandle(1)) - .expect(body) - .end(cb) - - request(server)[method]('/bar') - .expect(200) - .expect(shouldHitHandle(1)) - .expect(body) - .end(cb) + series([ + function (cb) { + request(server)[method]('/') + .expect(404) + .expect(shouldNotHitHandle(1)) + .end(cb) + }, + function (cb) { + request(server)[method]('/foo') + .expect(200) + .expect(shouldHitHandle(1)) + .expect(body) + .end(cb) + }, + function (cb) { + request(server)[method]('/bar') + .expect(200) + .expect(shouldHitHandle(1)) + .expect(body) + .end(cb) + } + ], done) }) it('should support regexp path', function (done) { - var cb = after(3, done) var router = new Router() var server = createServer(router) router[method](/^\/[a-z]oo$/, createHitHandle(1), helloWorld) - - request(server)[method]('/') - .expect(404) - .expect(shouldNotHitHandle(1)) - .end(cb) - - request(server)[method]('/foo') - .expect(200) - .expect(shouldHitHandle(1)) - .expect(body) - .end(cb) - - request(server)[method]('/zoo') - .expect(200) - .expect(shouldHitHandle(1)) - .expect(body) - .end(cb) + series([ + function (cb) { + request(server)[method]('/') + .expect(404) + .expect(shouldNotHitHandle(1)) + .end(cb) + }, + function (cb) { + request(server)[method]('/foo') + .expect(200) + .expect(shouldHitHandle(1)) + .expect(body) + .end(cb) + }, + function (cb) { + request(server)[method]('/zoo') + .expect(200) + .expect(shouldHitHandle(1)) + .expect(body) + .end(cb) + } + ], done) }) it('should support parameterized path', function (done) { - var cb = after(4, done) var router = new Router() var server = createServer(router) router[method]('/:thing', createHitHandle(1), helloWorld) - request(server)[method]('/') - .expect(404) - .expect(shouldNotHitHandle(1)) - .end(cb) - - request(server)[method]('/foo') - .expect(200) - .expect(shouldHitHandle(1)) - .expect(body) - .end(cb) - - request(server)[method]('/bar') - .expect(200) - .expect(shouldHitHandle(1)) - .expect(body) - .end(cb) - - request(server)[method]('/foo/bar') - .expect(404) - .expect(shouldNotHitHandle(1)) - .end(cb) + series([ + function (cb) { + request(server)[method]('/') + .expect(404) + .expect(shouldNotHitHandle(1)) + .end(cb) + }, + function (cb) { + request(server)[method]('/foo') + .expect(200) + .expect(shouldHitHandle(1)) + .expect(body) + .end(cb) + }, + function (cb) { + request(server)[method]('/bar') + .expect(200) + .expect(shouldHitHandle(1)) + .expect(body) + .end(cb) + }, + function (cb) { + request(server)[method]('/foo/bar') + .expect(404) + .expect(shouldNotHitHandle(1)) + .end(cb) + } + ], done) }) it('should accept multiple arguments', function (done) { @@ -477,27 +532,33 @@ describe('Router', function () { }) it('should invoke function for all requests', function (done) { - var cb = after(4, done) var router = new Router() var server = createServer(router) router.use(saw) - request(server) - .get('/') - .expect(200, 'saw GET /', cb) - - request(server) - .put('/') - .expect(200, 'saw PUT /', cb) - - request(server) - .post('/foo') - .expect(200, 'saw POST /foo', cb) - - rawrequest(server) - .options('*') - .expect(200, 'saw OPTIONS *', cb) + series([ + function (cb) { + request(server) + .get('/') + .expect(200, 'saw GET /', cb) + }, + function (cb) { + request(server) + .put('/') + .expect(200, 'saw PUT /', cb) + }, + function (cb) { + request(server) + .post('/foo') + .expect(200, 'saw POST /foo', cb) + }, + function (cb) { + rawrequest(server) + .options('*') + .expect(200, 'saw OPTIONS *', cb) + } + ], done) }) it('should not invoke for blank URLs', function (done) { @@ -870,91 +931,111 @@ describe('Router', function () { }) it('should invoke when req.url starts with path', function (done) { - var cb = after(3, done) var router = new Router() var server = createServer(router) router.use('/foo', saw) - - request(server) - .get('/') - .expect(404, cb) - - request(server) - .post('/foo') - .expect(200, 'saw POST /', cb) - - request(server) - .post('/foo/bar') - .expect(200, 'saw POST /bar', cb) + series([ + function (cb) { + request(server) + .get('/') + .expect(404, cb) + }, + function (cb) { + request(server) + .post('/foo') + .expect(200, 'saw POST /', cb) + }, + function (cb) { + request(server) + .post('/foo/bar') + .expect(200, 'saw POST /bar', cb) + } + ], done) }) it('should match if path has trailing slash', function (done) { - var cb = after(3, done) var router = new Router() var server = createServer(router) router.use('/foo/', saw) - request(server) - .get('/') - .expect(404, cb) - - request(server) - .post('/foo') - .expect(200, 'saw POST /', cb) - - request(server) - .post('/foo/bar') - .expect(200, 'saw POST /bar', cb) + series([ + function (cb) { + request(server) + .get('/') + .expect(404, cb) + }, + function (cb) { + request(server) + .post('/foo') + .expect(200, 'saw POST /', cb) + }, + function (cb) { + request(server) + .post('/foo/bar') + .expect(200, 'saw POST /bar', cb) + } + ], done) }) it('should support array of paths', function (done) { - var cb = after(3, done) var router = new Router() var server = createServer(router) router.use(['/foo/', '/bar'], saw) - request(server) - .get('/') - .expect(404, cb) - - request(server) - .get('/foo') - .expect(200, 'saw GET /', cb) - - request(server) - .get('/bar') - .expect(200, 'saw GET /', cb) + series([ + function (cb) { + request(server) + .get('/') + .expect(404, cb) + }, + function (cb) { + request(server) + .get('/foo') + .expect(200, 'saw GET /', cb) + }, + function (cb) { + request(server) + .get('/bar') + .expect(200, 'saw GET /', cb) + } + ], done) }) it('should support regexp path', function (done) { - var cb = after(5, done) var router = new Router() var server = createServer(router) router.use(/^\/[a-z]oo/, saw) - - request(server) - .get('/') - .expect(404, cb) - - request(server) - .get('/foo') - .expect(200, 'saw GET /', cb) - - request(server) - .get('/fooo') - .expect(404, cb) - - request(server) - .get('/zoo/bear') - .expect(200, 'saw GET /bear', cb) - - request(server) - .get('/get/zoo') - .expect(404, cb) + series([ + function (cb) { + request(server) + .get('/') + .expect(404, cb) + }, + function (cb) { + request(server) + .get('/foo') + .expect(200, 'saw GET /', cb) + }, + function (cb) { + request(server) + .get('/fooo') + .expect(404, cb) + }, + function (cb) { + request(server) + .get('/zoo/bear') + .expect(200, 'saw GET /bear', cb) + }, + function (cb) { + request(server) + .get('/get/zoo') + .expect(404, cb) + } + ], done) }) it('should ensure regexp matches path prefix', function (done) { @@ -975,27 +1056,32 @@ describe('Router', function () { }) it('should support parameterized path', function (done) { - var cb = after(4, done) var router = new Router() var server = createServer(router) router.use('/:thing', saw) - - request(server) - .get('/') - .expect(404, cb) - - request(server) - .get('/foo') - .expect(200, 'saw GET /', cb) - - request(server) - .get('/bar') - .expect(200, 'saw GET /', cb) - - request(server) - .get('/foo/bar') - .expect(200, 'saw GET /bar', cb) + series([ + function (cb) { + request(server) + .get('/') + .expect(404, cb) + }, + function (cb) { + request(server) + .get('/foo') + .expect(200, 'saw GET /', cb) + }, + function (cb) { + request(server) + .get('/bar') + .expect(200, 'saw GET /', cb) + }, + function (cb) { + request(server) + .get('/foo/bar') + .expect(200, 'saw GET /bar', cb) + } + ], done) }) it('should accept multiple arguments', function (done) { @@ -1013,113 +1099,134 @@ describe('Router', function () { describe('with "caseSensitive" option', function () { it('should not match paths case-sensitively by default', function (done) { - var cb = after(3, done) var router = new Router() var server = createServer(router) router.use('/foo', saw) - - request(server) - .get('/foo/bar') - .expect(200, 'saw GET /bar', cb) - - request(server) - .get('/FOO/bar') - .expect(200, 'saw GET /bar', cb) - - request(server) - .get('/FOO/BAR') - .expect(200, 'saw GET /BAR', cb) + series([ + function (cb) { + request(server) + .get('/foo/bar') + .expect(200, 'saw GET /bar', cb) + }, + function (cb) { + request(server) + .get('/FOO/bar') + .expect(200, 'saw GET /bar', cb) + }, + function (cb) { + request(server) + .get('/FOO/BAR') + .expect(200, 'saw GET /BAR', cb) + } + ], done) }) it('should not match paths case-sensitively when false', function (done) { - var cb = after(3, done) var router = new Router({ caseSensitive: false }) var server = createServer(router) router.use('/foo', saw) - - request(server) - .get('/foo/bar') - .expect(200, 'saw GET /bar', cb) - - request(server) - .get('/FOO/bar') - .expect(200, 'saw GET /bar', cb) - - request(server) - .get('/FOO/BAR') - .expect(200, 'saw GET /BAR', cb) + series([ + function (cb) { + request(server) + .get('/foo/bar') + .expect(200, 'saw GET /bar', cb) + }, + function (cb) { + request(server) + .get('/FOO/bar') + .expect(200, 'saw GET /bar', cb) + }, + function (cb) { + request(server) + .get('/FOO/BAR') + .expect(200, 'saw GET /BAR', cb) + } + ], done) }) it('should match paths case-sensitively when true', function (done) { - var cb = after(3, done) var router = new Router({ caseSensitive: true }) var server = createServer(router) router.use('/foo', saw) - - request(server) - .get('/foo/bar') - .expect(200, 'saw GET /bar', cb) - - request(server) - .get('/FOO/bar') - .expect(404, cb) - - request(server) - .get('/FOO/BAR') - .expect(404, cb) + series([ + function (cb) { + request(server) + .get('/foo/bar') + .expect(200, 'saw GET /bar', cb) + }, + function (cb) { + request(server) + .get('/FOO/bar') + .expect(404, cb) + }, + function (cb) { + request(server) + .get('/FOO/BAR') + .expect(404, cb) + } + ], done) }) }) describe('with "strict" option', function () { it('should accept optional trailing slashes by default', function (done) { - var cb = after(2, done) var router = new Router() var server = createServer(router) router.use('/foo', saw) - - request(server) - .get('/foo') - .expect(200, 'saw GET /', cb) - - request(server) - .get('/foo/') - .expect(200, 'saw GET /', cb) + series([ + function (cb) { + request(server) + .get('/foo') + .expect(200, 'saw GET /', cb) + }, + function (cb) { + request(server) + .get('/foo/') + .expect(200, 'saw GET /', cb) + } + ], done) }) it('should accept optional trailing slashes when false', function (done) { - var cb = after(2, done) var router = new Router({ strict: false }) var server = createServer(router) router.use('/foo', saw) - - request(server) - .get('/foo') - .expect(200, 'saw GET /', cb) - - request(server) - .get('/foo/') - .expect(200, 'saw GET /', cb) + series([ + function (cb) { + request(server) + .get('/foo') + .expect(200, 'saw GET /', cb) + }, + function (cb) { + request(server) + .get('/foo/') + .expect(200, 'saw GET /', cb) + } + ], done) }) it('should accept optional trailing slashes when true', function (done) { - var cb = after(2, done) var router = new Router({ strict: true }) var server = createServer(router) router.use('/foo', saw) - - request(server) - .get('/foo') - .expect(200, 'saw GET /', cb) - - request(server) - .get('/foo/') - .expect(200, 'saw GET /', cb) + series([ + function (cb) { + request(server) + .get('/foo') + .expect(200, 'saw GET /', cb) + }, + function (cb) { + request(server) + .get('/foo/') + .expect(200, 'saw GET /', cb) + } + ], done) }) })