92 KiB
TOC
- app.all()
- app.del()
- app
- HEAD
- app.head()
- app.parent
- app.route
- app.path()
- in development
- in production
- app.listen()
- OPTIONS
- app.options()
- app.router
- config
- exports
- throw after .end()
- req
- req.is()
- res
- .attachment()
- .attachment(filename)
- .cache(type)
- .charset
- .clearCookie(name)
- .clearCookie(name, options)
- .cookie(name, object)
- .cookie(name, string)
- .cookie(name, string, options)
- .get(field)
- .json(object)
- .json(status, object)
- .locals(obj)
- .redirect(url)
- .redirect(status, url)
- when the request method is HEAD
- when accepting html
- when accepting text
- .render(name)
- .render(name, option)
- .render(name, options, fn)
- .render(name, fn)
- .send(null)
- .send(undefined)
- .send(code)
- .send(code, body)
- .send(String)
- .send(Buffer)
- .send(Object)
- when .statusCode is 204
- when .statusCode is 304
- .sendfile(path, fn)
- .sendfile(path)
- .set(field, value)
- .set(object)
- .signedCook(name, object)
- .signedCookie(name, string)
- .status(code)
- .type(str)
- Router
- utils.isAbsolute()
- utils.flatten(arr)
- utils.escape(html)
- utils.parseQuality(str)
- utils.parseAccept(str)
- utils.accepts(type, str)
- when a string is not given
- when a string is empty
- when / is given
- when accepting type/subtype
- when accepting */subtype
- when accepting type/*
- when an extension is given
var app = express();
app.all('/tobi', function(req, res){
res.end(req.method);
});
request(app)
.put('/tobi')
.expect('PUT', function(){
request(app)
.get('/tobi')
.expect('GET', done);
});
should .
var app = express()
, n = 0;
app.all('/*', function(req, res, next){
if (n++) return done(new Error('DELETE called several times'));
next();
});
request(app)
.delete('/tobi')
.expect(404, done);
var app = express();
app.del('/tobi', function(req, res){
res.end('deleted tobi!');
});
request(app)
.delete('/tobi')
.expect('deleted tobi!', done);
var app = express();
app.set('views', __dirname + '/fixtures');
app.engine('.html', render);
app.locals.user = { name: 'tobi' };
app.render('user.html', function(err, str){
if (err) return done(err);
str.should.equal('<p>tobi</p>');
done();
})
should work without leading ".".
var app = express();
app.set('views', __dirname + '/fixtures');
app.engine('html', render);
app.locals.user = { name: 'tobi' };
app.render('user.html', function(err, str){
if (err) return done(err);
str.should.equal('<p>tobi</p>');
done();
})
should work "view engine" setting.
var app = express();
app.set('views', __dirname + '/fixtures');
app.engine('html', render);
app.set('view engine', 'html');
app.locals.user = { name: 'tobi' };
app.render('user', function(err, str){
if (err) return done(err);
str.should.equal('<p>tobi</p>');
done();
})
var app = express();
app.get('/tobi', function(req, res){
// send() detects HEAD
res.send('tobi');
});
request(app)
.head('/tobi')
.expect(200, done);
var app = express()
, called;
app.head('/tobi', function(req, res){
called = true;
res.end('');
});
app.get('/tobi', function(req, res){
assert(0, 'should not call GET');
res.send('tobi');
});
request(app)
.head('/tobi')
.expect(200, function(){
assert(called);
done();
});
var app = express();
app.on('foo', done);
app.emit('foo');
var app = express()
, blog = express()
, blogAdmin = express();
app.use('/blog', blog);
blog.use('/admin', blogAdmin);
assert(!app.parent, 'app.parent');
blog.parent.should.equal(app);
blogAdmin.parent.should.equal(blog);
var app = express()
, blog = express()
, blogAdmin = express();
app.use('/blog', blog);
blog.use('/admin', blogAdmin);
app.route.should.equal('/');
blog.route.should.equal('/blog');
blogAdmin.route.should.equal('/admin');
var app = express()
, blog = express()
, blogAdmin = express();
app.use('/blog', blog);
blog.use('/admin', blogAdmin);
app.path().should.equal('');
blog.path().should.equal('/blog');
blogAdmin.path().should.equal('/blog/admin');
var app = express();
app.enabled('view cache').should.be.false;
process.env.NODE_ENV = 'production';
var app = express();
app.enabled('view cache').should.be.true;
process.env.NODE_ENV = 'test';
var app = express();
app.del('/tobi', function(req, res){
res.end('deleted tobi!');
});
var server = app.listen(9999, function(){
server.close();
done();
});
var app = express();
Object.keys(app.locals).should.eql(['use', 'settings']);
app.locals({ user: 'tobi', age: 1 });
app.locals({ age: 2 });
Object.keys(app.locals).should.eql(['use', 'settings', 'user', 'age']);
app.locals.user.should.equal('tobi');
app.locals.age.should.equal(2);
var app = express();
app.set('title', 'House of Manny');
var obj = app.locals.settings;
obj.should.have.property('env', 'test');
obj.should.have.property('title', 'House of Manny');
var app = express();
var calls = [];
app.set('views', __dirname + '/fixtures');
app.locals.first = 'tobi';
app.locals.use(function(req, res, done){
process.nextTick(function(){
calls.push('one');
res.locals.last = 'holowaychuk';
done();
});
});
app.locals.use(function(req, res, done){
process.nextTick(function(){
calls.push('two');
res.locals.species = 'ferret';
done();
});
});
app.use(function(req, res){
calls.push('use');
res.render('pet.jade');
});
request(app)
.get('/')
.end(function(res){
calls.should.eql(['use', 'one', 'two']);
res.body.should.equal('<p>tobi holowaychuk is a ferret</p>');
done();
})
should not override res.render() locals.
var app = express();
app.set('views', __dirname + '/fixtures');
app.locals.first = 'tobi';
app.locals.use(function(req, res){
res.locals.last = 'holowaychuk';
res.locals.species = 'ferret';
});
app.use(function(req, res){
res.render('pet.jade', { last: 'ibot' });
});
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>tobi ibot is a ferret</p>');
done();
})
var app = express();
app.set('views', __dirname + '/fixtures');
app.locals.first = 'tobi';
app.locals.use(function(req, res){
res.locals.last = 'holowaychuk';
res.locals.species = 'ferret';
});
app.use(function(req, res){
res.render('pet.jade');
});
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>tobi holowaychuk is a ferret</p>');
done();
})
var app = express();
app.del('/', function(){});
app.get('/users', function(req, res){});
app.put('/users', function(req, res){});
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();
});
var app = express();
app.options('/users', function(req, res){
res.set('Allow', 'GET');
res.send('GET');
});
app.get('/users', function(req, res){});
app.put('/users', function(req, res){});
request(app)
.options('/users')
.end(function(res){
res.body.should.equal('GET');
res.headers.should.have.property('allow', 'GET');
done();
});
var app = express();
app.param(function(name, regexp){
if (regexp instanceof RegExp) {
return function(req, res, next, val){
var captures;
if (captures = regexp.exec(String(val))) {
req.params[name] = captures[1];
next();
} else {
next('route');
}
}
}
})
app.param(':name', /^([a-zA-Z]+)$/);
app.get('/user/:name', function(req, res){
res.send(req.params.name);
});
request(app)
.get('/user/tj')
.end(function(res){
res.body.should.equal('tj');
request(app)
.get('/user/123')
.end(function(res){
res.should.have.status(404);
done();
});
});
var app = express();
app.param(['id', 'uid'], function(req, res, next, id){
id = Number(id);
if (isNaN(id)) return next('route');
req.params.id = id;
next();
});
app.get('/post/:id', function(req, res){
var id = req.params.id;
id.should.be.a('number');
res.send('' + id);
});
app.get('/user/:uid', function(req, res){
var id = req.params.id;
id.should.be.a('number');
res.send('' + id);
});
request(app)
.get('/user/123')
.end(function(res){
res.body.should.equal('123');
request(app)
.get('/post/123')
.end(function(res){
res.body.should.equal('123');
done();
})
})
var app = express();
app.param('id', function(req, res, next, id){
id = Number(id);
if (isNaN(id)) return next('route');
req.params.id = id;
next();
});
app.get('/user/:id', function(req, res){
var id = req.params.id;
id.should.be.a('number');
res.send('' + id);
});
request(app)
.get('/user/123')
.end(function(res){
res.body.should.equal('123');
done();
})
var app = express();
app.locals.user = { name: 'tobi' };
app.render(__dirname + '/fixtures/user.jade', function(err, str){
if (err) return done(err);
str.should.equal('<p>tobi</p>');
done();
})
should support absolute paths with "view engine".
var app = express();
app.set('view engine', 'jade');
app.locals.user = { name: 'tobi' };
app.render(__dirname + '/fixtures/user', function(err, str){
if (err) return done(err);
str.should.equal('<p>tobi</p>');
done();
})
should expose app.locals.
var app = express();
app.set('views', __dirname + '/fixtures');
app.locals.user = { name: 'tobi' };
app.render('user.jade', function(err, str){
if (err) return done(err);
str.should.equal('<p>tobi</p>');
done();
})
should support index..
var app = express();
app.set('views', __dirname + '/fixtures');
app.set('view engine', 'jade');
app.render('blog/post', function(err, str){
if (err) return done(err);
str.should.equal('<h1>blog post</h1>');
done();
})
var app = express();
app.set('views', __dirname + '/fixtures');
app.render('user.jade', function(err, str){
// nextTick to prevent cyclic
process.nextTick(function(){
err.message.should.match(/user is not defined/);
done();
});
})
var app = express();
app.set('views', __dirname + '/fixtures');
app.render('email.jade', function(err, str){
if (err) return done(err);
str.should.equal('<p>This is an email</p>');
done();
})
var app = express();
app.set('view engine', 'jade');
app.set('views', __dirname + '/fixtures');
app.render('email', function(err, str){
if (err) return done(err);
str.should.equal('<p>This is an email</p>');
done();
})
var app = express();
app.set('views', __dirname + '/fixtures');
var user = { name: 'tobi' };
app.render('user.jade', { user: user }, function(err, str){
if (err) return done(err);
str.should.equal('<p>tobi</p>');
done();
})
should expose app.locals.
var app = express();
app.set('views', __dirname + '/fixtures');
app.locals.user = { name: 'tobi' };
app.render('user.jade', {}, function(err, str){
if (err) return done(err);
str.should.equal('<p>tobi</p>');
done();
})
should give precedence to app.render() locals.
var app = express();
app.set('views', __dirname + '/fixtures');
app.locals.user = { name: 'tobi' };
var jane = { name: 'jane' };
app.render('user.jade', { user: jane }, function(err, str){
if (err) return done(err);
str.should.equal('<p>jane</p>');
done();
})
var app = express();
app.request.querystring = function(){
return require('url').parse(this.url).query;
};
app.use(function(req, res){
res.end(req.querystring());
});
request(app)
.get('/foo?name=tobi')
.end(function(res){
res.body.should.equal('name=tobi');
done();
});
var app = express();
app.response.shout = function(str){
this.send(str.toUpperCase());
};
app.use(function(req, res){
res.shout('hey');
});
request(app)
.get('/')
.end(function(res){
res.body.should.equal('HEY');
done();
});
should not be influenced by other app protos.
var app = express()
, app2 = express();
app.response.shout = function(str){
this.send(str.toUpperCase());
};
app2.response.shout = function(str){
this.send(str);
};
app.use(function(req, res){
res.shout('hey');
});
request(app)
.get('/')
.end(function(res){
res.body.should.equal('HEY');
done();
});
var app = express();
var calls = [];
app.use(function(req, res, next){
calls.push('before');
next();
});
app.use(app.router);
app.use(function(req, res, next){
calls.push('after');
res.end();
});
app.get('/', function(req, res, next){
calls.push('GET /')
next();
});
request(app)
.get('/')
.end(function(res){
calls.should.eql(['before', 'GET /', 'after'])
done();
})
should be auto .use()d on the first app.VERB() call.
var app = express();
var calls = [];
app.use(function(req, res, next){
calls.push('before');
next();
});
app.get('/', function(req, res, next){
calls.push('GET /')
next();
});
app.use(function(req, res, next){
calls.push('after');
res.end();
});
request(app)
.get('/')
.end(function(res){
calls.should.eql(['before', 'GET /', 'after'])
done();
})
should allow escaped regexp.
var app = express();
app.get('/user/\\d+', function(req, res){
res.end('woot');
});
request(app)
.get('/user/10')
.end(function(res){
res.statusCode.should.equal(200);
request(app)
.get('/user/tj')
.expect(404, done);
});
should allow literal ".".
var app = express();
app.get('/api/users/:from..:to', function(req, res){
var from = req.params.from
, to = req.params.to;
res.end('users from ' + from + ' to ' + to);
});
request(app)
.get('/api/users/1..50')
.expect('users from 1 to 50', done);
var app = express();
var calls = [];
app[method]('/foo', function(req, res){
if ('head' == method) {
res.end();
} else {
res.end(method);
}
});
request(app)
[method]('/foo')
.expect('head' == method ? '' : method, done);
should include POST.
var app = express();
var calls = [];
app[method]('/foo', function(req, res){
if ('head' == method) {
res.end();
} else {
res.end(method);
}
});
request(app)
[method]('/foo')
.expect('head' == method ? '' : method, done);
should include PUT.
var app = express();
var calls = [];
app[method]('/foo', function(req, res){
if ('head' == method) {
res.end();
} else {
res.end(method);
}
});
request(app)
[method]('/foo')
.expect('head' == method ? '' : method, done);
should include HEAD.
var app = express();
var calls = [];
app[method]('/foo', function(req, res){
if ('head' == method) {
res.end();
} else {
res.end(method);
}
});
request(app)
[method]('/foo')
.expect('head' == method ? '' : method, done);
should include DELETE.
var app = express();
var calls = [];
app[method]('/foo', function(req, res){
if ('head' == method) {
res.end();
} else {
res.end(method);
}
});
request(app)
[method]('/foo')
.expect('head' == method ? '' : method, done);
should include OPTIONS.
var app = express();
var calls = [];
app[method]('/foo', function(req, res){
if ('head' == method) {
res.end();
} else {
res.end(method);
}
});
request(app)
[method]('/foo')
.expect('head' == method ? '' : method, done);
should include TRACE.
var app = express();
var calls = [];
app[method]('/foo', function(req, res){
if ('head' == method) {
res.end();
} else {
res.end(method);
}
});
request(app)
[method]('/foo')
.expect('head' == method ? '' : method, done);
should include COPY.
var app = express();
var calls = [];
app[method]('/foo', function(req, res){
if ('head' == method) {
res.end();
} else {
res.end(method);
}
});
request(app)
[method]('/foo')
.expect('head' == method ? '' : method, done);
should include LOCK.
var app = express();
var calls = [];
app[method]('/foo', function(req, res){
if ('head' == method) {
res.end();
} else {
res.end(method);
}
});
request(app)
[method]('/foo')
.expect('head' == method ? '' : method, done);
should include MKCOL.
var app = express();
var calls = [];
app[method]('/foo', function(req, res){
if ('head' == method) {
res.end();
} else {
res.end(method);
}
});
request(app)
[method]('/foo')
.expect('head' == method ? '' : method, done);
should include MOVE.
var app = express();
var calls = [];
app[method]('/foo', function(req, res){
if ('head' == method) {
res.end();
} else {
res.end(method);
}
});
request(app)
[method]('/foo')
.expect('head' == method ? '' : method, done);
should include PROPFIND.
var app = express();
var calls = [];
app[method]('/foo', function(req, res){
if ('head' == method) {
res.end();
} else {
res.end(method);
}
});
request(app)
[method]('/foo')
.expect('head' == method ? '' : method, done);
should include PROPPATCH.
var app = express();
var calls = [];
app[method]('/foo', function(req, res){
if ('head' == method) {
res.end();
} else {
res.end(method);
}
});
request(app)
[method]('/foo')
.expect('head' == method ? '' : method, done);
should include UNLOCK.
var app = express();
var calls = [];
app[method]('/foo', function(req, res){
if ('head' == method) {
res.end();
} else {
res.end(method);
}
});
request(app)
[method]('/foo')
.expect('head' == method ? '' : method, done);
should include REPORT.
var app = express();
var calls = [];
app[method]('/foo', function(req, res){
if ('head' == method) {
res.end();
} else {
res.end(method);
}
});
request(app)
[method]('/foo')
.expect('head' == method ? '' : method, done);
should include MKACTIVITY.
var app = express();
var calls = [];
app[method]('/foo', function(req, res){
if ('head' == method) {
res.end();
} else {
res.end(method);
}
});
request(app)
[method]('/foo')
.expect('head' == method ? '' : method, done);
should include CHECKOUT.
var app = express();
var calls = [];
app[method]('/foo', function(req, res){
if ('head' == method) {
res.end();
} else {
res.end(method);
}
});
request(app)
[method]('/foo')
.expect('head' == method ? '' : method, done);
should include MERGE.
var app = express();
var calls = [];
app[method]('/foo', function(req, res){
if ('head' == method) {
res.end();
} else {
res.end(method);
}
});
request(app)
[method]('/foo')
.expect('head' == method ? '' : method, done);
should include M-SEARCH.
var app = express();
var calls = [];
app[method]('/foo', function(req, res){
if ('head' == method) {
res.end();
} else {
res.end(method);
}
});
request(app)
[method]('/foo')
.expect('head' == method ? '' : method, done);
should include NOTIFY.
var app = express();
var calls = [];
app[method]('/foo', function(req, res){
if ('head' == method) {
res.end();
} else {
res.end(method);
}
});
request(app)
[method]('/foo')
.expect('head' == method ? '' : method, done);
should include SUBSCRIBE.
var app = express();
var calls = [];
app[method]('/foo', function(req, res){
if ('head' == method) {
res.end();
} else {
res.end(method);
}
});
request(app)
[method]('/foo')
.expect('head' == method ? '' : method, done);
should include UNSUBSCRIBE.
var app = express();
var calls = [];
app[method]('/foo', function(req, res){
if ('head' == method) {
res.end();
} else {
res.end(method);
}
});
request(app)
[method]('/foo')
.expect('head' == method ? '' : method, done);
should include PATCH.
var app = express();
var calls = [];
app[method]('/foo', function(req, res){
if ('head' == method) {
res.end();
} else {
res.end(method);
}
});
request(app)
[method]('/foo')
.expect('head' == method ? '' : method, done);
var app = express();
app.get(/^\/user\/[0-9]+$/, function(req, res){
res.end('user');
});
request(app)
.get('/user/12?foo=bar')
.expect('user', done);
should populate req.params with the captures.
var app = express();
app.get(/^\/user\/([0-9]+)\/(view|edit)?$/, function(req, res){
var id = req.params.shift()
, op = req.params.shift();
res.end(op + 'ing user ' + id);
});
request(app)
.get('/user/10/edit')
.expect('editing user 10', done);
var app = express();
app.get(['/one', '/two'], function(req, res){
res.end('works');
});
request(app)
.get('/one')
.expect('works', function() {
request(app)
.get('/two')
.expect('works', done);
});
var app = express();
app.get('/user', function(req, res){
res.end('tj');
});
request(app)
.get('/USER')
.expect('tj', done);
var app = express();
app.enable('case sensitive routing');
app.get('/uSer', function(req, res){
res.end('tj');
});
request(app)
.get('/uSer')
.expect('tj', done);
should not match otherwise.
var app = express();
app.enable('case sensitive routing');
app.get('/uSer', function(req, res){
res.end('tj');
});
request(app)
.get('/user')
.expect(404, done);
var app = express();
app.get('/user', function(req, res){
res.end('tj');
});
request(app)
.get('/user/')
.expect('tj', done);
var app = express();
app.enable('strict routing');
app.get('/user/', function(req, res){
res.end('tj');
});
request(app)
.get('/user/')
.expect('tj', done);
should match no slashes.
var app = express();
app.enable('strict routing');
app.get('/user', function(req, res){
res.end('tj');
});
request(app)
.get('/user')
.expect('tj', done);
should fail when omitting the trailing slash.
var app = express();
app.enable('strict routing');
app.get('/user/', function(req, res){
res.end('tj');
});
request(app)
.get('/user')
.expect(404, done);
should fail when adding the trailing slash.
var app = express();
app.enable('strict routing');
app.get('/user', function(req, res){
res.end('tj');
});
request(app)
.get('/user/')
.expect(404, done);
var app = express();
app.get('/user/*.json', function(req, res){
res.end(req.params[0]);
});
request(app)
.get('/user/tj.json')
.expect('tj', done);
should work with several.
var app = express();
app.get('/api/*.*', function(req, res){
var resource = req.params.shift()
, format = req.params.shift();
res.end(resource + ' as ' + format);
});
request(app)
.get('/api/users/0.json')
.expect('users/0 as json', done);
should allow naming.
var app = express();
app.get('/api/:resource(*)', function(req, res){
var resource = req.params.resource;
res.end(resource);
});
request(app)
.get('/api/users/0.json')
.expect('users/0.json', done);
should span multiple segments.
var app = express();
app.get('/file/*', function(req, res){
res.end(req.params[0]);
});
request(app)
.get('/file/javascripts/jquery.js')
.expect('javascripts/jquery.js', done);
should be optional.
var app = express();
app.get('/file/*', function(req, res){
res.end(req.params[0]);
});
request(app)
.get('/file/')
.expect('', done);
should require a preceeding /.
var app = express();
app.get('/file/*', function(req, res){
res.end(req.params[0]);
});
request(app)
.get('/file')
.expect(404, done);
var app = express();
app.get('/user/:user', function(req, res){
res.end(req.params.user);
});
request(app)
.get('/user/tj')
.expect('tj', done);
should match a single segment only.
var app = express();
app.get('/user/:user', function(req, res){
res.end(req.params.user);
});
request(app)
.get('/user/tj/edit')
.expect(404, done);
should allow several capture groups.
var app = express();
app.get('/user/:user/:op', function(req, res){
res.end(req.params.op + 'ing ' + req.params.user);
});
request(app)
.get('/user/tj/edit')
.expect('editing tj', done);
var app = express();
app.get('/user/:user/:op?', function(req, res){
var op = req.params.op || 'view';
res.end(op + 'ing ' + req.params.user);
});
request(app)
.get('/user/tj')
.expect('viewing tj', done);
should populate the capture group.
var app = express();
app.get('/user/:user/:op?', function(req, res){
var op = req.params.op || 'view';
res.end(op + 'ing ' + req.params.user);
});
request(app)
.get('/user/tj/edit')
.expect('editing tj', done);
var app = express();
app.get('/:name.:format', function(req, res){
res.end(req.params.name + ' as ' + req.params.format);
});
request(app)
.get('/foo.json')
.expect('foo as json', function(){
request(app)
.get('/foo')
.expect(404, done);
});
var app = express();
app.get('/:name.:format?', function(req, res){
res.end(req.params.name + ' as ' + (req.params.format || 'html'));
});
request(app)
.get('/foo')
.expect('foo as html', function(){
request(app)
.get('/foo.json')
.expect('foo as json', done);
});
var app = express()
, calls = [];
app.get('/foo/:bar?', function(req, res, next){
calls.push('/foo/:bar?');
next();
});
app.get('/bar', function(req, res){
assert(0);
});
app.get('/foo', function(req, res, next){
calls.push('/foo');
next();
});
app.get('/foo', function(req, res, next){
calls.push('/foo 2');
res.end('done');
});
request(app)
.get('/foo')
.expect('done', function(){
calls.should.eql(['/foo/:bar?', '/foo', '/foo 2']);
done();
})
var app = express()
, calls = [];
app.get('/foo/:bar?', function(req, res, next){
calls.push('/foo/:bar?');
next();
});
app.get('/bar', function(req, res){
assert(0);
});
app.get('/foo', function(req, res, next){
calls.push('/foo');
next(new Error('fail'));
});
app.get('/foo', function(req, res, next){
assert(0);
});
app.use(function(err, req, res, next){
res.end(err.message);
})
request(app)
.get('/foo')
.expect('fail', function(){
calls.should.eql(['/foo/:bar?', '/foo']);
done();
})
var blog = express()
, app = express();
blog.on('mount', function(arg){
arg.should.equal(app);
done();
});
app.use(blog);
var blog = express()
, app = express();
blog.get('/blog', function(req, res){
res.end('blog');
});
app.use(blog);
request(app)
.get('/blog')
.expect('blog', done);
should support mount-points.
var blog = express()
, forum = express()
, app = express();
blog.get('/', function(req, res){
res.end('blog');
});
forum.get('/', function(req, res){
res.end('forum');
});
app.use('/blog', blog);
app.use('/forum', forum);
request(app)
.get('/blog')
.expect('blog', function(){
request(app)
.get('/forum')
.expect('forum', done);
});
should set the child's .parent.
var blog = express()
, app = express();
app.use('/blog', blog);
blog.parent.should.equal(app);
var app = express();
var calls = [];
app.configure(function(){
calls.push('all');
});
app.configure('test', function(){
calls.push('test');
});
app.configure(function(){
calls.push('all 2');
});
app.configure('test', function(){
calls.push('test 2');
});
calls.should.eql(['all', 'test', 'all 2', 'test 2'])
var app = express();
var calls = [];
app.configure(function(){
calls.push('all');
});
app.configure('test', function(){
calls.push('test');
});
app.configure('test', function(){
calls.push('test 2');
});
calls.should.eql(['all', 'test', 'test 2'])
var app = express();
var calls = [];
app.set('env', 'development');
app.configure('development', function(){
calls.push('dev');
});
app.configure('test', function(){
calls.push('test');
});
calls.should.eql(['dev']);
var app = express();
var calls = [];
app.set('env', 'development');
app.configure('development', function(){
calls.push('dev');
});
app.configure('test', 'development', function(){
calls.push('dev 2');
});
app.configure('development', 'test', function(){
calls.push('dev 3');
});
app.configure('test', function(){
calls.push('dev 3');
});
calls.should.eql(['dev', 'dev 2', 'dev 3']);
var app = express();
app.set('foo', 'bar').should.equal(app);
should return the app when undefined.
var app = express();
app.set('foo', undefined).should.equal(app);
var app = express();
assert(undefined === app.get('foo'));
should otherwise return the value.
var app = express();
app.set('foo', 'bar');
app.get('foo').should.equal('bar');
var app = express()
, blog = express();
app.set('title', 'Express');
app.use(blog);
blog.get('title').should.equal('Express');
should given precedence to the child.
var app = express()
, blog = express();
app.use(blog);
app.set('title', 'Express');
blog.set('title', 'Some Blog');
blog.get('title').should.equal('Some Blog');
var app = express();
app.enable('tobi').should.equal(app);
app.get('tobi').should.be.true;
var app = express();
app.disable('tobi').should.equal(app);
app.get('tobi').should.be.false;
var app = express();
app.enabled('foo').should.be.false;
should return true when set.
var app = express();
app.set('foo', 'bar');
app.enabled('foo').should.be.true;
var app = express();
app.disabled('foo').should.be.true;
should return false when set.
var app = express();
app.set('foo', 'bar');
app.disabled('foo').should.be.false;
express.should.have.property('version');
should expose connect middleware.
express.should.have.property('bodyParser');
express.should.have.property('session');
express.should.have.property('static');
should expose HTTP methods.
express.methods.should.be.an.instanceof(Array);
express.methods.should.include('get');
express.methods.should.include('put');
express.methods.should.include('post');
should expose Router.
express.Router.should.be.a('function');
should expose the application prototype.
express.application.set.should.be.a('function');
should expose the request prototype.
express.request.accepts.should.be.a('function');
should expose the response prototype.
express.response.send.should.be.a('function');
should permit modifying the .application prototype.
express.application.foo = function(){ return 'bar'; };
express().foo().should.equal('bar');
should permit modifying the .request prototype.
express.request.foo = function(){ return 'bar'; };
var app = express();
app.use(function(req, res, next){
res.end(req.foo());
});
request(app)
.get('/')
.expect('bar', done);
should permit modifying the .response prototype.
express.response.foo = function(){ this.send('bar'); };
var app = express();
app.use(function(req, res, next){
res.foo();
});
request(app)
.get('/')
.expect('bar', done);
var app = express();
app.get('/', function(req, res){
res.end('yay');
throw new Error('boom');
});
request(app)
.get('/')
.end(function(res){
res.should.have.status(200);
res.body.should.equal('yay');
done();
});
var app = express();
app.use(function(req, res){
req.accepted[0].value.should.equal('application/json');
req.accepted[1].value.should.equal('text/html');
res.end();
});
request(app)
.get('/')
.set('Accept', 'text/html;q=.5, application/json')
.expect(200, done);
var app = express();
app.use(function(req, res){
req.accepted.should.have.length(0);
res.end();
});
request(app)
.get('/')
.expect(200, done);
var app = express();
app.use(function(req, res){
req.acceptedCharsets[0].should.equal('unicode-1-1');
req.acceptedCharsets[1].should.equal('iso-8859-5');
res.end();
});
request(app)
.get('/')
.set('Accept-Charset', 'iso-8859-5;q=.2, unicode-1-1;q=0.8')
.expect(200, done);
var app = express();
app.use(function(req, res){
req.acceptedCharsets.should.have.length(0);
res.end();
});
request(app)
.get('/')
.expect(200, done);
var app = express();
app.use(function(req, res){
req.acceptedLanguages[0].should.equal('en-us');
req.acceptedLanguages[1].should.equal('en');
res.end();
});
request(app)
.get('/')
.set('Accept-Language', 'en;q=.5, en-us')
.expect(200, done);
var app = express();
app.use(function(req, res){
req.acceptedLanguages.should.have.length(0);
res.end();
});
request(app)
.get('/')
.expect(200, done);
var app = express();
app.use(function(req, res, next){
res.end(req.accepts('json') ? 'yes' : 'no');
});
request(app)
.get('/')
.expect('yes', done);
should return true when present.
var app = express();
app.use(function(req, res, next){
res.end(req.accepts('json') ? 'yes' : 'no');
});
request(app)
.get('/')
.set('Accept', 'application/json')
.expect('yes', done);
should return false otherwise.
var app = express();
app.use(function(req, res, next){
res.end(req.accepts('json') ? 'yes' : 'no');
});
request(app)
.get('/')
.set('Accept', 'text/html')
.expect('no', done);
var app = express();
app.use(function(req, res, next){
res.end(req.acceptsCharset('utf-8') ? 'yes' : 'no');
});
request(app)
.get('/')
.expect('yes', done);
var app = express();
app.use(function(req, res, next){
res.end(req.acceptsCharset('utf-8') ? 'yes' : 'no');
});
request(app)
.get('/')
.set('Accept-Charset', 'foo, bar, utf-8')
.expect('yes', done);
should return false otherwise.
var app = express();
app.use(function(req, res, next){
res.end(req.acceptsCharset('utf-8') ? 'yes' : 'no');
});
request(app)
.get('/')
.set('Accept-Charset', 'foo, bar')
.expect('no', done);
var app = express();
app.use(express.cookieParser());
app.use(function(req, res){
res.end(req.cookies.name + ' ' + req.cookies.species);
});
request(app)
.get('/')
.set('Cookie', 'name=tobi; species=ferret')
.end(function(res){
res.body.should.equal('tobi ferret');
done();
})
should parse JSON cookies.
var app = express();
app.use(express.cookieParser());
app.use(function(req, res){
res.end(req.cookies.user.name);
});
request(app)
.get('/')
.set('Cookie', 'user=j%3A%7B%22name%22%3A%22tobi%22%7D')
.end(function(res){
res.body.should.equal('tobi');
done();
})
var app = express();
app.use(function(req, res){
res.set('ETag', '12345');
res.send(req.fresh);
});
request(app)
.get('/')
.set('If-None-Match', '12345')
.end(function(res){
res.body.should.equal('true');
done();
});
should return false when the resource is modified.
var app = express();
app.use(function(req, res){
res.set('ETag', '123');
res.send(req.fresh);
});
request(app)
.get('/')
.set('If-None-Match', '12345')
.end(function(res){
res.body.should.equal('false');
done();
});
var app = express();
app.use(function(req, res){
res.end(req.get('Content-Type'));
});
request(app)
.post('/')
.set('Content-Type', 'application/json')
.end(function(res){
res.body.should.equal('application/json');
done();
});
should special-case Referer.
var app = express();
app.use(function(req, res){
res.end(req.get('Referer'));
});
request(app)
.post('/')
.set('Referrer', 'http://foobar.com')
.end(function(res){
res.body.should.equal('http://foobar.com');
done();
});
req('application/json; charset=utf-8')
.is('json')
.should.be.true;
req('')
.is('json')
.should.be.false;
req('application/json')
.is('json')
.should.be.true;
req('text/html')
.is('json')
.should.be.false;
req('application/json')
.is('application/json')
.should.be.true;
req('image/jpeg')
.is('application/json')
.should.be.false;
req('application/json')
.is('*/json')
.should.be.true;
req('image/jpeg')
.is('*/json')
.should.be.false;
req('text/html; charset=utf-8')
.is('*/html')
.should.be.true;
req('text/plain; charset=utf-8')
.is('*/html')
.should.be.false;
req('image/png')
.is('image/*')
.should.be.true;
req('text/html')
.is('image/*')
.should.be.false;
req('text/html; charset=utf-8')
.is('text/*')
.should.be.true;
req('something/html; charset=utf-8')
.is('text/*')
.should.be.false;
var app = express();
app.use(function(req, res){
res.end(req.param('name', 'tj'));
});
request(app)
.get('/')
.end(function(res){
res.body.should.equal('tj');
done();
})
var app = express();
app.use(function(req, res){
res.end(req.param('name'));
});
request(app)
.get('/?name=tj')
.end(function(res){
res.body.should.equal('tj');
done();
})
should check req.body.
var app = express();
app.use(express.bodyParser());
app.use(function(req, res){
res.end(req.param('name'));
});
request(app)
.post('/')
.set('Content-Type', 'application/json')
.write('{"name":"tj"}')
.end(function(res){
res.body.should.equal('tj');
done();
})
should check req.params.
var app = express();
app.get('/user/:name', function(req, res){
res.end(req.param('name'));
});
request(app)
.get('/user/tj')
.end(function(res){
res.body.should.equal('tj');
done();
})
var app = express();
app.use(function(req, res){
res.end(req.path);
});
request(app)
.get('/login?redirect=/post/1/comments')
.end(function(res){
res.body.should.equal('/login');
done();
})
var app = express();
app.use(function(req, res){
res.end(req.protocol);
});
request(app)
.get('/')
.end(function(res){
res.body.should.equal('http');
done();
})
var app = express();
app.enable('trust proxy');
app.use(function(req, res){
res.end(req.protocol);
});
request(app)
.get('/')
.set('X-Forwarded-Proto', 'https')
.end(function(res){
res.body.should.equal('https');
done();
})
should default to http.
var app = express();
app.enable('trust proxy');
app.use(function(req, res){
res.end(req.protocol);
});
request(app)
.get('/')
.end(function(res){
res.body.should.equal('http');
done();
})
var app = express();
app.use(function(req, res){
res.end(req.protocol);
});
request(app)
.get('/')
.set('X-Forwarded-Proto', 'https')
.end(function(res){
res.body.should.equal('http');
done();
})
var app = express();
app.use(function(req, res){
req.query.should.eql({});
res.end();
});
request(app)
.get('/')
.end(function(res){
done();
});
should contain the parsed query-string.
var app = express();
app.use(function(req, res){
req.query.should.eql({ user: { name: 'tj' }});
res.end();
});
request(app)
.get('/?user[name]=tj')
.end(function(res){
done();
});
var app = express();
app.get('/user/:id/:op?', function(req, res, next){
req.route.method.should.equal('get');
req.route.path.should.equal('/user/:id/:op?');
next();
});
app.get('/user/:id/edit', function(req, res){
req.route.method.should.equal('get');
req.route.path.should.equal('/user/:id/edit');
res.end();
});
request(app)
.get('/user/12/edit')
.expect(200, done);
var app = express();
app.use(express.cookieParser('foo bar baz'));
app.use(function(req, res){
req.cookies.should.not.have.property('name');
res.end(req.signedCookies.name);
});
request(app)
.get('/')
.set('Cookie', 'name=tobi.2HDdGQqJ6jQU1S9dagggYDPaxGE')
.end(function(res){
res.body.should.equal('tobi');
done();
})
should parse JSON cookies.
var app = express();
app.use(express.cookieParser('foo bar baz'));
app.use(function(req, res){
req.cookies.should.not.have.property('user');
res.end(req.signedCookies.user.name);
});
request(app)
.get('/')
.set('Cookie', 'user=j%3A%7B%22name%22%3A%22tobi%22%7D.aEbp4PGZo63zMX%2FcIMSn2M9pvms')
.end(function(res){
res.body.should.equal('tobi');
done();
})
var app = express();
app.use(express.cookieParser('foo bar baz'));
app.use(function(req, res){
req.signedCookies.should.not.have.property('name');
res.end(req.cookies.name);
});
request(app)
.get('/')
.set('Cookie', 'name=tobi.2HDdGQqJ6jQU1S9dagasdfasdf')
.end(function(res){
res.body.should.equal('tobi.2HDdGQqJ6jQU1S9dagasdfasdf');
done();
})
var app = express();
app.use(function(req, res){
res.set('ETag', '12345');
res.send(req.stale);
});
request(app)
.get('/')
.set('If-None-Match', '12345')
.end(function(res){
res.body.should.equal('false');
done();
});
should return true when the resource is modified.
var app = express();
app.use(function(req, res){
res.set('ETag', '123');
res.send(req.stale);
});
request(app)
.get('/')
.set('If-None-Match', '12345')
.end(function(res){
res.body.should.equal('true');
done();
});
var app = express();
app.use(function(req, res){
res.send(req.subdomains);
});
request(app)
.get('/')
.set('Host', 'tobi.ferrets.example.com')
.end(function(res){
res.body.should.equal('["ferrets","tobi"]');
done();
})
var app = express();
app.use(function(req, res){
res.send(req.subdomains);
});
request(app)
.get('/')
.set('Host', 'example.com')
.end(function(res){
res.body.should.equal('[]');
done();
})
var app = express();
app.use(function(req, res){
req.xhr.should.be.true;
res.end();
});
request(app)
.get('/')
.set('X-Requested-With', 'xmlhttprequest')
.end(function(res){
done();
})
should case-insensitive.
var app = express();
app.use(function(req, res){
req.xhr.should.be.true;
res.end();
});
request(app)
.get('/')
.set('X-Requested-With', 'XMLHttpRequest')
.end(function(res){
done();
})
should return false otherwise.
var app = express();
app.use(function(req, res){
req.xhr.should.be.false;
res.end();
});
request(app)
.get('/')
.set('X-Requested-With', 'blahblah')
.end(function(res){
done();
})
should return false when not present.
var app = express();
app.use(function(req, res){
req.xhr.should.be.false;
res.end();
});
request(app)
.get('/')
.end(function(res){
done();
})
var app = express();
app.use(function(req, res){
res.attachment().send('foo');
});
request(app)
.get('/')
.end(function(res){
res.headers.should.have.property('content-disposition', 'attachment');
done();
})
var app = express();
app.use(function(req, res){
res.attachment('/path/to/image.png');
res.send('foo');
});
request(app)
.get('/')
.end(function(res){
res.headers.should.have.property('content-disposition', 'attachment; filename="image.png"');
done();
})
should set the Content-Type.
var app = express();
app.use(function(req, res){
res.attachment('/path/to/image.png');
res.send('foo');
});
request(app)
.get('/')
.end(function(res){
res.headers.should.have.property('content-type', 'image/png');
done();
})
var app = express();
app.use(function(req, res){
res.cache('public').end('whoop');
});
request(app)
.get('/')
.end(function(res){
res.headers['cache-control'].should.equal('public');
res.body.should.equal('whoop');
done();
})
var app = express();
app.use(function(req, res){
res.cache('private', { maxAge: 60 * 1000 }).end();
});
request(app)
.get('/')
.end(function(res){
res.headers['cache-control'].should.equal('private, max-age=60');
done();
})
var app = express();
app.use(function(req, res){
res.charset = 'utf-8';
res.set('Content-Type', 'text/x-foo');
res.end(res.get('Content-Type'));
});
request(app)
.get('/')
.end(function(res){
res.body.should.equal('text/x-foo; charset=utf-8');
done();
})
should take precedence over res.send() defaults.
var app = express();
app.use(function(req, res){
res.charset = 'whoop';
res.send('hey');
});
request(app)
.get('/')
.end(function(res){
res.headers.should.have.property('content-type', 'text/html; charset=whoop');
done();
})
var app = express();
app.use(function(req, res){
res.clearCookie('sid').end();
});
request(app)
.get('/')
.end(function(res){
var val = 'sid=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT';
res.headers['set-cookie'].should.eql([val]);
done();
})
var app = express();
app.use(function(req, res){
res.clearCookie('sid', { path: '/admin' }).end();
});
request(app)
.get('/')
.end(function(res){
var val = 'sid=; path=/admin; expires=Thu, 01 Jan 1970 00:00:00 GMT';
res.headers['set-cookie'].should.eql([val]);
done();
})
var app = express();
app.use(function(req, res){
res.cookie('user', { name: 'tobi' }).end();
});
request(app)
.get('/')
.end(function(res){
var val = ['user=j%3A%7B%22name%22%3A%22tobi%22%7D; path=/'];
res.headers['set-cookie'].should.eql(val);
done();
})
var app = express();
app.use(function(req, res){
res.cookie('name', 'tobi').end();
});
request(app)
.get('/')
.end(function(res){
var val = ['name=tobi; path=/'];
res.headers['set-cookie'].should.eql(val);
done();
})
should allow multiple calls.
var app = express();
app.use(function(req, res){
res.cookie('name', 'tobi');
res.cookie('age', 1);
res.end();
});
request(app)
.get('/')
.end(function(res){
var val = ['name=tobi; path=/', 'age=1; path=/'];
res.headers['set-cookie'].should.eql(val);
done();
})
var app = express();
app.use(function(req, res){
res.cookie('name', 'tobi', { httpOnly: true, secure: true });
res.end();
});
request(app)
.get('/')
.end(function(res){
var val = ['name=tobi; path=/; httpOnly; secure'];
res.headers['set-cookie'].should.eql(val);
done();
})
var app = express();
app.use(function(req, res){
res.cookie('name', 'tobi', { maxAge: 1000 });
res.end();
});
request(app)
.get('/')
.end(function(res){
res.headers['set-cookie'][0].should.not.include('Thu, 01 Jan 1970 00:00:01 GMT');
done();
})
request(app)
.get('/')
.set('Accept', 'text/html; q=.5, application/json, */*; q=.1')
.expect('{"message":"hey"}', done);
should allow wildcard type/subtypes.
request(app)
.get('/')
.set('Accept', 'text/html; q=.5, application/*, */*; q=.1')
.expect('{"message":"hey"}', done);
should default the Content-Type.
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();
});
request(app)
.get('/')
.expect('hey', done);
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();
});
request(app)
.get('/')
.set('Accept', 'text/html; q=.5, application/json, */*; q=.1')
.expect('{"message":"hey"}', done);
should allow wildcard type/subtypes.
request(app)
.get('/')
.set('Accept', 'text/html; q=.5, application/*, */*; q=.1')
.expect('{"message":"hey"}', done);
should default the Content-Type.
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();
});
request(app)
.get('/')
.expect('hey', done);
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();
});
var app = express();
app.use(function(req, res){
res.setHeader('Content-Type', 'text/x-foo');
res.end(res.get('Content-Type'));
});
request(app)
.get('/')
.end(function(res){
res.body.should.equal('text/x-foo');
done();
})
var app = express();
app.use(function(req, res){
res.json(null);
});
request(app)
.get('/')
.end(function(res){
res.headers.should.have.property('content-type', 'application/json; charset=utf-8');
res.body.should.equal('null');
done();
})
var app = express();
app.use(function(req, res){
res.json({ name: 'tobi' });
});
request(app)
.get('/')
.end(function(res){
res.headers.should.have.property('content-type', 'application/json; charset=utf-8');
res.body.should.equal('{"name":"tobi"}');
done();
})
var app = express();
app.set('json replacer', function(key, val){
return '_' == key[0]
? undefined
: val;
});
app.use(function(req, res){
res.json({ name: 'tobi', _id: 12345 });
});
request(app)
.get('/')
.end(function(res){
res.body.should.equal('{"name":"tobi"}');
done();
});
process.env.NODE_ENV = 'development';
var app = express();
app.get('json spaces').should.equal(2);
process.env.NODE_ENV = 'test';
should be undefined otherwise.
var app = express();
assert(undefined === app.get('json spaces'));
should be passed to JSON.stringify().
var app = express();
app.set('json spaces', 2);
app.use(function(req, res){
res.json({ name: 'tobi', age: 2 });
});
request(app)
.get('/')
.end(function(res){
res.body.should.equal('{\n "name": "tobi",\n "age": 2\n}');
done();
});
var app = express();
app.use(function(req, res){
res.json(201, { id: 1 });
});
request(app)
.get('/')
.end(function(res){
res.statusCode.should.equal(201);
res.headers.should.have.property('content-type', 'application/json; charset=utf-8');
res.body.should.equal('{"id":1}');
done();
})
var app = express();
app.use(function(req, res){
Object.keys(res.locals).should.eql([]);
res.locals({ user: 'tobi', age: 1 });
res.locals.user.should.equal('tobi');
res.locals.age.should.equal(1);
res.end();
});
request(app)
.get('/')
.end(function(res){
done();
})
var app = express();
app.enable('trust proxy');
app.use(function(req, res){
res.redirect('/login');
});
request(app)
.get('/')
.set('Host', 'example.com')
.set('X-Forwarded-Proto', 'https')
.end(function(res){
res.statusCode.should.equal(302);
res.headers.should.have.property('location', 'https://example.com/login');
done();
})
should default to a 302 redirect.
var app = express();
app.use(function(req, res){
res.redirect('http://google.com');
});
request(app)
.get('/')
.end(function(res){
res.statusCode.should.equal(302);
res.headers.should.have.property('location', 'http://google.com');
done();
})
var app = express();
app.use(function(req, res){
res.redirect('/login');
});
request(app)
.get('/')
.set('Host', 'example.com')
.end(function(res){
res.headers.should.have.property('location', 'http://example.com/login');
done();
})
var app = express();
app.use(function(req, res){
res.redirect('./edit');
});
request(app)
.get('/post/1')
.set('Host', 'example.com')
.end(function(res){
res.headers.should.have.property('location', 'http://example.com/post/1/./edit');
done();
})
var app = express();
app.use(function(req, res){
res.redirect('../new');
});
request(app)
.get('/post/1')
.set('Host', 'example.com')
.end(function(res){
res.headers.should.have.property('location', 'http://example.com/post/1/../new');
done();
})
var app = express();
app.use(function(req, res){
res.redirect('login');
});
request(app)
.get('/')
.set('Host', 'example.com')
.end(function(res){
res.headers.should.have.property('location', 'http://example.com/login');
done();
})
var app = express()
, blog = express()
, admin = express();
admin.use(function(req, res){
res.redirect('login');
});
app.use('/blog', blog);
blog.use('/admin', admin);
request(app)
.get('/blog/admin')
.set('Host', 'example.com')
.end(function(res){
res.headers.should.have.property('location', 'http://example.com/blog/admin/login');
done();
})
var app = express()
, admin = express();
admin.use(function(req, res){
res.redirect('admin/login');
});
app.use('/blog', admin);
request(app)
.get('/blog')
.set('Host', 'example.com')
.end(function(res){
res.headers.should.have.property('location', 'http://example.com/blog/admin/login');
done();
})
var app = express()
, admin = express();
admin.use(function(req, res){
res.redirect('/admin/login');
});
app.use('/blog', admin);
request(app)
.get('/blog')
.set('Host', 'example.com')
.end(function(res){
res.headers.should.have.property('location', 'http://example.com/admin/login');
done();
})
var app = express();
app.use(function(req, res){
res.redirect(303, 'http://google.com');
});
request(app)
.get('/')
.end(function(res){
res.statusCode.should.equal(303);
res.headers.should.have.property('location', 'http://google.com');
done();
})
var app = express();
app.use(function(req, res){
res.redirect('http://google.com');
});
request(app)
.head('/')
.end(function(res){
res.headers.should.have.property('location', 'http://google.com');
res.body.should.equal('');
done();
})
var app = express();
app.use(function(req, res){
res.redirect('http://google.com');
});
request(app)
.get('/')
.set('Accept', 'text/html')
.end(function(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>');
done();
})
var app = express();
app.use(function(req, res){
res.redirect('http://google.com');
});
request(app)
.get('/')
.set('Accept', 'text/plain, */*')
.end(function(res){
res.headers.should.have.property('location', 'http://google.com');
res.body.should.equal('Moved Temporarily. Redirecting to http://google.com');
done();
})
var app = express();
app.locals.user = { name: 'tobi' };
app.use(function(req, res){
res.render(__dirname + '/fixtures/user.jade');
});
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>tobi</p>');
done();
});
should support absolute paths with "view engine".
var app = express();
app.locals.user = { name: 'tobi' };
app.set('view engine', 'jade');
app.use(function(req, res){
res.render(__dirname + '/fixtures/user');
});
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>tobi</p>');
done();
});
should expose app.locals.
var app = express();
app.set('views', __dirname + '/fixtures');
app.locals.user = { name: 'tobi' };
app.use(function(req, res){
res.render('user.jade');
});
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>tobi</p>');
done();
});
should support index..
var app = express();
app.set('views', __dirname + '/fixtures');
app.set('view engine', 'jade');
app.use(function(req, res){
res.render('blog/post');
});
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<h1>blog post</h1>');
done();
});
var app = express();
app.set('views', __dirname + '/fixtures');
app.use(function(req, res){
res.render('user.jade');
});
app.use(function(err, req, res, next){
res.end(err.message);
});
request(app)
.get('/')
.end(function(res){
res.body.should.match(/user is not defined/);
done();
});
var app = express();
app.set('view engine', 'jade');
app.set('views', __dirname + '/fixtures');
app.use(function(req, res){
res.render('email');
});
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>This is an email</p>');
done();
});
var app = express();
app.set('views', __dirname + '/fixtures');
var user = { name: 'tobi' };
app.use(function(req, res){
res.render('user.jade', { user: user });
});
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>tobi</p>');
done();
});
should expose app.locals.
var app = express();
app.set('views', __dirname + '/fixtures');
app.locals.user = { name: 'tobi' };
app.use(function(req, res){
res.render('user.jade', {});
});
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>tobi</p>');
done();
});
should expose res.locals.
var app = express();
app.set('views', __dirname + '/fixtures');
app.use(function(req, res){
res.locals.user = { name: 'tobi' };
res.render('user.jade', {});
});
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>tobi</p>');
done();
});
should give precedence to res.locals over app.locals.
var app = express();
app.set('views', __dirname + '/fixtures');
app.locals.user = { name: 'tobi' };
app.use(function(req, res){
res.locals.user = { name: 'jane' };
res.render('user.jade', {});
});
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>jane</p>');
done();
});
should give precedence to res.render() locals over res.locals.
var app = express();
app.set('views', __dirname + '/fixtures');
var jane = { name: 'jane' };
app.use(function(req, res){
res.locals.user = { name: 'tobi' };
res.render('user.jade', { user: jane });
});
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>jane</p>');
done();
});
should give precedence to res.render() locals over app.locals.
var app = express();
app.set('views', __dirname + '/fixtures');
app.locals.user = { name: 'tobi' };
var jane = { name: 'jane' };
app.use(function(req, res){
res.render('user.jade', { user: jane });
});
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>jane</p>');
done();
});
var app = express();
app.set('views', __dirname + '/fixtures');
app.use(function(req, res){
var tobi = { name: 'tobi' };
res.render('user.jade', { user: tobi }, function(err, html){
html = html.replace('tobi', 'loki');
res.end(html);
});
});
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>loki</p>');
done();
});
var app = express();
app.set('views', __dirname + '/fixtures');
app.use(function(req, res){
res.locals.user = { name: 'tobi' };
res.render('user.jade', function(err, html){
html = html.replace('tobi', 'loki');
res.end(html);
});
});
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>loki</p>');
done();
});
var app = express();
app.set('views', __dirname + '/fixtures');
app.use(function(req, res){
res.render('user.jade', function(err){
res.end(err.message);
});
});
request(app)
.get('/')
.end(function(res){
res.body.should.match(/is not defined/);
done();
});
var app = express();
app.use(function(req, res){
res.send(null);
});
request(app)
.get('/')
.end(function(res){
res.body.should.equal('');
done();
})
var app = express();
app.use(function(req, res){
res.send(undefined);
});
request(app)
.get('/')
.end(function(res){
res.body.should.equal('');
done();
})
var app = express();
app.use(function(req, res){
res.send(201).should.equal(res);
});
request(app)
.get('/')
.end(function(res){
res.body.should.equal('Created');
res.statusCode.should.equal(201);
done();
})
var app = express();
app.use(function(req, res){
res.send(201, 'Created :)');
});
request(app)
.get('/')
.end(function(res){
res.body.should.equal('Created :)');
res.statusCode.should.equal(201);
done();
})
var app = express();
app.use(function(req, res){
res.send('<p>hey</p>');
});
request(app)
.get('/')
.end(function(res){
res.headers.should.have.property('content-type', 'text/html; charset=utf-8');
res.body.should.equal('<p>hey</p>');
res.statusCode.should.equal(200);
done();
})
should not override Content-Type.
var app = express();
app.use(function(req, res){
res.set('Content-Type', 'text/plain').send('hey');
});
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();
})
var app = express();
app.use(function(req, res){
res.send(new Buffer('hello'));
});
request(app)
.get('/')
.end(function(res){
res.headers.should.have.property('content-type', 'application/octet-stream');
res.body.should.equal('hello');
res.statusCode.should.equal(200);
done();
})
should not override Content-Type.
var app = express();
app.use(function(req, res){
res.set('Content-Type', 'text/plain').send(new Buffer('hey'));
});
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();
})
var app = express();
app.use(function(req, res){
res.send({ name: 'tobi' });
});
request(app)
.get('/')
.end(function(res){
res.headers.should.have.property('content-type', 'application/json; charset=utf-8');
res.body.should.equal('{"name":"tobi"}');
done();
})
var app = express();
app.use(function(req, res){
res.send('yay');
});
request(app)
.head('/')
.end(function(res){
res.body.should.equal('');
done();
})
var app = express();
app.use(function(req, res){
res.status(204).send('foo');
});
request(app)
.get('/')
.end(function(res){
res.headers.should.not.have.property('content-type');
res.headers.should.not.have.property('content-length');
res.body.should.equal('');
done();
})
var app = express();
app.use(function(req, res){
res.status(304).send('foo');
});
request(app)
.get('/')
.end(function(res){
res.headers.should.not.have.property('content-type');
res.headers.should.not.have.property('content-length');
res.body.should.equal('');
done();
})
var app = express()
, calls = 0;
app.use(function(req, res){
res.sendfile('test/fixtures/user.html', function(err){
assert(!err);
++calls;
});
});
request(app)
.get('/')
.end(function(res){
calls.should.equal(1);
res.statusCode.should.equal(200);
done();
});
should invoke the callback on 404.
var app = express()
, calls = 0;
app.use(function(req, res){
res.sendfile('test/fixtures/nope.html', function(err){
assert(!res.headerSent);
++calls;
res.send(err.message);
});
});
request(app)
.get('/')
.end(function(res){
calls.should.equal(1);
res.body.should.equal('Not Found');
res.statusCode.should.equal(200);
done();
});
should not override manual content-types.
var app = express();
app.use(function(req, res){
res.contentType('txt');
res.sendfile('test/fixtures/user.html');
});
request(app)
.get('/')
.end(function(res){
res.should.have.header('content-type', 'text/plain');
done();
});
should invoke the callback on 403.
var app = express()
, calls = 0;
app.use(function(req, res){
res.sendfile('test/fixtures/foo/../user.html', function(err){
assert(!res.headerSent);
++calls;
res.send(err.message);
});
});
request(app)
.get('/')
.end(function(res){
res.body.should.equal('Forbidden');
res.statusCode.should.equal(200);
calls.should.equal(1);
done();
});
var app = express();
app.use(function(req, res){
res.sendfile(__dirname + '/fixtures/user.html');
});
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>{{user.name}}</p>');
res.headers.should.have.property('content-type', 'text/html; charset=UTF-8');
done();
});
var app = express();
app.use(function(req, res){
res.sendfile('test/fixtures/user.html');
});
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>{{user.name}}</p>');
res.headers.should.have.property('content-type', 'text/html; charset=UTF-8');
done();
});
should serve relative to "root".
var app = express();
app.use(function(req, res){
res.sendfile('user.html', { root: 'test/fixtures/' });
});
request(app)
.get('/')
.end(function(res){
res.body.should.equal('<p>{{user.name}}</p>');
res.headers.should.have.property('content-type', 'text/html; charset=UTF-8');
done();
});
should consider ../ malicious when "root" is not set.
var app = express();
app.use(function(req, res){
res.sendfile('test/fixtures/foo/../user.html');
});
request(app)
.get('/')
.end(function(res){
res.statusCode.should.equal(403);
done();
});
should allow ../ when "root" is set.
var app = express();
app.use(function(req, res){
res.sendfile('foo/../user.html', { root: 'test/fixtures' });
});
request(app)
.get('/')
.end(function(res){
res.statusCode.should.equal(200);
done();
});
should disallow requesting out of "root".
var app = express();
app.use(function(req, res){
res.sendfile('foo/../../user.html', { root: 'test/fixtures' });
});
request(app)
.get('/')
.end(function(res){
res.statusCode.should.equal(403);
done();
});
should next(404) when not found.
var app = express()
, calls = 0;
app.use(function(req, res){
res.sendfile('user.html');
});
app.use(function(req, res){
assert(0, 'this should not be called');
});
app.use(function(err, req, res, next){
++calls;
next(err);
});
request(app)
.get('/')
.end(function(res){
res.statusCode.should.equal(404);
calls.should.equal(1);
done();
});
var app = express()
, calls = 0;
app.use(function(req, res){
res.sendfile(__dirname + '/fixtures/name.txt');
});
request(app)
.get('/')
.expect('tobi', done);
var app = express();
app.use(function(req, res){
res.set('Content-Type', 'text/x-foo').end();
});
request(app)
.get('/')
.end(function(res){
res.headers.should.have.property('content-type', 'text/x-foo');
done();
})
var app = express();
app.use(function(req, res){
res.set({
'X-Foo': 'bar',
'X-Bar': 'baz'
}).end();
});
request(app)
.get('/')
.end(function(res){
res.headers.should.have.property('x-foo', 'bar');
res.headers.should.have.property('x-bar', 'baz');
done();
})
var app = express();
app.use(express.cookieParser('foo bar baz'));
app.use(function(req, res){
res.signedCookie('user', { name: 'tobi' }).end();
});
request(app)
.get('/')
.end(function(res){
var val = ['user=j%3A%7B%22name%22%3A%22tobi%22%7D.aEbp4PGZo63zMX%2FcIMSn2M9pvms; path=/'];
res.headers['set-cookie'].should.eql(val);
done();
})
var app = express();
app.use(express.cookieParser('foo bar baz'));
app.use(function(req, res){
res.signedCookie('name', 'tobi').end();
});
request(app)
.get('/')
.end(function(res){
var val = ['name=tobi.2HDdGQqJ6jQU1S9dagggYDPaxGE; path=/'];
res.headers['set-cookie'].should.eql(val);
done();
})
var app = express();
app.use(function(req, res){
res.status(201).end('Created');
});
request(app)
.get('/')
.end(function(res){
res.body.should.equal('Created');
res.statusCode.should.equal(201);
done();
})
var app = express();
app.use(function(req, res){
res.type('foo.js').end('var name = "tj";');
});
request(app)
.get('/')
.end(function(res){
res.headers.should.have.property('content-type', 'application/javascript');
done();
})
router.route('get', '/foo', function(){});
router.route('get', '/foob?', function(){});
router.route('get', '/bar', function(){});
var req = { method: 'GET', url: '/foo?bar=baz' };
var route = router.match(req, 0);
route.constructor.name.should.equal('Route');
route.method.should.equal('get');
route.path.should.equal('/foo');
var route = router.match(req, 1);
req._route_index.should.equal(1);
route.path.should.equal('/foob?');
var route = router.match(req, 2);
assert(!route);
req.url = '/bar';
var route = router.match(req);
route.path.should.equal('/bar');
router.route('get', '/foo', function(req, res){
res.send('foo');
});
app.use(router.middleware);
request(app)
.get('/foo')
.expect('foo', done);
assert(utils.isAbsolute('c:\\'));
assert(!utils.isAbsolute(':\\'));
should unices.
assert(utils.isAbsolute('/foo/bar'));
assert(!utils.isAbsolute('foo/bar'));
var arr = ['one', ['two', ['three', 'four'], 'five']];
utils.flatten(arr)
.should.eql(['one', 'two', 'three', 'four', 'five']);
utils.escape('<script>foo & "bar"')
.should.equal('<script>foo & "bar"')
utils.parseQuality('text/html')
.should.eql([{ value: 'text/html', quality: 1 }]);
should parse qvalues.
utils.parseQuality('text/html; q=0.5')
.should.eql([{ value: 'text/html', quality: 0.5 }]);
utils.parseQuality('text/html; q=.2')
.should.eql([{ value: 'text/html', quality: 0.2 }]);
should work with messed up whitespace.
utils.parseQuality('text/html ; q = .2')
.should.eql([{ value: 'text/html', quality: 0.2 }]);
should work with multiples.
var str = 'da, en;q=.5, en-gb;q=.8';
var arr = utils.parseQuality(str);
arr[0].value.should.equal('da');
arr[1].value.should.equal('en-gb');
arr[2].value.should.equal('en');
should sort by quality.
var str = 'text/plain;q=.2, application/json, text/html;q=0.5';
var arr = utils.parseQuality(str);
arr[0].value.should.equal('application/json');
arr[1].value.should.equal('text/html');
arr[2].value.should.equal('text/plain');
should exclude those with a quality of 0.
var str = 'text/plain;q=.2, application/json, text/html;q=0';
var arr = utils.parseQuality(str);
arr.should.have.length(2);
var arr = utils.parseAccept('text/html');
arr[0].type.should.equal('text');
should provide .subtype.
var arr = utils.parseAccept('text/html');
arr[0].subtype.should.equal('html');
utils.accepts('text/html')
.should.be.true;
utils.accepts('text/html', '')
.should.be.true;
utils.accepts('text/html', 'text/plain, */*')
.should.be.true;
utils.accepts('text/html', 'text/plain, text/html')
.should.be.true;
should return false otherwise.
utils.accepts('text/html', 'text/plain, application/json')
.should.be.false;
utils.accepts('text/html', 'text/*')
.should.be.true;
should return false otherwise.
utils.accepts('text/html', 'image/*')
.should.be.false;
utils.accepts('text/html', '*/html')
.should.be.true;
should return false otherwise.
utils.accepts('text/html', '*/json')
.should.be.false;
utils.accepts('html', 'text/html, application/json')
.should.be.true;
should return false otherwise.
utils.accepts('html', 'text/plain, application/json')
.should.be.false;
should support *.
utils.accepts('html', 'text/*')
.should.be.true;
utils.accepts('html', '*/html')
.should.be.true;