Mocha 1.0
The Mocha JavaScript test framework has hit 1.0 with a bunch of great contributions from the community, here’s the change log:
- Added js API. Closes #265
- Added: initial run of tests with
--watch. Closes #345
- Added: mark
location as a global on the CS. Closes #311
- Added
markdown reporter (github flavour)
- Added: scrolling menu to coverage.html. Closes #335
- Added source line to html report for Safari [Tyson Tate]
- Added “min” reporter, useful for
--watch [Jakub Nešetřil]
- Added support for arbitrary compilers via . Closes #338 [Ian Young]
- Added Teamcity export to lib/reporters/index [Michael Riley]
- Fixed chopping of first char in error reporting. Closes #334 [reported by topfunky]
- Fixed terrible FF / Opera stack traces
Compiler support
coffee-script out of the box was removed, now you can used the --compilers <ext>:<module>,... flag to map a compiler to the given extension name. For example mocha --compilers coffee:coffee-script. There are simply too many foo -> JavaScript transpilers to directly support, this pushes that back on the author.
Min reporter
First up is the min reporter by Jakub Nešetřil, this tiny reporter works great with --watch, outputting the summary only, though still reporting verbose errors on failure. 
Markdown reporter
I added a markdown reporter which can be used to display your tests as documentation in a Github wiki page, or simply a markdown file in your repository that you can link to. For example here are the Connect markdown test docs.
I’m not super happy with how much padding Github adds, so the TOC looks pretty messy, but all of these document-style reporting mechanisms make you think twice about how clean and organized your tests are.
JavaScript API
A new JS API was added, which mocha(1) now utilizes. This higher-level JS API will make it easier for those who want to script the testing process with Mocha. I have yet to document this API but it looks like this:
var Mocha = require('mocha');
var mocha = new Mocha;
mocha.reporter('spec').ui('bdd');
mocha.addFile('test/suite.js');
mocha.addFile('test/runner.js');
mocha.addFile('test/runnable.js');
var runner = mocha.run(function(){
console.log('finished');
});
runner.on('pass', function(test){
console.log('... %s passed', test.title);
});
runner.on('fail', function(test){
console.log('... %s failed', test.title);
});
Connect 2.0
Connect 2.0 is here with new core middleware, miscellaneous improvements, and some new docs.
var app = connect()
.use(connect.logger('dev'))
.use(connect.static('public'))
.use(function(req, res){
res.end('hello world\n');
})
app.listen(3000);
HTTP and HTTPS
Previously connect.Server inherited from Node’s core net.Server, this made it difficult to provide both HTTP and HTTPS for your application. The result of connect() (formerly connect.createServer()) is now simply a JavaScript Function. This means that you may omit the call to app.listen(), and simply pass app to a Node net.Server as shown here:
var connect = require('connect')
, http = require('http')
, https = require('https');
var app = connect()
.use(connect.logger('dev'))
.use(connect.static('public'))
.use(function(req, res){
res.end('hello world\n');
})
http.createServer(app).listen(80);
https.createServer(tlsOptions, app).listen(443);
Body parsers
The bodyParser() middleware is now nothing but a short-hand for adding the json(), multipart(), and urlencoded() middleware. Each of these populate req.body with an object containing the parsed values, multipart() provides req.body and req.files for uploads.
Core compression
As of Node 0.6.0 fast, native compression capabilities are available, so now we have the compress() middleware supporting deflate and gzip.
Cookie parser
The cookieParser() middleware now supports signed cookies, and accepts a secret. This replaces the need to pass session({ secret: string }) to the session() middleware. Signed cookies are available via req.signedCookies, and unsigned as req.cookies.
Error delegation
Previously a few of the core middleware would respond to error situations directly, these have been changed to simply next(err)-them along. This change allows you to specify customized behaviour by adding an error-handling middleware:
app.use(function(err, req, res, next){
if (4 == err.status / 100) {
// render a client-error page
} else {
// render a server-error page
}
});
Session
As mentioned session() no longer requires a secret. The cookie .maxAge has been defaulted to null, meaning that it will be a browser-session cookie, expiring once the visitor closes their browser.
Third-party middleware
Third-party middleware should remain perfectly functional. This release of Connect is not compatible with Express 2.x, Express 3.0 is coming soon.
Changelog
The following significant changes were made, as well as several others that do not impact public API, such as a full rewrite of the tests using Mocha.
- Added
cookieSession() middleware for cookie-only sessions
- Added
compress() middleware for gzip / deflate support
- Added
session() “proxy” setting to trust X-Forwarded-Proto
- Added
json() middleware to parse “application/json”
- Added
urlencoded() middleware to parse “application/x-www-form-urlencoded”
- Added
multipart() middleware to parse “multipart/form-data”
- Added
cookieParser(secret) support so anything using this middleware may access signed cookies
- Added signed cookie support to
cookieParser()
- Added support for JSON-serialized cookies to
cookieParser()
- Added
err.status support in Connect’s default end-point
- Added X-Cache MISS / HIT to
staticCache()
- Added public
res.headerSent checking nodes res._headerSent until node does
- Changed
basicAuth() req.remoteUser to req.user
- Changed: default
session() to a browser-session cookie. Closes #475
- Changed: no longer lowercase cookie names
- Changed
bodyParser() to use json(), urlencoded(), and multipart()
- Changed:
errorHandler() is now a development-only middleware
- Changed middleware to
next() errors when possible so applications can unify logging / handling
- Removed
http[s].Server inheritance, now just a function, making it easy to have an app providing both http and https
- Removed
.createServer() (use connect())
- Removed
secret option from session(), use cookieParser(secret)
- Removed
connect.session.ignore array support
- Removed
router() middleware. Closes #262
- Fixed: set-cookie only once for browser-session cookies
- Fixed FQDN support. dont add leading “/”
- Fixed 404 XSS attack vector. Closes #473
- Fixed HEAD support for 404s and 500s generated by Connect’s end-point
Mocha test coverage
The latest release of Mocha adds two new reporters, now totaling 13 packaged with the library. The two new ones are “json-cov” and “html-cov”, the latter inherits from the former in order to produce a single-page test coverage report.

If you’re curious what a live example looks like, check out this page.
Setup
With Node’s require.paths array out of the picture there’s a bit of boiler-plate involved in setting up test coverage for your project, but it’s pretty minimal. First you’ll want to install the jscoverage executable, this program parses your source code and spits out an instrumented version, effectively a bunch of lines that look like this:
$_jscoverage[filename][line]++;
This enables libraries like Mocha to execute the code as they normally would, however we can then extract this coverage information and generate fancy reports. jscoverage takes the input directory, and an output directory, I usually calls this “lib-cov”:
$ jscoverage lib lib-cov
Typically when testing your library you’ll use relative require() calls that look like this: var express = require('../'), and the library entry point is ./index.js. Normally this file might look something like below, or you may not have an ./index.js file at all.
module.exports = require('./lib/express');
By using ./index.js we can then alter this statement to conditionally export the instrumented version when the EXPRESS_COV environment variable is present:
module.exports = process.env.EXPRESS_COV
? require('./lib-cov/express')
: require('./lib/express');
Then all you need to do is invoke mocha with --reporter html-cov and redirect the stdout to a file such as coverage.html. Line 25 the test-cov target of the Express Makefile illustrates how I typically handle this but depending on your setup it may vary.
That’s it! remember to add “coverage.html” to your .npmignore and .gitignore files ;)
Stylus gets @extend
@extend is a great little feature which originated in SASS, and now finds a home in Stylus. If you’ve ever written CSS like this, you know it can become quite the pain to maintain large lists of selectors:
.message,
.warning,
.error {
font-size: 14px;
padding: 5px 10px;
border: 1px solid #eee;
border-radius: 5px;
}
.warning {
color: yellow;
}
.error {
color: red;
}
@extend makes this process flow naturally, and even supports inheritance. In Stylus you may use @extend or @extends, I prefer the latter personally but that’s up to you! Using this feature you would define .message on it’s own, and simply __@extend_ it from within the other rulesets:
.message {
font-size: 14px;
padding: 5px 10px;
border: 1px solid #eee;
border-radius: 5px;
}
.warning {
@extends .message;
color: yellow;
}
.error {
@extends .message;
color: red;
}
Taking this even further with inheritance:
.fatal-error {
@extends .error;
font-weight: bold
}
Would yield the following CSS:
.message,
.warning,
.error,
.fatal-error {
font-size: 14px;
padding: 5px 10px;
border: 1px solid #eee;
border-radius: 5px;
}
.warning {
color: #ff0;
}
.error,
.fatal-error {
color: #f00;
}
.fatal-error {
font-weight: bold;
}
Here’s another example:
form
button
padding: 10px
border: 1px solid #eee
border-radius: 5px
ul
li a
@extends form button
Yielding:
form button,
ul li a {
padding: 10px;
border: 1px solid #eee;
border-radius: 5px;
}
And of course you may utilize the alternative Stylus syntax if you prefer:
.message
font-size: 14px
padding: 5px 10px
border: 1px solid #eee
border-radius: 5px
.warning
@extends .message
color: yellow
.error
@extends .message
color: red
.fatal-error
@extends .error
font-weight: bold
Grab Stylus 0.22.4 for these goodies!
This short Vimeo screencast illustrates why Stylus is the most like CSS as a stylesheet “preprocessor”. More on Stylus here.
Connect 1.8.0 - multipart support
Connect 1.8.0 is a tiny but substantial release because it adds multipart/form-data support via Felix Geisendörfer’s fantastic multipart parser formidable, it’s great and chances are you’re already using it!
The bodyParser() middleware now unifies multipart, json, and x-www-form-urlencoded parsing, providing the req.body object containing the parsed data. For security purposes the files are placed in a separate object, req.files, however just as accessible. A constant struggle that I’ve seen in the community is the concept of “missing” request data events so this will
prevent further confusion. The downside to this is that if you wish to report upload progress, or access files and fields as the request is streamed, you will have to use formidable directly.
Before this addition your use of formidable might look something like the following (with Express):
app.post('/someform', function(req, res, next){
var form = new formidable.IncomingForm;
form.parse(req, function(err, fields, files){
if (err) return next(err);
// do something with files.image etc
});
});
With the new bodyParser() all you need is:
app.use(express.bodyParser());
app.post('/some-form', function(req, res){
// do something with req.files.image
})
The middleware takes the same options that are mentioned on formidable’s GitHub repo page, so you can specify things like size limits, retaining extensions, the upload directory etc.
app.use(express.bodyParser({
uploadDir: '/tmp/uploads'
}));
That’s it! but I think this will cover well above the 80% use-case and prevent a lot of headaches that people have with the previous the inconsistencies.