add new style middleware support through @jonathanong's koa-compose patch

This commit is contained in:
TJ Holowaychuk 2013-11-07 16:15:47 -08:00
parent a9ae563051
commit 2d35cdff50
4 changed files with 124 additions and 182 deletions

View file

@ -9,20 +9,16 @@ var n = parseInt(process.env.MW || '1', 10);
console.log(' %s middleware', n); console.log(' %s middleware', n);
while (n--) { while (n--) {
app.use(function(next){ app.use(function *(next){
return function *(){
yield next; yield next;
}
}); });
} }
var body = new Buffer('Hello World'); var body = new Buffer('Hello World');
app.use(function(next){ app.use(function *(next){
return function *(){
yield next; yield next;
this.body = body; this.body = body;
}
}); });
app.listen(3333); app.listen(3333);

View file

@ -126,15 +126,13 @@ app.context = function(obj){
app.callback = function(){ app.callback = function(){
var mw = [respond].concat(this.middleware); var mw = [respond].concat(this.middleware);
var fn = compose(mw)(downstream); var gen = compose(mw);
var self = this; var self = this;
return function(req, res){ return function(req, res){
var ctx = new self.Context(self, req, res); var ctx = new self.Context(self, req, res);
co.call(ctx, function *(){ co.call(ctx, gen)(function(err){
yield fn;
})(function(err){
if (err) ctx.onerror(err); if (err) ctx.onerror(err);
}); });
} }
@ -157,8 +155,7 @@ app.onerror = function(err){
* Response middleware. * Response middleware.
*/ */
function respond(next){ function *respond(next){
return function *respond(){
this.status = 200; this.status = 200;
if (this.app.poweredBy) this.set('X-Powered-By', 'koa'); if (this.app.poweredBy) this.set('X-Powered-By', 'koa');
@ -208,17 +205,8 @@ function respond(next){
this.length = Buffer.byteLength(body); this.length = Buffer.byteLength(body);
if (head) return res.end(); if (head) return res.end();
res.end(body); res.end(body);
}
} }
/**
* Default downstream middleware.
*
* @api private
*/
function *downstream(){}
/** /**
* Create a new `Context` constructor. * Create a new `Context` constructor.
* *

View file

@ -21,12 +21,12 @@
], ],
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"co": "2.0.0", "co": "2.2.0",
"debug": "*", "debug": "*",
"mime": "1.2.10", "mime": "1.2.10",
"fresh": "0.2.0", "fresh": "0.2.0",
"negotiator": "0.2.7", "negotiator": "0.2.7",
"koa-compose": "1.0.0", "koa-compose": "2.0.0",
"cookies": "~0.3.6" "cookies": "~0.3.6"
}, },
"devDependencies": { "devDependencies": {

View file

@ -10,28 +10,22 @@ describe('app.use(fn)', function(){
var app = koa(); var app = koa();
var calls = []; var calls = [];
app.use(function(next){ app.use(function *(next){
return function *(){
calls.push(1); calls.push(1);
yield next; yield next;
calls.push(6); calls.push(6);
}
}); });
app.use(function(next){ app.use(function *(next){
return function *(){
calls.push(2); calls.push(2);
yield next; yield next;
calls.push(5); calls.push(5);
}
}); });
app.use(function(next){ app.use(function *(next){
return function *(){
calls.push(3); calls.push(3);
yield next; yield next;
calls.push(4); calls.push(4);
}
}); });
var server = app.listen(); var server = app.listen();
@ -51,10 +45,8 @@ describe('app.respond', function(){
it('should not respond with the body', function(done){ it('should not respond with the body', function(done){
var app = koa(); var app = koa();
app.use(function(next){ app.use(function *(){
return function *(){
this.body = 'Hello'; this.body = 'Hello';
}
}); });
var server = app.listen(); var server = app.listen();
@ -87,10 +79,8 @@ describe('app.respond', function(){
it('should respond with the associated status message', function(done){ it('should respond with the associated status message', function(done){
var app = koa(); var app = koa();
app.use(function(next){ app.use(function *(){
return function *(){
this.status = 400; this.status = 400;
}
}); });
var server = app.listen(); var server = app.listen();
@ -106,10 +96,8 @@ describe('app.respond', function(){
it('should respond', function(done){ it('should respond', function(done){
var app = koa(); var app = koa();
app.use(function(next){ app.use(function *(){
return function *(){
this.body = 'Hello'; this.body = 'Hello';
}
}); });
var server = app.listen(); var server = app.listen();
@ -124,10 +112,8 @@ describe('app.respond', function(){
it('should respond', function(done){ it('should respond', function(done){
var app = koa(); var app = koa();
app.use(function(next){ app.use(function *(){
return function *(){
this.body = new Buffer('Hello'); this.body = new Buffer('Hello');
}
}); });
var server = app.listen(); var server = app.listen();
@ -142,11 +128,9 @@ describe('app.respond', function(){
it('should respond', function(done){ it('should respond', function(done){
var app = koa(); var app = koa();
app.use(function(next){ app.use(function *(){
return function *(){
this.body = fs.createReadStream('package.json'); this.body = fs.createReadStream('package.json');
this.set('Content-Type', 'application/json'); this.set('Content-Type', 'application/json');
}
}); });
var server = app.listen(); var server = app.listen();
@ -165,11 +149,9 @@ describe('app.respond', function(){
it('should handle errors', function(done){ it('should handle errors', function(done){
var app = koa(); var app = koa();
app.use(function(next){ app.use(function *(){
return function *(){
this.set('Content-Type', 'application/json'); this.set('Content-Type', 'application/json');
this.body = fs.createReadStream('does not exist'); this.body = fs.createReadStream('does not exist');
}
}); });
var server = app.listen(); var server = app.listen();
@ -186,10 +168,8 @@ describe('app.respond', function(){
it('should respond with json', function(done){ it('should respond with json', function(done){
var app = koa(); var app = koa();
app.use(function(next){ app.use(function *(){
return function *(){
this.body = { hello: 'world' }; this.body = { hello: 'world' };
}
}); });
var server = app.listen(); var server = app.listen();
@ -206,10 +186,8 @@ describe('app.respond', function(){
app.jsonSpaces = 0; app.jsonSpaces = 0;
app.use(function(next){ app.use(function *(){
return function *(){
this.body = { hello: 'world' }; this.body = { hello: 'world' };
}
}); });
var server = app.listen(); var server = app.listen();
@ -226,10 +204,8 @@ describe('app.respond', function(){
it('should emit "error" on the app', function(done){ it('should emit "error" on the app', function(done){
var app = koa(); var app = koa();
app.use(function(next){ app.use(function *(){
return function *(){
throw new Error('boom'); throw new Error('boom');
}
}); });
app.on('error', function(err){ app.on('error', function(err){
@ -246,13 +222,11 @@ describe('app.respond', function(){
it('should expose the message', function(done){ it('should expose the message', function(done){
var app = koa(); var app = koa();
app.use(function(next){ app.use(function *(){
return function *(){
var err = new Error('sorry!'); var err = new Error('sorry!');
err.status = 403; err.status = 403;
err.expose = true; err.expose = true;
throw err; throw err;
}
}); });
request(app.listen()) request(app.listen())
@ -266,12 +240,10 @@ describe('app.respond', function(){
it('should respond with .status', function(done){ it('should respond with .status', function(done){
var app = koa(); var app = koa();
app.use(function(next){ app.use(function *(){
return function *(){
var err = new Error('s3 explodes'); var err = new Error('s3 explodes');
err.status = 403; err.status = 403;
throw err; throw err;
}
}); });
request(app.listen()) request(app.listen())
@ -284,10 +256,8 @@ describe('app.respond', function(){
it('should respond with 500', function(done){ it('should respond with 500', function(done){
var app = koa(); var app = koa();
app.use(function(next){ app.use(function *(){
return function *(){
throw new Error('boom!'); throw new Error('boom!');
}
}); });
var server = app.listen(); var server = app.listen();
@ -301,8 +271,7 @@ describe('app.respond', function(){
it('should be catchable', function(done){ it('should be catchable', function(done){
var app = koa(); var app = koa();
app.use(function(next){ app.use(function *(next){
return function *(){
try { try {
yield next; yield next;
this.body = 'Hello'; this.body = 'Hello';
@ -310,14 +279,11 @@ describe('app.respond', function(){
error = err; error = err;
this.body = 'Got error'; this.body = 'Got error';
} }
}
}); });
app.use(function(next){ app.use(function *(next){
return function *(){
throw new Error('boom!'); throw new Error('boom!');
this.body = 'Oh no'; this.body = 'Oh no';
}
}); });
var server = app.listen(); var server = app.listen();
@ -339,12 +305,10 @@ describe('app.context(obj)', function(){
b: 2 b: 2
}); });
app.use(function(next){ app.use(function *(next){
return function *(){
this.a.should.equal(1); this.a.should.equal(1);
this.b.should.equal(2); this.b.should.equal(2);
this.status = 204; this.status = 204;
}
}); });
var server = app.listen(); var server = app.listen();
@ -368,13 +332,11 @@ describe('app.context(obj)', function(){
} }
}); });
app.use(function(next){ app.use(function *(next){
return function *(){
this.something.should.equal('hi'); this.something.should.equal('hi');
this.something = 'hello'; this.something = 'hello';
this.something.should.equal('hello'); this.something.should.equal('hello');
this.status = 204; this.status = 204;
}
}); });
var server = app.listen(); var server = app.listen();
@ -396,12 +358,10 @@ describe('app.context(obj)', function(){
b: 2 b: 2
}); });
app.use(function(next){ app.use(function *(){
return function *(){
this.a.should.equal(1); this.a.should.equal(1);
this.b.should.equal(2); this.b.should.equal(2);
this.status = 204; this.status = 204;
}
}); });
var server = app.listen(); var server = app.listen();
@ -420,11 +380,9 @@ describe('app.context(obj)', function(){
a: 1 a: 1
}); });
app2.use(function(next){ app2.use(function *(next){
return function *(){
assert.equal(this.a, undefined); assert.equal(this.a, undefined);
this.status = 204; this.status = 204;
}
}); });
var server = http.createServer(app2.callback()); var server = http.createServer(app2.callback());