mirror of
https://github.com/expressjs/express.git
synced 2026-02-26 18:57:43 +00:00
Compare commits
33 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0dc5836d5e | ||
|
|
8751d7ecf8 | ||
|
|
c21226aa7c | ||
|
|
3e358458f4 | ||
|
|
766b3aecf7 | ||
|
|
8ab96ab80d | ||
|
|
1f2e00ef8d | ||
|
|
b49453cf0d | ||
|
|
faffcb889c | ||
|
|
3c0ec59432 | ||
|
|
d4a2843500 | ||
|
|
e7ad49bbbe | ||
|
|
ad9a414fae | ||
|
|
c18c2a8e68 | ||
|
|
1d54868c12 | ||
|
|
f7e73e2da0 | ||
|
|
867728b5ab | ||
|
|
f6bbeafd26 | ||
|
|
f14e39d451 | ||
|
|
084f5d891b | ||
|
|
b0f72e13d9 | ||
|
|
8d7d80ef9d | ||
|
|
cf5de082b5 | ||
|
|
1944451082 | ||
|
|
602e5a8200 | ||
|
|
83b8b7acb7 | ||
|
|
e660f19507 | ||
|
|
ff412b927d | ||
|
|
392ef1eb06 | ||
|
|
dcecdc9be6 | ||
|
|
ed69b68892 | ||
|
|
42b982e13c | ||
|
|
359f12791a |
@@ -8,3 +8,4 @@ matrix:
|
||||
- node_js: "0.11"
|
||||
fast_finish: true
|
||||
script: "npm run-script test-travis"
|
||||
after_script: "npm install coveralls@2.10.0 && cat ./coverage/lcov.info | coveralls"
|
||||
|
||||
39
History.md
39
History.md
@@ -1,3 +1,42 @@
|
||||
3.9.0 / 2014-05-30
|
||||
==================
|
||||
|
||||
* custom etag control with `app.set('etag', val)`
|
||||
- `app.set('etag', function(body, encoding){ return '"etag"' })` custom etag generation
|
||||
- `app.set('etag', 'weak')` weak tag
|
||||
- `app.set('etag', 'strong')` strong etag
|
||||
- `app.set('etag', false)` turn off
|
||||
- `app.set('etag', true)` standard etag
|
||||
* Include ETag in HEAD requests
|
||||
* mark `res.send` ETag as weak and reduce collisions
|
||||
* update connect to 2.18.0
|
||||
- deps: compression@1.0.3
|
||||
- deps: serve-index@1.1.0
|
||||
- deps: serve-static@1.2.0
|
||||
* update send to 0.4.0
|
||||
- Calculate ETag with md5 for reduced collisions
|
||||
- Ignore stream errors after request ends
|
||||
- deps: debug@0.8.1
|
||||
|
||||
3.8.1 / 2014-05-27
|
||||
==================
|
||||
|
||||
* update connect to 2.17.3
|
||||
- deps: body-parser@1.2.2
|
||||
- deps: express-session@1.2.1
|
||||
- deps: method-override@1.0.2
|
||||
|
||||
3.8.0 / 2014-05-21
|
||||
==================
|
||||
|
||||
* keep previous `Content-Type` for `res.jsonp`
|
||||
* set proper `charset` in `Content-Type` for `res.send`
|
||||
* update connect to 2.17.1
|
||||
- fix `res.charset` appending charset when `content-type` has one
|
||||
- deps: express-session@1.2.0
|
||||
- deps: morgan@1.1.1
|
||||
- deps: serve-index@1.0.3
|
||||
|
||||
3.7.0 / 2014-05-18
|
||||
==================
|
||||
|
||||
|
||||
@@ -118,6 +118,7 @@ app.post('/login', function(req, res){
|
||||
});
|
||||
});
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
|
||||
@@ -20,5 +20,8 @@ app.get('/', function(req, res){
|
||||
res.render('pets', { pets: pets });
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
console.log('Express listening on port 3000');
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
|
||||
@@ -37,7 +37,8 @@ function format(path) {
|
||||
|
||||
app.get('/users', format('./users'));
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('listening on port 3000');
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
|
||||
@@ -26,7 +26,8 @@ function count(req, res) {
|
||||
res.send('viewed ' + n + ' times\n');
|
||||
}
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express server listening on port 3000');
|
||||
}
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
|
||||
@@ -15,8 +15,7 @@ var express = require('../../')
|
||||
app.use(express.favicon());
|
||||
|
||||
// custom log format
|
||||
if ('test' != process.env.NODE_ENV)
|
||||
app.use(express.logger(':method :url'));
|
||||
if ('test' != process.env.NODE_ENV) app.use(express.logger(':method :url'));
|
||||
|
||||
// parses request cookies, populating
|
||||
// req.cookies and req.signedCookies
|
||||
@@ -48,7 +47,8 @@ app.post('/', function(req, res){
|
||||
res.redirect('back');
|
||||
});
|
||||
|
||||
if (!module.parent){
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,8 @@ app.use(function(err, req, res, next){
|
||||
}
|
||||
});
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,8 @@ app.get('/', function(req, res){
|
||||
});
|
||||
});
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express app started on port 3000');
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
|
||||
@@ -17,9 +17,7 @@ app.enable('verbose errors');
|
||||
|
||||
// disable them in production
|
||||
// use $ NODE_ENV=production node examples/error-pages
|
||||
if ('production' == app.settings.env) {
|
||||
app.disable('verbose errors');
|
||||
}
|
||||
if ('production' == app.settings.env) app.disable('verbose errors');
|
||||
|
||||
app.use(express.favicon());
|
||||
|
||||
@@ -106,7 +104,8 @@ app.get('/500', function(req, res, next){
|
||||
next(new Error('keyboard cat!'));
|
||||
});
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
silent || console.log('Express started on port 3000');
|
||||
}
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
|
||||
@@ -42,7 +42,8 @@ app.get('/next', function(req, res, next){
|
||||
});
|
||||
});
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,5 +56,8 @@ app.get('/user', function(req, res){
|
||||
res.render('page');
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
console.log('app listening on port 3000');
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
|
||||
@@ -7,5 +7,8 @@ app.get('/', function(req, res){
|
||||
res.send('Hello World');
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
|
||||
@@ -41,5 +41,8 @@ app.get('/', function(req, res){
|
||||
res.render('users', { users: users });
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
console.log('Express app started on port 3000');
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ app.get('/fail', function(req, res){
|
||||
res.render('missing', { title: 'Markdown Example' });
|
||||
})
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
|
||||
@@ -30,7 +30,8 @@ app.post('/', function(req, res, next){
|
||||
, req.body.title));
|
||||
});
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ exports.edit = function(req, res, next){
|
||||
|
||||
exports.update = function(req, res, next){
|
||||
var body = req.body;
|
||||
req.pet.name = body.user.name;
|
||||
req.pet.name = body.pet.name;
|
||||
res.message('Information updated!');
|
||||
res.redirect('/pet/' + req.pet.id);
|
||||
};
|
||||
|
||||
@@ -86,7 +86,8 @@ app.use(function(req, res, next){
|
||||
res.status(404).render('404', { url: req.originalUrl });
|
||||
});
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('\n listening on port 3000\n');
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
|
||||
@@ -50,5 +50,8 @@ app.get('/', function(req, res, next){
|
||||
});
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
console.log('listening on port 3000');
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@ var users = [
|
||||
// Convert :to and :from to integers
|
||||
|
||||
app.param(['to', 'from'], function(req, res, next, num, name){
|
||||
req.params[name] = num = parseInt(num, 10);
|
||||
if( isNaN(num) ){
|
||||
req.params[name] = parseInt(num, 10);
|
||||
if( isNaN(req.params[name]) ){
|
||||
next(new Error('failed to parseInt '+num));
|
||||
} else {
|
||||
next();
|
||||
@@ -64,7 +64,8 @@ app.get('/users/:from-:to', function(req, res, next){
|
||||
res.send('users ' + names.slice(from, to).join(', '));
|
||||
});
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,10 @@ app.resource = function(path, obj) {
|
||||
obj.range(req, res, a, b, format);
|
||||
});
|
||||
this.get(path + '/:id', obj.show);
|
||||
this.delete(path + '/:id', obj.destroy);
|
||||
this.delete(path + '/:id', function(req, res){
|
||||
var id = parseInt(req.params.id, 10);
|
||||
obj.destroy(req, res, id);
|
||||
});
|
||||
};
|
||||
|
||||
// Fake records
|
||||
@@ -41,8 +44,7 @@ var User = {
|
||||
show: function(req, res){
|
||||
res.send(users[req.params.id] || { error: 'Cannot find user' });
|
||||
},
|
||||
destroy: function(req, res){
|
||||
var id = req.params.id;
|
||||
destroy: function(req, res, id){
|
||||
var destroyed = id in users;
|
||||
delete users[id];
|
||||
res.send(destroyed ? 'destroyed' : 'Cannot find user');
|
||||
@@ -85,7 +87,8 @@ app.get('/', function(req, res){
|
||||
].join('\n'));
|
||||
});
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,4 +60,8 @@ app.map({
|
||||
}
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
|
||||
@@ -81,5 +81,8 @@ app.delete('/user/:id', loadUser, andRestrictTo('admin'), function(req, res){
|
||||
res.send('Deleted user ' + req.user.name);
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
console.log('Express app started on port 3000');
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
|
||||
@@ -36,5 +36,8 @@ app.put('/user/:id/edit', user.update);
|
||||
|
||||
app.get('/posts', post.list);
|
||||
|
||||
app.listen(3000);
|
||||
console.log('Express app started on port 3000');
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
|
||||
@@ -57,5 +57,8 @@ app.get('/client.js', function(req, res){
|
||||
res.sendfile(__dirname + '/client.js');
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
console.log('app listening on port 3000');
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
|
||||
@@ -28,5 +28,8 @@ app.get('/', function(req, res){
|
||||
res.send(body + '<p>viewed <strong>' + req.session.views + '</strong> times.</p>');
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
console.log('Express app started on port 3000');
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
|
||||
@@ -42,5 +42,8 @@ var app = express();
|
||||
app.use(express.vhost('*.example.com', redirect)) // Serves all subdomains via Redirect app
|
||||
app.use(express.vhost('example.com', main)); // Serves top level domain via Main server app
|
||||
|
||||
app.listen(3000);
|
||||
console.log('Express app started on port 3000');
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ app.get('/Readme.md', function(req, res){
|
||||
res.render('Readme.md');
|
||||
})
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
|
||||
@@ -142,5 +142,8 @@ app.all('/api/*', function(req, res, next){
|
||||
|
||||
*/
|
||||
|
||||
app.listen(3000);
|
||||
console.log('Application listening on port 3000');
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
|
||||
@@ -109,7 +109,8 @@ app.get('/api/user/:name/repos', function(req, res, next){
|
||||
else next();
|
||||
});
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express server listening on port 3000');
|
||||
}
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ var connect = require('connect')
|
||||
, middleware = require('./middleware')
|
||||
, debug = require('debug')('express:application')
|
||||
, locals = require('./utils').locals
|
||||
, compileETag = require('./utils').compileETag
|
||||
, compileTrust = require('./utils').compileTrust
|
||||
, View = require('./view')
|
||||
, utils = connect.utils
|
||||
@@ -46,7 +47,7 @@ app.init = function(){
|
||||
app.defaultConfiguration = function(){
|
||||
// default settings
|
||||
this.enable('x-powered-by');
|
||||
this.enable('etag');
|
||||
this.set('etag', 'weak');
|
||||
this.set('env', process.env.NODE_ENV || 'development');
|
||||
this.set('subdomain offset', 2);
|
||||
this.set('trust proxy', false);
|
||||
@@ -251,18 +252,27 @@ app.param = function(name, fn){
|
||||
*/
|
||||
|
||||
app.set = function(setting, val){
|
||||
if (1 == arguments.length) {
|
||||
if (arguments.length === 1) {
|
||||
// app.get(setting)
|
||||
return this.settings[setting];
|
||||
} else {
|
||||
this.settings[setting] = val;
|
||||
|
||||
if (setting === 'trust proxy') {
|
||||
debug('compile trust proxy %j', val);
|
||||
this.set('trust proxy fn', compileTrust(val));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
// set value
|
||||
this.settings[setting] = val;
|
||||
|
||||
// trigger matched settings
|
||||
switch (setting) {
|
||||
case 'etag':
|
||||
debug('compile etag %s', val);
|
||||
this.set('etag fn', compileETag(val));
|
||||
break;
|
||||
case 'trust proxy':
|
||||
debug('compile trust proxy %s', val);
|
||||
this.set('trust proxy fn', compileTrust(val));
|
||||
break;
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,8 +9,8 @@ var http = require('http')
|
||||
, sign = require('cookie-signature').sign
|
||||
, normalizeType = require('./utils').normalizeType
|
||||
, normalizeTypes = require('./utils').normalizeTypes
|
||||
, setCharset = require('./utils').setCharset
|
||||
, deprecate = require('./utils').deprecate
|
||||
, etag = require('./utils').etag
|
||||
, statusCodes = http.STATUS_CODES
|
||||
, cookie = require('cookie')
|
||||
, send = require('send')
|
||||
@@ -83,6 +83,8 @@ res.links = function(links){
|
||||
res.send = function(body){
|
||||
var req = this.req;
|
||||
var head = 'HEAD' == req.method;
|
||||
var type;
|
||||
var encoding;
|
||||
var len;
|
||||
|
||||
// settings
|
||||
@@ -125,18 +127,31 @@ res.send = function(body){
|
||||
break;
|
||||
}
|
||||
|
||||
// write strings in utf-8
|
||||
if ('string' === typeof body) {
|
||||
encoding = 'utf8';
|
||||
type = this.get('Content-Type');
|
||||
|
||||
// reflect this in content-type
|
||||
if ('string' === typeof type) {
|
||||
this.set('Content-Type', setCharset(type, 'utf-8'));
|
||||
}
|
||||
}
|
||||
|
||||
// populate Content-Length
|
||||
if (undefined !== body && !this.get('Content-Length')) {
|
||||
this.set('Content-Length', len = Buffer.isBuffer(body)
|
||||
len = Buffer.isBuffer(body)
|
||||
? body.length
|
||||
: Buffer.byteLength(body));
|
||||
: Buffer.byteLength(body, encoding);
|
||||
this.set('Content-Length', len);
|
||||
}
|
||||
|
||||
// ETag support
|
||||
// TODO: W/ support
|
||||
if (app.settings.etag && len && 'GET' == req.method) {
|
||||
var etag = len !== undefined && app.get('etag fn');
|
||||
if (etag && ('GET' === req.method || 'HEAD' === req.method)) {
|
||||
if (!this.get('ETag')) {
|
||||
this.set('ETag', etag(body));
|
||||
etag = etag(body, encoding);
|
||||
etag && this.set('ETag', etag);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,7 +167,8 @@ res.send = function(body){
|
||||
}
|
||||
|
||||
// respond
|
||||
this.end(head ? null : body);
|
||||
this.end((head ? null : body), encoding);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
@@ -248,7 +264,7 @@ res.jsonp = function(obj){
|
||||
|
||||
// content-type
|
||||
this.charset = this.charset || 'utf-8';
|
||||
this.set('Content-Type', 'application/json');
|
||||
this.get('Content-Type') || this.set('Content-Type', 'application/json');
|
||||
|
||||
// fixup callback
|
||||
if (Array.isArray(callback)) {
|
||||
|
||||
111
lib/utils.js
111
lib/utils.js
@@ -6,7 +6,8 @@
|
||||
var mime = require('connect').mime
|
||||
, deprecate = require('util').deprecate
|
||||
, proxyaddr = require('proxy-addr')
|
||||
, crc32 = require('buffer-crc32');
|
||||
, crc32 = require('buffer-crc32')
|
||||
, crypto = require('crypto');
|
||||
|
||||
/**
|
||||
* toString ref.
|
||||
@@ -14,6 +15,11 @@ var mime = require('connect').mime
|
||||
|
||||
var toString = {}.toString;
|
||||
|
||||
/**
|
||||
* Simple detection of charset parameter in content-type
|
||||
*/
|
||||
var charsetRegExp = /;\s*charset\s*=/;
|
||||
|
||||
/**
|
||||
* Deprecate function, like core `util.deprecate`,
|
||||
* but with NODE_ENV and color support.
|
||||
@@ -39,15 +45,47 @@ exports.deprecate = function(fn, msg){
|
||||
};
|
||||
|
||||
/**
|
||||
* Return ETag for `body`.
|
||||
* Return strong ETag for `body`.
|
||||
*
|
||||
* @param {String|Buffer} body
|
||||
* @param {String} [encoding]
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.etag = function(body){
|
||||
return '"' + crc32.signed(body) + '"';
|
||||
exports.etag = function etag(body, encoding){
|
||||
if (body.length === 0) {
|
||||
// fast-path empty body
|
||||
return '"1B2M2Y8AsgTpgAmY7PhCfg=="'
|
||||
}
|
||||
|
||||
var hash = crypto
|
||||
.createHash('md5')
|
||||
.update(body, encoding)
|
||||
.digest('base64')
|
||||
return '"' + hash + '"'
|
||||
};
|
||||
|
||||
/**
|
||||
* Return weak ETag for `body`.
|
||||
*
|
||||
* @param {String|Buffer} body
|
||||
* @param {String} [encoding]
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.wetag = function wetag(body, encoding){
|
||||
if (body.length === 0) {
|
||||
// fast-path empty body
|
||||
return 'W/"0-0"'
|
||||
}
|
||||
|
||||
var buf = Buffer.isBuffer(body)
|
||||
? body
|
||||
: new Buffer(body, encoding)
|
||||
var len = buf.length
|
||||
return 'W/"' + len.toString(16) + '-' + crc32.unsigned(buf) + '"'
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -339,6 +377,40 @@ exports.pathRegexp = function(path, keys, sensitive, strict) {
|
||||
return new RegExp('^' + path + '$', sensitive ? '' : 'i');
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile "etag" value to function.
|
||||
*
|
||||
* @param {Boolean|String|Function} val
|
||||
* @return {Function}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.compileETag = function(val) {
|
||||
var fn;
|
||||
|
||||
if (typeof val === 'function') {
|
||||
return val;
|
||||
}
|
||||
|
||||
switch (val) {
|
||||
case true:
|
||||
fn = exports.wetag;
|
||||
break;
|
||||
case false:
|
||||
break;
|
||||
case 'strong':
|
||||
fn = exports.etag;
|
||||
break;
|
||||
case 'weak':
|
||||
fn = exports.wetag;
|
||||
break;
|
||||
default:
|
||||
throw new TypeError('unknown value for etag function: ' + val);
|
||||
}
|
||||
|
||||
return fn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile "proxy trust" value to function.
|
||||
*
|
||||
@@ -367,3 +439,34 @@ exports.compileTrust = function(val) {
|
||||
|
||||
return proxyaddr.compile(val || []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the charset in a given Content-Type string.
|
||||
*
|
||||
* @param {String} type
|
||||
* @param {String} charset
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.setCharset = function(type, charset){
|
||||
if (!type || !charset) return type;
|
||||
|
||||
var exists = charsetRegExp.test(type);
|
||||
|
||||
// removing existing charset
|
||||
if (exists) {
|
||||
var parts = type.split(';');
|
||||
|
||||
for (var i = 1; i < parts.length; i++) {
|
||||
if (charsetRegExp.test(';' + parts[i])) {
|
||||
parts.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
type = parts.join(';');
|
||||
}
|
||||
|
||||
return type + '; charset=' + charset;
|
||||
};
|
||||
|
||||
24
package.json
24
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "express",
|
||||
"description": "Sinatra inspired web development framework",
|
||||
"version": "3.7.0",
|
||||
"version": "3.9.0",
|
||||
"author": "TJ Holowaychuk <tj@vision-media.ca>",
|
||||
"contributors": [
|
||||
{
|
||||
@@ -47,33 +47,31 @@
|
||||
"repository": "git://github.com/visionmedia/express",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"connect": "2.16.2",
|
||||
"buffer-crc32": "0.2.1",
|
||||
"connect": "2.18.0",
|
||||
"commander": "1.3.2",
|
||||
"methods": "1.0.0",
|
||||
"mkdirp": "0.5.0",
|
||||
"parseurl": "1.0.1",
|
||||
"proxy-addr": "1.0.0",
|
||||
"range-parser": "1.0.0",
|
||||
"send": "0.4.0",
|
||||
"cookie": "0.1.2",
|
||||
"buffer-crc32": "0.2.1",
|
||||
"fresh": "0.2.2",
|
||||
"send": "0.3.0",
|
||||
"cookie-signature": "1.0.3",
|
||||
"merge-descriptors": "0.0.2",
|
||||
"debug": ">= 0.8.0 < 1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"coveralls": "2.10.0",
|
||||
"ejs": "~0.8.4",
|
||||
"istanbul": "0.2.10",
|
||||
"mocha": "~1.18.2",
|
||||
"should": "~3.3.1",
|
||||
"jade": "~0.30.0",
|
||||
"mocha": "~1.20.0",
|
||||
"should": "~4.0.0",
|
||||
"ejs": "~1.0.0",
|
||||
"jade": "~1.3.1",
|
||||
"hjs": "~0.0.6",
|
||||
"stylus": "~0.40.0",
|
||||
"marked": "0.3.2",
|
||||
"connect-redis": "~1.4.5",
|
||||
"marked": "0.2.10",
|
||||
"supertest": "~0.12.1"
|
||||
"supertest": "~0.13.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
@@ -85,6 +83,6 @@
|
||||
"prepublish": "npm prune",
|
||||
"test": "mocha --require test/support/env --reporter dot --check-leaks test/ test/acceptance/",
|
||||
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --require test/support/env --reporter dot --check-leaks test/ test/acceptance/",
|
||||
"test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --require test/support/env --reporter spec --check-leaks test/ test/acceptance/ && cat ./coverage/lcov.info | coveralls"
|
||||
"test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --require test/support/env --reporter spec --check-leaks test/ test/acceptance/"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,16 +7,43 @@ describe('content-negotiation', function(){
|
||||
it('should default to text/html', function(done){
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('<ul><li>Tobi</li><li>Loki</li><li>Jane</li></ul>')
|
||||
.end(done);
|
||||
.expect(200, '<ul><li>Tobi</li><li>Loki</li><li>Jane</li></ul>', done)
|
||||
})
|
||||
|
||||
it('should accept to text/plain', function(done){
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('Accept', 'text/plain')
|
||||
.expect(' - Tobi\n - Loki\n - Jane\n')
|
||||
.end(done);
|
||||
.expect(200, ' - Tobi\n - Loki\n - Jane\n', done)
|
||||
})
|
||||
|
||||
it('should accept to application/json', function(done){
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('Accept', 'application/json')
|
||||
.expect(200, '[{"name":"Tobi"},{"name":"Loki"},{"name":"Jane"}]', done)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('GET /users', function(){
|
||||
it('should default to text/html', function(done){
|
||||
request(app)
|
||||
.get('/users')
|
||||
.expect(200, '<ul><li>Tobi</li><li>Loki</li><li>Jane</li></ul>', done)
|
||||
})
|
||||
|
||||
it('should accept to text/plain', function(done){
|
||||
request(app)
|
||||
.get('/users')
|
||||
.set('Accept', 'text/plain')
|
||||
.expect(200, ' - Tobi\n - Loki\n - Jane\n', done)
|
||||
})
|
||||
|
||||
it('should accept to application/json', function(done){
|
||||
request(app)
|
||||
.get('/users')
|
||||
.set('Accept', 'application/json')
|
||||
.expect(200, '[{"name":"Tobi"},{"name":"Loki"},{"name":"Jane"}]', done)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -18,6 +18,35 @@ describe('cookies', function(){
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it('should respond to cookie', function(done){
|
||||
request(app)
|
||||
.post('/')
|
||||
.send({ remember: 1 })
|
||||
.expect(302, function(err, res){
|
||||
if (err) return done(err)
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('Cookie', res.headers['set-cookie'][0])
|
||||
.expect(200, /Remembered/, done)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('GET /forget', function(){
|
||||
it('should clear cookie', function(done){
|
||||
request(app)
|
||||
.post('/')
|
||||
.send({ remember: 1 })
|
||||
.expect(302, function(err, res){
|
||||
if (err) return done(err)
|
||||
request(app)
|
||||
.get('/forget')
|
||||
.set('Cookie', res.headers['set-cookie'][0])
|
||||
.expect('Set-Cookie', /remember=;/)
|
||||
.expect(302, done)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('POST /', function(){
|
||||
@@ -25,10 +54,20 @@ describe('cookies', function(){
|
||||
request(app)
|
||||
.post('/')
|
||||
.send({ remember: 1 })
|
||||
.end(function(err, res){
|
||||
.expect(302, function(err, res){
|
||||
res.headers.should.have.property('set-cookie')
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it('should no set cookie w/o reminder', function(done){
|
||||
request(app)
|
||||
.post('/')
|
||||
.send({})
|
||||
.expect(302, function(err, res){
|
||||
res.headers.should.not.have.property('set-cookie')
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -7,14 +7,11 @@ describe('ejs', function(){
|
||||
it('should respond with html', function(done){
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.should.have.status(200);
|
||||
res.should.have.header('Content-Type', 'text/html; charset=utf-8');
|
||||
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();
|
||||
});
|
||||
.expect('Content-Type', 'text/html; charset=utf-8')
|
||||
.expect(/<li>tobi <tobi@learnboost\.com><\/li>/)
|
||||
.expect(/<li>loki <loki@learnboost\.com><\/li>/)
|
||||
.expect(/<li>jane <jane@learnboost\.com><\/li>/)
|
||||
.expect(200, done)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
var app = require('../../examples/markdown')
|
||||
, request = require('supertest');
|
||||
var request = require('supertest')
|
||||
|
||||
describe('markdown', function(){
|
||||
describe('GET /', function(){
|
||||
@@ -18,4 +18,4 @@ describe('markdown', function(){
|
||||
.expect(500,done)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -7,10 +7,38 @@ describe('mvc', function(){
|
||||
it('should redirect to /users', function(done){
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('Location', '/users')
|
||||
.expect(302, done)
|
||||
})
|
||||
})
|
||||
|
||||
describe('GET /pet/0', function(){
|
||||
it('should get pet', function(done){
|
||||
request(app)
|
||||
.get('/pet/0')
|
||||
.expect(200, /Tobi/, done)
|
||||
})
|
||||
})
|
||||
|
||||
describe('GET /pet/0/edit', function(){
|
||||
it('should get pet edit page', function(done){
|
||||
request(app)
|
||||
.get('/pet/0/edit')
|
||||
.expect(/<form/)
|
||||
.expect(200, /Tobi/, done)
|
||||
})
|
||||
})
|
||||
|
||||
describe('PUT /pet/2', function(){
|
||||
it('should update the pet', function(done){
|
||||
request(app)
|
||||
.put('/pet/3')
|
||||
.send({ pet: { name: 'Boots' } })
|
||||
.end(function(err, res){
|
||||
res.should.have.status(302);
|
||||
res.headers.location.should.include('/users');
|
||||
done();
|
||||
if (err) return done(err);
|
||||
request(app)
|
||||
.get('/pet/3/edit')
|
||||
.expect(200, /Boots/, done)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -19,13 +47,11 @@ describe('mvc', function(){
|
||||
it('should display a list of users', function(done){
|
||||
request(app)
|
||||
.get('/users')
|
||||
.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();
|
||||
})
|
||||
.expect(/<h1>Users<\/h1>/)
|
||||
.expect(/>TJ</)
|
||||
.expect(/>Guillermo</)
|
||||
.expect(/>Nathan</)
|
||||
.expect(200, done)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -34,21 +60,16 @@ describe('mvc', function(){
|
||||
it('should display the user', function(done){
|
||||
request(app)
|
||||
.get('/user/0')
|
||||
.end(function(err, res){
|
||||
res.text.should.include('<h1>TJ <a href="/user/0/edit">edit');
|
||||
done();
|
||||
})
|
||||
.expect(200, /<h1>TJ <a href="\/user\/0\/edit">edit/, done)
|
||||
})
|
||||
|
||||
it('should display the users pets', function(done){
|
||||
request(app)
|
||||
.get('/user/0')
|
||||
.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();
|
||||
})
|
||||
.expect(/\/pet\/0">Tobi/)
|
||||
.expect(/\/pet\/1">Loki/)
|
||||
.expect(/\/pet\/2">Jane/)
|
||||
.expect(200, done)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -65,11 +86,8 @@ describe('mvc', function(){
|
||||
it('should display the edit form', function(done){
|
||||
request(app)
|
||||
.get('/user/1/edit')
|
||||
.end(function(err, res){
|
||||
res.text.should.include('<h1>Guillermo</h1>');
|
||||
res.text.should.include('value="put"');
|
||||
done();
|
||||
})
|
||||
.expect(/Guillermo/)
|
||||
.expect(200, /<form/, done)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -79,13 +97,26 @@ describe('mvc', function(){
|
||||
.put('/user/1')
|
||||
.send({ user: { name: 'Tobo' }})
|
||||
.end(function(err, res){
|
||||
if (err) return done(err);
|
||||
request(app)
|
||||
.get('/user/1/edit')
|
||||
.end(function(err, res){
|
||||
res.text.should.include('<h1>Tobo</h1>');
|
||||
done();
|
||||
})
|
||||
.expect(200, /Tobo/, done)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('POST /user/:id/pet', function(){
|
||||
it('should create a pet for user', function(done){
|
||||
request(app)
|
||||
.post('/user/2/pet')
|
||||
.send({ pet: { name: 'Snickers' }})
|
||||
.expect('Location', '/user/2')
|
||||
.expect(302, function(err, res){
|
||||
if (err) return done(err)
|
||||
request(app)
|
||||
.get('/user/2')
|
||||
.expect(200, /Snickers/, done)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var app = require('../../examples/params/app')
|
||||
, request = require('supertest');
|
||||
var request = require('supertest')
|
||||
|
||||
describe('params', function(){
|
||||
describe('GET /', function(){
|
||||
@@ -18,6 +18,14 @@ describe('params', function(){
|
||||
})
|
||||
})
|
||||
|
||||
describe('GET /user/9', function(){
|
||||
it('should fail to find user', function(done){
|
||||
request(app)
|
||||
.get('/user/9')
|
||||
.expect(/failed to find user/,done)
|
||||
})
|
||||
})
|
||||
|
||||
describe('GET /users/0-2', function(){
|
||||
it('should respond with three users', function(done){
|
||||
request(app)
|
||||
@@ -25,4 +33,12 @@ describe('params', function(){
|
||||
.expect(/users tj, tobi/,done)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('GET /users/foo-bar', function(){
|
||||
it('should fail integer parsing', function(done){
|
||||
request(app)
|
||||
.get('/users/foo-bar')
|
||||
.expect(/failed to parseInt foo/,done)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var app = require('../../examples/resource/app')
|
||||
, request = require('supertest');
|
||||
var request = require('supertest')
|
||||
|
||||
describe('resource', function(){
|
||||
describe('GET /', function(){
|
||||
@@ -26,6 +26,14 @@ describe('resource', function(){
|
||||
})
|
||||
})
|
||||
|
||||
describe('GET /users/9', function(){
|
||||
it('should respond with error', function(done){
|
||||
request(app)
|
||||
.get('/users/9')
|
||||
.expect('{"error":"Cannot find user"}', done)
|
||||
})
|
||||
})
|
||||
|
||||
describe('GET /users/1..3', function(){
|
||||
it('should respond with users 1 through 3', function(done){
|
||||
request(app)
|
||||
@@ -35,13 +43,21 @@ describe('resource', function(){
|
||||
})
|
||||
|
||||
describe('DELETE /users/1', function(){
|
||||
it('should respond with users 1 through 3', function(done){
|
||||
it('should delete user 1', function(done){
|
||||
request(app)
|
||||
.del('/users/1')
|
||||
.expect(/^destroyed/,done)
|
||||
})
|
||||
})
|
||||
|
||||
describe('DELETE /users/9', function(){
|
||||
it('should fail', function(done){
|
||||
request(app)
|
||||
.del('/users/9')
|
||||
.expect('Cannot find user', done)
|
||||
})
|
||||
})
|
||||
|
||||
describe('GET /users/1..3.json', function(){
|
||||
it('should respond with users 2 and 3 as json', function(done){
|
||||
request(app)
|
||||
@@ -49,4 +65,4 @@ describe('resource', function(){
|
||||
.expect(/^\[null,{"name":"aaron"},{"name":"guillermo"}\]/,done)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -24,11 +24,72 @@ describe('web-service', function(){
|
||||
it('should respond users json', function(done){
|
||||
request(app)
|
||||
.get('/api/users?api-key=foo')
|
||||
.end(function(err, res){
|
||||
res.should.be.json;
|
||||
res.text.should.equal('[{"name":"tobi"},{"name":"loki"},{"name":"jane"}]');
|
||||
done();
|
||||
});
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, '[{"name":"tobi"},{"name":"loki"},{"name":"jane"}]', done)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('GET /api/repos', function(){
|
||||
describe('without an api key', function(){
|
||||
it('should respond with 400 bad request', function(done){
|
||||
request(app)
|
||||
.get('/api/repos')
|
||||
.expect(400, done);
|
||||
})
|
||||
})
|
||||
|
||||
describe('with an invalid api key', function(){
|
||||
it('should respond with 401 unauthorized', function(done){
|
||||
request(app)
|
||||
.get('/api/repos?api-key=rawr')
|
||||
.expect(401, done);
|
||||
})
|
||||
})
|
||||
|
||||
describe('with a valid api key', function(){
|
||||
it('should respond repos json', function(done){
|
||||
request(app)
|
||||
.get('/api/repos?api-key=foo')
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(/"name":"express"/)
|
||||
.expect(/"url":"http:\/\/github.com\/visionmedia\/express"/)
|
||||
.expect(200, done)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('GET /api/user/:name/repos', function(){
|
||||
describe('without an api key', function(){
|
||||
it('should respond with 400 bad request', function(done){
|
||||
request(app)
|
||||
.get('/api/user/loki/repos')
|
||||
.expect(400, done);
|
||||
})
|
||||
})
|
||||
|
||||
describe('with an invalid api key', function(){
|
||||
it('should respond with 401 unauthorized', function(done){
|
||||
request(app)
|
||||
.get('/api/user/loki/repos?api-key=rawr')
|
||||
.expect(401, done);
|
||||
})
|
||||
})
|
||||
|
||||
describe('with a valid api key', function(){
|
||||
it('should respond user repos json', function(done){
|
||||
request(app)
|
||||
.get('/api/user/loki/repos?api-key=foo')
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(/"name":"stylus"/)
|
||||
.expect(/"url":"http:\/\/github.com\/learnboost\/stylus"/)
|
||||
.expect(200, done)
|
||||
})
|
||||
|
||||
it('should 404 with unknown user', function(done){
|
||||
request(app)
|
||||
.get('/api/user/bob/repos?api-key=foo')
|
||||
.expect(404, done)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -37,12 +98,8 @@ describe('web-service', function(){
|
||||
it('should respond with 404 json', function(done){
|
||||
request(app)
|
||||
.get('/api/something?api-key=bar')
|
||||
.end(function(err, res){
|
||||
res.should.have.status(404);
|
||||
res.should.be.json;
|
||||
res.text.should.equal('{"error":"Lame, can\'t find that"}');
|
||||
done();
|
||||
});
|
||||
.expect('Content-Type', /json/)
|
||||
.expect(404, '{"error":"Lame, can\'t find that"}', done)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -16,6 +16,29 @@ describe('HEAD', function(){
|
||||
.head('/tobi')
|
||||
.expect(200, done);
|
||||
})
|
||||
|
||||
it('should output the same headers as GET requests', function(done){
|
||||
var app = express();
|
||||
|
||||
app.get('/tobi', function(req, res){
|
||||
// send() detects HEAD
|
||||
res.send('tobi');
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/tobi')
|
||||
.expect(200, function(err, res){
|
||||
if (err) return done(err);
|
||||
var headers = res.headers;
|
||||
request(app)
|
||||
.get('/tobi')
|
||||
.expect(200, function(err, res){
|
||||
if (err) return done(err);
|
||||
assert.deepEqual(res.headers, headers);
|
||||
done();
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
describe('app.head()', function(){
|
||||
|
||||
11
test/app.js
11
test/app.js
@@ -71,4 +71,13 @@ describe('in production', function(){
|
||||
app.enabled('view cache').should.be.true;
|
||||
process.env.NODE_ENV = 'test';
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('without NODE_ENV', function(){
|
||||
it('should default to development', function(){
|
||||
process.env.NODE_ENV = '';
|
||||
var app = express();
|
||||
app.get('env').should.equal('development');
|
||||
process.env.NODE_ENV = 'test';
|
||||
})
|
||||
})
|
||||
|
||||
@@ -37,6 +37,11 @@ describe('app', function(){
|
||||
});
|
||||
|
||||
})
|
||||
|
||||
it('should fail if not given fn', function(){
|
||||
var app = express();
|
||||
app.param.bind(app, ':name', 'bob').should.throw();
|
||||
})
|
||||
})
|
||||
|
||||
describe('.param(names, fn)', function(){
|
||||
@@ -95,5 +100,61 @@ describe('app', function(){
|
||||
.get('/user/123')
|
||||
.expect('123', done);
|
||||
})
|
||||
|
||||
it('should work with encoded values', function(done){
|
||||
var app = express();
|
||||
|
||||
app.param('name', function(req, res, next, name){
|
||||
req.params.name = name;
|
||||
next();
|
||||
});
|
||||
|
||||
app.get('/user/:name', function(req, res){
|
||||
var name = req.params.name;
|
||||
res.send('' + name);
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/user/foo%25bar')
|
||||
.expect('foo%bar', done);
|
||||
})
|
||||
|
||||
it('should catch thrown error', function(done){
|
||||
var app = express();
|
||||
|
||||
app.param('id', function(req, res, next, id){
|
||||
throw new Error('err!');
|
||||
});
|
||||
|
||||
app.get('/user/:id', function(req, res){
|
||||
var id = req.params.id;
|
||||
res.send('' + id);
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/user/123')
|
||||
.expect(500, done);
|
||||
})
|
||||
|
||||
it('should defer to next route', function(done){
|
||||
var app = express();
|
||||
|
||||
app.param('id', function(req, res, next, id){
|
||||
next('route');
|
||||
});
|
||||
|
||||
app.get('/user/:id', function(req, res){
|
||||
var id = req.params.id;
|
||||
res.send('' + id);
|
||||
});
|
||||
|
||||
app.get('/:name/123', function(req, res){
|
||||
res.send('name');
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/user/123')
|
||||
.expect('name', done);
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -54,6 +54,27 @@ describe('app', function(){
|
||||
})
|
||||
})
|
||||
|
||||
it('should handle render error throws', function(done){
|
||||
var app = express();
|
||||
|
||||
function View(name, options){
|
||||
this.name = name;
|
||||
this.path = 'fale';
|
||||
}
|
||||
|
||||
View.prototype.render = function(options, fn){
|
||||
throw new Error('err!');
|
||||
};
|
||||
|
||||
app.set('view', View);
|
||||
|
||||
app.render('something', function(err, str){
|
||||
err.should.be.ok;
|
||||
err.message.should.equal('err!');
|
||||
done();
|
||||
})
|
||||
})
|
||||
|
||||
describe('when the file does not exist', function(){
|
||||
it('should provide a helpful error', function(done){
|
||||
var app = express();
|
||||
@@ -74,7 +95,7 @@ describe('app', function(){
|
||||
app.render('user.jade', function(err, str){
|
||||
// nextTick to prevent cyclic
|
||||
process.nextTick(function(){
|
||||
err.message.should.match(/user is not defined/);
|
||||
err.message.should.match(/Cannot read property 'name' of undefined/);
|
||||
done();
|
||||
});
|
||||
})
|
||||
@@ -132,6 +153,68 @@ describe('app', function(){
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('caching', function(){
|
||||
it('should always lookup view without cache', function(done){
|
||||
var app = express();
|
||||
var count = 0;
|
||||
|
||||
function View(name, options){
|
||||
this.name = name;
|
||||
this.path = 'fake';
|
||||
count++;
|
||||
}
|
||||
|
||||
View.prototype.render = function(options, fn){
|
||||
fn(null, 'abstract engine');
|
||||
};
|
||||
|
||||
app.set('view cache', false);
|
||||
app.set('view', View);
|
||||
|
||||
app.render('something', function(err, str){
|
||||
if (err) return done(err);
|
||||
count.should.equal(1);
|
||||
str.should.equal('abstract engine');
|
||||
app.render('something', function(err, str){
|
||||
if (err) return done(err);
|
||||
count.should.equal(2);
|
||||
str.should.equal('abstract engine');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('should cache with "view cache" setting', function(done){
|
||||
var app = express();
|
||||
var count = 0;
|
||||
|
||||
function View(name, options){
|
||||
this.name = name;
|
||||
this.path = 'fake';
|
||||
count++;
|
||||
}
|
||||
|
||||
View.prototype.render = function(options, fn){
|
||||
fn(null, 'abstract engine');
|
||||
};
|
||||
|
||||
app.set('view cache', true);
|
||||
app.set('view', View);
|
||||
|
||||
app.render('something', function(err, str){
|
||||
if (err) return done(err);
|
||||
count.should.equal(1);
|
||||
str.should.equal('abstract engine');
|
||||
app.render('something', function(err, str){
|
||||
if (err) return done(err);
|
||||
count.should.equal(1);
|
||||
str.should.equal('abstract engine');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('.render(name, options, fn)', function(){
|
||||
@@ -175,5 +258,37 @@ describe('app', function(){
|
||||
done();
|
||||
})
|
||||
})
|
||||
|
||||
describe('caching', function(){
|
||||
it('should cache with cache option', function(done){
|
||||
var app = express();
|
||||
var count = 0;
|
||||
|
||||
function View(name, options){
|
||||
this.name = name;
|
||||
this.path = 'fake';
|
||||
count++;
|
||||
}
|
||||
|
||||
View.prototype.render = function(options, fn){
|
||||
fn(null, 'abstract engine');
|
||||
};
|
||||
|
||||
app.set('view cache', false);
|
||||
app.set('view', View);
|
||||
|
||||
app.render('something', {cache: true}, function(err, str){
|
||||
if (err) return done(err);
|
||||
count.should.equal(1);
|
||||
str.should.equal('abstract engine');
|
||||
app.render('something', {cache: true}, function(err, str){
|
||||
if (err) return done(err);
|
||||
count.should.equal(1);
|
||||
str.should.equal('abstract engine');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -564,6 +564,30 @@ describe('app.router', function(){
|
||||
})
|
||||
})
|
||||
|
||||
describe('when next("route") is called', function(){
|
||||
it('should jump to next route', function(done){
|
||||
var app = express()
|
||||
|
||||
function fn(req, res, next){
|
||||
res.set('X-Hit', '1')
|
||||
next('route')
|
||||
}
|
||||
|
||||
app.get('/foo', fn, function(req, res, next){
|
||||
res.end('failure')
|
||||
});
|
||||
|
||||
app.get('/foo', function(req, res){
|
||||
res.end('success')
|
||||
})
|
||||
|
||||
request(app)
|
||||
.get('/foo')
|
||||
.expect('X-Hit', '1')
|
||||
.expect(200, 'success', done)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when next(err) is called', function(){
|
||||
it('should break out of app.router', function(done){
|
||||
var app = express()
|
||||
|
||||
@@ -13,6 +13,29 @@ describe('config', function(){
|
||||
var app = express();
|
||||
app.set('foo', undefined).should.equal(app);
|
||||
})
|
||||
|
||||
describe('"etag"', function(){
|
||||
it('should throw on bad value', function(){
|
||||
var app = express()
|
||||
app.set.bind(app, 'etag', 42).should.throw(/unknown value/)
|
||||
})
|
||||
|
||||
it('should set "etag fn"', function(){
|
||||
var app = express()
|
||||
var fn = function(){}
|
||||
app.set('etag', fn)
|
||||
app.get('etag fn').should.equal(fn)
|
||||
})
|
||||
})
|
||||
|
||||
describe('"trust proxy"', function(){
|
||||
it('should set "trust proxy fn"', function(){
|
||||
var app = express()
|
||||
var fn = function(){}
|
||||
app.set('trust proxy', fn)
|
||||
app.get('trust proxy fn').should.equal(fn)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('.get()', function(){
|
||||
@@ -91,4 +114,4 @@ describe('config', function(){
|
||||
app.disabled('foo').should.be.false;
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
36
test/req.acceptsEncoding.js
Normal file
36
test/req.acceptsEncoding.js
Normal file
@@ -0,0 +1,36 @@
|
||||
|
||||
var express = require('../')
|
||||
, request = require('supertest');
|
||||
|
||||
describe('req', function(){
|
||||
describe('.acceptsEncodings', function(){
|
||||
it('should be true if encoding accpeted', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
req.acceptsEncoding('gzip').should.be.true;
|
||||
req.acceptsEncoding('deflate').should.be.true;
|
||||
res.end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('Accept-Encoding', ' gzip, deflate')
|
||||
.expect(200, done);
|
||||
})
|
||||
|
||||
it('should be false if encoding not accpeted', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
req.acceptsEncoding('bogus').should.be.false;
|
||||
res.end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('Accept-Encoding', ' gzip, deflate')
|
||||
.expect(200, done);
|
||||
})
|
||||
})
|
||||
})
|
||||
53
test/req.acceptsLanguage.js
Normal file
53
test/req.acceptsLanguage.js
Normal file
@@ -0,0 +1,53 @@
|
||||
|
||||
var express = require('../')
|
||||
, request = require('supertest');
|
||||
|
||||
describe('req', function(){
|
||||
describe('.acceptsLanguage', function(){
|
||||
it('should be true if language accpeted', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
req.acceptsLanguage('en-us').should.be.true;
|
||||
req.acceptsLanguage('en').should.be.true;
|
||||
res.end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('Accept-Language', 'en;q=.5, en-us')
|
||||
.expect(200, done);
|
||||
})
|
||||
|
||||
it('should be false if language not accpeted', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
req.acceptsLanguage('es').should.be.false;
|
||||
res.end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('Accept-Language', 'en;q=.5, en-us')
|
||||
.expect(200, done);
|
||||
})
|
||||
|
||||
describe('when Accept-Language is not present', function(){
|
||||
it('should always return true', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
req.acceptsLanguage('en').should.be.true;
|
||||
req.acceptsLanguage('es').should.be.true;
|
||||
req.acceptsLanguage('jp').should.be.true;
|
||||
res.end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect(200, done);
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -6,15 +6,16 @@ describe('req', function(){
|
||||
describe('.fresh', function(){
|
||||
it('should return true when the resource is not modified', function(done){
|
||||
var app = express();
|
||||
var etag = '"12345"';
|
||||
|
||||
app.use(function(req, res){
|
||||
res.set('ETag', '12345');
|
||||
res.set('ETag', etag);
|
||||
res.send(req.fresh);
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('If-None-Match', '12345')
|
||||
.set('If-None-Match', etag)
|
||||
.expect(304, done);
|
||||
})
|
||||
|
||||
@@ -22,14 +23,14 @@ describe('req', function(){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.set('ETag', '123');
|
||||
res.set('ETag', '"123"');
|
||||
res.send(req.fresh);
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('If-None-Match', '12345')
|
||||
.expect('false', done);
|
||||
.set('If-None-Match', '"12345"')
|
||||
.expect(200, 'false', done);
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
var express = require('../');
|
||||
var assert = require('assert');
|
||||
var express = require('..');
|
||||
|
||||
function req(ret) {
|
||||
return {
|
||||
@@ -27,5 +28,11 @@ describe('req', function(){
|
||||
ret.type = 'users';
|
||||
req('users=0-').range(Infinity).should.eql(ret);
|
||||
})
|
||||
|
||||
it('should return undefined if no range', function(){
|
||||
var ret = [{ start: 0, end: 50 }, { start: 60, end: 100 }];
|
||||
ret.type = 'bytes';
|
||||
assert(req('').range(120) === undefined);
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -6,15 +6,16 @@ describe('req', function(){
|
||||
describe('.stale', function(){
|
||||
it('should return false when the resource is not modified', function(done){
|
||||
var app = express();
|
||||
var etag = '"12345"';
|
||||
|
||||
app.use(function(req, res){
|
||||
res.set('ETag', '12345');
|
||||
res.set('ETag', etag);
|
||||
res.send(req.stale);
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('If-None-Match', '12345')
|
||||
.set('If-None-Match', etag)
|
||||
.expect(304, done);
|
||||
})
|
||||
|
||||
@@ -22,14 +23,14 @@ describe('req', function(){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.set('ETag', '123');
|
||||
res.set('ETag', '"123"');
|
||||
res.send(req.stale);
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('If-None-Match', '12345')
|
||||
.expect('true', done);
|
||||
.set('If-None-Match', '"12345"')
|
||||
.expect(200, 'true', done);
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -36,7 +36,7 @@ describe('res', function(){
|
||||
|
||||
app.use(function(req, res){
|
||||
res.attachment('/path/to/image.png');
|
||||
res.send('foo');
|
||||
res.send(new Buffer(4));
|
||||
});
|
||||
|
||||
request(app)
|
||||
|
||||
@@ -18,7 +18,7 @@ describe('res', function(){
|
||||
.expect("text/x-foo; charset=utf-8", done);
|
||||
})
|
||||
|
||||
it('should take precedence over res.send() defaults', function(done){
|
||||
it('should be replaced by real charset in res.send', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
@@ -28,7 +28,7 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('Content-Type', 'text/html; charset=whoop', done);
|
||||
.expect('Content-Type', 'text/html; charset=utf-8', done);
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -89,7 +89,7 @@ describe('res', function(){
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.headers['set-cookie'][0].should.not.include('Thu, 01 Jan 1970 00:00:01 GMT');
|
||||
res.headers['set-cookie'][0].should.not.containEql('Thu, 01 Jan 1970 00:00:01 GMT');
|
||||
done();
|
||||
})
|
||||
})
|
||||
@@ -104,10 +104,7 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.headers['set-cookie'][0].should.include('Max-Age=1');
|
||||
done();
|
||||
})
|
||||
.expect('Set-Cookie', /Max-Age=1/, done)
|
||||
})
|
||||
|
||||
it('should not mutate the options object', function(done){
|
||||
|
||||
@@ -14,12 +14,9 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.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.text.should.equal('<p>{{user.name}}</p>');
|
||||
done();
|
||||
});
|
||||
.expect('Content-Type', 'text/html; charset=UTF-8')
|
||||
.expect('Content-Disposition', 'attachment; filename="user.html"')
|
||||
.expect(200, '<p>{{user.name}}</p>', done)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -33,11 +30,9 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.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();
|
||||
});
|
||||
.expect('Content-Type', 'text/html; charset=UTF-8')
|
||||
.expect('Content-Disposition', 'attachment; filename="document"')
|
||||
.expect(200, done)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -52,10 +47,11 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.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"');
|
||||
});
|
||||
.expect('Content-Type', 'text/html; charset=UTF-8')
|
||||
.expect('Content-Disposition', 'attachment; filename="user.html"')
|
||||
.expect(200, function(err){
|
||||
assert.ifError(err)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -70,10 +66,11 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.should.have.header('Content-Type', 'text/html; charset=UTF-8');
|
||||
res.should.have.header('Content-Disposition', 'attachment; filename="document"');
|
||||
});
|
||||
.expect('Content-Type', 'text/html; charset=UTF-8')
|
||||
.expect('Content-Disposition', 'attachment; filename="document"')
|
||||
.expect(200, function(err){
|
||||
assert.ifError(err)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ function test(app) {
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('Accept', 'text/html; q=.5, text/plain')
|
||||
.expect('Content-Type', 'text/plain; charset=UTF-8')
|
||||
.expect('Content-Type', 'text/plain; charset=utf-8')
|
||||
.expect('hey', done);
|
||||
})
|
||||
|
||||
@@ -119,12 +119,12 @@ function test(app) {
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('Accept', 'text/html')
|
||||
.expect('Content-Type', 'text/html; charset=UTF-8');
|
||||
.expect('Content-Type', 'text/html; charset=utf-8');
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('Accept', 'text/plain')
|
||||
.expect('Content-Type', 'text/plain; charset=UTF-8');
|
||||
.expect('Content-Type', 'text/plain; charset=utf-8');
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
|
||||
@@ -17,6 +17,20 @@ describe('res', function(){
|
||||
.expect('{"foo":"bar"}', done);
|
||||
})
|
||||
|
||||
it('should not override previous Content-Types', function(done){
|
||||
var app = express();
|
||||
|
||||
app.get('/', function(req, res){
|
||||
res.type('application/vnd.example+json');
|
||||
res.json({ hello: 'world' });
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('Content-Type', 'application/vnd.example+json; charset=utf-8')
|
||||
.expect(200, '{"hello":"world"}', done);
|
||||
})
|
||||
|
||||
describe('when given primitives', function(){
|
||||
it('should respond with json for null', function(done){
|
||||
var app = express();
|
||||
@@ -27,11 +41,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('content-type', 'application/json; charset=utf-8');
|
||||
res.text.should.equal('null');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, 'null', done)
|
||||
})
|
||||
|
||||
it('should respond with json for Number', function(done){
|
||||
@@ -43,12 +54,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.statusCode.should.equal(200);
|
||||
res.headers.should.have.property('content-type', 'application/json; charset=utf-8');
|
||||
res.text.should.equal('300');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, '300', done)
|
||||
})
|
||||
|
||||
it('should respond with json for String', function(done){
|
||||
@@ -60,12 +67,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.statusCode.should.equal(200);
|
||||
res.headers.should.have.property('content-type', 'application/json; charset=utf-8');
|
||||
res.text.should.equal('"str"');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, '"str"', done)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -79,11 +82,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('content-type', 'application/json; charset=utf-8');
|
||||
res.text.should.equal('["foo","bar","baz"]');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, '["foo","bar","baz"]', done)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -97,11 +97,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('content-type', 'application/json; charset=utf-8');
|
||||
res.text.should.equal('{"name":"tobi"}');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, '{"name":"tobi"}', done)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -121,10 +118,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.text.should.equal('{"name":"tobi"}');
|
||||
done();
|
||||
});
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, '{"name":"tobi"}', done)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -152,10 +147,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.text.should.equal('{\n "name": "tobi",\n "age": 2\n}');
|
||||
done();
|
||||
});
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, '{\n "name": "tobi",\n "age": 2\n}', done)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -170,12 +163,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.statusCode.should.equal(201);
|
||||
res.headers.should.have.property('content-type', 'application/json; charset=utf-8');
|
||||
res.text.should.equal('{"id":1}');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(201, '{"id":1}', done)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -189,12 +178,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.statusCode.should.equal(201);
|
||||
res.headers.should.have.property('content-type', 'application/json; charset=utf-8');
|
||||
res.text.should.equal('{"id":1}');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(201, '{"id":1}', done)
|
||||
})
|
||||
|
||||
it('should use status as second number for backwards compat', function(done){
|
||||
@@ -206,12 +191,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.statusCode.should.equal(201);
|
||||
res.headers.should.have.property('content-type', 'application/json; charset=utf-8');
|
||||
res.text.should.equal('200');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(201, '200', done)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -225,11 +206,7 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.statusCode.should.equal(200);
|
||||
res.headers.should.have.property('content-type', 'application/vnd.example+json');
|
||||
res.text.should.equal('{"hello":"world"}');
|
||||
done();
|
||||
})
|
||||
.expect('content-type', 'application/vnd.example+json; charset=utf-8')
|
||||
.expect(200, '{"hello":"world"}', done)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -46,11 +46,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/?callback[a]=something')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('content-type', 'application/json; charset=utf-8');
|
||||
res.text.should.equal('{"count":1}');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, '{"count":1}', done)
|
||||
})
|
||||
|
||||
it('should allow renaming callback', function(done){
|
||||
@@ -119,6 +116,34 @@ describe('res', function(){
|
||||
});
|
||||
});
|
||||
|
||||
it('should not override previous Content-Types with no callback', function(done){
|
||||
var app = express();
|
||||
|
||||
app.get('/', function(req, res){
|
||||
res.type('application/vnd.example+json');
|
||||
res.jsonp({ hello: 'world' });
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('Content-Type', 'application/vnd.example+json; charset=utf-8')
|
||||
.expect(200, '{"hello":"world"}', done);
|
||||
})
|
||||
|
||||
it('should override previous Content-Types with callback', function(done){
|
||||
var app = express();
|
||||
|
||||
app.get('/', function(req, res){
|
||||
res.type('application/vnd.example+json');
|
||||
res.jsonp({ hello: 'world' });
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/?callback=cb')
|
||||
.expect('Content-Type', 'text/javascript; charset=utf-8')
|
||||
.expect(200, /cb\(\{"hello":"world"\}\);$/, done);
|
||||
})
|
||||
|
||||
describe('when given primitives', function(){
|
||||
it('should respond with json', function(done){
|
||||
var app = express();
|
||||
@@ -129,11 +154,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('content-type', 'application/json; charset=utf-8');
|
||||
res.text.should.equal('null');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, 'null', done)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -147,11 +169,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('content-type', 'application/json; charset=utf-8');
|
||||
res.text.should.equal('["foo","bar","baz"]');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, '["foo","bar","baz"]', done)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -165,11 +184,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('content-type', 'application/json; charset=utf-8');
|
||||
res.text.should.equal('{"name":"tobi"}');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, '{"name":"tobi"}', done)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -183,11 +199,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('content-type', 'application/json; charset=utf-8');
|
||||
res.text.should.equal('null');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, 'null', done)
|
||||
})
|
||||
|
||||
it('should respond with json for Number', function(done){
|
||||
@@ -199,12 +212,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.statusCode.should.equal(200);
|
||||
res.headers.should.have.property('content-type', 'application/json; charset=utf-8');
|
||||
res.text.should.equal('300');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, '300', done)
|
||||
})
|
||||
|
||||
it('should respond with json for String', function(done){
|
||||
@@ -216,12 +225,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.statusCode.should.equal(200);
|
||||
res.headers.should.have.property('content-type', 'application/json; charset=utf-8');
|
||||
res.text.should.equal('"str"');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, '"str"', done)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -241,10 +246,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.text.should.equal('{"name":"tobi"}');
|
||||
done();
|
||||
});
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, '{"name":"tobi"}', done)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -272,10 +275,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.text.should.equal('{\n "name": "tobi",\n "age": 2\n}');
|
||||
done();
|
||||
});
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, '{\n "name": "tobi",\n "age": 2\n}', done)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -290,12 +291,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.statusCode.should.equal(201);
|
||||
res.headers.should.have.property('content-type', 'application/json; charset=utf-8');
|
||||
res.text.should.equal('{"id":1}');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(201, '{"id":1}', done)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -309,12 +306,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.statusCode.should.equal(201);
|
||||
res.headers.should.have.property('content-type', 'application/json; charset=utf-8');
|
||||
res.text.should.equal('{"id":1}');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(201, '{"id":1}', done)
|
||||
})
|
||||
|
||||
it('should use status as second number for backwards compat', function(done){
|
||||
@@ -326,12 +319,22 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.statusCode.should.equal(201);
|
||||
res.headers.should.have.property('content-type', 'application/json; charset=utf-8');
|
||||
res.text.should.equal('200');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(201, '200', done)
|
||||
})
|
||||
})
|
||||
|
||||
it('should not override previous Content-Types', function(done){
|
||||
var app = express();
|
||||
|
||||
app.get('/', function(req, res){
|
||||
res.type('application/vnd.example+json');
|
||||
res.jsonp({ hello: 'world' });
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('content-type', 'application/vnd.example+json; charset=utf-8')
|
||||
.expect(200, '{"hello":"world"}', done)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -13,11 +13,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.statusCode.should.equal(302);
|
||||
res.headers.should.have.property('location', 'http://google.com');
|
||||
done();
|
||||
})
|
||||
.expect('location', 'http://google.com')
|
||||
.expect(302, done)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -159,12 +156,11 @@ describe('res', function(){
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('Accept', 'application/octet-stream')
|
||||
.end(function(err, res){
|
||||
res.should.have.status(302);
|
||||
res.headers.should.have.property('location', 'http://google.com');
|
||||
.expect('location', 'http://google.com')
|
||||
.expect('content-length', '0')
|
||||
.expect(302, '', function(err, res){
|
||||
if (err) return done(err)
|
||||
res.headers.should.not.have.property('content-type');
|
||||
res.headers.should.have.property('content-length', '0');
|
||||
res.text.should.equal('');
|
||||
done();
|
||||
})
|
||||
})
|
||||
|
||||
@@ -79,7 +79,7 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect(/user is not defined/, done);
|
||||
.expect(/Cannot read property 'name' of undefined/, done);
|
||||
})
|
||||
})
|
||||
|
||||
@@ -250,7 +250,7 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect(/is not defined/, done);
|
||||
.expect(/Cannot read property 'name' of undefined/, done);
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
194
test/res.send.js
194
test/res.send.js
@@ -105,7 +105,7 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('ETag', '"-1498647312"')
|
||||
.expect('ETag', 'W/"7ff-2796319984"')
|
||||
.end(done);
|
||||
})
|
||||
|
||||
@@ -135,9 +135,34 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('Content-Type', 'text/plain')
|
||||
.expect('hey')
|
||||
.expect(200, done);
|
||||
.expect('Content-Type', 'text/plain; charset=utf-8')
|
||||
.expect(200, 'hey', done);
|
||||
})
|
||||
|
||||
it('should override charset in Content-Type', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.set('Content-Type', 'text/plain; charset=iso-8859-1').send('hey');
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('Content-Type', 'text/plain; charset=utf-8')
|
||||
.expect(200, 'hey', done);
|
||||
})
|
||||
|
||||
it('should keep charset in Content-Type for Buffers', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.set('Content-Type', 'text/plain; charset=iso-8859-1').send(new Buffer('hi'));
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('Content-Type', 'text/plain; charset=iso-8859-1')
|
||||
.expect(200, 'hi', done);
|
||||
})
|
||||
})
|
||||
|
||||
@@ -169,7 +194,7 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('ETag', '"-1498647312"')
|
||||
.expect('ETag', 'W/"7ff-2796319984"')
|
||||
.end(done);
|
||||
})
|
||||
|
||||
@@ -201,11 +226,8 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('content-type', 'application/json; charset=utf-8');
|
||||
res.text.should.equal('{"name":"tobi"}');
|
||||
done();
|
||||
})
|
||||
.expect('Content-Type', 'application/json; charset=utf-8')
|
||||
.expect(200, '{"name":"tobi"}', done)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -265,15 +287,16 @@ describe('res', function(){
|
||||
|
||||
it('should always check regardless of length', function(done){
|
||||
var app = express();
|
||||
var etag = '"asdf"';
|
||||
|
||||
app.use(function(req, res, next){
|
||||
res.set('ETag', 'asdf');
|
||||
res.set('ETag', etag);
|
||||
res.send('hey');
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('If-None-Match', 'asdf')
|
||||
.set('If-None-Match', etag)
|
||||
.expect(304, done);
|
||||
})
|
||||
|
||||
@@ -287,22 +310,23 @@ describe('res', function(){
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('If-None-Match', '"-1498647312"')
|
||||
.set('If-None-Match', 'W/"7ff-2796319984"')
|
||||
.expect(304, done);
|
||||
})
|
||||
|
||||
it('should not perform freshness check unless 2xx or 304', function(done){
|
||||
var app = express();
|
||||
var etag = '"asdf"';
|
||||
|
||||
app.use(function(req, res, next){
|
||||
res.status(500);
|
||||
res.set('ETag', 'asdf');
|
||||
res.set('ETag', etag);
|
||||
res.send('hey');
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('If-None-Match', 'asdf')
|
||||
.set('If-None-Match', etag)
|
||||
.expect('hey')
|
||||
.expect(500, done);
|
||||
})
|
||||
@@ -321,22 +345,35 @@ describe('res', function(){
|
||||
|
||||
describe('"etag" setting', function(){
|
||||
describe('when enabled', function(){
|
||||
it('should send ETag even when content-length < 1024', function(done){
|
||||
it('should send ETag', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.send('kajdslfkasdf');
|
||||
});
|
||||
|
||||
app.enable('etag');
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('etag');
|
||||
done();
|
||||
});
|
||||
.expect('etag', 'W/"c-1525560792"', done)
|
||||
})
|
||||
|
||||
it('should send ETag ', function(done){
|
||||
it('should send ETag for empty string response', function(done){
|
||||
var app = express()
|
||||
|
||||
app.use(function(req, res){
|
||||
res.send('')
|
||||
});
|
||||
|
||||
app.enable('etag')
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('etag', 'W/"0-0"', done)
|
||||
})
|
||||
|
||||
it('should send ETag for long response', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
@@ -344,13 +381,44 @@ describe('res', function(){
|
||||
res.send(str);
|
||||
});
|
||||
|
||||
app.enable('etag');
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('etag', 'W/"7ff-2796319984"', done)
|
||||
});
|
||||
|
||||
it('should not override ETag when manually set', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.set('etag', '"asdf"');
|
||||
res.send(200);
|
||||
});
|
||||
|
||||
app.enable('etag');
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('etag', '"asdf"', done)
|
||||
});
|
||||
|
||||
it('should not send ETag for res.send()', function(done){
|
||||
var app = express()
|
||||
|
||||
app.use(function(req, res){
|
||||
res.send()
|
||||
});
|
||||
|
||||
app.enable('etag')
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('etag', '"-1498647312"');
|
||||
res.headers.should.not.have.property('etag');
|
||||
done();
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
describe('when disabled', function(){
|
||||
@@ -378,17 +446,85 @@ describe('res', function(){
|
||||
app.disable('etag');
|
||||
|
||||
app.use(function(req, res){
|
||||
res.set('etag', 1);
|
||||
res.set('etag', '"asdf"');
|
||||
res.send(200);
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('etag');
|
||||
done();
|
||||
});
|
||||
.expect('etag', '"asdf"', done)
|
||||
});
|
||||
});
|
||||
|
||||
describe('when "strong"', function(){
|
||||
it('should send strong ETag', function(done){
|
||||
var app = express()
|
||||
|
||||
app.set('etag', 'strong');
|
||||
|
||||
app.use(function(req, res){
|
||||
res.send('hello, world!');
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('etag', '"Otu60XkfuuPskIiUxJY4cA=="', done)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when "weak"', function(){
|
||||
it('should send weak ETag', function(done){
|
||||
var app = express()
|
||||
|
||||
app.set('etag', 'weak');
|
||||
|
||||
app.use(function(req, res){
|
||||
res.send('hello, world!');
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('etag', 'W/"d-1486392595"', done)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when a function', function(){
|
||||
it('should send custom ETag', function(done){
|
||||
var app = express()
|
||||
|
||||
app.set('etag', function(body, encoding){
|
||||
body.should.equal('hello, world!')
|
||||
encoding.should.equal('utf8')
|
||||
return '"custom"'
|
||||
});
|
||||
|
||||
app.use(function(req, res){
|
||||
res.send('hello, world!');
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('etag', '"custom"', done)
|
||||
})
|
||||
|
||||
it('should not send falsy ETag', function(done){
|
||||
var app = express()
|
||||
|
||||
app.set('etag', function(body, encoding){
|
||||
return undefined
|
||||
});
|
||||
|
||||
app.use(function(req, res){
|
||||
res.send('hello, world!');
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.headers.should.not.have.property('etag')
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -9,11 +9,7 @@ describe('res', function(){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.sendfile('test/fixtures/user.html', function(err){
|
||||
assert(!err);
|
||||
req.socket.listeners('error').should.have.length(1); // node's original handler
|
||||
done();
|
||||
});
|
||||
res.sendfile('test/fixtures/user.html', done)
|
||||
});
|
||||
|
||||
request(app)
|
||||
|
||||
@@ -20,8 +20,8 @@ describe('res', function(){
|
||||
|
||||
it('should coerce to a string', function(){
|
||||
res.headers = {};
|
||||
res.set('ETag', 123);
|
||||
res.get('ETag').should.equal('123');
|
||||
res.set('X-Number', 123);
|
||||
res.get('X-Number').should.equal('123');
|
||||
})
|
||||
})
|
||||
|
||||
@@ -41,8 +41,9 @@ describe('res', function(){
|
||||
|
||||
it('should coerce to an array of strings', function(){
|
||||
res.headers = {};
|
||||
res.set('ETag', [123, 456]);
|
||||
JSON.stringify(res.get('ETag')).should.equal('["123","456"]');
|
||||
res.set('X-Numbers', [123, 456]);
|
||||
JSON.stringify(res.get('X-Numbers'))
|
||||
.should.equal('["123","456"]');
|
||||
})
|
||||
})
|
||||
|
||||
@@ -66,8 +67,8 @@ describe('res', function(){
|
||||
|
||||
it('should coerce to a string', function(){
|
||||
res.headers = {};
|
||||
res.set({ ETag: 123 });
|
||||
res.get('ETag').should.equal('123');
|
||||
res.set({ 'X-Number': 123 });
|
||||
res.get('X-Number').should.equal('123');
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -2,24 +2,72 @@
|
||||
var utils = require('../lib/utils')
|
||||
, assert = require('assert');
|
||||
|
||||
describe('utils.etag(body)', function(){
|
||||
describe('utils.deprecate(fn, msg)', function(){
|
||||
var env
|
||||
before(function(){
|
||||
env = process.env.NODE_ENV
|
||||
})
|
||||
after(function(){
|
||||
process.env.NODE_ENV = env
|
||||
})
|
||||
|
||||
var str = 'Hello CRC';
|
||||
var strUTF8 = '<!DOCTYPE html>\n<html>\n<head>\n</head>\n<body><p>自動販売</p></body></html>';
|
||||
it('should pass-through fn in test environment', function(){
|
||||
var fn = function(){}
|
||||
process.env.NODE_ENV = 'test'
|
||||
utils.deprecate(fn).should.equal(fn)
|
||||
})
|
||||
|
||||
it('should return new fn in other environment', function(){
|
||||
var fn = function(){}
|
||||
process.env.NODE_ENV = ''
|
||||
utils.deprecate(fn).should.not.equal(fn)
|
||||
})
|
||||
})
|
||||
|
||||
describe('utils.etag(body, encoding)', function(){
|
||||
it('should support strings', function(){
|
||||
utils.etag(str).should.eql('"-2034458343"');
|
||||
utils.etag('express!')
|
||||
.should.eql('"zZdv4imtWD49AHEviejT6A=="')
|
||||
})
|
||||
|
||||
it('should support utf8 strings', function(){
|
||||
utils.etag(strUTF8).should.eql('"1395090196"');
|
||||
utils.etag('express❤', 'utf8')
|
||||
.should.eql('"fsFba4IxwQS6h6Umb+FNxw=="')
|
||||
})
|
||||
|
||||
it('should support buffer', function(){
|
||||
utils.etag(new Buffer(strUTF8)).should.eql('"1395090196"');
|
||||
utils.etag(new Buffer(str)).should.eql('"-2034458343"');
|
||||
var buf = new Buffer('express!')
|
||||
utils.etag(buf)
|
||||
.should.eql('"zZdv4imtWD49AHEviejT6A=="');
|
||||
})
|
||||
|
||||
it('should support empty string', function(){
|
||||
utils.etag('')
|
||||
.should.eql('"1B2M2Y8AsgTpgAmY7PhCfg=="');
|
||||
})
|
||||
})
|
||||
|
||||
describe('utils.wetag(body, encoding)', function(){
|
||||
it('should support strings', function(){
|
||||
utils.wetag('express!')
|
||||
.should.eql('W/"8-3098196679"')
|
||||
})
|
||||
|
||||
it('should support utf8 strings', function(){
|
||||
utils.wetag('express❤', 'utf8')
|
||||
.should.eql('W/"a-1751845617"')
|
||||
})
|
||||
|
||||
it('should support buffer', function(){
|
||||
var buf = new Buffer('express!')
|
||||
utils.wetag(buf)
|
||||
.should.eql('W/"8-3098196679"');
|
||||
})
|
||||
|
||||
it('should support empty string', function(){
|
||||
utils.wetag('')
|
||||
.should.eql('W/"0-0"');
|
||||
})
|
||||
})
|
||||
|
||||
describe('utils.isAbsolute()', function(){
|
||||
@@ -28,7 +76,11 @@ describe('utils.isAbsolute()', function(){
|
||||
assert(!utils.isAbsolute(':\\'));
|
||||
})
|
||||
|
||||
it('should unices', function(){
|
||||
it('should support windows unc', function(){
|
||||
assert(utils.isAbsolute('\\\\foo\\bar'))
|
||||
})
|
||||
|
||||
it('should support unices', function(){
|
||||
assert(utils.isAbsolute('/foo/bar'));
|
||||
assert(!utils.isAbsolute('foo/bar'));
|
||||
})
|
||||
@@ -218,4 +270,10 @@ describe('utils.accepts(type, str)', function(){
|
||||
.should.equal('html');
|
||||
})
|
||||
})
|
||||
|
||||
describe('when params included', function(){
|
||||
it('should match params', function(){
|
||||
assert(null == utils.accepts('text/html; charset=us-ascii', 'text/html; charset=utf-8'));
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user