Permalink
Browse files

add 'use' to cascade middleware.

make cascade middleware handle routers properly
  • Loading branch information...
1 parent ce78c76 commit 259a7cac6565f0d81dc76139ec625fadba2ad5b7 @nrstott committed Dec 10, 2012
Showing with 101 additions and 8 deletions.
  1. +29 −7 lib/middleware.js
  2. +57 −1 test/middleware.test.js
  3. +15 −0 test/test-util.js
View
@@ -6,7 +6,8 @@ var Q = require('promised-io/promise'),
util = require('./util'),
merge = util.merge,
EventEmitter = require('events').EventEmitter,
- _ = require('underscore');
+ _ = require('underscore'),
+ Router = require('./router').Router;
function join(forEachable) {
var body = '',
@@ -723,26 +724,32 @@ exports.binary = function(conditional, appTrue, appFalse) {
*/
exports.cascade = function(accept /*, apps */) {
var args = Array.prototype.slice.call(arguments)
- , apps = [];
+ , middlewareQueue = [];
accept = args.shift();
args.forEach(function(x) {
- apps.push(x);
+ middlewareQueue.push(x);
});
- return function(req) {
+ var cascadeApp = function(req) {
var deferred = Q.defer();
- function next(apps) {
- var nextAction = apps.shift();
+ function next() {
+ var nextAction = middlewareQueue.shift();
+
+ this.started = true;
+
+ if (Router.isRouter(nextAction)) {
+ nextAction.nextApp = next;
+ }
if (nextAction) {
Q.whenCall(function() { return nextAction(req); }, function(resp) {
if (accept(resp)) {
return deferred.resolve(resp);
} else {
- return next(apps);
+ return next();
}
}, deferred.reject);
} else {
@@ -754,6 +761,21 @@ exports.cascade = function(accept /*, apps */) {
return deferred.promise;
};
+
+ cascadeApp.use = function(middleware /*, parameters */) {
+ if (this.started) {
+ throw {
+ message: 'Cascade has already been started. The middleware may only be configured before it is started.',
+ code: 'BOGART_CASCADE_ALREADY_STARTED'
+ };
+ }
+
+ var args = Array.prototype.slice.call(arguments);
+
+ middlewareQueue.push(middleware);
+ };
+
+ return cascadeApp;
};
/**
View
@@ -5,7 +5,8 @@ var bogart = require('../lib/bogart')
, security = require("../lib/security")
, util = require('util')
, test = require('tap').test
- , plan = require('tap').plan;
+ , plan = require('tap').plan
+ , mockRequest = require('./test-util').mockRequest;
test("test parses JSON", function(t) {
var forEachDeferred = Q.defer()
@@ -402,6 +403,61 @@ test("test bodyAdapter adapts Stream", function(t) {
});
});
+test("test cascade works with a router", function(t){
+ var cascade = bogart.middleware.cascade(function() { return true; })
+ , router = bogart.router()
+ , txt = 'Hello World';
+
+ router.get('/', function(req){
+ return bogart.text(txt);
+ });
+
+ cascade.use(router);
+
+ var resPromise = cascade(mockRequest('/'));
+
+ resPromise.then(function(res){
+ t.equal(txt, res.body.join());
+ }, function(err){
+ t.ok(false, err, 'found error');
+ });
+
+ t.plan(1);
+});
+
+test("test cascade passes to second router", function(t){
+ var router1 = bogart.router()
+ , router2 = bogart.router()
+ , txt = 'Hello World'
+ , cascade = bogart.middleware.cascade(function(res) {
+ return res.status != 404;
+ });
+
+ router1.get('/', function(req) {
+ return {
+ status: 404,
+ body: []
+ };
+ });
+
+ router2.get('/', function(req) {
+ return bogart.text(txt);
+ });
+
+ cascade.use(router1);
+ cascade.use(router2);
+
+ var resPromise = cascade(mockRequest('/'));
+
+ resPromise.then(function(res) {
+ t.equal(txt, res.body.join());
+ }, function(err) {
+ t.ok(false, err, 'found error');
+ });
+
+ t.plan(1);
+});
+
/**
* Create a mock request
*
View
@@ -0,0 +1,15 @@
+function mockRequest(path) {
+ return {
+ headers: {},
+ pathInfo: path,
+ method: 'GET',
+ jsgi: { version: [0,3] },
+ env: {}
+ };
+}
+
+function rootRequest() {
+ return mockRequest('/');
+}
+
+exports.mockRequest = mockRequest;

0 comments on commit 259a7ca

Please sign in to comment.