Merge tag '4.17.3'

This commit is contained in:
Douglas Christopher Wilson 2022-02-17 00:27:11 -05:00
commit 318fd4b543
123 changed files with 807 additions and 309 deletions

View File

@ -27,23 +27,23 @@ jobs:
include:
- name: Node.js 4.0
node-version: "4.0"
npm-i: mocha@5.2.0 supertest@3.4.2
npm-i: mocha@5.2.0 nyc@11.9.0 supertest@3.4.2
- name: Node.js 4.x
node-version: "4.9"
npm-i: mocha@5.2.0 supertest@3.4.2
npm-i: mocha@5.2.0 nyc@11.9.0 supertest@3.4.2
- name: Node.js 5.x
node-version: "5.12"
npm-i: mocha@5.2.0 supertest@3.4.2
npm-i: mocha@5.2.0 nyc@11.9.0 supertest@3.4.2
- name: Node.js 6.x
node-version: "6.17"
npm-i: mocha@6.2.2
npm-i: mocha@6.2.2 nyc@14.1.1 supertest@6.1.6
- name: Node.js 7.x
node-version: "7.10"
npm-i: mocha@6.2.2
npm-i: mocha@6.2.2 nyc@14.1.1 supertest@6.1.6
- name: Node.js 8.x
node-version: "8.17"
@ -68,7 +68,7 @@ jobs:
node-version: "13.14"
- name: Node.js 14.x
node-version: "14.18"
node-version: "14.19"
steps:
- uses: actions/checkout@v2
@ -113,6 +113,7 @@ jobs:
echo "node@$(node -v)"
echo "npm@$(npm -v)"
npm -s ls ||:
(npm -s ls --depth=0 ||:) | awk -F'[ @]' 'NR>1 && $2 { print "::set-output name=" $2 "::" $3 }'
- name: Run tests
shell: bash

20
.gitignore vendored
View File

@ -1,27 +1,15 @@
# OS X
.DS_Store*
Icon?
._*
# Windows
Thumbs.db
ehthumbs.db
Desktop.ini
# Linux
.directory
*~
# npm
node_modules
package-lock.json
*.log
*.gz
# Coveralls
.nyc_output
coverage
# Benchmarking
benchmarks/graphs
# ignore additional files using core.excludesFile
# https://git-scm.com/docs/gitignore

View File

@ -1,3 +1,8 @@
5.x
===
This incorporates all changes after 4.17.2 up to 4.17.3.
5.0.0-beta.1 / 2022-02-14
=========================
@ -157,6 +162,21 @@ This is the first Express 5.0 alpha release, based off 4.10.1.
* add:
- `app.router` is a reference to the base router
4.17.3 / 2022-02-16
===================
* deps: accepts@~1.3.8
- deps: mime-types@~2.1.34
- deps: negotiator@0.6.3
* deps: body-parser@1.19.2
- deps: bytes@3.1.2
- deps: qs@6.9.7
- deps: raw-body@2.4.3
* deps: cookie@0.4.2
* deps: qs@6.9.7
* Fix handling of `__proto__` keys
* pref: remove unnecessary regexp for trust proxy
4.17.2 / 2021-12-16
===================

View File

@ -10,7 +10,7 @@ environment:
- nodejs_version: "11.15"
- nodejs_version: "12.22"
- nodejs_version: "13.14"
- nodejs_version: "14.18"
- nodejs_version: "14.19"
cache:
- node_modules
install:
@ -46,11 +46,25 @@ install:
} elseif ([int]$env:nodejs_version.split(".")[0] -lt 12) {
npm install --silent --save-dev mocha@8.4.0
}
- ps: |
# nyc for test coverage
# - use 10.3.2 for Node.js < 4
# - use 11.9.0 for Node.js < 6
# - use 14.1.1 for Node.js < 8
if ([int]$env:nodejs_version.split(".")[0] -lt 4) {
npm install --silent --save-dev nyc@10.3.2
} elseif ([int]$env:nodejs_version.split(".")[0] -lt 6) {
npm install --silent --save-dev nyc@11.9.0
} elseif ([int]$env:nodejs_version.split(".")[0] -lt 8) {
npm install --silent --save-dev nyc@14.1.1
}
- ps: |
# supertest for http calls
# - use 3.4.2 for Node.js < 6
if ([int]$env:nodejs_version.split(".")[0] -lt 6) {
npm install --silent --save-dev supertest@3.4.2
} elseif ([int]$env:nodejs_version.split(".")[0] -lt 8) {
npm install --silent --save-dev supertest@6.1.6
}
# Update Node.js modules
- ps: |

View File

@ -1,3 +1,5 @@
'use strict'
/**
* Module dependencies.
*/
@ -59,14 +61,14 @@ function authenticate(name, pass, fn) {
if (!module.parent) console.log('authenticating %s:%s', name, pass);
var user = users[name];
// query the db for the given username
if (!user) return fn(new Error('cannot find user'));
if (!user) return fn(null, null)
// apply the same algorithm to the POSTed password, applying
// the hash against the pass / salt, if there is a match we
// found the user
hash({ password: pass, salt: user.salt }, function (err, pass, salt, hash) {
if (err) return fn(err);
if (hash === user.hash) return fn(null, user)
fn(new Error('invalid password'));
fn(null, null)
});
}
@ -99,9 +101,10 @@ app.get('/login', function(req, res){
res.render('login');
});
app.post('/login', function(req, res){
app.post('/login', function (req, res, next) {
if (!req.body) return res.sendStatus(400)
authenticate(req.body.username, req.body.password, function(err, user){
if (err) return next(err)
if (user) {
// Regenerate session when signing in
// to prevent fixation

View File

@ -1,3 +1,5 @@
'use strict'
var users = [];
users.push({ name: 'Tobi' });

View File

@ -1,3 +1,5 @@
'use strict'
var express = require('../../');
var app = module.exports = express();
var users = require('./db');

View File

@ -1,3 +1,4 @@
'use strict'
var users = require('./db');

View File

@ -1,3 +1,5 @@
'use strict'
/**
* Module dependencies.
*/

View File

@ -1,3 +1,5 @@
'use strict'
/**
* Module dependencies.
*/

View File

@ -1,11 +1,18 @@
'use strict'
/**
* Module dependencies.
*/
var express = require('../../');
var path = require('path');
var resolvePath = require('resolve-path')
var app = module.exports = express();
// path to where the files are stored on disk
var FILES_DIR = path.join(__dirname, 'files')
app.get('/', function(req, res){
res.send('<ul>' +
'<li>Download <a href="/files/notes/groceries.txt">notes/groceries.txt</a>.</li>' +
@ -18,7 +25,7 @@ app.get('/', function(req, res){
// /files/* is accessed via req.params[0]
// but here we name it :file
app.get('/files/:file+', function (req, res, next) {
var filePath = path.join(__dirname, 'files', req.params.file);
var filePath = resolvePath(FILES_DIR, req.params.file)
res.download(filePath, function (err) {
if (!err) return; // file sent

View File

@ -1,3 +1,5 @@
'use strict'
/**
* Module dependencies.
*/

View File

@ -1,3 +1,5 @@
'use strict'
/**
* Module dependencies.
*/

View File

@ -1,3 +1,5 @@
'use strict'
/**
* Module dependencies.
*/

View File

@ -1,6 +1,8 @@
'use strict'
var express = require('../../');
var app = express();
var app = module.exports = express()
app.get('/', function(req, res){
res.send('Hello World');

View File

@ -1,3 +1,5 @@
'use strict'
/**
* Module dependencies.
*/

View File

@ -1,3 +1,5 @@
'use strict'
var express = require('../../..');
var apiv1 = express.Router();

View File

@ -1,3 +1,5 @@
'use strict'
var express = require('../../..');
var apiv2 = express.Router();

View File

@ -1,3 +1,5 @@
'use strict'
var express = require('../..');
var app = module.exports = express();

View File

@ -1,3 +1,5 @@
'use strict'
/**
* Module dependencies.
*/

View File

@ -1,3 +1,5 @@
'use strict'
exports.index = function(req, res){
res.redirect('/users');
};

View File

@ -1,3 +1,5 @@
'use strict'
/**
* Module dependencies.
*/

View File

@ -1,3 +1,5 @@
'use strict'
/**
* Module dependencies.
*/

View File

@ -1,3 +1,5 @@
'use strict'
/**
* Module dependencies.
*/

View File

@ -1,3 +1,5 @@
'use strict'
// faux database
var pets = exports.pets = [];

View File

@ -1,3 +1,5 @@
'use strict'
/**
* Module dependencies.
*/

View File

@ -1,3 +1,5 @@
'use strict'
/**
* Module dependencies.
*/

View File

@ -1,3 +1,4 @@
'use strict'
// install redis first:
// https://redis.io/

View File

@ -1,3 +1,5 @@
'use strict'
/**
* Module dependencies.
*/

View File

@ -1,3 +1,5 @@
'use strict'
/**
* Module dependencies.
*/

View File

@ -1,3 +1,5 @@
'use strict'
/**
* Module dependencies.
*/

View File

@ -1,3 +1,5 @@
'use strict'
/**
* Module dependencies.
*/

View File

@ -1,3 +1,5 @@
'use strict'
/**
* Module dependencies.
*/

View File

@ -1,3 +1,5 @@
'use strict'
// Fake posts database
var posts = [

View File

@ -1,3 +1,5 @@
'use strict'
exports.index = function(req, res){
res.render('index', { title: 'Route Separation Example' });
};

View File

@ -1,3 +1,5 @@
'use strict'
// Fake user database
var users = [

View File

@ -1,3 +1,4 @@
'use strict'
// install redis first:
// https://redis.io/

View File

@ -1,3 +1,5 @@
'use strict'
var search = document.querySelector('[type=search]');
var code = document.querySelector('pre');

View File

@ -1,3 +1,4 @@
'use strict'
// install redis first:
// https://redis.io/

View File

@ -1,3 +1,5 @@
'use strict'
/**
* Module dependencies.
*/

View File

@ -1,3 +1,5 @@
'use strict'
/**
* Module dependencies.
*/

View File

@ -1,3 +1,5 @@
'use strict'
/**
* Module dependencies.
*/

View File

@ -1,3 +1,5 @@
'use strict'
/**
* Module dependencies.
*/

View File

@ -1,3 +1,5 @@
'use strict'
/**
* Module dependencies.
*/

View File

@ -1,3 +1,5 @@
'use strict'
/**
* Module dependencies.
*/

View File

@ -1,3 +1,5 @@
'use strict'
module.exports = User;
// faux model

View File

@ -1,3 +1,5 @@
'use strict'
/**
* Module dependencies.
*/
@ -32,7 +34,7 @@ app.use('/api', function(req, res, next){
if (!key) return next(error(400, 'api key required'));
// key is invalid
if (!~apiKeys.indexOf(key)) return next(error(401, 'invalid api key'));
if (apiKeys.indexOf(key) === -1) return next(error(401, 'invalid api key'))
// all good, store req.key for route access
req.key = key;

View File

@ -389,7 +389,7 @@ res.sendFile = function sendFile(path, options, callback) {
* Optionally providing an alternate attachment `filename`,
* and optional callback `callback(err)`. The callback is invoked
* when the data transfer is complete, or when an error has
* ocurred. Be sure to check `res.headersSent` if you plan to respond.
* occurred. Be sure to check `res.headersSent` if you plan to respond.
*
* Optionally providing an `options` object to use with `res.sendFile()`.
* This function will set the `Content-Disposition` header, overriding

View File

@ -187,7 +187,8 @@ exports.compileTrust = function(val) {
if (typeof val === 'string') {
// Support comma-separated values
val = val.split(/ *, */);
val = val.split(',')
.map(function (v) { return v.trim() })
}
return proxyaddr.compile(val || []);

View File

@ -33,7 +33,7 @@
"body-parser": "2.0.0-beta.1",
"content-disposition": "0.5.4",
"content-type": "~1.0.4",
"cookie": "0.4.1",
"cookie": "0.4.2",
"cookie-signature": "1.0.6",
"debug": "3.1.0",
"depd": "~1.1.2",
@ -49,7 +49,7 @@
"parseurl": "~1.3.3",
"path-is-absolute": "1.0.1",
"proxy-addr": "~2.0.7",
"qs": "6.9.6",
"qs": "6.9.7",
"range-parser": "~1.2.1",
"router": "2.0.0-beta.1",
"safe-buffer": "5.2.1",
@ -70,15 +70,16 @@
"eslint": "7.32.0",
"express-session": "1.17.2",
"hbs": "4.2.0",
"istanbul": "0.4.5",
"marked": "0.7.0",
"method-override": "3.0.0",
"mocha": "9.1.3",
"mocha": "9.2.0",
"morgan": "1.10.0",
"multiparty": "4.2.2",
"multiparty": "4.2.3",
"nyc": "15.1.0",
"pbkdf2-password": "1.2.1",
"resolve-path": "1.4.0",
"should": "13.2.3",
"supertest": "6.1.6",
"supertest": "6.2.2",
"vhost": "~3.0.2"
},
"engines": {
@ -94,8 +95,8 @@
"scripts": {
"lint": "eslint .",
"test": "mocha --require test/support/env --reporter spec --bail --check-leaks test/ test/acceptance/",
"test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --require test/support/env --reporter spec --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-ci": "nyc --reporter=lcovonly --reporter=text npm test",
"test-cov": "nyc --reporter=html --reporter=text npm test",
"test-tap": "mocha --require test/support/env --reporter tap --check-leaks test/ test/acceptance/"
}
}

View File

@ -1,3 +1,4 @@
'use strict'
var after = require('after');
var should = require('should');

View File

@ -1,3 +1,4 @@
'use strict'
var after = require('after');
var express = require('../')

View File

@ -22,7 +22,7 @@ describe('auth', function(){
.expect(200, /<form/, done)
})
it('should display login error', function(done){
it('should display login error for bad user', function (done) {
request(app)
.post('/login')
.type('urlencoded')
@ -36,6 +36,21 @@ describe('auth', function(){
.expect(200, /Authentication failed/, done)
})
})
it('should display login error for bad password', function (done) {
request(app)
.post('/login')
.type('urlencoded')
.send('username=tj&password=nogood')
.expect('Location', '/login')
.expect(302, function (err, res) {
if (err) return done(err)
request(app)
.get('/login')
.set('Cookie', getCookie(res))
.expect(200, /Authentication failed/, done)
})
})
})
describe('GET /logout',function(){

View File

@ -36,4 +36,12 @@ describe('downloads', function(){
.expect(404, done)
})
})
describe('GET /files/../index.js', function () {
it('should respond with 403', function (done) {
request(app)
.get('/files/../index.js')
.expect(403, done)
})
})
})

View File

@ -0,0 +1,21 @@
var app = require('../../examples/hello-world')
var request = require('supertest')
describe('hello-world', function () {
describe('GET /', function () {
it('should respond with hello world', function (done) {
request(app)
.get('/')
.expect(200, 'Hello World', done)
})
})
describe('GET /missing', function () {
it('should respond with 404', function (done) {
request(app)
.get('/missing')
.expect(404, done)
})
})
})

View File

@ -1,10 +1,13 @@
'use strict'
var after = require('after')
var express = require('../')
, request = require('supertest');
describe('app.all()', function(){
it('should add a router per method', function(done){
var app = express();
var cb = after(2, done)
app.all('/tobi', function(req, res){
res.end(req.method);
@ -12,11 +15,11 @@ describe('app.all()', function(){
request(app)
.put('/tobi')
.expect('PUT', function(){
.expect(200, 'PUT', cb)
request(app)
.get('/tobi')
.expect('GET', done);
});
.expect(200, 'GET', cb)
})
it('should run the callback for a method just once', function(done){

View File

@ -1,4 +1,6 @@
'use strict'
var assert = require('assert')
var express = require('../')
, fs = require('fs');
var path = require('path')
@ -22,16 +24,16 @@ describe('app', function(){
app.render('user.html', function(err, str){
if (err) return done(err);
str.should.equal('<p>tobi</p>');
assert.strictEqual(str, '<p>tobi</p>')
done();
})
})
it('should throw when the callback is missing', function(){
var app = express();
(function(){
assert.throws(function () {
app.engine('.html', null);
}).should.throw('callback function required');
}, /callback function required/)
})
it('should work without leading "."', function(done){
@ -43,7 +45,7 @@ describe('app', function(){
app.render('user.html', function(err, str){
if (err) return done(err);
str.should.equal('<p>tobi</p>');
assert.strictEqual(str, '<p>tobi</p>')
done();
})
})
@ -58,7 +60,7 @@ describe('app', function(){
app.render('user', function(err, str){
if (err) return done(err);
str.should.equal('<p>tobi</p>');
assert.strictEqual(str, '<p>tobi</p>')
done();
})
})
@ -73,7 +75,7 @@ describe('app', function(){
app.render('user', function(err, str){
if (err) return done(err);
str.should.equal('<p>tobi</p>');
assert.strictEqual(str, '<p>tobi</p>')
done();
})
})

View File

@ -1,3 +1,4 @@
'use strict'
var express = require('../');
var request = require('supertest');
@ -46,23 +47,20 @@ describe('HEAD', function(){
describe('app.head()', function(){
it('should override', function(done){
var app = express()
, called;
app.head('/tobi', function(req, res){
called = true;
res.end('');
res.header('x-method', 'head')
res.end()
});
app.get('/tobi', function(req, res){
assert(0, 'should not call GET');
res.header('x-method', 'get')
res.send('tobi');
});
request(app)
.head('/tobi')
.expect(200, function(){
assert(called);
done();
});
.expect('x-method', 'head')
.expect(200, done)
})
})

View File

@ -1,3 +1,4 @@
'use strict'
var assert = require('assert')
var express = require('..')
@ -32,8 +33,8 @@ describe('app.parent', function(){
blog.use('/admin', blogAdmin);
assert(!app.parent, 'app.parent');
blog.parent.should.equal(app);
blogAdmin.parent.should.equal(blog);
assert.strictEqual(blog.parent, app)
assert.strictEqual(blogAdmin.parent, blog)
})
})
@ -48,10 +49,10 @@ describe('app.mountpath', function(){
app.use(fallback);
blog.use('/admin', admin);
admin.mountpath.should.equal('/admin');
app.mountpath.should.equal('/');
blog.mountpath.should.equal('/blog');
fallback.mountpath.should.equal('/');
assert.strictEqual(admin.mountpath, '/admin')
assert.strictEqual(app.mountpath, '/')
assert.strictEqual(blog.mountpath, '/blog')
assert.strictEqual(fallback.mountpath, '/')
})
})
@ -64,35 +65,56 @@ describe('app.path()', function(){
app.use('/blog', blog);
blog.use('/admin', blogAdmin);
app.path().should.equal('');
blog.path().should.equal('/blog');
blogAdmin.path().should.equal('/blog/admin');
assert.strictEqual(app.path(), '')
assert.strictEqual(blog.path(), '/blog')
assert.strictEqual(blogAdmin.path(), '/blog/admin')
})
})
describe('in development', function(){
before(function () {
this.env = process.env.NODE_ENV
process.env.NODE_ENV = 'development'
})
after(function () {
process.env.NODE_ENV = this.env
})
it('should disable "view cache"', function(){
process.env.NODE_ENV = 'development';
var app = express();
app.enabled('view cache').should.be.false()
process.env.NODE_ENV = 'test';
assert.ok(!app.enabled('view cache'))
})
})
describe('in production', function(){
before(function () {
this.env = process.env.NODE_ENV
process.env.NODE_ENV = 'production'
})
after(function () {
process.env.NODE_ENV = this.env
})
it('should enable "view cache"', function(){
process.env.NODE_ENV = 'production';
var app = express();
app.enabled('view cache').should.be.true()
process.env.NODE_ENV = 'test';
assert.ok(app.enabled('view cache'))
})
})
describe('without NODE_ENV', function(){
before(function () {
this.env = process.env.NODE_ENV
process.env.NODE_ENV = ''
})
after(function () {
process.env.NODE_ENV = this.env
})
it('should default to development', function(){
process.env.NODE_ENV = '';
var app = express();
app.get('env').should.equal('development');
process.env.NODE_ENV = 'test';
assert.strictEqual(app.get('env'), 'development')
})
})

View File

@ -1,3 +1,4 @@
'use strict'
var express = require('../')

View File

@ -1,16 +1,19 @@
'use strict'
var assert = require('assert')
var express = require('../')
var should = require('should')
describe('app', function(){
describe('.locals(obj)', function(){
it('should merge locals', function(){
var app = express();
Object.keys(app.locals).should.eql(['settings']);
should(Object.keys(app.locals)).eql(['settings'])
app.locals.user = 'tobi';
app.locals.age = 2;
Object.keys(app.locals).should.eql(['settings', 'user', 'age']);
app.locals.user.should.equal('tobi');
app.locals.age.should.equal(2);
should(Object.keys(app.locals)).eql(['settings', 'user', 'age'])
assert.strictEqual(app.locals.user, 'tobi')
assert.strictEqual(app.locals.age, 2)
})
})
@ -19,8 +22,8 @@ describe('app', function(){
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');
should(obj).have.property('env', 'test')
should(obj).have.property('title', 'House of Manny')
})
})
})

View File

@ -1,3 +1,4 @@
'use strict'
var express = require('../')
, request = require('supertest');

View File

@ -1,3 +1,4 @@
'use strict'
var express = require('../')
, request = require('supertest');
@ -16,23 +17,21 @@ describe('app', function(){
app.get('/post/:id', function(req, res){
var id = req.params.id;
id.should.be.a.Number()
res.send('' + id);
res.send((typeof id) + ':' + id)
});
app.get('/user/:uid', function(req, res){
var id = req.params.id;
id.should.be.a.Number()
res.send('' + id);
res.send((typeof id) + ':' + id)
});
request(app)
.get('/user/123')
.expect(200, '123', function (err) {
.expect(200, 'number:123', function (err) {
if (err) return done(err)
request(app)
.get('/post/123')
.expect('123', done);
.expect('number:123', done)
})
})
})
@ -50,13 +49,12 @@ describe('app', function(){
app.get('/user/:id', function(req, res){
var id = req.params.id;
id.should.be.a.Number()
res.send('' + id);
res.send((typeof id) + ':' + id)
});
request(app)
.get('/user/123')
.expect('123', done);
.expect(200, 'number:123', done)
})
it('should only call once per request', function(done) {

View File

@ -1,3 +1,4 @@
'use strict'
var assert = require('assert')
var express = require('..');
@ -13,7 +14,7 @@ describe('app', function(){
app.render(path.join(__dirname, 'fixtures', 'user.tmpl'), function (err, str) {
if (err) return done(err);
str.should.equal('<p>tobi</p>');
assert.strictEqual(str, '<p>tobi</p>')
done();
})
})
@ -26,7 +27,7 @@ describe('app', function(){
app.render(path.join(__dirname, 'fixtures', 'user'), function (err, str) {
if (err) return done(err);
str.should.equal('<p>tobi</p>');
assert.strictEqual(str, '<p>tobi</p>')
done();
})
})
@ -39,7 +40,7 @@ describe('app', function(){
app.render('user.tmpl', function (err, str) {
if (err) return done(err);
str.should.equal('<p>tobi</p>');
assert.strictEqual(str, '<p>tobi</p>')
done();
})
})
@ -52,7 +53,7 @@ describe('app', function(){
app.render('blog/post', function (err, str) {
if (err) return done(err);
str.should.equal('<h1>blog post</h1>');
assert.strictEqual(str, '<h1>blog post</h1>')
done();
})
})
@ -72,8 +73,8 @@ describe('app', function(){
app.set('view', View);
app.render('something', function(err, str){
err.should.be.ok()
err.message.should.equal('err!');
assert.ok(err)
assert.strictEqual(err.message, 'err!')
done();
})
})
@ -113,7 +114,7 @@ describe('app', function(){
app.render('email.tmpl', function (err, str) {
if (err) return done(err);
str.should.equal('<p>This is an email</p>');
assert.strictEqual(str, '<p>This is an email</p>')
done();
})
})
@ -128,7 +129,7 @@ describe('app', function(){
app.render('email', function(err, str){
if (err) return done(err);
str.should.equal('<p>This is an email</p>');
assert.strictEqual(str, '<p>This is an email</p>')
done();
})
})
@ -143,7 +144,7 @@ describe('app', function(){
app.render('user.tmpl', function (err, str) {
if (err) return done(err);
str.should.equal('<p>tobi</p>');
assert.strictEqual(str, '<p>tobi</p>')
done();
})
})
@ -161,7 +162,7 @@ describe('app', function(){
app.render('user.tmpl', function (err, str) {
if (err) return done(err);
str.should.equal('<span>tobi</span>');
assert.strictEqual(str, '<span>tobi</span>')
done();
})
})
@ -178,7 +179,7 @@ describe('app', function(){
app.render('name.tmpl', function (err, str) {
if (err) return done(err);
str.should.equal('<p>tobi</p>');
assert.strictEqual(str, '<p>tobi</p>')
done();
})
})
@ -219,7 +220,7 @@ describe('app', function(){
app.render('something', function(err, str){
if (err) return done(err);
str.should.equal('abstract engine');
assert.strictEqual(str, 'abstract engine')
done();
})
})
@ -245,12 +246,12 @@ describe('app', function(){
app.render('something', function(err, str){
if (err) return done(err);
count.should.equal(1);
str.should.equal('abstract engine');
assert.strictEqual(count, 1)
assert.strictEqual(str, 'abstract engine')
app.render('something', function(err, str){
if (err) return done(err);
count.should.equal(2);
str.should.equal('abstract engine');
assert.strictEqual(count, 2)
assert.strictEqual(str, 'abstract engine')
done();
})
})
@ -275,12 +276,12 @@ describe('app', function(){
app.render('something', function(err, str){
if (err) return done(err);
count.should.equal(1);
str.should.equal('abstract engine');
assert.strictEqual(count, 1)
assert.strictEqual(str, 'abstract engine')
app.render('something', function(err, str){
if (err) return done(err);
count.should.equal(1);
str.should.equal('abstract engine');
assert.strictEqual(count, 1)
assert.strictEqual(str, 'abstract engine')
done();
})
})
@ -298,7 +299,7 @@ describe('app', function(){
app.render('user.tmpl', { user: user }, function (err, str) {
if (err) return done(err);
str.should.equal('<p>tobi</p>');
assert.strictEqual(str, '<p>tobi</p>')
done();
})
})
@ -311,7 +312,7 @@ describe('app', function(){
app.render('user.tmpl', {}, function (err, str) {
if (err) return done(err);
str.should.equal('<p>tobi</p>');
assert.strictEqual(str, '<p>tobi</p>')
done();
})
})
@ -325,7 +326,7 @@ describe('app', function(){
app.render('user.tmpl', { user: jane }, function (err, str) {
if (err) return done(err);
str.should.equal('<p>jane</p>');
assert.strictEqual(str, '<p>jane</p>')
done();
})
})
@ -350,12 +351,12 @@ describe('app', function(){
app.render('something', {cache: true}, function(err, str){
if (err) return done(err);
count.should.equal(1);
str.should.equal('abstract engine');
assert.strictEqual(count, 1)
assert.strictEqual(str, 'abstract engine')
app.render('something', {cache: true}, function(err, str){
if (err) return done(err);
count.should.equal(1);
str.should.equal('abstract engine');
assert.strictEqual(count, 1)
assert.strictEqual(str, 'abstract engine')
done();
})
})

View File

@ -1,4 +1,6 @@
'use strict'
var after = require('after')
var express = require('../')
, request = require('supertest');
@ -19,5 +21,123 @@ describe('app', function(){
.get('/foo?name=tobi')
.expect('name=tobi', done);
})
it('should only extend for the referenced app', function (done) {
var app1 = express()
var app2 = express()
var cb = after(2, done)
app1.request.foobar = function () {
return 'tobi'
}
app1.get('/', function (req, res) {
res.send(req.foobar())
})
app2.get('/', function (req, res) {
res.send(req.foobar())
})
request(app1)
.get('/')
.expect(200, 'tobi', cb)
request(app2)
.get('/')
.expect(500, /(?:not a function|has no method)/, cb)
})
it('should inherit to sub apps', function (done) {
var app1 = express()
var app2 = express()
var cb = after(2, done)
app1.request.foobar = function () {
return 'tobi'
}
app1.use('/sub', app2)
app1.get('/', function (req, res) {
res.send(req.foobar())
})
app2.get('/', function (req, res) {
res.send(req.foobar())
})
request(app1)
.get('/')
.expect(200, 'tobi', cb)
request(app1)
.get('/sub')
.expect(200, 'tobi', cb)
})
it('should allow sub app to override', function (done) {
var app1 = express()
var app2 = express()
var cb = after(2, done)
app1.request.foobar = function () {
return 'tobi'
}
app2.request.foobar = function () {
return 'loki'
}
app1.use('/sub', app2)
app1.get('/', function (req, res) {
res.send(req.foobar())
})
app2.get('/', function (req, res) {
res.send(req.foobar())
})
request(app1)
.get('/')
.expect(200, 'tobi', cb)
request(app1)
.get('/sub')
.expect(200, 'loki', cb)
})
it('should not pollute parent app', function (done) {
var app1 = express()
var app2 = express()
var cb = after(2, done)
app1.request.foobar = function () {
return 'tobi'
}
app2.request.foobar = function () {
return 'loki'
}
app1.use('/sub', app2)
app1.get('/sub/foo', function (req, res) {
res.send(req.foobar())
})
app2.get('/', function (req, res) {
res.send(req.foobar())
})
request(app1)
.get('/sub')
.expect(200, 'loki', cb)
request(app1)
.get('/sub/foo')
.expect(200, 'tobi', cb)
})
})
})

View File

@ -1,4 +1,6 @@
'use strict'
var after = require('after')
var express = require('../')
, request = require('supertest');
@ -20,25 +22,122 @@ describe('app', function(){
.expect('HEY', done);
})
it('should not be influenced by other app protos', function(done){
var app = express()
, app2 = express();
it('should only extend for the referenced app', function (done) {
var app1 = express()
var app2 = express()
var cb = after(2, done)
app.response.shout = function(str){
this.send(str.toUpperCase());
};
app1.response.shout = function (str) {
this.send(str.toUpperCase())
}
app2.response.shout = function(str){
this.send(str);
};
app1.get('/', function (req, res) {
res.shout('foo')
})
app.use(function(req, res){
res.shout('hey');
});
app2.get('/', function (req, res) {
res.shout('foo')
})
request(app)
request(app1)
.get('/')
.expect('HEY', done);
.expect(200, 'FOO', cb)
request(app2)
.get('/')
.expect(500, /(?:not a function|has no method)/, cb)
})
it('should inherit to sub apps', function (done) {
var app1 = express()
var app2 = express()
var cb = after(2, done)
app1.response.shout = function (str) {
this.send(str.toUpperCase())
}
app1.use('/sub', app2)
app1.get('/', function (req, res) {
res.shout('foo')
})
app2.get('/', function (req, res) {
res.shout('foo')
})
request(app1)
.get('/')
.expect(200, 'FOO', cb)
request(app1)
.get('/sub')
.expect(200, 'FOO', cb)
})
it('should allow sub app to override', function (done) {
var app1 = express()
var app2 = express()
var cb = after(2, done)
app1.response.shout = function (str) {
this.send(str.toUpperCase())
}
app2.response.shout = function (str) {
this.send(str + '!')
}
app1.use('/sub', app2)
app1.get('/', function (req, res) {
res.shout('foo')
})
app2.get('/', function (req, res) {
res.shout('foo')
})
request(app1)
.get('/')
.expect(200, 'FOO', cb)
request(app1)
.get('/sub')
.expect(200, 'foo!', cb)
})
it('should not pollute parent app', function (done) {
var app1 = express()
var app2 = express()
var cb = after(2, done)
app1.response.shout = function (str) {
this.send(str.toUpperCase())
}
app2.response.shout = function (str) {
this.send(str + '!')
}
app1.use('/sub', app2)
app1.get('/sub/foo', function (req, res) {
res.shout('foo')
})
app2.get('/', function (req, res) {
res.shout('foo')
})
request(app1)
.get('/sub')
.expect(200, 'foo!', cb)
request(app1)
.get('/sub/foo')
.expect(200, 'FOO', cb)
})
})
})

View File

@ -1,3 +1,5 @@
'use strict'
var express = require('../');
var request = require('supertest');

View File

@ -1,3 +1,4 @@
'use strict'
var after = require('after');
var express = require('../')
@ -759,6 +760,7 @@ describe('app.router', function(){
describe('.:name', function(){
it('should denote a format', function(done){
var app = express();
var cb = after(2, done)
app.get('/:name.:format', function(req, res){
res.end(req.params.name + ' as ' + req.params.format);
@ -766,17 +768,18 @@ describe('app.router', function(){
request(app)
.get('/foo.json')
.expect('foo as json', function(){
.expect(200, 'foo as json', cb)
request(app)
.get('/foo')
.expect(404, done);
});
.expect(404, cb)
})
})
describe('.:name?', function(){
it('should denote an optional format', function(done){
var app = express();
var cb = after(2, done)
app.get('/:name.:format?', function(req, res){
res.end(req.params.name + ' as ' + (req.params.format || 'html'));
@ -784,11 +787,11 @@ describe('app.router', function(){
request(app)
.get('/foo')
.expect('foo as html', function(){
.expect(200, 'foo as html', cb)
request(app)
.get('/foo.json')
.expect('foo as json', done);
});
.expect(200, 'foo as json', done)
})
})
@ -1130,6 +1133,6 @@ describe('app.router', function(){
it('should be chainable', function(){
var app = express();
app.get('/', function(){}).should.equal(app);
assert.strictEqual(app.get('/', function () {}), app)
})
})

View File

@ -1,3 +1,6 @@
'use strict'
var assert = require('assert')
var express = require('../')
, request = require('supertest');
@ -34,20 +37,20 @@ describe('app', function(){
next();
}, function(err, req, res, next){
b = true;
err.message.should.equal('fabricated error');
assert.strictEqual(err.message, 'fabricated error')
next(err);
}, function(err, req, res, next){
c = true;
err.message.should.equal('fabricated error');
assert.strictEqual(err.message, 'fabricated error')
next();
}, function(err, req, res, next){
d = true;
next();
}, function(req, res){
a.should.be.false()
b.should.be.true()
c.should.be.true()
d.should.be.false()
assert.ok(!a)
assert.ok(b)
assert.ok(c)
assert.ok(!d)
res.sendStatus(204);
});

View File

@ -1,3 +1,4 @@
'use strict'
var after = require('after');
var assert = require('assert')
@ -10,7 +11,7 @@ describe('app', function(){
, app = express();
blog.on('mount', function(arg){
arg.should.equal(app);
assert.strictEqual(arg, app)
done();
});
@ -37,6 +38,7 @@ describe('app', function(){
var blog = express()
, forum = express()
, app = express();
var cb = after(2, done)
blog.get('/', function(req, res){
res.end('blog');
@ -51,11 +53,11 @@ describe('app', function(){
request(app)
.get('/blog')
.expect('blog', function(){
.expect(200, 'blog', cb)
request(app)
.get('/forum')
.expect('forum', done);
});
.expect(200, 'forum', done)
})
it('should set the child\'s .parent', function(){
@ -63,7 +65,7 @@ describe('app', function(){
, app = express();
app.use('/blog', blog);
blog.parent.should.equal(app);
assert.strictEqual(blog.parent, app)
})
it('should support dynamic routes', function(done){
@ -102,11 +104,11 @@ describe('app', function(){
});
blog.once('mount', function (parent) {
parent.should.equal(app);
assert.strictEqual(parent, app)
cb();
});
other.once('mount', function (parent) {
parent.should.equal(app);
assert.strictEqual(parent, app)
cb();
});

View File

@ -1,3 +1,4 @@
'use strict'
var assert = require('assert');
var express = require('..');

View File

@ -1,3 +1,4 @@
'use strict'
var assert = require('assert')
var express = require('../');

View File

@ -1,3 +1,4 @@
'use strict'
var assert = require('assert')
var Buffer = require('safe-buffer').Buffer

View File

@ -1,3 +1,4 @@
'use strict'
var assert = require('assert')
var Buffer = require('safe-buffer').Buffer

View File

@ -1,3 +1,4 @@
'use strict'
var assert = require('assert')
var Buffer = require('safe-buffer').Buffer

View File

@ -1,3 +1,4 @@
'use strict'
var assert = require('assert')
var Buffer = require('safe-buffer').Buffer

View File

@ -1,3 +1,4 @@
'use strict'
var assert = require('assert')
var Buffer = require('safe-buffer').Buffer

View File

@ -1,3 +1,4 @@
'use strict'
var assert = require('assert')
var express = require('../');

View File

@ -1,3 +1,4 @@
'use strict'
var express = require('../')
, request = require('supertest');

View File

@ -1,3 +1,4 @@
'use strict'
var express = require('../')
, request = require('supertest');

View File

@ -1,3 +1,4 @@
'use strict'
var express = require('../')
, request = require('supertest');

View File

@ -1,36 +1,39 @@
'use strict'
var express = require('../')
, request = require('supertest');
describe('req', function(){
describe('.acceptsEncodings', function () {
it('should be true if encoding accepted', function(done){
it('should return encoding if accepted', function (done) {
var app = express();
app.use(function(req, res){
req.acceptsEncodings('gzip').should.be.ok()
req.acceptsEncodings('deflate').should.be.ok()
res.end();
});
app.get('/', function (req, res) {
res.send({
gzip: req.acceptsEncodings('gzip'),
deflate: req.acceptsEncodings('deflate')
})
})
request(app)
.get('/')
.set('Accept-Encoding', ' gzip, deflate')
.expect(200, done);
.expect(200, { gzip: 'gzip', deflate: 'deflate' }, done)
})
it('should be false if encoding not accepted', function(done){
var app = express();
app.use(function(req, res){
req.acceptsEncodings('bogus').should.not.be.ok()
res.end();
});
app.get('/', function (req, res) {
res.send({
bogus: req.acceptsEncodings('bogus')
})
})
request(app)
.get('/')
.set('Accept-Encoding', ' gzip, deflate')
.expect(200, done);
.expect(200, { bogus: false }, done)
})
})
})

View File

@ -1,52 +1,56 @@
'use strict'
var express = require('../')
, request = require('supertest');
describe('req', function(){
describe('.acceptsLanguages', function(){
it('should be true if language accepted', function(done){
it('should return language if accepted', function (done) {
var app = express();
app.use(function(req, res){
req.acceptsLanguages('en-us').should.be.ok()
req.acceptsLanguages('en').should.be.ok()
res.end();
});
app.get('/', function (req, res) {
res.send({
'en-us': req.acceptsLanguages('en-us'),
en: req.acceptsLanguages('en')
})
})
request(app)
.get('/')
.set('Accept-Language', 'en;q=.5, en-us')
.expect(200, done);
.expect(200, { 'en-us': 'en-us', en: 'en' }, done)
})
it('should be false if language not accepted', function(done){
var app = express();
app.use(function(req, res){
req.acceptsLanguages('es').should.not.be.ok()
res.end();
});
app.get('/', function (req, res) {
res.send({
es: req.acceptsLanguages('es')
})
})
request(app)
.get('/')
.set('Accept-Language', 'en;q=.5, en-us')
.expect(200, done);
.expect(200, { es: false }, done)
})
describe('when Accept-Language is not present', function(){
it('should always return true', function(done){
it('should always return language', function (done) {
var app = express();
app.use(function(req, res){
req.acceptsLanguages('en').should.be.ok()
req.acceptsLanguages('es').should.be.ok()
req.acceptsLanguages('jp').should.be.ok()
res.end();
});
app.get('/', function (req, res) {
res.send({
en: req.acceptsLanguages('en'),
es: req.acceptsLanguages('es'),
jp: req.acceptsLanguages('jp')
})
})
request(app)
.get('/')
.expect(200, done);
.expect(200, { en: 'en', es: 'es', jp: 'jp' }, done)
})
})
})

View File

@ -1,3 +1,4 @@
'use strict'
var express = require('..')
var request = require('supertest')

View File

@ -1,3 +1,4 @@
'use strict'
var express = require('../')
, request = require('supertest');

View File

@ -1,3 +1,4 @@
'use strict'
var express = require('../')
, request = require('supertest')

View File

@ -1,3 +1,4 @@
'use strict'
var express = require('../')
, request = require('supertest')

View File

@ -1,3 +1,4 @@
'use strict'
var express = require('../')
, request = require('supertest')

View File

@ -1,3 +1,4 @@
'use strict'
var express = require('../')
, request = require('supertest');
@ -21,7 +22,7 @@ describe('req', function(){
.expect('client', done);
})
it('should return the addr after trusted proxy', function(done){
it('should return the addr after trusted proxy based on count', function (done) {
var app = express();
app.set('trust proxy', 2);
@ -36,6 +37,21 @@ describe('req', function(){
.expect('p1', done);
})
it('should return the addr after trusted proxy based on list', function (done) {
var app = express()
app.set('trust proxy', '10.0.0.1, 10.0.0.2, 127.0.0.1, ::1')
app.get('/', function (req, res) {
res.send(req.ip)
})
request(app)
.get('/')
.set('X-Forwarded-For', '10.0.0.2, 10.0.0.3, 10.0.0.1', '10.0.0.4')
.expect('10.0.0.3', done)
})
it('should return the addr after trusted proxy, from sub app', function (done) {
var app = express();
var sub = express();

View File

@ -1,3 +1,4 @@
'use strict'
var express = require('../')
, request = require('supertest');

View File

@ -1,3 +1,4 @@
'use strict'
var express = require('..')
var request = require('supertest')

View File

@ -1,3 +1,4 @@
'use strict'
var express = require('../')
, request = require('supertest');

View File

@ -1,3 +1,4 @@
'use strict'
var express = require('../')
, request = require('supertest');

View File

@ -1,4 +1,6 @@
'use strict'
var assert = require('assert')
var express = require('../')
, request = require('supertest');
@ -82,7 +84,8 @@ describe('req', function(){
describe('when "query parser" an unknown value', function () {
it('should throw', function () {
createApp.bind(null, 'bogus').should.throw(/unknown value.*query parser/);
assert.throws(createApp.bind(null, 'bogus'),
/unknown value.*query parser/)
});
});
})

View File

@ -1,3 +1,4 @@
'use strict'
var express = require('..');
var request = require('supertest')

View File

@ -1,3 +1,4 @@
'use strict'
var express = require('../')
, request = require('supertest');
@ -8,18 +9,20 @@ describe('req', function(){
var app = express();
app.get('/user/:id/:op?', function(req, res, next){
req.route.path.should.equal('/user/:id/:op?');
res.header('path-1', req.route.path)
next();
});
app.get('/user/:id/edit', function(req, res){
req.route.path.should.equal('/user/:id/edit');
res.header('path-2', req.route.path)
res.end();
});
request(app)
.get('/user/12/edit')
.expect(200, done);
.expect('path-1', '/user/:id/:op?')
.expect('path-2', '/user/:id/edit')
.expect(200, done)
})
})
})

View File

@ -1,3 +1,4 @@
'use strict'
var express = require('../')
, request = require('supertest');

View File

@ -1,3 +1,4 @@
'use strict'
var express = require('../')
, request = require('supertest')

View File

@ -1,3 +1,4 @@
'use strict'
var express = require('../')
, request = require('supertest');

View File

@ -1,3 +1,4 @@
'use strict'
var express = require('../')
, request = require('supertest');

Some files were not shown because too many files have changed in this diff Show More