diff --git a/benchmarks/middleware.js b/benchmarks/middleware.js index e082cf1..d23755a 100644 --- a/benchmarks/middleware.js +++ b/benchmarks/middleware.js @@ -11,16 +11,17 @@ let n = parseInt(process.env.MW || '1', 10); console.log(` ${n} middleware`); while (n--) { - app.use(function *(ctx, next){ - yield next(); + app.use(function(ctx, next){ + return next(); }); } const body = new Buffer('Hello World'); -app.use(function *(ctx, next){ - yield next(); - this.body = body; +app.use(function(ctx, next){ + return next().then(function(){ + this.body = body; + }); }); app.listen(3333); diff --git a/lib/application.js b/lib/application.js index f4a59eb..b6e2b03 100644 --- a/lib/application.js +++ b/lib/application.js @@ -21,7 +21,6 @@ const assert = require('assert'); const Stream = require('stream'); const http = require('http'); const only = require('only'); -const co = require('co'); /** * Expose `Application` class. @@ -93,7 +92,9 @@ module.exports = class Application extends Emitter { use(fn) { debug('use %s', fn._name || fn.name || '-'); if (typeof fn !== 'function') throw new TypeError('middleware must be a function!'); - if (isGeneratorFunction(fn)) fn = co.wrap(fn); + if (isGeneratorFunction(fn)) { + throw new TypeError('Support for generators has been removed. Use Promises or wrap your generator with co.wrap'); + } this.middleware.push(fn); return this; } diff --git a/package.json b/package.json index 78867fb..8176819 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,6 @@ "license": "MIT", "dependencies": { "accepts": "^1.2.2", - "co": "^4.4.0", "content-disposition": "~0.5.0", "content-type": "^1.0.0", "cookies": "~0.5.0", diff --git a/test/application/context.js b/test/application/context.js index 718c148..257cb57 100644 --- a/test/application/context.js +++ b/test/application/context.js @@ -11,7 +11,7 @@ describe('app.context', function(){ const app2 = new Koa(); it('should merge properties', function(done){ - app1.use(function *(ctx, next){ + app1.use(function(ctx, next){ assert.equal(ctx.msg, 'hello'); ctx.status = 204; }); @@ -22,7 +22,7 @@ describe('app.context', function(){ }); it('should not affect the original prototype', function(done){ - app2.use(function *(ctx, next){ + app2.use(function(ctx, next){ assert.equal(ctx.msg, undefined); ctx.status = 204; }); diff --git a/test/application/index.js b/test/application/index.js index 9dd7e5c..86320bb 100644 --- a/test/application/index.js +++ b/test/application/index.js @@ -9,7 +9,7 @@ describe('app', function(){ it('should handle socket errors', function(done){ const app = new Koa(); - app.use(function *(ctx, next){ + app.use(function(ctx, next){ // triggers ctx.socket.writable == false ctx.socket.emit('error', new Error('boom')); }); @@ -27,7 +27,7 @@ describe('app', function(){ it('should not .writeHead when !socket.writable', function(done){ const app = new Koa(); - app.use(function *(ctx, next){ + app.use(function(ctx, next){ // set .writable to false ctx.socket.writable = false; ctx.status = 204; diff --git a/test/application/request.js b/test/application/request.js index 3050127..3f85cc1 100644 --- a/test/application/request.js +++ b/test/application/request.js @@ -11,7 +11,7 @@ describe('app.request', function(){ const app2 = new Koa(); it('should merge properties', function(done){ - app1.use(function *(ctx, next){ + app1.use(function(ctx, next){ assert.equal(ctx.request.message, 'hello'); ctx.status = 204; }); @@ -22,7 +22,7 @@ describe('app.request', function(){ }); it('should not affect the original prototype', function(done){ - app2.use(function *(ctx, next){ + app2.use(function(ctx, next){ assert.equal(ctx.request.message, undefined); ctx.status = 204; }); diff --git a/test/application/respond.js b/test/application/respond.js index 982367b..bb7d640 100644 --- a/test/application/respond.js +++ b/test/application/respond.js @@ -9,10 +9,10 @@ const fs = require('fs'); describe('app.respond', function(){ describe('when ctx.respond === false', function(){ - it('should function *(ctx)', function(done){ + it('should function (ctx)', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ ctx.body = 'Hello'; ctx.respond = false; @@ -38,7 +38,7 @@ describe('app.respond', function(){ it('should not send Content-Type header', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ ctx.body = ''; ctx.type = null; }); @@ -60,7 +60,7 @@ describe('app.respond', function(){ it('should not respond with the body', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ ctx.body = 'Hello'; }); @@ -81,7 +81,7 @@ describe('app.respond', function(){ it('should keep json headers', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ ctx.body = { hello: 'world' }; }); @@ -102,7 +102,7 @@ describe('app.respond', function(){ it('should keep string headers', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ ctx.body = 'hello world'; }); @@ -123,7 +123,7 @@ describe('app.respond', function(){ it('should keep buffer headers', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ ctx.body = new Buffer('hello world'); }); @@ -144,7 +144,7 @@ describe('app.respond', function(){ it('should respond with a 404 if no body was set', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ }); @@ -158,7 +158,7 @@ describe('app.respond', function(){ it('should respond with a 200 if body = ""', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ ctx.body = ''; }); @@ -172,7 +172,7 @@ describe('app.respond', function(){ it('should not overwrite the content-type', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ ctx.status = 200; ctx.type = 'application/javascript'; }); @@ -202,7 +202,7 @@ describe('app.respond', function(){ it('should not cause an app error', function(done){ const app = new Koa(); - app.use(function *(ctx, next){ + app.use(function(ctx, next){ const res = ctx.res; ctx.status = 200; res.setHeader('Content-Type', 'text/html'); @@ -229,7 +229,7 @@ describe('app.respond', function(){ it('should send the right body', function(done){ const app = new Koa(); - app.use(function *(ctx, next){ + app.use(function(ctx, next){ const res = ctx.res; ctx.status = 200; res.setHeader('Content-Type', 'text/html'); @@ -253,7 +253,7 @@ describe('app.respond', function(){ it('should respond with the associated status message', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ ctx.status = 400; }); @@ -271,7 +271,7 @@ describe('app.respond', function(){ it('should respond without a body', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ ctx.status = 204; }); @@ -294,7 +294,7 @@ describe('app.respond', function(){ it('should respond without a body', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ ctx.status = 205; }); @@ -317,7 +317,7 @@ describe('app.respond', function(){ it('should respond without a body', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ ctx.status = 304; }); @@ -341,7 +341,7 @@ describe('app.respond', function(){ const app = new Koa(); statuses['700'] = 'custom status'; - app.use(function *(ctx){ + app.use(function(ctx){ ctx.status = 700; }); @@ -363,7 +363,7 @@ describe('app.respond', function(){ it('should respond with the custom status message', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ ctx.status = 200; ctx.message = 'ok'; }); @@ -386,7 +386,7 @@ describe('app.respond', function(){ it('should respond with the status code number', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ ctx.res.statusCode = 701; }); @@ -404,7 +404,7 @@ describe('app.respond', function(){ it('should respond 204 by default', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ ctx.body = null; }); @@ -425,7 +425,7 @@ describe('app.respond', function(){ it('should respond 204 with status=200', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ ctx.status = 200; ctx.body = null; }); @@ -447,7 +447,7 @@ describe('app.respond', function(){ it('should respond 205 with status=205', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ ctx.status = 205; ctx.body = null; }); @@ -469,7 +469,7 @@ describe('app.respond', function(){ it('should respond 304 with status=304', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ ctx.status = 304; ctx.body = null; }); @@ -493,7 +493,7 @@ describe('app.respond', function(){ it('should respond', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ ctx.body = 'Hello'; }); @@ -509,7 +509,7 @@ describe('app.respond', function(){ it('should respond', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ ctx.body = new Buffer('Hello'); }); @@ -525,7 +525,7 @@ describe('app.respond', function(){ it('should respond', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ ctx.body = fs.createReadStream('package.json'); ctx.set('Content-Type', 'application/json; charset=utf-8'); }); @@ -547,7 +547,7 @@ describe('app.respond', function(){ it('should strip content-length when overwriting', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ ctx.body = 'hello'; ctx.body = fs.createReadStream('package.json'); ctx.set('Content-Type', 'application/json; charset=utf-8'); @@ -570,7 +570,7 @@ describe('app.respond', function(){ it('should keep content-length if not overwritten', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ ctx.length = fs.readFileSync('package.json').length; ctx.body = fs.createReadStream('package.json'); ctx.set('Content-Type', 'application/json; charset=utf-8'); @@ -593,7 +593,7 @@ describe('app.respond', function(){ it('should keep content-length if overwritten with the same stream', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ ctx.length = fs.readFileSync('package.json').length; const stream = fs.createReadStream('package.json'); ctx.body = stream; @@ -618,7 +618,7 @@ describe('app.respond', function(){ it('should handle errors', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ ctx.set('Content-Type', 'application/json; charset=utf-8'); ctx.body = fs.createReadStream('does not exist'); }); @@ -635,7 +635,7 @@ describe('app.respond', function(){ it('should handle errors when no content status', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ ctx.status = 204; ctx.body = fs.createReadStream('does not exist'); }); @@ -650,7 +650,7 @@ describe('app.respond', function(){ it('should handle all intermediate stream body errors', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ ctx.body = fs.createReadStream('does not exist'); ctx.body = fs.createReadStream('does not exist'); ctx.body = fs.createReadStream('does not exist'); @@ -668,7 +668,7 @@ describe('app.respond', function(){ it('should respond with json', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ ctx.body = { hello: 'world' }; }); @@ -685,7 +685,7 @@ describe('app.respond', function(){ it('should emit "error" on the app', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ throw new Error('boom'); }); @@ -703,7 +703,7 @@ describe('app.respond', function(){ it('should expose the message', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ const err = new Error('sorry!'); err.status = 403; err.expose = true; @@ -721,7 +721,7 @@ describe('app.respond', function(){ it('should respond with .status', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ const err = new Error('s3 explodes'); err.status = 403; throw err; @@ -737,7 +737,7 @@ describe('app.respond', function(){ it('should respond with 500', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ throw new Error('boom!'); }); @@ -752,16 +752,15 @@ describe('app.respond', function(){ it('should be catchable', function(done){ const app = new Koa(); - app.use(function *(ctx, next){ - try { - yield next(); + app.use(function(ctx, next){ + return next().then(function(){ ctx.body = 'Hello'; - } catch (err) { + }).catch(function(){ ctx.body = 'Got error'; - } + }); }); - app.use(function *(ctx, next){ + app.use(function(ctx, next){ throw new Error('boom!'); }); @@ -778,7 +777,7 @@ describe('app.respond', function(){ it('should 200', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ ctx.status = 304; ctx.body = 'hello'; ctx.status = 200; @@ -795,7 +794,7 @@ describe('app.respond', function(){ it('should 204', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ ctx.status = 200; ctx.body = 'hello'; ctx.set('content-type', 'text/plain; charset=utf8'); diff --git a/test/application/response.js b/test/application/response.js index e4e0d41..29b365c 100644 --- a/test/application/response.js +++ b/test/application/response.js @@ -11,7 +11,7 @@ describe('app.response', function(){ const app2 = new Koa(); it('should merge properties', function(done){ - app1.use(function *(ctx, next){ + app1.use(function(ctx, next){ assert.equal(ctx.response.msg, 'hello'); ctx.status = 204; }); @@ -22,7 +22,7 @@ describe('app.response', function(){ }); it('should not affect the original prototype', function(done){ - app2.use(function *(ctx, next){ + app2.use(function(ctx, next){ assert.equal(ctx.response.msg, undefined); ctx.status = 204; }); diff --git a/test/application/use.js b/test/application/use.js index a8fbfdf..fd7e948 100644 --- a/test/application/use.js +++ b/test/application/use.js @@ -9,22 +9,25 @@ describe('app.use(fn)', function(){ const app = new Koa(); const calls = []; - app.use(function *(ctx, next){ + app.use(function(ctx, next){ calls.push(1); - yield next(); - calls.push(6); + return next().then(function(){ + calls.push(6); + }); }); - app.use(function *(ctx, next){ + app.use(function(ctx, next){ calls.push(2); - yield next(); - calls.push(5); + return next().then(function(){ + calls.push(5); + }); }); - app.use(function *(ctx, next){ + app.use(function(ctx, next){ calls.push(3); - yield next(); - calls.push(4); + return next().then(function(){ + calls.push(4); + }); }); const server = app.listen(); @@ -59,4 +62,10 @@ describe('app.use(fn)', function(){ (() => app.use('not a function')).should.throw('middleware must be a function!'); done(); }); + + it('should throw error for generator', function(){ + const app = new Koa(); + + (() => app.use(function *(){})).should.throw('Support for generators has been removed. Use Promises or wrap your generator with co.wrap'); + }); }); diff --git a/test/context/cookies.js b/test/context/cookies.js index 38957f0..a8641de 100644 --- a/test/context/cookies.js +++ b/test/context/cookies.js @@ -8,7 +8,7 @@ describe('ctx.cookies.set()', function(){ it('should set an unsigned cookie', function(done){ const app = new Koa(); - app.use(function *(ctx, next){ + app.use(function(ctx, next){ ctx.cookies.set('name', 'jon'); ctx.status = 204; }); @@ -33,7 +33,7 @@ describe('ctx.cookies.set()', function(){ it('should error', function(done){ const app = new Koa(); - app.use(function *(ctx, next){ + app.use(function(ctx, next){ try { ctx.cookies.set('foo', 'bar', { signed: true }); } catch (err) { @@ -52,7 +52,7 @@ describe('ctx.cookies.set()', function(){ app.keys = ['a', 'b']; - app.use(function *(ctx, next){ + app.use(function(ctx, next){ ctx.cookies.set('name', 'jon', { signed: true }); ctx.status = 204; }); diff --git a/test/context/onerror.js b/test/context/onerror.js index 75b3171..b8e66a2 100644 --- a/test/context/onerror.js +++ b/test/context/onerror.js @@ -8,7 +8,7 @@ describe('ctx.onerror(err)', function(){ it('should respond', function(done){ const app = new Koa(); - app.use(function *(ctx, next){ + app.use(function(ctx, next){ ctx.body = 'something else'; ctx.throw(418, 'boom'); @@ -27,7 +27,7 @@ describe('ctx.onerror(err)', function(){ it('should unset all headers', function(done){ const app = new Koa(); - app.use(function *(ctx, next){ + app.use(function(ctx, next){ ctx.set('Vary', 'Accept-Encoding'); ctx.set('X-CSRF-Token', 'asdf'); ctx.body = 'response'; @@ -57,7 +57,7 @@ describe('ctx.onerror(err)', function(){ it('should respond 500', function(done){ const app = new Koa(); - app.use(function *(ctx, next){ + app.use(function(ctx, next){ ctx.body = 'something else'; const err = new Error('some error'); err.status = 'notnumber'; @@ -78,7 +78,7 @@ describe('ctx.onerror(err)', function(){ it('should respond 500', function(done){ const app = new Koa(); - app.use(function *(ctx, next){ + app.use(function(ctx, next){ ctx.body = 'something else'; const err = new Error('some error'); err.status = 9999; @@ -100,7 +100,7 @@ describe('ctx.onerror(err)', function(){ it('should response non-error thrown message', function(done){ const app = new Koa(); - app.use(function *(ctx, next){ + app.use(function(ctx, next){ throw 'string error'; // eslint-disable-line no-throw-literal }); diff --git a/test/context/state.js b/test/context/state.js index 7f316d3..b6bea98 100644 --- a/test/context/state.js +++ b/test/context/state.js @@ -9,7 +9,7 @@ describe('ctx.state', function(){ it('should provide a ctx.state namespace', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ assert.deepEqual(ctx.state, {}); }); diff --git a/test/request/href.js b/test/request/href.js index d5524a7..aaeaa71 100644 --- a/test/request/href.js +++ b/test/request/href.js @@ -26,7 +26,7 @@ describe('ctx.href', function(){ it('should work with `GET http://example.com/foo`', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ ctx.body = ctx.href; }); app.listen(function(){ diff --git a/test/response/attachment.js b/test/response/attachment.js index 7b73d2b..38d393e 100644 --- a/test/response/attachment.js +++ b/test/response/attachment.js @@ -34,7 +34,7 @@ describe('ctx.attachment([filename])', function(){ it('should work with http client', function(done){ const app = new Koa(); - app.use(function *(ctx, next){ + app.use(function(ctx, next){ ctx.attachment('path/to/include-no-ascii-char-中文名-ok.json'); ctx.body = {foo: 'bar'}; }); diff --git a/test/response/status.js b/test/response/status.js index 6900645..b00b2b6 100644 --- a/test/response/status.js +++ b/test/response/status.js @@ -62,7 +62,7 @@ describe('res.status=', function(){ it('should strip content related header fields', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ ctx.body = { foo: 'bar' }; ctx.set('Content-Type', 'application/json; charset=utf-8'); ctx.set('Content-Length', '15'); @@ -88,7 +88,7 @@ describe('res.status=', function(){ it('should strip content releated header fields after status set', function(done){ const app = new Koa(); - app.use(function *(ctx){ + app.use(function(ctx){ ctx.status = status; ctx.body = { foo: 'bar' }; ctx.set('Content-Type', 'application/json; charset=utf-8');