'use strict'; const assert = require('assert'); const Koa = require('../../'); const net = require('net'); describe('res.writable', () => { describe('when continuous requests in one persistent connection', () => { function requestTwice(server, done){ const port = server.address().port; const buf = new Buffer('GET / HTTP/1.1\r\nHost: localhost:' + port + '\r\nConnection: keep-alive\r\n\r\n'); const client = net.connect(port); const datas = []; client .on('error', done) .on('data', data => datas.push(data)) .on('end', () => done(null, datas)); setImmediate(() => client.write(buf)); setImmediate(() => client.write(buf)); setTimeout(() => client.end(), 100); } it('should always writable and response all requests', done => { const app = new Koa(); let count = 0; app.use(ctx => { count++; ctx.body = 'request ' + count + ', writable: ' + ctx.writable; }); const server = app.listen(); requestTwice(server, (_, datas) => { const responses = Buffer.concat(datas).toString(); assert.equal(/request 1, writable: true/.test(responses), true); assert.equal(/request 2, writable: true/.test(responses), true); done(); }); }); }); describe('when socket closed before response sent', () => { function requestClosed(server){ const port = server.address().port; const buf = Buffer.from('GET / HTTP/1.1\r\nHost: localhost:' + port + '\r\nConnection: keep-alive\r\n\r\n'); const client = net.connect(port); setImmediate(() => { client.write(buf); client.end(); }); } it('should not writable', done => { const app = new Koa(); app.use(ctx => { sleep(1000) .then(() => { if (ctx.writable) return done(new Error('ctx.writable should not be true')); done(); }); }); const server = app.listen(); requestClosed(server); }); }); describe('when response finished', () => { function request(server){ const port = server.address().port; const buf = Buffer.from('GET / HTTP/1.1\r\nHost: localhost:' + port + '\r\nConnection: keep-alive\r\n\r\n'); const client = net.connect(port); setImmediate(() => { client.write(buf); }); setTimeout(() => { client.end(); }, 100); } it('should not writable', done => { const app = new Koa(); app.use(ctx => { ctx.res.end(); if (ctx.writable) return done(new Error('ctx.writable should not be true')); done(); }); const server = app.listen(); request(server); }); }); }); function sleep(time){ return new Promise(resolve => setTimeout(resolve, time)); }