Remove co dependency

closes 
closes 

Change tests to use plain functions and promises

Add test

return promise in middleware

Change benchmarks to use plain functions and promises

typeerror
This commit is contained in:
Felix Becker 2015-10-27 15:59:40 +01:00 committed by jongleberry
parent ded7a17140
commit ebb4850709
15 changed files with 92 additions and 83 deletions

View file

@ -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);

View file

@ -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;
}

View file

@ -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",

View file

@ -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;
});

View file

@ -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;

View file

@ -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;
});

View file

@ -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');

View file

@ -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;
});

View file

@ -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');
});
});

View file

@ -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;
});

View file

@ -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
});

View file

@ -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, {});
});

View file

@ -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(){

View file

@ -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'};
});

View file

@ -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');