updated tests to use "supertest"

This commit is contained in:
TJ Holowaychuk
2012-06-26 17:14:07 -07:00
parent 170dcc2907
commit 0f5560eebd
44 changed files with 278 additions and 690 deletions

View File

@@ -14,11 +14,13 @@ test: test-unit test-acceptance
test-unit:
@NODE_ENV=test ./node_modules/.bin/mocha \
--reporter $(REPORTER)
--reporter $(REPORTER) \
--bail
test-acceptance:
@NODE_ENV=test ./node_modules/.bin/mocha \
--reporter $(REPORTER) \
--bail \
test/acceptance/*.js
test-cov: lib-cov

View File

@@ -28,7 +28,8 @@
"stylus": "*",
"should": "*",
"connect-redis": "*",
"github-flavored-markdown": "*"
"github-flavored-markdown": "*",
"supertest": "0.0.1"
},
"publishConfig": { "tag": "3.0" },
"keywords": ["express", "framework", "sinatra", "web", "rest", "restful", "router"],

View File

@@ -1,8 +1,8 @@
var app = require('../../examples/auth/app')
, request = require('../support/http');
function redirects(to,fn){
return function(res){
function redirects(to, fn){
return function(err, res){
res.statusCode.should.equal(302)
res.headers.should.have.property('location').match(to);
fn()
@@ -14,80 +14,29 @@ function getCookie(res) {
}
describe('auth', function(){
var cookie;
describe('GET /',function(){
it('should redirect to /login', function(done){
request(app)
.get('/')
.end(redirects(/\/login$/,done))
.get('/')
.end(redirects(/\/login$/, done))
})
})
describe('GET /restricted (w/o cookie)',function(){
it('should redirect to /login', function(done){
request(app)
.get('/restricted')
.end(redirects(/\/login$/,done))
.get('/restricted')
.end(redirects(/\/login$/,done))
})
})
describe('POST /login', function(){
it('should fail without proper credentials', function(done){
request(app)
.post('/login')
.set('content-type','application/x-www-form-urlencoded')
.write('&username=not-tj&password=foobar')
.end(redirects(/\/login$/,done))
})
it('should authenticate', function(done){
request(app)
.post('/login')
.set('content-type', 'application/x-www-form-urlencoded')
.write('username=tj&password=foobar')
.end(function(res){
res.statusCode.should.equal(302);
cookie = getCookie(res);
request(app)
.get('/login')
.set('Cookie', cookie)
.end(function(res){
res.body.should.include('Authenticated as tj');
done();
})
})
})
})
describe('GET /restricted (w. cookie)',function(){
it('should respond with 200', function(done){
request(app)
.get('/restricted')
.set('Cookie', cookie)
.expect(200, done);
})
})
describe('GET /logout',function(){
it('should respond with 302 and clear cookie',function(done){
request(app)
.get('/logout')
.set('Cookie', cookie)
.end(function(res){
res.statusCode.should.equal(302);
res.headers.should.not.have.property('set-cookie')
done();
})
})
})
describe('GET /restricted (w. expired cookie)',function(){
it('should respond with 302',function(done){
request(app)
.get('/restricted')
.set('Cookie', cookie)
.expect(302, done)
.post('/login')
.type('urlencoded')
.send('username=not-tj&password=foobar')
.end(redirects(/\/login$/, done))
})
})
})

View File

@@ -7,20 +7,16 @@ describe('content-negotiation', function(){
it('should default to text/html', function(done){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<ul><li>Tobi</li><li>Loki</li><li>Jane</li></ul>');
done();
})
.expect('<ul><li>Tobi</li><li>Loki</li><li>Jane</li></ul>')
.end(done);
})
it('should accept to text/plain', function(done){
request(app)
.get('/')
.set('Accept', 'text/plain')
.end(function(res){
res.body.should.equal(' - Tobi\n - Loki\n - Jane\n');
done();
})
.expect(' - Tobi\n - Loki\n - Jane\n')
.end(done);
})
})
})

View File

@@ -1,3 +1,4 @@
var app = require('../../examples/cookies/app')
, request = require('../support/http');
@@ -5,29 +6,29 @@ describe('cookies', function(){
describe('GET /', function(){
it('should have a form', function(done){
request(app)
.get('/')
.expect(/<form/,done)
.get('/')
.expect(/<form/, done);
})
it('should respond with no cookies', function(done){
request(app)
.get('/')
.end(function(res){
res.headers.should.not.have.property('set-cookie')
done()
})
.get('/')
.end(function(err, res){
res.headers.should.not.have.property('set-cookie')
done()
})
})
})
describe('POST /', function(){
it('should set a cookie', function(done){
request(app)
.post('/')
.set('Content-Type','application/x-www-form-urlencoded')
.write('remember=1')
.end(function(res){
res.headers.should.have.property('set-cookie')
done()
})
.post('/')
.send({ remember: 1 })
.end(function(err, res){
res.headers.should.have.property('set-cookie')
done()
})
})
})
})

View File

@@ -1,3 +1,4 @@
var app = require('../../examples/downloads/app')
, request = require('../support/http');
@@ -5,28 +6,28 @@ describe('downloads', function(){
describe('GET /', function(){
it('should have a link to amazing.txt', function(done){
request(app)
.get('/')
.expect(/href="\/files\/amazing.txt"/,done)
.get('/')
.expect(/href="\/files\/amazing.txt"/, done)
})
})
describe('GET /files/amazing.txt', function(){
it('should have a download header', function(done){
request(app)
.get('/files/amazing.txt')
.end(function(res){
res.should.have.property('statusCode',200)
res.headers.should.have.property('content-disposition', 'attachment; filename="amazing.txt"')
done()
})
.get('/files/amazing.txt')
.end(function(err, res){
res.status.should.equal(200);
res.headers.should.have.property('content-disposition', 'attachment; filename="amazing.txt"')
done()
})
})
})
describe('GET /files/missing.txt', function(){
it('should respond with 404', function(done){
request(app)
.get('/files/missing.txt')
.expect(404,done)
.get('/files/missing.txt')
.expect(404, done)
})
})
})

View File

@@ -7,12 +7,12 @@ describe('ejs', function(){
it('should respond with html', function(done){
request(app)
.get('/')
.end(function(res){
.end(function(err, res){
res.should.have.status(200);
res.should.have.header('Content-Type', 'text/html; charset=utf-8');
res.body.should.include('<li>tobi tobi@learnboost.com</li>');
res.body.should.include('<li>loki loki@learnboost.com</li>');
res.body.should.include('<li>jane jane@learnboost.com</li>');
res.text.should.include('<li>tobi tobi@learnboost.com</li>');
res.text.should.include('<li>loki loki@learnboost.com</li>');
res.text.should.include('<li>jane jane@learnboost.com</li>');
done();
});
})

View File

@@ -37,7 +37,6 @@ describe('error-pages', function(){
})
})
describe('Accept: application/json',function(){
describe('GET /403', function(){
it('should respond with 403', function(done){
@@ -53,9 +52,8 @@ describe('error-pages', function(){
request(app)
.get('/404')
.set('Accept','application/json')
.end(function(res){
res.should.have.property('statusCode',200)
res.should.have.property('body',JSON.stringify({error:'Not found'}))
.end(function(err, res){
res.body.should.eql({ error: 'Not found' });
done()
})
})
@@ -65,7 +63,7 @@ describe('error-pages', function(){
it('should respond with 500', function(done){
request(app)
.get('/500')
.set('Accept','application/json')
.set('Accept', 'application/json')
.expect(500, done)
})
})
@@ -76,22 +74,19 @@ describe('error-pages', function(){
describe('GET /403', function(){
it('should respond with 403', function(done){
request(app)
.get('/403')
.set('Accept','text/plain')
.expect(403, done)
.get('/403')
.set('Accept','text/plain')
.expect(403, done)
})
})
describe('GET /404', function(){
it('should respond with 404', function(done){
request(app)
.get('/404')
.set('Accept','text/plain')
.end(function(res){
res.should.have.property('statusCode',200)
res.should.have.property('body','Not found')
done()
})
.get('/404')
.set('Accept', 'text/plain')
.expect(200)
.expect('Not found', done);
})
})

View File

@@ -1,42 +0,0 @@
var app = require('../../examples/multipart/app')
, request = require('../support/http')
, path = 'test/acceptance/fixtures/grey.png'
, fs = require('fs')
var logo = fs.readFileSync(path)
, boundary = '------expressmultipart';
describe('multipart', function(){
describe('GET /', function(){
it('should respond with a form', function(done){
request(app)
.get('/')
.expect(/<form/, done)
})
})
describe('POST /', function(){
it('should upload logo as multipart', function(done){
request(app)
.post('/')
.set('content-type','multipart/form-data; boundary='+boundary.slice(2))
.write(boundary + '\r\n')
.write('Content-Disposition: form-data; name="title"\r\n')
.write('\r\n')
.write('grey\r\n')
.write(boundary + '\r\n')
.write('Content-Disposition: form-data; name="image"; filename="grey.png"\r\n')
.write('Content-Type: image/png\r\n')
.write('\r\n')
.write(logo+'\r\n')
.write(boundary+'--\r\n')
.end(function(res){
res.body.should.match(/uploaded grey.png/)
res.body.should.match(/\(224 Kb\)/)
res.body.should.match(/as grey/)
done()
})
})
})
})

View File

@@ -7,7 +7,7 @@ describe('mvc', function(){
it('should redirect to /users', function(done){
request(app)
.get('/')
.end(function(res){
.end(function(err, res){
res.should.have.status(302);
res.headers.location.should.include('/users');
done();
@@ -19,11 +19,11 @@ describe('mvc', function(){
it('should display a list of users', function(done){
request(app)
.get('/users')
.end(function(res){
res.body.should.include('<h1>Users</h1>');
res.body.should.include('>TJ<');
res.body.should.include('>Guillermo<');
res.body.should.include('>Nathan<');
.end(function(err, res){
res.text.should.include('<h1>Users</h1>');
res.text.should.include('>TJ<');
res.text.should.include('>Guillermo<');
res.text.should.include('>Nathan<');
done();
})
})
@@ -34,8 +34,8 @@ describe('mvc', function(){
it('should display the user', function(done){
request(app)
.get('/user/0')
.end(function(res){
res.body.should.include('<h1>TJ <a href="/user/0/edit">edit');
.end(function(err, res){
res.text.should.include('<h1>TJ <a href="/user/0/edit">edit');
done();
})
})
@@ -43,10 +43,10 @@ describe('mvc', function(){
it('should display the users pets', function(done){
request(app)
.get('/user/0')
.end(function(res){
res.body.should.include('/pet/0">Tobi');
res.body.should.include('/pet/1">Loki');
res.body.should.include('/pet/2">Jane');
.end(function(err, res){
res.text.should.include('/pet/0">Tobi');
res.text.should.include('/pet/1">Loki');
res.text.should.include('/pet/2">Jane');
done();
})
})
@@ -65,9 +65,9 @@ describe('mvc', function(){
it('should display the edit form', function(done){
request(app)
.get('/user/1/edit')
.end(function(res){
res.body.should.include('<h1>Guillermo</h1>');
res.body.should.include('value="put"');
.end(function(err, res){
res.text.should.include('<h1>Guillermo</h1>');
res.text.should.include('value="put"');
done();
})
})
@@ -77,13 +77,12 @@ describe('mvc', function(){
it('should update the user', function(done){
request(app)
.put('/user/1')
.set('Content-Type', 'application/json')
.write('{"user":{"name":"Tobo"}}')
.end(function(res){
.send({ user: { name: 'Tobo' }})
.end(function(err, res){
request(app)
.get('/user/1/edit')
.end(function(res){
res.body.should.include('<h1>Tobo</h1>');
.end(function(err, res){
res.text.should.include('<h1>Tobo</h1>');
done();
})
})

View File

@@ -37,7 +37,7 @@ describe('resource', function(){
describe('DELETE /users/1', function(){
it('should respond with users 1 through 3', function(done){
request(app)
.delete('/users/1')
.del('/users/1')
.expect(/^destroyed/,done)
})
})

View File

@@ -24,9 +24,9 @@ describe('web-service', function(){
it('should respond users json', function(done){
request(app)
.get('/api/users?api-key=foo')
.end(function(res){
.end(function(err, res){
res.should.be.json;
res.body.should.equal('[{"name":"tobi"},{"name":"loki"},{"name":"jane"}]');
res.text.should.equal('[{"name":"tobi"},{"name":"loki"},{"name":"jane"}]');
done();
});
})
@@ -37,10 +37,10 @@ describe('web-service', function(){
it('should respond with 404 json', function(done){
request(app)
.get('/api/something?api-key=bar')
.end(function(res){
.end(function(err, res){
res.should.have.status(404);
res.should.be.json;
res.body.should.equal('{"error":"Lame, can\'t find that"}');
res.text.should.equal('{"error":"Lame, can\'t find that"}');
done();
});
})

View File

@@ -29,7 +29,7 @@ describe('app.all()', function(){
});
request(app)
.delete('/tobi')
.del('/tobi')
.expect(404, done);
})
})

View File

@@ -11,7 +11,7 @@ describe('app.del()', function(){
});
request(app)
.delete('/tobi')
.del('/tobi')
.expect('deleted tobi!', done);
})
})

View File

@@ -34,9 +34,10 @@ describe('app', function(){
request(app)
.get('/')
.end(function(res){
.end(function(err, res){
if (err) return done(err);
calls.should.eql(['use', 'one', 'two']);
res.body.should.equal('<p>tobi holowaychuk is a ferret</p>');
res.text.should.equal('<p>tobi holowaychuk is a ferret</p>');
done();
})
})
@@ -59,10 +60,7 @@ describe('app', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>tobi holowaychuk is a ferret</p>');
done();
})
.expect('<p>tobi holowaychuk is a ferret</p>', done);
})
})
@@ -83,10 +81,7 @@ describe('app', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>tobi ibot is a ferret</p>');
done();
})
.expect('<p>tobi ibot is a ferret</p>', done);
})
})
})

View File

@@ -12,12 +12,8 @@ describe('OPTIONS', function(){
request(app)
.options('/users')
.end(function(res){
res.body.should.equal('GET,PUT');
res.headers.should.have.property('content-type');
res.headers.should.have.property('allow', 'GET,PUT');
done();
});
.expect('GET,PUT')
.expect('Allow', 'GET,PUT', done);
})
})
@@ -35,10 +31,7 @@ describe('app.options()', function(){
request(app)
.options('/users')
.end(function(res){
res.body.should.equal('GET');
res.headers.should.have.property('allow', 'GET');
done();
});
.expect('GET')
.expect('Allow', 'GET', done);
})
})

View File

@@ -29,14 +29,11 @@ describe('app', function(){
request(app)
.get('/user/tj')
.end(function(res){
res.body.should.equal('tj');
.end(function(err, res){
res.text.should.equal('tj');
request(app)
.get('/user/123')
.end(function(res){
res.should.have.status(404);
done();
});
.expect(404, done);
});
})
@@ -67,15 +64,12 @@ describe('app', function(){
request(app)
.get('/user/123')
.end(function(res){
res.body.should.equal('123');
.end(function(err, res){
res.text.should.equal('123');
request(app)
.get('/post/123')
.end(function(res){
res.body.should.equal('123');
done();
})
.expect('123', done);
})
})
})
@@ -99,10 +93,7 @@ describe('app', function(){
request(app)
.get('/user/123')
.end(function(res){
res.body.should.equal('123');
done();
})
.expect('123', done);
})
})
})

View File

@@ -17,10 +17,7 @@ describe('app', function(){
request(app)
.get('/foo?name=tobi')
.end(function(res){
res.body.should.equal('name=tobi');
done();
});
.expect('name=tobi', done);
})
})
})

View File

@@ -17,10 +17,7 @@ describe('app', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('HEY');
done();
});
.expect('HEY', done);
})
it('should not be influenced by other app protos', function(done){
@@ -41,10 +38,7 @@ describe('app', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('HEY');
done();
});
.expect('HEY', done);
})
})
})

View File

@@ -8,6 +8,7 @@ describe('app.router', function(){
describe('methods supported', function(){
methods.forEach(function(method){
it('should include ' + method.toUpperCase(), function(done){
if (method == 'delete') method = 'del';
var app = express();
var calls = [];
@@ -267,7 +268,7 @@ describe('app.router', function(){
request(app)
.get('/user/10')
.end(function(res){
.end(function(err, res){
res.statusCode.should.equal(200);
request(app)
.get('/user/tj')

View File

@@ -13,10 +13,7 @@ describe('throw after .end()', function(){
request(app)
.get('/')
.end(function(res){
res.should.have.status(200);
res.body.should.equal('yay');
done();
});
.expect('yay')
.expect(200, done);
})
})

View File

@@ -29,10 +29,7 @@ describe('req', function(){
request(app)
.get('/')
.set('If-None-Match', '12345')
.end(function(res){
res.body.should.equal('false');
done();
});
.expect('false', done);
})
})
})

View File

@@ -16,10 +16,7 @@ describe('req', function(){
request(app)
.post('/')
.set('Content-Type', 'application/json')
.end(function(res){
res.body.should.equal('application/json');
done();
});
.expect('application/json', done);
})
it('should special-case Referer', function(done){
@@ -32,10 +29,7 @@ describe('req', function(){
request(app)
.post('/')
.set('Referrer', 'http://foobar.com')
.end(function(res){
res.body.should.equal('http://foobar.com');
done();
});
.expect('http://foobar.com', done);
})
})
})

View File

@@ -13,10 +13,7 @@ describe('req', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('tj');
done();
})
.expect('tj', done);
})
})
@@ -30,10 +27,7 @@ describe('req', function(){
request(app)
.get('/?name=tj')
.end(function(res){
res.body.should.equal('tj');
done();
})
.expect('tj', done);
})
it('should check req.body', function(done){
@@ -47,12 +41,8 @@ describe('req', function(){
request(app)
.post('/')
.set('Content-Type', 'application/json')
.write('{"name":"tj"}')
.end(function(res){
res.body.should.equal('tj');
done();
})
.send({ name: 'tj' })
.expect('tj', done);
})
it('should check req.params', function(done){
@@ -64,10 +54,7 @@ describe('req', function(){
request(app)
.get('/user/tj')
.end(function(res){
res.body.should.equal('undefinedtj');
done();
})
.expect('undefinedtj', done);
})
})
})

View File

@@ -13,10 +13,7 @@ describe('req', function(){
request(app)
.get('/login?redirect=/post/1/comments')
.end(function(res){
res.body.should.equal('/login');
done();
})
.expect('/login', done);
})
})
})

View File

@@ -13,10 +13,7 @@ describe('req', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('http');
done();
})
.expect('http', done);
})
describe('when "trust proxy" is enabled', function(){
@@ -32,10 +29,7 @@ describe('req', function(){
request(app)
.get('/')
.set('X-Forwarded-Proto', 'https')
.end(function(res){
res.body.should.equal('https');
done();
})
.expect('https', done);
})
it('should default to http', function(done){
@@ -49,10 +43,7 @@ describe('req', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('http');
done();
})
.expect('http', done);
})
})
@@ -67,10 +58,7 @@ describe('req', function(){
request(app)
.get('/')
.set('X-Forwarded-Proto', 'https')
.end(function(res){
res.body.should.equal('http');
done();
})
.expect('http', done);
})
})
})

View File

@@ -29,10 +29,7 @@ describe('req', function(){
request(app)
.get('/')
.set('If-None-Match', '12345')
.end(function(res){
res.body.should.equal('true');
done();
});
.expect('true', done);
})
})
})

View File

@@ -15,10 +15,7 @@ describe('req', function(){
request(app)
.get('/')
.set('Host', 'tobi.ferrets.example.com')
.end(function(res){
res.body.should.equal('["ferrets","tobi"]');
done();
})
.expect('["ferrets","tobi"]', done);
})
})
@@ -33,10 +30,7 @@ describe('req', function(){
request(app)
.get('/')
.set('Host', 'example.com')
.end(function(res){
res.body.should.equal('[]');
done();
})
.expect('[]', done);
})
})
})

View File

@@ -13,10 +13,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.headers.should.have.property('content-disposition', 'attachment');
done();
})
.expect('Content-Disposition', 'attachment', done);
})
})
@@ -31,10 +28,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.headers.should.have.property('content-disposition', 'attachment; filename="image.png"');
done();
})
.expect('Content-Disposition', 'attachment; filename="image.png"', done);
})
it('should set the Content-Type', function(done){
@@ -47,10 +41,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.headers.should.have.property('content-type', 'image/png');
done();
})
.expect('Content-Type', 'image/png', done);
})
})
})

View File

@@ -15,10 +15,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('text/x-foo; charset=utf-8');
done();
})
.expect("text/x-foo; charset=utf-8", done);
})
it('should take precedence over res.send() defaults', function(done){
@@ -31,10 +28,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.headers.should.have.property('content-type', 'text/html; charset=whoop');
done();
})
.expect('Content-Type', 'text/html; charset=whoop', done);
})
})
})

View File

@@ -13,9 +13,9 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
.end(function(err, res){
var val = 'sid=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT';
res.headers['set-cookie'].should.eql([val]);
res.header['set-cookie'].should.eql([val]);
done();
})
})
@@ -31,9 +31,9 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
.end(function(err, res){
var val = 'sid=; Path=/admin; Expires=Thu, 01 Jan 1970 00:00:00 GMT';
res.headers['set-cookie'].should.eql([val]);
res.header['set-cookie'].should.eql([val]);
done();
})
})

View File

@@ -14,7 +14,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
.end(function(err, res){
var val = ['user=j:{%22name%22:%22tobi%22}; Path=/'];
res.headers['set-cookie'].should.eql(val);
done();
@@ -32,7 +32,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
.end(function(err, res){
var val = ['name=tobi; Path=/'];
res.headers['set-cookie'].should.eql(val);
done();
@@ -50,7 +50,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
.end(function(err, res){
var val = ['name=tobi; Path=/', 'age=1; Path=/'];
res.headers['set-cookie'].should.eql(val);
done();
@@ -69,7 +69,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
.end(function(err, res){
var val = ['name=tobi; Path=/; HttpOnly; Secure'];
res.headers['set-cookie'].should.eql(val);
done();
@@ -87,7 +87,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
.end(function(err, res){
res.headers['set-cookie'][0].should.not.include('Thu, 01 Jan 1970 00:00:01 GMT');
done();
})
@@ -106,7 +106,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
.end(function(err, res){
var val = res.headers['set-cookie'][0];
val = cookie.parse(val.split('.')[0]);
val.user.should.equal('j:{"name":"tobi"}');
@@ -127,7 +127,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
.end(function(err, res){
var val = ['name=tobi.xJjV2iZ6EI7C8E5kzwbfA9PVLl1ZR07UTnuTgQQ4EnQ; Path=/'];
res.headers['set-cookie'].should.eql(val);
done();

View File

@@ -14,10 +14,10 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
.end(function(err, res){
res.should.have.header('Content-Type', 'text/html; charset=UTF-8');
res.should.have.header('Content-Disposition', 'attachment; filename="user.html"');
res.body.should.equal('<p>{{user.name}}</p>');
res.text.should.equal('<p>{{user.name}}</p>');
done();
});
})
@@ -33,7 +33,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
.end(function(err, res){
res.should.have.header('Content-Type', 'text/html; charset=UTF-8');
res.should.have.header('Content-Disposition', 'attachment; filename="document"');
done();
@@ -52,7 +52,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
.end(function(err, res){
res.should.have.header('Content-Type', 'text/html; charset=UTF-8');
res.should.have.header('Content-Disposition', 'attachment; filename="user.html"');
});
@@ -70,7 +70,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
.end(function(err, res){
res.should.have.header('Content-Type', 'text/html; charset=UTF-8');
res.should.have.header('Content-Disposition', 'attachment; filename="document"');
});

View File

@@ -93,21 +93,15 @@ function test(app) {
request(app)
.get('/')
.set('Accept', 'text/html; q=.5, text/plain')
.end(function(res){
res.headers['content-type'].should.equal('text/plain');
res.body.should.equal('hey');
done();
});
.expect('Content-Type', 'text/plain')
.expect('hey', done);
})
it('should Vary: Accept', function(done){
request(app)
.get('/')
.set('Accept', 'text/html; q=.5, text/plain')
.end(function(res){
res.headers.vary.should.equal('Accept');
done();
});
.expect('Vary', 'Accept', done);
})
describe('when Accept is not present', function(){
@@ -123,11 +117,8 @@ function test(app) {
request(app)
.get('/')
.set('Accept', 'foo/bar')
.end(function(res){
res.should.have.status(406);
res.body.should.equal('Supports: text/plain, text/html, application/json');
done();
});
.expect('Supports: text/plain, text/html, application/json')
.expect(406, done)
})
})
}

View File

@@ -15,9 +15,9 @@ describe('res', function(){
request(app)
.get('/?callback=something')
.end(function(res){
.end(function(err, res){
res.headers.should.have.property('content-type', 'text/javascript; charset=utf-8');
res.body.should.equal('something({"count":1});');
res.text.should.equal('something({"count":1});');
done();
})
})
@@ -31,9 +31,9 @@ describe('res', function(){
request(app)
.get('/?callback=callbacks[123]')
.end(function(res){
.end(function(err, res){
res.headers.should.have.property('content-type', 'text/javascript; charset=utf-8');
res.body.should.equal('callbacks[123]({"count":1});');
res.text.should.equal('callbacks[123]({"count":1});');
done();
})
})
@@ -49,9 +49,9 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
.end(function(err, res){
res.headers.should.have.property('content-type', 'application/json; charset=utf-8');
res.body.should.equal('null');
res.text.should.equal('null');
done();
})
})
@@ -67,9 +67,9 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
.end(function(err, res){
res.headers.should.have.property('content-type', 'application/json; charset=utf-8');
res.body.should.equal('["foo","bar","baz"]');
res.text.should.equal('["foo","bar","baz"]');
done();
})
})
@@ -85,9 +85,9 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
.end(function(err, res){
res.headers.should.have.property('content-type', 'application/json; charset=utf-8');
res.body.should.equal('{"name":"tobi"}');
res.text.should.equal('{"name":"tobi"}');
done();
})
})
@@ -109,8 +109,8 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('{"name":"tobi"}');
.end(function(err, res){
res.text.should.equal('{"name":"tobi"}');
done();
});
})
@@ -140,8 +140,8 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('{\n "name": "tobi",\n "age": 2\n}');
.end(function(err, res){
res.text.should.equal('{\n "name": "tobi",\n "age": 2\n}');
done();
});
})
@@ -158,10 +158,10 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
.end(function(err, res){
res.statusCode.should.equal(201);
res.headers.should.have.property('content-type', 'application/json; charset=utf-8');
res.body.should.equal('{"id":1}');
res.text.should.equal('{"id":1}');
done();
})
})

View File

@@ -40,9 +40,9 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
.end(function(err, res){
calls.should.eql(['render', 'one', 'two']);
res.body.should.equal('<p>tobi holowaychuk is a ferret</p>');
res.text.should.equal('<p>tobi holowaychuk is a ferret</p>');
done();
})
})
@@ -68,8 +68,8 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>tobi holowaychuk is a ferret</p>');
.end(function(err, res){
res.text.should.equal('<p>tobi holowaychuk is a ferret</p>');
done();
})
})
@@ -95,8 +95,8 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>tobi ibot is a ferret</p>');
.end(function(err, res){
res.text.should.equal('<p>tobi ibot is a ferret</p>');
done();
})
})

View File

@@ -17,7 +17,7 @@ describe('res', function(){
.get('/')
.set('Host', 'example.com')
.set('X-Forwarded-Proto', 'https')
.end(function(res){
.end(function(err, res){
res.statusCode.should.equal(302);
res.headers.should.have.property('location', 'https://example.com/login');
done();
@@ -33,7 +33,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
.end(function(err, res){
res.statusCode.should.equal(302);
res.headers.should.have.property('location', 'http://google.com');
done();
@@ -51,7 +51,7 @@ describe('res', function(){
request(app)
.get('/')
.set('Host', 'example.com')
.end(function(res){
.end(function(err, res){
res.headers.should.have.property('location', 'http://example.com/login');
done();
})
@@ -69,7 +69,7 @@ describe('res', function(){
request(app)
.get('/post/1')
.set('Host', 'example.com')
.end(function(res){
.end(function(err, res){
res.headers.should.have.property('location', 'http://example.com/post/1/./edit');
done();
})
@@ -87,7 +87,7 @@ describe('res', function(){
request(app)
.get('/post/1')
.set('Host', 'example.com')
.end(function(res){
.end(function(err, res){
res.headers.should.have.property('location', 'http://example.com/post/1/../new');
done();
})
@@ -105,7 +105,7 @@ describe('res', function(){
request(app)
.get('/')
.set('Host', 'example.com')
.end(function(res){
.end(function(err, res){
res.headers.should.have.property('location', 'http://example.com/login');
done();
})
@@ -129,7 +129,7 @@ describe('res', function(){
request(app)
.get('/blog/admin')
.set('Host', 'example.com')
.end(function(res){
.end(function(err, res){
res.headers.should.have.property('location', 'http://example.com/blog/admin/login');
done();
})
@@ -150,7 +150,7 @@ describe('res', function(){
request(app)
.get('/blog')
.set('Host', 'example.com')
.end(function(res){
.end(function(err, res){
res.headers.should.have.property('location', 'http://example.com/blog/admin/login');
done();
})
@@ -171,7 +171,7 @@ describe('res', function(){
request(app)
.get('/blog')
.set('Host', 'example.com')
.end(function(res){
.end(function(err, res){
res.headers.should.have.property('location', 'http://example.com/admin/login');
done();
})
@@ -190,7 +190,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
.end(function(err, res){
res.statusCode.should.equal(303);
res.headers.should.have.property('location', 'http://google.com');
done();
@@ -208,9 +208,9 @@ describe('res', function(){
request(app)
.head('/')
.end(function(res){
.end(function(err, res){
res.headers.should.have.property('location', 'http://google.com');
res.body.should.equal('');
res.text.should.equal('');
done();
})
})
@@ -227,9 +227,9 @@ describe('res', function(){
request(app)
.get('/')
.set('Accept', 'text/html')
.end(function(res){
.end(function(err, res){
res.headers.should.have.property('location', 'http://google.com');
res.body.should.equal('<p>Moved Temporarily. Redirecting to <a href="http://google.com">http://google.com</a></p>');
res.text.should.equal('<p>Moved Temporarily. Redirecting to <a href="http://google.com">http://google.com</a></p>');
done();
})
})
@@ -246,10 +246,10 @@ describe('res', function(){
request(app)
.get('/')
.set('Accept', 'text/plain, */*')
.end(function(res){
.end(function(err, res){
res.headers.should.have.property('location', 'http://google.com');
res.headers.should.have.property('content-length', '51');
res.body.should.equal('Moved Temporarily. Redirecting to http://google.com');
res.text.should.equal('Moved Temporarily. Redirecting to http://google.com');
done();
})
})
@@ -266,12 +266,12 @@ describe('res', function(){
request(app)
.get('/')
.set('Accept', 'foo/bar')
.end(function(res){
.end(function(err, res){
res.should.have.status(302);
res.headers.should.have.property('location', 'http://google.com');
res.headers.should.not.have.property('content-type');
res.headers.should.have.property('content-length', '0');
res.body.should.equal('');
res.text.should.equal('');
done();
})
})

View File

@@ -15,10 +15,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>tobi</p>');
done();
});
.expect('<p>tobi</p>', done);
})
it('should support absolute paths with "view engine"', function(done){
@@ -33,10 +30,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>tobi</p>');
done();
});
.expect('<p>tobi</p>', done);
})
it('should expose app.locals', function(done){
@@ -51,10 +45,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>tobi</p>');
done();
});
.expect('<p>tobi</p>', done);
})
it('should support index.<engine>', function(done){
@@ -69,10 +60,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<h1>blog post</h1>');
done();
});
.expect('<h1>blog post</h1>', done);
})
describe('when an error occurs', function(){
@@ -91,10 +79,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.match(/user is not defined/);
done();
});
.expect(/user is not defined/, done);
})
})
@@ -111,10 +96,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>This is an email</p>');
done();
});
.expect('<p>This is an email</p>', done);
})
})
})
@@ -133,10 +115,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>tobi</p>');
done();
});
.expect('<p>tobi</p>', done);
})
it('should expose app.locals', function(done){
@@ -151,10 +130,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>tobi</p>');
done();
});
.expect('<p>tobi</p>', done);
})
it('should expose res.locals', function(done){
@@ -169,10 +145,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>tobi</p>');
done();
});
.expect('<p>tobi</p>', done);
})
it('should give precedence to res.locals over app.locals', function(done){
@@ -188,10 +161,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>jane</p>');
done();
});
.expect('<p>jane</p>', done);
})
it('should give precedence to res.render() locals over res.locals', function(done){
@@ -207,10 +177,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>jane</p>');
done();
});
.expect('<p>jane</p>', done);
})
it('should give precedence to res.render() locals over app.locals', function(done){
@@ -226,10 +193,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>jane</p>');
done();
});
.expect('<p>jane</p>', done);
})
})
@@ -249,10 +213,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>loki</p>');
done();
});
.expect('<p>loki</p>', done);
})
})
@@ -272,10 +233,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>loki</p>');
done();
});
.expect('<p>loki</p>', done);
})
describe('when an error occurs', function(){
@@ -292,12 +250,8 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.match(/is not defined/);
done();
});
.expect(/is not defined/, done);
})
})
})
})

View File

@@ -13,10 +13,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('');
done();
})
.expect('', done);
})
})
@@ -30,10 +27,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('');
done();
})
.expect('', done);
})
})
@@ -47,11 +41,8 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('Created');
res.statusCode.should.equal(201);
done();
})
.expect('Created')
.expect(201, done);
})
})
@@ -65,11 +56,8 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('Created :)');
res.statusCode.should.equal(201);
done();
})
.expect('Created :)')
.expect(201, done);
})
})
@@ -83,11 +71,8 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('Bad!');
res.statusCode.should.equal(400);
done();
})
.expect('Bad!')
.expect(400, done);
})
})
@@ -101,9 +86,9 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
.end(function(err, res){
res.headers.should.have.property('content-type', 'text/html; charset=utf-8');
res.body.should.equal('<p>hey</p>');
res.text.should.equal('<p>hey</p>');
res.statusCode.should.equal(200);
done();
})
@@ -119,10 +104,8 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.headers.should.have.property('etag', '-1498647312');
done();
})
.expect('ETag', '-1498647312')
.end(done);
})
it('should not override Content-Type', function(done){
@@ -134,12 +117,9 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.headers.should.have.property('content-type', 'text/plain');
res.body.should.equal('hey');
res.statusCode.should.equal(200);
done();
})
.expect('Content-Type', 'text/plain')
.expect('hey')
.expect(200, done);
})
})
@@ -153,9 +133,9 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
.end(function(err, res){
res.headers.should.have.property('content-type', 'text/html; charset=utf-8');
res.body.should.equal('<p>hey</p>');
res.text.should.equal('<p>hey</p>');
res.statusCode.should.equal(200);
done();
})
@@ -170,9 +150,9 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
.end(function(err, res){
res.headers.should.have.property('content-type', 'text/plain');
res.body.should.equal('hey');
res.text.should.equal('hey');
res.statusCode.should.equal(200);
done();
})
@@ -189,9 +169,9 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
.end(function(err, res){
res.headers.should.have.property('content-type', 'application/octet-stream');
res.body.should.equal('hello');
res.text.should.equal('hello');
res.statusCode.should.equal(200);
done();
})
@@ -207,10 +187,8 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.headers.should.have.property('etag', '-1498647312');
done();
})
.expect('ETag', '-1498647312')
.end(done);
})
it('should not override Content-Type', function(done){
@@ -222,9 +200,9 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
.end(function(err, res){
res.headers.should.have.property('content-type', 'text/plain');
res.body.should.equal('hey');
res.text.should.equal('hey');
res.statusCode.should.equal(200);
done();
})
@@ -241,9 +219,9 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
.end(function(err, res){
res.headers.should.have.property('content-type', 'application/json; charset=utf-8');
res.body.should.equal('{"name":"tobi"}');
res.text.should.equal('{"name":"tobi"}');
done();
})
})
@@ -259,10 +237,7 @@ describe('res', function(){
request(app)
.head('/')
.end(function(res){
res.body.should.equal('');
done();
})
.expect('', done);
})
})
@@ -276,10 +251,10 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
.end(function(err, res){
res.headers.should.not.have.property('content-type');
res.headers.should.not.have.property('content-length');
res.body.should.equal('');
res.text.should.equal('');
done();
})
})
@@ -295,10 +270,10 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
.end(function(err, res){
res.headers.should.not.have.property('content-type');
res.headers.should.not.have.property('content-length');
res.body.should.equal('');
res.text.should.equal('');
done();
})
})
@@ -344,10 +319,7 @@ describe('res', function(){
request(app)
.get('/')
.set('If-None-Match', 'asdf')
.end(function(res){
res.should.have.status(500);
res.body.should.equal('hey');
done();
});
.expect('hey')
.expect(500, done);
})
})

View File

@@ -17,9 +17,8 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.should.have.status(200);
});
.expect(200)
.end(function(){});
})
it('should utilize the same options as express.static()', function(done){
@@ -31,10 +30,8 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.should.have.header('Cache-Control', 'public, max-age=60');
done();
});
.expect('Cache-Control', 'public, max-age=60')
.end(done);
})
it('should invoke the callback on 404', function(done){
@@ -51,9 +48,9 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
.end(function(err, res){
calls.should.equal(1);
res.body.should.equal('Not Found');
res.text.should.equal('Not Found');
res.statusCode.should.equal(200);
done();
});
@@ -69,10 +66,8 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.should.have.header('content-type', 'text/plain');
done();
});
.expect('Content-Type', 'text/plain')
.end(done);
})
it('should invoke the callback on 403', function(done){
@@ -89,12 +84,8 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('Forbidden');
res.statusCode.should.equal(200);
calls.should.equal(1);
done();
});
.expect('Forbidden')
.expect(200, done);
})
})
@@ -109,8 +100,8 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>{{user.name}}</p>');
.end(function(err, res){
res.text.should.equal('<p>{{user.name}}</p>');
res.headers.should.have.property('content-type', 'text/html; charset=UTF-8');
done();
});
@@ -127,8 +118,8 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>{{user.name}}</p>');
.end(function(err, res){
res.text.should.equal('<p>{{user.name}}</p>');
res.headers.should.have.property('content-type', 'text/html; charset=UTF-8');
done();
});
@@ -143,8 +134,8 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>{{user.name}}</p>');
.end(function(err, res){
res.text.should.equal('<p>{{user.name}}</p>');
res.headers.should.have.property('content-type', 'text/html; charset=UTF-8');
done();
});
@@ -159,10 +150,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.statusCode.should.equal(403);
done();
});
.expect(403, done);
})
it('should allow ../ when "root" is set', function(done){
@@ -174,10 +162,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.statusCode.should.equal(200);
done();
});
.expect(200, done);
})
it('should disallow requesting out of "root"', function(done){
@@ -189,10 +174,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.statusCode.should.equal(403);
done();
});
.expect(403, done);
})
it('should next(404) when not found', function(done){
@@ -214,7 +196,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
.end(function(err, res){
res.statusCode.should.equal(404);
calls.should.equal(1);
done();
@@ -223,17 +205,16 @@ describe('res', function(){
describe('with non-GET', function(){
it('should still serve', function(done){
var app = express()
, calls = 0;
var app = express()
, calls = 0;
app.use(function(req, res){
res.sendfile(__dirname + '/fixtures/name.txt');
});
app.use(function(req, res){
res.sendfile(__dirname + '/fixtures/name.txt');
});
request(app)
.get('/')
.expect('tobi', done);
request(app)
.get('/')
.expect('tobi', done);
})
})
})

View File

@@ -14,10 +14,8 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.headers.should.have.property('content-type', 'text/x-foo');
done();
})
.expect('Content-Type', 'text/x-foo')
.end(done);
})
it('should coerce to a string', function(){
@@ -40,11 +38,9 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.headers.should.have.property('x-foo', 'bar');
res.headers.should.have.property('x-bar', 'baz');
done();
})
.expect('X-Foo', 'bar')
.expect('X-Bar', 'baz')
.end(done);
})
it('should coerce to a string', function(){

View File

@@ -13,11 +13,8 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.body.should.equal('Created');
res.statusCode.should.equal(201);
done();
})
.expect('Created')
.expect(201, done);
})
})
})

View File

@@ -13,10 +13,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.headers.should.have.property('content-type', 'application/javascript');
done();
})
.expect('Content-Type', 'application/javascript', done);
})
it('should default to application/octet-stream', function(done){
@@ -28,10 +25,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.headers.should.have.property('content-type', 'application/octet-stream');
done();
})
.expect('Content-Type', 'application/octet-stream', done);
})
it('should set the Content-Type with type/subtype', function(done){
@@ -44,10 +38,7 @@ describe('res', function(){
request(app)
.get('/')
.end(function(res){
res.headers.should.have.property('content-type', 'application/vnd.amazon.ebook');
done();
})
.expect('Content-Type', 'application/vnd.amazon.ebook', done);
})
})
})

View File

@@ -1,105 +1,2 @@
/**
* Module dependencies.
*/
var EventEmitter = require('events').EventEmitter
, methods = require('methods')
, http = require('http');
module.exports = request;
function request(app) {
return new Request(app);
}
function Request(app) {
var self = this;
this.data = [];
this.header = {};
this.app = app;
if (!this.server) {
this.server = http.Server(app);
this.server.listen(0, function(){
self.addr = self.server.address();
self.listening = true;
});
}
}
/**
* Inherit from `EventEmitter.prototype`.
*/
Request.prototype.__proto__ = EventEmitter.prototype;
methods.forEach(function(method){
Request.prototype[method] = function(path){
return this.request(method, path);
};
});
Request.prototype.set = function(field, val){
this.header[field] = val;
return this;
};
Request.prototype.write = function(data){
this.data.push(data);
return this;
};
Request.prototype.request = function(method, path){
this.method = method;
this.path = path;
return this;
};
Request.prototype.expect = function(body, fn){
this.end(function(res){
if ('number' == typeof body) {
res.statusCode.should.equal(body);
} else if (body instanceof RegExp) {
res.body.should.match(body);
} else {
res.body.should.equal(body);
}
fn();
});
};
Request.prototype.end = function(fn){
var self = this;
if (this.listening) {
var req = http.request({
method: this.method
, port: this.addr.port
, host: this.addr.address
, path: this.path
, headers: this.header
});
this.data.forEach(function(chunk){
req.write(chunk);
});
req.on('response', function(res){
var buf = '';
res.setEncoding('utf8');
res.on('data', function(chunk){ buf += chunk });
res.on('end', function(){
res.body = buf;
fn(res);
});
});
req.end();
} else {
this.server.on('listening', function(){
self.end(fn);
});
}
return this;
};
module.exports = require('supertest');