parent
16db0f60c4
commit
2e8cdab8bc
22 changed files with 217 additions and 304 deletions
3
Makefile
3
Makefile
|
@ -5,8 +5,7 @@ REQUIRED = --require should --require should-http
|
|||
TESTS = test/application/* \
|
||||
test/context/* \
|
||||
test/request/* \
|
||||
test/response/* \
|
||||
test/experimental/index.js
|
||||
test/response/*
|
||||
|
||||
lint:
|
||||
@./node_modules/.bin/eslint lib test
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
all: middleware experimental
|
||||
all: middleware
|
||||
|
||||
middleware:
|
||||
@./run 1 $@
|
||||
|
@ -12,15 +12,4 @@ middleware:
|
|||
@./run 100 $@
|
||||
@echo
|
||||
|
||||
experimental:
|
||||
@./run 1 $@
|
||||
@./run 5 $@
|
||||
@./run 10 $@
|
||||
@./run 15 $@
|
||||
@./run 20 $@
|
||||
@./run 30 $@
|
||||
@./run 50 $@
|
||||
@./run 100 $@
|
||||
@echo
|
||||
|
||||
.PHONY: all middleware experimental
|
||||
.PHONY: all middleware
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
const http = require('http');
|
||||
const Koa = require('../..');
|
||||
const app = new Koa();
|
||||
|
||||
app.experimental = true;
|
||||
|
||||
// number of middleware
|
||||
|
||||
let n = parseInt(process.env.MW || '1', 10);
|
||||
console.log(` ${n} async middleware`);
|
||||
|
||||
while (n--) {
|
||||
app.use(async function (next){
|
||||
await next;
|
||||
});
|
||||
}
|
||||
|
||||
const body = new Buffer('Hello World');
|
||||
|
||||
app.use(async function (next){
|
||||
await next;
|
||||
this.body = body;
|
||||
});
|
||||
|
||||
app.listen(3333);
|
|
@ -1,9 +0,0 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
// support async await by babel
|
||||
require('babel/register')({
|
||||
optional: ['asyncToGenerator']
|
||||
});
|
||||
|
||||
require('./async');
|
|
@ -5,9 +5,9 @@
|
|||
* Module dependencies.
|
||||
*/
|
||||
|
||||
const isGeneratorFunction = require('is-generator-function');
|
||||
const debug = require('debug')('koa:application');
|
||||
const Emitter = require('events').EventEmitter;
|
||||
const compose_es7 = require('composition');
|
||||
const onFinished = require('on-finished');
|
||||
const response = require('./response');
|
||||
const compose = require('koa-compose');
|
||||
|
@ -91,11 +91,9 @@ module.exports = class Application extends Emitter {
|
|||
*/
|
||||
|
||||
use(fn) {
|
||||
if (!this.experimental) {
|
||||
// es7 async functions are allowed
|
||||
assert(fn && 'GeneratorFunction' == fn.constructor.name, 'app.use() requires a generator function');
|
||||
}
|
||||
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);
|
||||
this.middleware.push(fn);
|
||||
return this;
|
||||
}
|
||||
|
@ -109,9 +107,7 @@ module.exports = class Application extends Emitter {
|
|||
*/
|
||||
|
||||
callback() {
|
||||
const fn = this.experimental
|
||||
? compose_es7(this.middleware)
|
||||
: co.wrap(compose(this.middleware));
|
||||
const fn = compose(this.middleware);
|
||||
|
||||
if (!this.listeners('error').length) this.on('error', this.onerror);
|
||||
|
||||
|
@ -119,8 +115,8 @@ module.exports = class Application extends Emitter {
|
|||
res.statusCode = 404;
|
||||
const ctx = this.createContext(req, res);
|
||||
onFinished(res, ctx.onerror);
|
||||
fn.call(ctx).then(function() {
|
||||
respond.call(ctx);
|
||||
fn(ctx).then(function() {
|
||||
respond(ctx);
|
||||
}).catch(ctx.onerror);
|
||||
};
|
||||
}
|
||||
|
@ -176,33 +172,33 @@ module.exports = class Application extends Emitter {
|
|||
* Response helper.
|
||||
*/
|
||||
|
||||
function respond() {
|
||||
function respond(ctx) {
|
||||
// allow bypassing koa
|
||||
if (false === this.respond) return;
|
||||
if (false === ctx.respond) return;
|
||||
|
||||
const res = this.res;
|
||||
if (res.headersSent || !this.writable) return;
|
||||
const res = ctx.res;
|
||||
if (res.headersSent || !ctx.writable) return;
|
||||
|
||||
let body = this.body;
|
||||
const code = this.status;
|
||||
let body = ctx.body;
|
||||
const code = ctx.status;
|
||||
|
||||
// ignore body
|
||||
if (statuses.empty[code]) {
|
||||
// strip headers
|
||||
this.body = null;
|
||||
ctx.body = null;
|
||||
return res.end();
|
||||
}
|
||||
|
||||
if ('HEAD' == this.method) {
|
||||
if (isJSON(body)) this.length = Buffer.byteLength(JSON.stringify(body));
|
||||
if ('HEAD' == ctx.method) {
|
||||
if (isJSON(body)) ctx.length = Buffer.byteLength(JSON.stringify(body));
|
||||
return res.end();
|
||||
}
|
||||
|
||||
// status body
|
||||
if (null == body) {
|
||||
this.type = 'text';
|
||||
body = this.message || String(code);
|
||||
this.length = Buffer.byteLength(body);
|
||||
ctx.type = 'text';
|
||||
body = ctx.message || String(code);
|
||||
ctx.length = Buffer.byteLength(body);
|
||||
return res.end(body);
|
||||
}
|
||||
|
||||
|
@ -213,6 +209,6 @@ function respond() {
|
|||
|
||||
// body: json
|
||||
body = JSON.stringify(body);
|
||||
this.length = Buffer.byteLength(body);
|
||||
ctx.length = Buffer.byteLength(body);
|
||||
res.end(body);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
"dependencies": {
|
||||
"accepts": "^1.2.2",
|
||||
"co": "^4.4.0",
|
||||
"composition": "^2.1.1",
|
||||
"content-disposition": "~0.5.0",
|
||||
"content-type": "^1.0.0",
|
||||
"cookies": "~0.5.0",
|
||||
|
@ -32,7 +31,8 @@
|
|||
"fresh": "^0.3.0",
|
||||
"http-assert": "^1.1.0",
|
||||
"http-errors": "^1.2.8",
|
||||
"koa-compose": "^2.3.0",
|
||||
"is-generator-function": "^1.0.3",
|
||||
"koa-compose": "^3.0.0",
|
||||
"koa-is-json": "^1.0.0",
|
||||
"mime-types": "^2.0.7",
|
||||
"on-finished": "^2.1.0",
|
||||
|
|
|
@ -11,9 +11,9 @@ describe('app.context', function(){
|
|||
const app2 = new Koa();
|
||||
|
||||
it('should merge properties', function(done){
|
||||
app1.use(function *(next){
|
||||
assert.equal(this.msg, 'hello');
|
||||
this.status = 204;
|
||||
app1.use(function *(ctx, next){
|
||||
assert.equal(ctx.msg, 'hello');
|
||||
ctx.status = 204;
|
||||
});
|
||||
|
||||
request(app1.listen())
|
||||
|
@ -22,9 +22,9 @@ describe('app.context', function(){
|
|||
});
|
||||
|
||||
it('should not affect the original prototype', function(done){
|
||||
app2.use(function *(next){
|
||||
assert.equal(this.msg, undefined);
|
||||
this.status = 204;
|
||||
app2.use(function *(ctx, next){
|
||||
assert.equal(ctx.msg, undefined);
|
||||
ctx.status = 204;
|
||||
});
|
||||
|
||||
request(app2.listen())
|
||||
|
|
|
@ -9,9 +9,9 @@ describe('app', function(){
|
|||
it('should handle socket errors', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(next){
|
||||
// triggers this.socket.writable == false
|
||||
this.socket.emit('error', new Error('boom'));
|
||||
app.use(function *(ctx, next){
|
||||
// triggers ctx.socket.writable == false
|
||||
ctx.socket.emit('error', new Error('boom'));
|
||||
});
|
||||
|
||||
app.on('error', function(err){
|
||||
|
@ -27,13 +27,13 @@ describe('app', function(){
|
|||
it('should not .writeHead when !socket.writable', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(next){
|
||||
app.use(function *(ctx, next){
|
||||
// set .writable to false
|
||||
this.socket.writable = false;
|
||||
this.status = 204;
|
||||
ctx.socket.writable = false;
|
||||
ctx.status = 204;
|
||||
// throw if .writeHead or .end is called
|
||||
this.res.writeHead =
|
||||
this.res.end = function(){
|
||||
ctx.res.writeHead =
|
||||
ctx.res.end = function(){
|
||||
throw new Error('response sent');
|
||||
};
|
||||
});
|
||||
|
|
|
@ -11,9 +11,9 @@ describe('app.request', function(){
|
|||
const app2 = new Koa();
|
||||
|
||||
it('should merge properties', function(done){
|
||||
app1.use(function *(next){
|
||||
assert.equal(this.request.message, 'hello');
|
||||
this.status = 204;
|
||||
app1.use(function *(ctx, next){
|
||||
assert.equal(ctx.request.message, 'hello');
|
||||
ctx.status = 204;
|
||||
});
|
||||
|
||||
request(app1.listen())
|
||||
|
@ -22,9 +22,9 @@ describe('app.request', function(){
|
|||
});
|
||||
|
||||
it('should not affect the original prototype', function(done){
|
||||
app2.use(function *(next){
|
||||
assert.equal(this.request.message, undefined);
|
||||
this.status = 204;
|
||||
app2.use(function *(ctx, next){
|
||||
assert.equal(ctx.request.message, undefined);
|
||||
ctx.status = 204;
|
||||
});
|
||||
|
||||
request(app2.listen())
|
||||
|
|
|
@ -8,15 +8,15 @@ const Koa = require('../..');
|
|||
const fs = require('fs');
|
||||
|
||||
describe('app.respond', function(){
|
||||
describe('when this.respond === false', function(){
|
||||
it('should bypass app.respond', function(done){
|
||||
describe('when ctx.respond === false', function(){
|
||||
it('should function *(ctx)', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.body = 'Hello';
|
||||
this.respond = false;
|
||||
app.use(function *(ctx){
|
||||
ctx.body = 'Hello';
|
||||
ctx.respond = false;
|
||||
|
||||
const res = this.res;
|
||||
const res = ctx.res;
|
||||
res.statusCode = 200;
|
||||
setImmediate(function(){
|
||||
res.setHeader('Content-Type', 'text/plain');
|
||||
|
@ -38,9 +38,9 @@ describe('app.respond', function(){
|
|||
it('should not send Content-Type header', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.body = '';
|
||||
this.type = null;
|
||||
app.use(function *(ctx){
|
||||
ctx.body = '';
|
||||
ctx.type = null;
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
@ -60,8 +60,8 @@ describe('app.respond', function(){
|
|||
it('should not respond with the body', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.body = 'Hello';
|
||||
app.use(function *(ctx){
|
||||
ctx.body = 'Hello';
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
@ -81,8 +81,8 @@ describe('app.respond', function(){
|
|||
it('should keep json headers', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.body = { hello: 'world' };
|
||||
app.use(function *(ctx){
|
||||
ctx.body = { hello: 'world' };
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
@ -102,8 +102,8 @@ describe('app.respond', function(){
|
|||
it('should keep string headers', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.body = 'hello world';
|
||||
app.use(function *(ctx){
|
||||
ctx.body = 'hello world';
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
@ -123,8 +123,8 @@ describe('app.respond', function(){
|
|||
it('should keep buffer headers', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.body = new Buffer('hello world');
|
||||
app.use(function *(ctx){
|
||||
ctx.body = new Buffer('hello world');
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
@ -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 *(){
|
||||
app.use(function *(ctx){
|
||||
|
||||
});
|
||||
|
||||
|
@ -158,8 +158,8 @@ describe('app.respond', function(){
|
|||
it('should respond with a 200 if body = ""', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.body = '';
|
||||
app.use(function *(ctx){
|
||||
ctx.body = '';
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
@ -172,9 +172,9 @@ describe('app.respond', function(){
|
|||
it('should not overwrite the content-type', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.status = 200;
|
||||
this.type = 'application/javascript';
|
||||
app.use(function *(ctx){
|
||||
ctx.status = 200;
|
||||
ctx.type = 'application/javascript';
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
@ -202,9 +202,9 @@ describe('app.respond', function(){
|
|||
it('should not cause an app error', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(next){
|
||||
const res = this.res;
|
||||
this.status = 200;
|
||||
app.use(function *(ctx, next){
|
||||
const res = ctx.res;
|
||||
ctx.status = 200;
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
res.write('Hello');
|
||||
setTimeout(function(){
|
||||
|
@ -233,9 +233,9 @@ describe('app.respond', function(){
|
|||
it('should send the right body', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(next){
|
||||
const res = this.res;
|
||||
this.status = 200;
|
||||
app.use(function *(ctx, next){
|
||||
const res = ctx.res;
|
||||
ctx.status = 200;
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
res.write('Hello');
|
||||
setTimeout(function(){
|
||||
|
@ -257,8 +257,8 @@ describe('app.respond', function(){
|
|||
it('should respond with the associated status message', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.status = 400;
|
||||
app.use(function *(ctx){
|
||||
ctx.status = 400;
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
@ -275,8 +275,8 @@ describe('app.respond', function(){
|
|||
it('should respond without a body', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.status = 204;
|
||||
app.use(function *(ctx){
|
||||
ctx.status = 204;
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
@ -298,8 +298,8 @@ describe('app.respond', function(){
|
|||
it('should respond without a body', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.status = 205;
|
||||
app.use(function *(ctx){
|
||||
ctx.status = 205;
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
@ -321,8 +321,8 @@ describe('app.respond', function(){
|
|||
it('should respond without a body', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.status = 304;
|
||||
app.use(function *(ctx){
|
||||
ctx.status = 304;
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
@ -345,8 +345,8 @@ describe('app.respond', function(){
|
|||
const app = new Koa();
|
||||
statuses['700'] = 'custom status';
|
||||
|
||||
app.use(function *(){
|
||||
this.status = 700;
|
||||
app.use(function *(ctx){
|
||||
ctx.status = 700;
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
@ -367,9 +367,9 @@ describe('app.respond', function(){
|
|||
it('should respond with the custom status message', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.status = 200;
|
||||
this.message = 'ok';
|
||||
app.use(function *(ctx){
|
||||
ctx.status = 200;
|
||||
ctx.message = 'ok';
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
@ -390,8 +390,8 @@ describe('app.respond', function(){
|
|||
it('should respond with the status code number', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.res.statusCode = 701;
|
||||
app.use(function *(ctx){
|
||||
ctx.res.statusCode = 701;
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
@ -408,8 +408,8 @@ describe('app.respond', function(){
|
|||
it('should respond 204 by default', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.body = null;
|
||||
app.use(function *(ctx){
|
||||
ctx.body = null;
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
@ -429,9 +429,9 @@ describe('app.respond', function(){
|
|||
it('should respond 204 with status=200', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.status = 200;
|
||||
this.body = null;
|
||||
app.use(function *(ctx){
|
||||
ctx.status = 200;
|
||||
ctx.body = null;
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
@ -451,9 +451,9 @@ describe('app.respond', function(){
|
|||
it('should respond 205 with status=205', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.status = 205;
|
||||
this.body = null;
|
||||
app.use(function *(ctx){
|
||||
ctx.status = 205;
|
||||
ctx.body = null;
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
@ -473,9 +473,9 @@ describe('app.respond', function(){
|
|||
it('should respond 304 with status=304', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.status = 304;
|
||||
this.body = null;
|
||||
app.use(function *(ctx){
|
||||
ctx.status = 304;
|
||||
ctx.body = null;
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
@ -497,8 +497,8 @@ describe('app.respond', function(){
|
|||
it('should respond', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.body = 'Hello';
|
||||
app.use(function *(ctx){
|
||||
ctx.body = 'Hello';
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
@ -513,8 +513,8 @@ describe('app.respond', function(){
|
|||
it('should respond', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.body = new Buffer('Hello');
|
||||
app.use(function *(ctx){
|
||||
ctx.body = new Buffer('Hello');
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
@ -529,9 +529,9 @@ describe('app.respond', function(){
|
|||
it('should respond', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.body = fs.createReadStream('package.json');
|
||||
this.set('Content-Type', 'application/json; charset=utf-8');
|
||||
app.use(function *(ctx){
|
||||
ctx.body = fs.createReadStream('package.json');
|
||||
ctx.set('Content-Type', 'application/json; charset=utf-8');
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
@ -551,10 +551,10 @@ describe('app.respond', function(){
|
|||
it('should strip content-length when overwriting', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.body = 'hello';
|
||||
this.body = fs.createReadStream('package.json');
|
||||
this.set('Content-Type', 'application/json; charset=utf-8');
|
||||
app.use(function *(ctx){
|
||||
ctx.body = 'hello';
|
||||
ctx.body = fs.createReadStream('package.json');
|
||||
ctx.set('Content-Type', 'application/json; charset=utf-8');
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
@ -574,10 +574,10 @@ describe('app.respond', function(){
|
|||
it('should keep content-length if not overwritten', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.length = fs.readFileSync('package.json').length;
|
||||
this.body = fs.createReadStream('package.json');
|
||||
this.set('Content-Type', 'application/json; charset=utf-8');
|
||||
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');
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
@ -597,12 +597,12 @@ describe('app.respond', function(){
|
|||
it('should keep content-length if overwritten with the same stream', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.length = fs.readFileSync('package.json').length;
|
||||
app.use(function *(ctx){
|
||||
ctx.length = fs.readFileSync('package.json').length;
|
||||
const stream = fs.createReadStream('package.json');
|
||||
this.body = stream;
|
||||
this.body = stream;
|
||||
this.set('Content-Type', 'application/json; charset=utf-8');
|
||||
ctx.body = stream;
|
||||
ctx.body = stream;
|
||||
ctx.set('Content-Type', 'application/json; charset=utf-8');
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
@ -622,9 +622,9 @@ describe('app.respond', function(){
|
|||
it('should handle errors', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.set('Content-Type', 'application/json; charset=utf-8');
|
||||
this.body = fs.createReadStream('does not exist');
|
||||
app.use(function *(ctx){
|
||||
ctx.set('Content-Type', 'application/json; charset=utf-8');
|
||||
ctx.body = fs.createReadStream('does not exist');
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
@ -639,9 +639,9 @@ describe('app.respond', function(){
|
|||
it('should handle errors when no content status', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.status = 204;
|
||||
this.body = fs.createReadStream('does not exist');
|
||||
app.use(function *(ctx){
|
||||
ctx.status = 204;
|
||||
ctx.body = fs.createReadStream('does not exist');
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
@ -654,10 +654,10 @@ describe('app.respond', function(){
|
|||
it('should handle all intermediate stream body errors', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.body = fs.createReadStream('does not exist');
|
||||
this.body = fs.createReadStream('does not exist');
|
||||
this.body = fs.createReadStream('does not exist');
|
||||
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');
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
@ -672,8 +672,8 @@ describe('app.respond', function(){
|
|||
it('should respond with json', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.body = { hello: 'world' };
|
||||
app.use(function *(ctx){
|
||||
ctx.body = { hello: 'world' };
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
@ -689,7 +689,7 @@ describe('app.respond', function(){
|
|||
it('should emit "error" on the app', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
app.use(function *(ctx){
|
||||
throw new Error('boom');
|
||||
});
|
||||
|
||||
|
@ -707,7 +707,7 @@ describe('app.respond', function(){
|
|||
it('should expose the message', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
app.use(function *(ctx){
|
||||
const err = new Error('sorry!');
|
||||
err.status = 403;
|
||||
err.expose = true;
|
||||
|
@ -725,7 +725,7 @@ describe('app.respond', function(){
|
|||
it('should respond with .status', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
app.use(function *(ctx){
|
||||
const err = new Error('s3 explodes');
|
||||
err.status = 403;
|
||||
throw err;
|
||||
|
@ -741,7 +741,7 @@ describe('app.respond', function(){
|
|||
it('should respond with 500', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
app.use(function *(ctx){
|
||||
throw new Error('boom!');
|
||||
});
|
||||
|
||||
|
@ -756,16 +756,16 @@ describe('app.respond', function(){
|
|||
it('should be catchable', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(next){
|
||||
app.use(function *(ctx, next){
|
||||
try {
|
||||
yield next;
|
||||
this.body = 'Hello';
|
||||
yield next();
|
||||
ctx.body = 'Hello';
|
||||
} catch (err) {
|
||||
this.body = 'Got error';
|
||||
ctx.body = 'Got error';
|
||||
}
|
||||
});
|
||||
|
||||
app.use(function *(next){
|
||||
app.use(function *(ctx, next){
|
||||
throw new Error('boom!');
|
||||
});
|
||||
|
||||
|
@ -782,10 +782,10 @@ describe('app.respond', function(){
|
|||
it('should 200', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.status = 304;
|
||||
this.body = 'hello';
|
||||
this.status = 200;
|
||||
app.use(function *(ctx){
|
||||
ctx.status = 304;
|
||||
ctx.body = 'hello';
|
||||
ctx.status = 200;
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
@ -799,11 +799,11 @@ describe('app.respond', function(){
|
|||
it('should 204', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.status = 200;
|
||||
this.body = 'hello';
|
||||
this.set('content-type', 'text/plain; charset=utf8');
|
||||
this.status = 204;
|
||||
app.use(function *(ctx){
|
||||
ctx.status = 200;
|
||||
ctx.body = 'hello';
|
||||
ctx.set('content-type', 'text/plain; charset=utf8');
|
||||
ctx.status = 204;
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
|
|
@ -11,9 +11,9 @@ describe('app.response', function(){
|
|||
const app2 = new Koa();
|
||||
|
||||
it('should merge properties', function(done){
|
||||
app1.use(function *(next){
|
||||
assert.equal(this.response.msg, 'hello');
|
||||
this.status = 204;
|
||||
app1.use(function *(ctx, next){
|
||||
assert.equal(ctx.response.msg, 'hello');
|
||||
ctx.status = 204;
|
||||
});
|
||||
|
||||
request(app1.listen())
|
||||
|
@ -22,9 +22,9 @@ describe('app.response', function(){
|
|||
});
|
||||
|
||||
it('should not affect the original prototype', function(done){
|
||||
app2.use(function *(next){
|
||||
assert.equal(this.response.msg, undefined);
|
||||
this.status = 204;
|
||||
app2.use(function *(ctx, next){
|
||||
assert.equal(ctx.response.msg, undefined);
|
||||
ctx.status = 204;
|
||||
});
|
||||
|
||||
request(app2.listen())
|
||||
|
|
|
@ -9,21 +9,21 @@ describe('app.use(fn)', function(){
|
|||
const app = new Koa();
|
||||
const calls = [];
|
||||
|
||||
app.use(function *(next){
|
||||
app.use(function *(ctx, next){
|
||||
calls.push(1);
|
||||
yield next;
|
||||
yield next();
|
||||
calls.push(6);
|
||||
});
|
||||
|
||||
app.use(function *(next){
|
||||
app.use(function *(ctx, next){
|
||||
calls.push(2);
|
||||
yield next;
|
||||
yield next();
|
||||
calls.push(5);
|
||||
});
|
||||
|
||||
app.use(function *(next){
|
||||
app.use(function *(ctx, next){
|
||||
calls.push(3);
|
||||
yield next;
|
||||
yield next();
|
||||
calls.push(4);
|
||||
});
|
||||
|
||||
|
@ -39,19 +39,17 @@ describe('app.use(fn)', function(){
|
|||
});
|
||||
});
|
||||
|
||||
it('should error when a non-generator function is passed', function(){
|
||||
// https://github.com/koajs/koa/pull/530#issuecomment-148138051
|
||||
it('should catch thrown errors in non-async functions', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
try {
|
||||
app.use(function(){});
|
||||
} catch (err) {
|
||||
err.message.should.equal('app.use() requires a generator function');
|
||||
}
|
||||
});
|
||||
app.use(ctx => {
|
||||
ctx.throw('Not Found', 404);
|
||||
});
|
||||
|
||||
it('should not error when a non-generator function is passed when .experimental=true', function(){
|
||||
const app = new Koa();
|
||||
app.experimental = true;
|
||||
app.use(function(){});
|
||||
request(app.listen())
|
||||
.get('/')
|
||||
.expect(404)
|
||||
.end(done);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -8,9 +8,9 @@ describe('ctx.cookies.set()', function(){
|
|||
it('should set an unsigned cookie', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(next){
|
||||
this.cookies.set('name', 'jon');
|
||||
this.status = 204;
|
||||
app.use(function *(ctx, next){
|
||||
ctx.cookies.set('name', 'jon');
|
||||
ctx.status = 204;
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
@ -34,11 +34,11 @@ describe('ctx.cookies.set()', function(){
|
|||
it('should error', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(next){
|
||||
app.use(function *(ctx, next){
|
||||
try {
|
||||
this.cookies.set('foo', 'bar', { signed: true });
|
||||
ctx.cookies.set('foo', 'bar', { signed: true });
|
||||
} catch (err) {
|
||||
this.body = err.message;
|
||||
ctx.body = err.message;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -53,9 +53,9 @@ describe('ctx.cookies.set()', function(){
|
|||
|
||||
app.keys = ['a', 'b'];
|
||||
|
||||
app.use(function *(next){
|
||||
this.cookies.set('name', 'jon', { signed: true });
|
||||
this.status = 204;
|
||||
app.use(function *(ctx, next){
|
||||
ctx.cookies.set('name', 'jon', { signed: true });
|
||||
ctx.status = 204;
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
|
|
@ -8,10 +8,10 @@ describe('ctx.onerror(err)', function(){
|
|||
it('should respond', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(next){
|
||||
this.body = 'something else';
|
||||
app.use(function *(ctx, next){
|
||||
ctx.body = 'something else';
|
||||
|
||||
this.throw(418, 'boom');
|
||||
ctx.throw(418, 'boom');
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
@ -27,12 +27,12 @@ describe('ctx.onerror(err)', function(){
|
|||
it('should unset all headers', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(next){
|
||||
this.set('Vary', 'Accept-Encoding');
|
||||
this.set('X-CSRF-Token', 'asdf');
|
||||
this.body = 'response';
|
||||
app.use(function *(ctx, next){
|
||||
ctx.set('Vary', 'Accept-Encoding');
|
||||
ctx.set('X-CSRF-Token', 'asdf');
|
||||
ctx.body = 'response';
|
||||
|
||||
this.throw(418, 'boom');
|
||||
ctx.throw(418, 'boom');
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
@ -57,8 +57,8 @@ describe('ctx.onerror(err)', function(){
|
|||
it('should respond 500', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(next){
|
||||
this.body = 'something else';
|
||||
app.use(function *(ctx, next){
|
||||
ctx.body = 'something else';
|
||||
const err = new Error('some error');
|
||||
err.status = 'notnumber';
|
||||
throw err;
|
||||
|
@ -78,8 +78,8 @@ describe('ctx.onerror(err)', function(){
|
|||
it('should respond 500', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(next){
|
||||
this.body = 'something else';
|
||||
app.use(function *(ctx, next){
|
||||
ctx.body = 'something else';
|
||||
const err = new Error('some error');
|
||||
err.status = 9999;
|
||||
throw err;
|
||||
|
@ -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 *(next){
|
||||
app.use(function *(ctx, next){
|
||||
throw 'string error'; // eslint-disable-line no-throw-literal
|
||||
});
|
||||
|
||||
|
|
|
@ -9,8 +9,8 @@ describe('ctx.state', function(){
|
|||
it('should provide a ctx.state namespace', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
assert.deepEqual(this.state, {});
|
||||
app.use(function *(ctx){
|
||||
assert.deepEqual(ctx.state, {});
|
||||
});
|
||||
|
||||
const server = app.listen();
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Separate file primarily because we use `require('babel/register')`.
|
||||
*/
|
||||
|
||||
const request = require('supertest');
|
||||
const Koa = require('../..');
|
||||
|
||||
describe('.experimental=true', function(){
|
||||
it('should support async functions', function(done){
|
||||
const app = new Koa();
|
||||
app.experimental = true;
|
||||
app.use(async function (next){
|
||||
const string = await Promise.resolve('asdf');
|
||||
this.body = string;
|
||||
});
|
||||
|
||||
request(app.callback())
|
||||
.get('/')
|
||||
.expect('asdf')
|
||||
.expect(200, done);
|
||||
});
|
||||
});
|
|
@ -1,7 +0,0 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
require('babel/register')({
|
||||
optional: ['asyncToGenerator']
|
||||
});
|
||||
require('./async');
|
|
@ -26,8 +26,8 @@ describe('ctx.href', function(){
|
|||
|
||||
it('should work with `GET http://example.com/foo`', function(done){
|
||||
const app = new Koa();
|
||||
app.use(function *(){
|
||||
this.body = this.href;
|
||||
app.use(function *(ctx){
|
||||
ctx.body = ctx.href;
|
||||
});
|
||||
app.listen(function(){
|
||||
const address = this.address();
|
||||
|
|
|
@ -34,9 +34,9 @@ describe('ctx.attachment([filename])', function(){
|
|||
it('should work with http client', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(next){
|
||||
this.attachment('path/to/include-no-ascii-char-中文名-ok.json');
|
||||
this.body = {foo: 'bar'};
|
||||
app.use(function *(ctx, next){
|
||||
ctx.attachment('path/to/include-no-ascii-char-中文名-ok.json');
|
||||
ctx.body = {foo: 'bar'};
|
||||
});
|
||||
|
||||
request(app.listen())
|
||||
|
|
|
@ -90,10 +90,10 @@ describe('res.body=', function(){
|
|||
describe('when an xml string is given', function(){
|
||||
it('should default to html', function(){
|
||||
/**
|
||||
* This test is to show that we're not going
|
||||
* ctx test is to show that we're not going
|
||||
* to be stricter with the html sniff
|
||||
* or that we will sniff other string types.
|
||||
* You should `.type=` if this simple test fails.
|
||||
* You should `.type=` if ctx simple test fails.
|
||||
*/
|
||||
|
||||
const res = response();
|
||||
|
|
|
@ -62,15 +62,15 @@ describe('res.status=', function(){
|
|||
it('should strip content related header fields', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.body = { foo: 'bar' };
|
||||
this.set('Content-Type', 'application/json; charset=utf-8');
|
||||
this.set('Content-Length', '15');
|
||||
this.set('Transfer-Encoding', 'chunked');
|
||||
this.status = status;
|
||||
assert(null == this.response.header['content-type']);
|
||||
assert(null == this.response.header['content-length']);
|
||||
assert(null == this.response.header['transfer-encoding']);
|
||||
app.use(function *(ctx){
|
||||
ctx.body = { foo: 'bar' };
|
||||
ctx.set('Content-Type', 'application/json; charset=utf-8');
|
||||
ctx.set('Content-Length', '15');
|
||||
ctx.set('Transfer-Encoding', 'chunked');
|
||||
ctx.status = status;
|
||||
assert(null == ctx.response.header['content-type']);
|
||||
assert(null == ctx.response.header['content-length']);
|
||||
assert(null == ctx.response.header['transfer-encoding']);
|
||||
});
|
||||
|
||||
request(app.listen())
|
||||
|
@ -88,12 +88,12 @@ describe('res.status=', function(){
|
|||
it('should strip content releated header fields after status set', function(done){
|
||||
const app = new Koa();
|
||||
|
||||
app.use(function *(){
|
||||
this.status = status;
|
||||
this.body = { foo: 'bar' };
|
||||
this.set('Content-Type', 'application/json; charset=utf-8');
|
||||
this.set('Content-Length', '15');
|
||||
this.set('Transfer-Encoding', 'chunked');
|
||||
app.use(function *(ctx){
|
||||
ctx.status = status;
|
||||
ctx.body = { foo: 'bar' };
|
||||
ctx.set('Content-Type', 'application/json; charset=utf-8');
|
||||
ctx.set('Content-Length', '15');
|
||||
ctx.set('Transfer-Encoding', 'chunked');
|
||||
});
|
||||
|
||||
request(app.listen())
|
||||
|
|
|
@ -55,7 +55,7 @@ describe('ctx.type', function(){
|
|||
describe('with no Content-Type', function(){
|
||||
it('should return ""', function(){
|
||||
const ctx = context();
|
||||
// TODO: this is lame
|
||||
// TODO: ctx is lame
|
||||
assert('' === ctx.type);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue