Compare commits

..

46 Commits
2.4.5 ... 2.5.3

Author SHA1 Message Date
TJ Holowaychuk
92c1c953dc Release 2.5.3 2011-12-30 15:31:10 -08:00
TJ Holowaychuk
8b372b3faa fixed a require 2011-12-30 15:30:00 -08:00
TJ Holowaychuk
da3a743c1b backported req.is() charset fix 2011-12-30 15:29:21 -08:00
TJ Holowaychuk
09c9537381 tweak eol 2011-12-28 10:15:18 -07:00
TJ Holowaychuk
9cf1800731 Merge pull request #942 from atsuya/fix_eol
Use os.platform to determine End-of-line
2011-12-28 09:14:56 -08:00
Atsuya Takagi
0d0fd347ab determine enf of line based on os.platform. 2011-12-28 01:26:53 -08:00
Tj Holowaychuk
5cf8023dc3 connect 1.x dep 2011-12-16 08:51:55 -08:00
Tj Holowaychuk
380a6c5363 Release 2.5.2 2011-12-10 11:07:21 -08:00
Tj Holowaychuk
c047b64ab5 removed less support since compiler() has gone away 2011-12-10 11:05:49 -08:00
Tj Holowaychuk
ae2bcb2615 express(1) LF -> CRLF for windows 2011-12-10 11:05:20 -08:00
Tj Holowaychuk
02cdf0c72b fixed express(1) --version 2011-11-18 08:03:16 -08:00
Tj Holowaychuk
a7520ad00c Release 2.5.1 2011-11-17 11:36:13 -08:00
Tj Holowaychuk
bf7807619d updated connect to 1.8.x 2011-11-17 11:32:56 -08:00
Tj Holowaychuk
b5346005af typo 2011-11-04 08:55:57 -07:00
Tj Holowaychuk
334a8d3fa2 Removed sass.js support from express(1)
sass.js is lame, use stylus
2011-11-04 08:35:10 -07:00
Tj Holowaychuk
7c6c07497a "node": ">= 0.4.1 < 0.7.0" 2011-10-24 16:01:46 -07:00
Tj Holowaychuk
95f6cda9c4 Release 2.5.0 2011-10-24 16:00:46 -07:00
Tj Holowaychuk
e2de941d09 Release 0.5.0 2011-10-24 16:00:35 -07:00
Tj Holowaychuk
f7d67ce766 Added ./routes dir for generated app by default 2011-10-24 15:58:22 -07:00
Tj Holowaychuk
b63f2ca903 Added npm install reminder to express(1) app gen 2011-10-24 15:46:42 -07:00
Tj Holowaychuk
77c2d89be6 fixing tests 2011-10-24 14:59:21 -07:00
Tj Holowaychuk
458097fe7b fixing tests 2011-10-24 14:51:09 -07:00
Tj Holowaychuk
1b25240d36 update expresso/should 2011-10-24 14:47:06 -07:00
Tj Holowaychuk
1cce4d98ff Removed make test-cov since it wont work with node 0.5.x 2011-10-24 14:37:09 -07:00
Tj Holowaychuk
09b5c79073 OCD 2011-10-24 14:36:45 -07:00
Tj Holowaychuk
9348500366 readme 2011-10-24 14:36:30 -07:00
Tj Holowaychuk
0f6a044d98 Fixed express(1) public dir for windows. Closes #866 2011-10-14 08:38:21 -07:00
Tj Holowaychuk
049a557341 remove test stuff 2011-10-07 08:30:31 -07:00
Tj Holowaychuk
94a6f42efd clean up jade example 2011-10-07 08:28:57 -07:00
Tj Holowaychuk
a4aed5f51a jade example using template inheritance 2011-10-07 08:25:43 -07:00
Tj Holowaychuk
3e6f45cb72 update jade dev dep 2011-10-07 08:19:11 -07:00
Tj Holowaychuk
3bd4de7f73 bump express(1) version 2011-10-06 12:05:44 -07:00
Tj Holowaychuk
5c04f85f93 Release 2.4.7 2011-10-05 15:41:50 -07:00
Tj Holowaychuk
77f885d4a0 connect 1.7.x to fix npm issue... 2011-10-05 15:34:22 -07:00
Tj Holowaychuk
c2fc9a83e8 Added mkdirp to express(1). Closes #795 2011-09-21 08:24:37 -07:00
Tj Holowaychuk
d8b20bd2d5 Added simple json-config example
for some who might prefer this. there are benefits to both
2011-09-13 09:00:09 -07:00
Tj Holowaychuk
d3c4fd91c9 typo 2011-09-12 10:39:22 -07:00
Tj Holowaychuk
00e44f6fc9 Fixed res.redirect() HEAD support. [reported by xerox] 2011-09-07 10:01:28 -07:00
Tj Holowaychuk
6692f911ab Fixed req.flash(), only escape args 2011-09-06 15:14:09 -07:00
Tj Holowaychuk
4f0b3f4684 Added shorthand for the parsed request's pathname 2011-09-02 16:41:58 -07:00
Tj Holowaychuk
cbf330c3db Fixed absolute path checking on windows. Closes #829 [reported by andrewpmckenzie] 2011-08-29 08:40:30 -07:00
Tj Holowaychuk
13010987b0 logger for jade example 2011-08-24 03:14:21 -07:00
Tj Holowaychuk
b078481cdb Release 2.5.6 2011-08-22 10:20:04 -07:00
Tj Holowaychuk
3888468a96 Fixed multiple param callback regression. Closes #824 [reported by TroyGoode] 2011-08-22 10:04:46 -07:00
Tj Holowaychuk
a6b70ceca4 fixed tests 2011-08-22 09:47:43 -07:00
Tj Holowaychuk
45757a0f1a bump express(1) version 2011-08-20 04:33:51 -07:00
25 changed files with 357 additions and 195 deletions

1
.gitignore vendored
View File

@@ -11,3 +11,4 @@ lib-cov
benchmarks/graphs
testing.js
node_modules/
testing

View File

@@ -1,10 +1,52 @@
2.5.3 / 2011-12-30
==================
* Fixed `req.is()` when a charset is present
2.5.2 / 2011-12-10
==================
* Fixed: express(1) LF -> CRLF for windows
2.5.1 / 2011-11-17
==================
* Changed: updated connect to 1.8.x
* Removed sass.js support from express(1)
2.5.0 / 2011-10-24
==================
* Added ./routes dir for generated app by default
* Added npm install reminder to express(1) app gen
* Added 0.5.x support
* Removed `make test-cov` since it wont work with node 0.5.x
* Fixed express(1) public dir for windows. Closes #866
2.4.7 / 2011-10-05
==================
* Added mkdirp to express(1). Closes #795
* Added simple _json-config_ example
* Added shorthand for the parsed request's pathname via `req.path`
* Changed connect dep to 1.7.x to fix npm issue...
* Fixed `res.redirect()` __HEAD__ support. [reported by xerox]
* Fixed `req.flash()`, only escape args
* Fixed absolute path checking on windows. Closes #829 [reported by andrewpmckenzie]
2.4.6 / 2011-08-22
==================
* Fixed multiple param callback regression. Closes #824 [reported by TroyGoode]
2.4.5 / 2011-08-19
==================
* Added support for routes to handle errors. Closes #809
* Added `app.routes.all()`. Closes #803
* Added "basepath" setting to work in conjunction with reverse proxies etc. * Refactored `Route` to use a single array of callbacks
* Added "basepath" setting to work in conjunction with reverse proxies etc.
* Refactored `Route` to use a single array of callbacks
* Added support for multiple callbacks for `app.param()`. Closes #801
Closes #805
* Changed: removed .call(self) for route callbacks

View File

@@ -1,16 +1,10 @@
DOCS = $(shell find docs/*.md)
HTMLDOCS =$(DOCS:.md=.html)
HTMLDOCS = $(DOCS:.md=.html)
TESTS = $(shell find test/*.test.js)
test:
@NODE_ENV=test ./node_modules/.bin/expresso \
-I lib \
$(TESTFLAGS) \
$(TESTS)
test-cov:
@TESTFLAGS=--cov $(MAKE) test
@NODE_ENV=test ./node_modules/.bin/expresso $(TESTS)
docs: $(HTMLDOCS)
@ echo "... generating TOC"
@@ -32,4 +26,4 @@ site:
docclean:
rm -f docs/*.{1,html}
.PHONY: site test test-cov docs docclean
.PHONY: site test docs docclean

View File

@@ -95,7 +95,9 @@ The following are the major contributors of Express (in no specific order).
Express 1.x is compatible with node 0.2.x and connect < 1.0.
Express 2.x is compatible with node 0.4.x and connect 1.x
Express 2.x is compatible with node 0.4.x or 0.6.x, and connect 1.x
Express 3.x (master) will be compatible with node 0.6.x and connect 2.x
## Viewing Examples

View File

@@ -5,13 +5,15 @@
*/
var fs = require('fs')
, exec = require('child_process').exec;
, os = require('os')
, exec = require('child_process').exec
, mkdirp = require('mkdirp');
/**
* Framework version.
*/
var version = '2.4.4';
var version = '2.5.2';
/**
* Add session support.
@@ -25,6 +27,12 @@ var sessions = false;
var cssEngine;
/**
* End-of-line code.
*/
var eol = 'win32' == os.platform() ? '\r\n' : '\n';
/**
* Template engine to utilize.
*/
@@ -42,11 +50,26 @@ var usage = ''
+ ' Options:\n'
+ ' -s, --sessions add session support\n'
+ ' -t, --template <engine> add template <engine> support (jade|ejs). default=jade\n'
+ ' -c, --css <engine> add stylesheet <engine> support (less|sass|stylus). default=plain css\n'
+ ' -c, --css <engine> add stylesheet <engine> support (stylus). default=plain css\n'
+ ' -v, --version output framework version\n'
+ ' -h, --help output help information\n'
;
/**
* Routes index template.
*/
var index = [
''
, '/*'
, ' * GET home page.'
, ' */'
, ''
, 'exports.index = function(req, res){'
, ' res.render(\'index\', { title: \'Express\' })'
, '};'
].join(eol);
/**
* Jade layout template.
*/
@@ -58,7 +81,7 @@ var jadeLayout = [
, ' title= title'
, ' link(rel=\'stylesheet\', href=\'/stylesheets/style.css\')'
, ' body!= body'
].join('\n');
].join(eol);
/**
* Jade index template.
@@ -67,7 +90,7 @@ var jadeLayout = [
var jadeIndex = [
'h1= title'
, 'p Welcome to #{title}'
].join('\n');
].join(eol);
/**
* EJS layout template.
@@ -84,7 +107,7 @@ var ejsLayout = [
, ' <%- body %>'
, ' </body>'
, '</html>'
].join('\n');
].join(eol);
/**
* EJS index template.
@@ -93,7 +116,7 @@ var ejsLayout = [
var ejsIndex = [
'<h1><%= title %></h1>'
, '<p>Welcome to <%= title %></p>'
].join('\n');
].join(eol);
/**
* Default css template.
@@ -108,34 +131,7 @@ var css = [
, 'a {'
, ' color: #00B7FF;'
, '}'
].join('\n');
/**
* Default less template.
*/
var less = [
'body {'
, ' padding: 50px;'
, ' font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;'
, '}'
, ''
, 'a {'
, ' color: #00B7FF;'
, '}'
].join('\n');
/**
* Default sass template.
*/
var sass = [
'body'
, ' :padding 50px'
, ' :font 14px "Lucida Grande", Helvetica, Arial, sans-serif'
, 'a'
, ' :color #00B7FF'
].join('\n');
].join(eol);
/**
* Default stylus template.
@@ -147,7 +143,7 @@ var stylus = [
, ' font: 14px "Lucida Grande", Helvetica, Arial, sans-serif'
, 'a'
, ' color: #00B7FF'
].join('\n');
].join(eol);
/**
* App template.
@@ -159,7 +155,8 @@ var app = [
, ' * Module dependencies.'
, ' */'
, ''
, 'var express = require(\'express\');'
, 'var express = require(\'express\')'
, ' , routes = require(\'./routes\')'
, ''
, 'var app = module.exports = express.createServer();'
, ''
@@ -184,16 +181,12 @@ var app = [
, ''
, '// Routes'
, ''
, 'app.get(\'/\', function(req, res){'
, ' res.render(\'index\', {'
, ' title: \'Express\''
, ' });'
, '});'
, 'app.get(\'/\', routes.index);'
, ''
, 'app.listen(3000);'
, 'console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);'
, ''
].join('\n');
].join(eol);
// Parse arguments
@@ -259,7 +252,16 @@ while (args.length) {
*/
function createApplicationAt(path) {
console.log();
process.on('exit', function(){
console.log();
console.log(' dont forget to install dependencies:');
console.log(' $ cd %s && npm install', path);
console.log();
});
mkdir(path, function(){
mkdir(path + '/public');
mkdir(path + '/public/javascripts');
mkdir(path + '/public/images');
mkdir(path + '/public/stylesheets', function(){
@@ -267,16 +269,15 @@ function createApplicationAt(path) {
case 'stylus':
write(path + '/public/stylesheets/style.styl', stylus);
break;
case 'less':
write(path + '/public/stylesheets/style.less', less);
break;
case 'sass':
write(path + '/public/stylesheets/style.sass', sass);
break;
default:
write(path + '/public/stylesheets/style.css', css);
}
});
mkdir(path + '/routes', function(){
write(path + '/routes/index.js', index);
});
mkdir(path + '/views', function(){
switch (templateEngine) {
case 'ejs':
@@ -292,12 +293,8 @@ function createApplicationAt(path) {
// CSS Engine support
switch (cssEngine) {
case 'sass':
case 'less':
app = app.replace('{css}', '\n app.use(express.compiler({ src: __dirname + \'/public\', enable: [\'' + cssEngine + '\'] }));');
break;
case 'stylus':
app = app.replace('{css}', '\n app.use(require(\'stylus\').middleware({ src: __dirname + \'/public\' }));');
app = app.replace('{css}', eol + ' app.use(require(\'stylus\').middleware({ src: __dirname + \'/public\' }));');
break;
default:
app = app.replace('{css}', '');
@@ -305,22 +302,22 @@ function createApplicationAt(path) {
// Session support
app = app.replace('{sess}', sessions
? '\n app.use(express.cookieParser());\n app.use(express.session({ secret: \'your secret here\' }));'
? eol + ' app.use(express.cookieParser());' + eol + ' app.use(express.session({ secret: \'your secret here\' }));'
: '');
// Template support
app = app.replace(':TEMPLATE', templateEngine);
// package.json
var json = '{\n';
json += ' "name": "application-name"\n';
json += ' , "version": "0.0.1"\n';
json += ' , "private": true\n';
json += ' , "dependencies": {\n';
json += ' "express": "' + version + '"\n';
if (cssEngine) json += ' , "' + cssEngine + '": ">= 0.0.1"\n';
if (templateEngine) json += ' , "' + templateEngine + '": ">= 0.0.1"\n';
json += ' }\n';
var json = '{' + eol;
json += ' "name": "application-name"' + eol;
json += ' , "version": "0.0.1"' + eol;
json += ' , "private": true' + eol;
json += ' , "dependencies": {' + eol;
json += ' "express": "' + version + '"' + eol;
if (cssEngine) json += ' , "' + cssEngine + '": ">= 0.0.1"' + eol;
if (templateEngine) json += ' , "' + templateEngine + '": ">= 0.0.1"' + eol;
json += ' }' + eol;
json += '}';
@@ -398,9 +395,9 @@ function prompt(msg, fn) {
*/
function mkdir(path, fn) {
exec('mkdir -p ' + path, function(err){
mkdirp(path, 0755, function(err){
if (err) throw err;
console.log(' \x1b[36mcreate\x1b[0m : ' + path);
console.log(' \033[36mcreate\033[0m : ' + path);
fn && fn();
});
}

View File

@@ -13,13 +13,17 @@ var pub = __dirname + '/public';
// and then serve with connect's staticProvider
var app = express.createServer();
app.use(express.logger('dev'));
app.use(express.compiler({ src: pub, enable: ['sass'] }));
app.use(app.router);
app.use(express.static(pub));
app.use(express.errorHandler({ dump: true, stack: true }));
// Optional since express defaults to CWD/views
// we're using jade's template inheritance, so we dont need
// the express layout concept
app.set('view options', { layout: false });
// Optional since express defaults to CWD/views
app.set('views', __dirname + '/views');
// Set our default template engine to "jade"
@@ -34,30 +38,15 @@ function User(name, email) {
// Dummy users
var users = [
new User('tj', 'tj@vision-media.ca')
, new User('ciaran', 'ciaranj@gmail.com')
, new User('aaron', 'aaron.heckmann+github@gmail.com')
new User('Tobi', 'tobi@learnboost.com')
, new User('Loki', 'loki@learnboost.com')
, new User('Jane', 'jane@learnboost.com')
];
app.get('/', function(req, res){
res.render('users', { users: users });
});
app.get('/users/callback', function(req, res){
// a callback is also accepted
res.partial('users/user', users, function(err, html){
if (err) throw err;
res.send(html);
});
});
app.get('/users', function(req, res){
// we can use res.partial() as if
// we were in a view, utilizing the same api
// to render a fragment
res.partial('users/user', users);
});
app.get('/users/list', function(req, res){
// use "object" to utilize the name deduced from
// the view filename. The examples below are equivalent

View File

@@ -1,3 +0,0 @@
head
title Jade Example
link(rel="stylesheet", href="/stylesheets/style.css")

View File

@@ -1,4 +1,8 @@
!!!
doctype 5
html
include header
body!= body
head
block title
title Jade Example
link(rel="stylesheet", href="/stylesheets/style.css")
body
block content

View File

@@ -1,3 +1,12 @@
- if (users.length)
h1 Users
#users!= partial('user', users)
extends ../layout
block title
title Users
block content
if users.length
h1 Users
#users
for user in users
include ./user

View File

@@ -1,3 +1,4 @@
ul#users
- each user in list
li!= partial('user', user)
for user in list
li
include ./user

View File

@@ -0,0 +1,26 @@
/**
* Module dependencies.
*/
var express = require('../../');
app = express.createServer();
// load the config for this environment (NODE_ENV)
var config = require('./config')[app.settings.env];
// apply settings
for (var key in config) app.set(key, config[key]);
// apply middleware
config.middleware.forEach(app.use.bind(app));
app.get('/', function(req, res){
res.render('index', { layout: false });
});
app.listen(3000);

View File

@@ -0,0 +1,19 @@
// ok so it's not JSON, but close enough :)
var express = require('../../');
exports.development = {
'view engine': 'jade'
, 'views': __dirname + '/views'
, 'title': 'My Site'
, 'middleware': [
express.logger('dev')
, app.router
, express.static(__dirname + '/public')
]
};
exports.production = {
};

View File

@@ -0,0 +1,4 @@
html
body
h1 #{settings.title}
p Simple example

View File

@@ -28,7 +28,7 @@ var exports = module.exports = connect.middleware;
* Framework version.
*/
exports.version = '2.4.5';
exports.version = '2.5.3';
/**
* Shortcut for `new Server(...)`.

View File

@@ -12,6 +12,7 @@
var http = require('http')
, req = http.IncomingMessage.prototype
, utils = require('./utils')
, parse = require('url').parse
, mime = require('mime');
/**
@@ -87,6 +88,17 @@ req.get = function(field, param){
return RegExp.$1 || RegExp.$2;
};
/**
* Short-hand for `require('url').parse(req.url).pathname`.
*
* @return {String}
* @api public
*/
req.__defineGetter__('path', function(){
return parse(this.url).pathname;
});
/**
* Check if the _Accept_ header is present, and includes the given `type`.
*
@@ -217,10 +229,10 @@ req.flash = function(type, msg){
, args = arguments
, formatters = this.app.flashFormatters || {};
formatters.__proto__ = flashFormatters;
msg = utils.miniMarkdown(utils.escape(msg));
msg = utils.miniMarkdown(msg);
msg = msg.replace(/%([a-zA-Z])/g, function(_, format){
var formatter = formatters[format];
if (formatter) return formatter(args[i++]);
if (formatter) return formatter(utils.escape(args[i++]));
});
return (msgs[type] = msgs[type] || []).push(msg);
} else if (type) {
@@ -280,16 +292,18 @@ req.flash = function(type, msg){
req.is = function(type){
var fn = this.app.is(type);
if (fn) return fn(this);
var contentType = this.headers['content-type'];
if (!contentType) return;
var ct = this.headers['content-type'];
if (!ct) return false;
ct = ct.split(';')[0];
if (!~type.indexOf('/')) type = mime.lookup(type);
if (~type.indexOf('*')) {
type = type.split('/')
contentType = contentType.split('/');
if ('*' == type[0] && type[1] == contentType[1]) return true;
if ('*' == type[1] && type[0] == contentType[0]) return true;
type = type.split('/');
ct = ct.split('/');
if ('*' == type[0] && type[1] == ct[1]) return true;
if ('*' == type[1] && type[0] == ct[0]) return true;
return false;
}
return !! ~contentType.indexOf(type);
return !! ~ct.indexOf(type);
};
// Callback for isXMLHttpRequest / xhr

View File

@@ -105,7 +105,7 @@ res.send = function(body, headers, status){
// respond
this.statusCode = status;
this.end('HEAD' == this.req.method ? undefined : body);
this.end('HEAD' == this.req.method ? null : body);
return this;
};
@@ -376,6 +376,7 @@ res.redirect = function(url, status){
, req = this.req
, base = app.set('basepath') || app.route
, status = status || 302
, head = 'HEAD' == req.method
, body;
// Setup redirect map
@@ -418,7 +419,7 @@ res.redirect = function(url, status){
// Respond
this.statusCode = status;
this.header('Location', url);
this.end(body);
this.end(head ? null : body);
};
/**

View File

@@ -226,10 +226,11 @@ Router.prototype._dispatch = function(req, res, next){
// param callbacks
function param(err) {
paramIndex = 0;
key = keys[i++];
paramVal = key && req.params[key.name];
paramCallbacks = key && params[key.name];
try {
if ('route' == err) {
nextRoute();

View File

@@ -5,6 +5,19 @@
* MIT Licensed
*/
/**
* Check if `path` looks absolute.
*
* @param {String} path
* @return {Boolean}
* @api private
*/
exports.isAbsolute = function(path){
if ('/' == path[0]) return true;
if (':' == path[1] && '\\' == path[2]) return true;
};
/**
* Merge object `b` with `a` giving precedence to
* values in object `a`.

View File

@@ -10,6 +10,7 @@
*/
var path = require('path')
, utils = require('../utils')
, extname = path.extname
, dirname = path.dirname
, basename = path.basename
@@ -99,7 +100,7 @@ View.prototype.resolvePath = function(){
// Implicit engine
if (!~this.basename.indexOf('.')) path += this.extension;
// Absolute
if ('/' == path[0]) return path;
if (utils.isAbsolute(path)) return path;
// Relative to parent
if (this.relative && this.parent) return this.parent.dirname + '/' + path;
// Relative to root

View File

@@ -1,7 +1,7 @@
{
"name": "express",
"description": "Sinatra inspired web development framework",
"version": "2.4.5",
"version": "2.5.3",
"author": "TJ Holowaychuk <tj@vision-media.ca>",
"contributors": [
{ "name": "TJ Holowaychuk", "email": "tj@vision-media.ca" },
@@ -10,18 +10,19 @@
{ "name": "Guillermo Rauch", "email": "rauchg@gmail.com" }
],
"dependencies": {
"connect": ">= 1.5.2 < 2.0.0",
"connect": "1.x",
"mime": ">= 0.0.1",
"qs": ">= 0.3.1"
"qs": ">= 0.3.1",
"mkdirp": "0.0.7"
},
"devDependencies": {
"connect-form": "0.2.1",
"ejs": "0.4.2",
"expresso": "0.7.2",
"expresso": "0.9.2",
"hamljs": "0.5.1",
"jade": "0.11.0",
"jade": "0.16.2",
"stylus": "0.13.0",
"should": "0.2.1",
"should": "0.3.2",
"express-messages": "0.0.2",
"node-markdown": ">= 0.0.1",
"connect-redis": ">= 0.0.1"
@@ -34,5 +35,5 @@
"test": "make test",
"prepublish" : "npm prune"
},
"engines": { "node": ">= 0.4.1 < 0.5.0" }
"engines": { "node": ">= 0.4.1 < 0.7.0" }
}

View File

@@ -3,7 +3,7 @@
* Module dependencies.
*/
var express = require('express')
var express = require('../')
, connect = require('connect')
, assert = require('assert')
, should = require('should')
@@ -37,22 +37,22 @@ module.exports = {
'test basic server': function(){
var server = express.createServer();
server.get('/', function(req, res){
server.set('env').should.equal('test');
res.writeHead(200, {});
res.end('wahoo');
});
server.put('/user/:id', function(req, res){
res.writeHead(200, {});
res.end('updated user ' + req.params.id)
});
server.del('/something', function(req, res){
res.send('Destroyed');
});
server.delete('/something/else', function(req, res){
res.send('Destroyed');
});
@@ -61,7 +61,7 @@ module.exports = {
req.staff = { id: req.params.id };
next();
});
server.get('/staff/:id', function(req, res){
res.send('GET Staff ' + req.staff.id);
});
@@ -73,7 +73,7 @@ module.exports = {
server.all('*', function(req, res){
res.send('requested ' + req.url);
});
assert.response(server,
{ url: '/' },
{ body: 'wahoo' });
@@ -81,15 +81,15 @@ module.exports = {
assert.response(server,
{ url: '/user/12', method: 'PUT' },
{ body: 'updated user 12' });
assert.response(server,
{ url: '/something', method: 'DELETE' },
{ body: 'Destroyed' });
assert.response(server,
{ url: '/something/else', method: 'DELETE' },
{ body: 'Destroyed' });
assert.response(server,
{ url: '/staff/12' },
{ body: 'GET Staff 12' });
@@ -105,17 +105,17 @@ module.exports = {
'test constructor middleware': function(beforeExit){
var calls = [];
function one(req, res, next){
calls.push('one');
next();
}
function two(req, res, next){
calls.push('two');
next();
}
var app = express.createServer(one, two);
app.get('/', function(req, res){
res.writeHead(200, {});
@@ -144,14 +144,14 @@ module.exports = {
assert.response(app,
{ url: '/' },
{ body: 'Internal Server Error' });
// Custom handler
var app = express.createServer();
app.error(function(err, req, res){
res.send('Shit: ' + err.message, 500);
});
app.get('/', function(req, res, next){
next(new Error('broken'));
});
@@ -174,7 +174,7 @@ module.exports = {
app.error(function(err, req, res, next){
res.send(err.message, 500);
});
app.get('/', function(req, res, next){
throw new Error('broken');
});
@@ -220,7 +220,7 @@ module.exports = {
'test #use()': function(){
var app = express.createServer();
app.get('/users', function(req, res, next){
next(new Error('fail!!'));
});
@@ -244,13 +244,13 @@ module.exports = {
}).configure('production', function(){
calls.push('production');
});
should.equal(ret, server, 'Test #configure() returns server for chaining');
assert.response(server,
{ url: '/' },
{ body: 'Cannot GET /' });
beforeExit(function(){
calls.should.eql(['any', 'dev']);
});
@@ -258,7 +258,7 @@ module.exports = {
'test #configure() immediate call': function(){
var app = express.createServer();
app.configure(function(){
app.use(connect.bodyParser());
});
@@ -266,18 +266,17 @@ module.exports = {
app.post('/', function(req, res){
res.send(req.param('name') || 'nope');
});
assert.response(app,
{ url: '/', method: 'POST', data: 'name=tj', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }},
{ body: 'tj' });
},
'test #configure() precedence': function(){
var app = express.createServer();
app.configure(function(){
app.use(function(req, res, next){
res.writeHead(200, {});
res.write('first');
next();
});
@@ -291,28 +290,28 @@ module.exports = {
res.write(' route ');
next();
});
assert.response(app,
{ url: '/' },
{ body: 'first route last' });
},
'test #configure() multiple envs': function(){
var app = express.createServer();
app.set('env', 'prod');
var calls = [];
app.configure('stage', 'prod', function(){
calls.push('stage/prod');
});
app.configure('prod', function(){
calls.push('prod');
});
calls.should.eql(['stage/prod', 'prod']);
},
'test #set()': function(){
var app = express.createServer();
var ret = app.set('title', 'My App').set('something', 'else');
@@ -320,7 +319,7 @@ module.exports = {
app.set('title').should.equal('My App');
app.set('something').should.equal('else');
},
'test .settings': function(){
var app = express.createServer();
app.set('title', 'My App');
@@ -352,36 +351,36 @@ module.exports = {
var app = express.createServer();
app.use(connect.bodyParser());
assert.equal(2, app.stack.length);
app.post('/', function(req, res){
res.send(JSON.stringify(req.body || ''));
});
app.get('/', function(){
});
assert.equal(3, app.stack.length);
assert.response(app,
{ url: '/', method: 'POST', data: 'name=tj', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }},
{ body: '{"name":"tj"}' });
},
'test "basepath" setting': function(){
var app = express.createServer();
app.set('basepath', '/shop');
app.get('/redirect', function(req, res){
res.redirect('/cart');
});
assert.response(app,
{ url: '/redirect', headers: { Host: 'foo.com' }},
{ headers: { Location: 'http://foo.com/shop/cart' }});
},
'test mounting': function(){
var called
, app = express.createServer()
@@ -394,16 +393,16 @@ module.exports = {
assert.equal(this, map, 'mounted() is not in context of the child app');
assert.equal(app, parent, 'mounted() was not called with parent app');
});
reg.use(function(req, res){ res.end('hey'); });
app.use('/regular', reg);
app.use('/blog', blog);
app.use('/contact', map);
blog.route.should.equal('/blog');
map.route.should.equal('/contact');
should.equal(true, called);
app.set("test", "parent setting");
blog.set('test').should.equal('parent setting');
@@ -412,7 +411,7 @@ module.exports = {
map.set('basepath').should.equal('/contact');
res.send('main app');
});
blog.get('/', function(req, res){
res.send('blog index');
});
@@ -437,26 +436,26 @@ module.exports = {
{ url: '/regular' },
{ body: 'hey' });
},
'test .app property after returning control to parent': function() {
var app = express.createServer()
, blog = express.createServer();
// Mounted servers did not restore `req.app` and `res.app` when
// passing control back to parent via `out()` in `#handle()`.
blog.get('/', function(req, res, next){
req.app.should.equal(blog);
res.app.should.equal(blog);
next();
});
app.use(blog);
app.use(function(req, res, next) {
res.send((res.app === app) ? 'restored' : 'not-restored');
});
assert.response(app,
{ url: '/' },
{ body: 'restored' }
@@ -467,23 +466,23 @@ module.exports = {
function handle(req, res) {
res.send('got ' + req.string);
}
var app = express.createServer();
app.get('/', function(req, res, next){
req.string = '/';
next();
}, handle);
app.get('/another', function(req, res, next){
req.string = '/another';
next();
}, handle);
assert.response(app,
{ url: '/' },
{ body: 'got /' });
assert.response(app,
{ url: '/another' },
{ body: 'got /another' });
@@ -491,11 +490,11 @@ module.exports = {
'invalid chars': function(){
var app = express.createServer();
app.get('/:name', function(req, res, next){
res.send('invalid');
});
assert.response(app,
{ url: '/%a0' },
{ status: 500 });

View File

@@ -3,12 +3,24 @@
* Module dependencies.
*/
var express = require('express')
var express = require('../')
, connect = require('connect')
, assert = require('assert')
, should = require('should');
module.exports = {
'test #path': function(){
var app = express.createServer();
app.get('/search', function(req, res){
res.send(req.path);
});
assert.response(app,
{ url: '/search?q=tobi' },
{ body: '/search' });
},
'test #isXMLHttpRequest': function(){
var app = express.createServer();
@@ -155,12 +167,15 @@ module.exports = {
req.flash('info').should.eql(['one']);
req.flash('info', 'Email _sent_.');
req.flash('info', '<script>');
req.flash('info').should.eql(['Email <em>sent</em>.', '&lt;script&gt;']);
req.flash('info', '<em>%s</em>', 'html');
req.flash('info').should.eql(['Email <em>sent</em>.', '<em>html</em>']);
req.flash('info', 'Welcome _%s_ to %s', 'TJ', 'something');
req.flash('info').should.eql(['Welcome <em>TJ</em> to something']);
req.flash('info', 'Welcome %s', '<script>');
req.flash('info').should.eql(['Welcome &lt;script&gt;']);
req.flash('error', 'Foo %u', 'bar');
req.flash('error').should.eql(['Foo BAR']);

View File

@@ -3,7 +3,7 @@
* Module dependencies.
*/
var express = require('express')
var express = require('../')
, Stream = require('stream').Stream
, assert = require('assert')
, should = require('should');
@@ -379,6 +379,10 @@ module.exports = {
res.redirect('blog');
});
assert.response(app,
{ url: '/home', method: 'HEAD' },
{ body: '' });
assert.response(app,
{ url: '/html', headers: { Accept: 'text/html,text/plain', Host: 'foo.com' }},
{ body: '<p>Moved Temporarily. Redirecting to <a href="http://google.com">http://google.com</a></p>' });
@@ -506,10 +510,6 @@ module.exports = {
});
});
assert.response(app,
{ url: '/forum' },
{ body: 'got an error' });
assert.response(app,
{ url: '/does-not-exist' },
{ body: 'got an error' });

View File

@@ -3,7 +3,7 @@
* Module dependencies.
*/
var express = require('express')
var express = require('../')
, connect = require('connect')
, assert = require('assert')
, should = require('should')
@@ -789,5 +789,37 @@ module.exports = {
assert.response(app,
{ url: '/user/12' },
{ body: 'recovered from error: fail' });
},
'test multiple param callbacks': function(){
var app = express.createServer();
app.param('user', function(req, res, next, id){
req.user = { id: id };
next();
});
app.param('forum_id', function(req, res, next, id){
req.forum = { id: id };
next();
});
app.param('thread_id', function(req, res, next, id){
req.thread = { id: id };
next();
});
function array(req, res, next) {
req.arr = [req.user.id, req.forum.id, req.thread.id];
next();
}
app.get('/:user/:forum_id/:thread_id', array, function(req, res){
res.send(req.arr);
});
assert.response(app,
{ url: '/1/2/3' },
{ body: '["1","2","3"]' });
}
};

View File

@@ -3,7 +3,7 @@
* Module dependencies.
*/
var express = require('express')
var express = require('../')
, connect = require('connect')
, assert = require('assert')
, should = require('should')