Code coverage report for lib/processingChain.js

Statements: 91.23% (52 / 57)      Branches: 83.33% (30 / 36)      Functions: 100% (9 / 9)      Lines: 92.45% (49 / 53)      Ignored: none     

All files » lib/ » processingChain.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 921     1     1 13 13     1 25 4   21     1 4     1 1     1 4 4 4 4         4 3 1 1   2             4 10 10 2 2 2   10 8 9 8     8     8 8 2   6     2     4 1 1   3       1 3 2 3 2   1        
var _ = require("lodash"),
	logger = require("./logger")
 
module.exports = ProcessingChain;
 
 
function ProcessingChain( ) {
	this.chain = [];
	this.errorHandlers = [];
}
 
ProcessingChain.prototype.add = function( proc ) {
	if(proc.fn.length == 4) //it's an error handler
		this.errorHandlers.push(proc);
	else
		this.chain.push(proc);
}
 
ProcessingChain.prototype.getTotal = function() {
	return this.chain.length;
};
 
ProcessingChain.prototype.pop = function() {
	this.chain.pop();
}
 
ProcessingChain.prototype.runChain = function( req, res, finalFn, handler ) {
	var currentItem = 0;
	var totalItems = this.chain.length;
	var self = this;
	Iif(totalItems == 0) {
		if(typeof finalFn == 'function') finalFn(req, res);
		return;
	}
 
	var nextError = function ( err ) {
		if ( currentItem < totalItems - 1 ) {
			currentItem++
			self.errorHandlers[currentItem].fn(err, req, res, nextError)
		} else {
			Eif(typeof finalFn == 'function') finalFn(req, res);
			else {
				throw new Error("Next called on error handler, but there are no more function s in the middleware chain")
			}
		}
	}
 
	var next = function(err) {
		var chain = self.chain;
		if ( err ) { //If there is an error, switch to the error handlers chain
			chain = self.errorHandlers;
			currentItem = -1;
			totalItems = self.errorHandlers.length;
		}
		if ( currentItem < totalItems - 1 ) {
			for(var idx = currentItem + 1; idx < chain.length; idx++) {
				if( (chain[idx].names && (handler && chain[idx].names.indexOf(handler.name) != -1)) || !chain[idx].names || _.isEmpty(chain[idx].names)) {
					break
				}
			}
			Iif(idx === chain.length) {
				throw new Error("Next called, but there are no more functions in the middleware chain.")
			}
			currentItem = idx
			if(err) {
				chain[currentItem].fn(err, req, res, nextError)
			} else {
				chain[currentItem].fn(req, res, next)
			}
		} else {
			Eif(typeof finalFn == 'function') finalFn(req, res);
		}
	}
	if(handler) {
		var firstItem = self.findFirstValidItem(handler.name)
		firstItem.fn(req, res, next)
	} else {
		this.chain[0].fn(req, res, next )
	}
};
 
ProcessingChain.prototype.findFirstValidItem = function(name) {
	if(!name) return this.chain[0]	
	return _.find(this.chain, function(item) { 
		if(item.names && Array.isArray(item.names) && item.names.length > 0) {
			return item.names.indexOf(name) != -1
		} else {
			return true
		}
	})
}