UNPKG

chai-express-handler

Version:

Helpers for testing Express handlers with the Chai assertion library.

118 lines (105 loc) 2.55 kB
/** * Module dependencies. */ var Request = require('./request') , Response = require('./response') , middleware = require('./middleware') , flatten = require('array-flatten') , slice = Array.prototype.slice; /** * Creates an instance of `Test`. * * @constructor * @api protected */ function Test(callbacks) { this._callbacks = flatten(slice.call(arguments, 0)); this._callbacks.unshift(middleware.query()); this._callbacks.unshift(middleware.init()); } /** * Register a callback to be invoked when request is prepared. * * @param {Function} cb * @return {Test} for chaining * @api public */ Test.prototype.request = function(cb) { this._request = cb; return this; }; /** * Register a callback to be invoked when handler `end()`s response. * * @param {Function} cb * @return {Test} for chaining * @api public */ Test.prototype.finish = function(cb) { this._finish = cb; return this; }; /** * Register a callback to be invoked when handler calls `next()`. * * @param {Function} cb * @return {Test} for chaining * @api public */ Test.prototype.next = function(cb) { this._next = cb; return this; }; /** * Dispatch mock request to handler. * * @api public */ Test.prototype.listen = function() { var self = this , req = new Request() , res = new Response() , prepare = this._request; res.once('finish', function() { if (!self._finish) { throw new Error('res#end should not be called'); } self._finish.call(this); }); function ready(err) { function next(err) { if (!self._next) { throw new Error('next should not be called'); } self._next.call(self, err, req, res); } var i = 0; function callbacks(err) { var fn = self._callbacks[i++]; if (!fn) { return next(err); } try { if (err) { if (fn.length < 4) { return callbacks(err); } fn(err, req, res, callbacks); } else { if (fn.length < 4) { return fn(req, res, callbacks); } callbacks(); } } catch (err) { // NOTE: Route handlers are not expected to throw exceptions. So, in // the context of a unit test, exceptions are re-thrown, rather // than being caught and passed to `next`. throw err; } } callbacks(err); } if (prepare && prepare.length == 3) { prepare(req, res, ready); } else if (prepare) { prepare(req, res); ready(); } else { ready(); } }; /** * Expose `Test`. */ module.exports = Test;