Code coverage report for vatican/lib/processingChain.js

Statements: 95.24% (60 / 63)      Branches: 82.22% (37 / 45)      Functions: 100% (9 / 9)      Lines: 96.61% (57 / 59)      Ignored: none     

All files » vatican/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 92 93 94 95 96 97 98 99 100 1011   1     1 15 15     1 26     26 3   23     1 3     1 1     1 4 4 4 4 4 4   4 4 4 4 4         4 2 1 1   1       4   12 1 1 1   12 9   9 5 7 5         9 9 1   8     3     4 2 2   2       1 5 4 5 3   2        
var _ = require("lodash")
 
module.exports = ProcessingChain;
 
 
function ProcessingChain( ) {
	this.chain = [];
	this.errorHandlers = [];
}
 
ProcessingChain.prototype.add = function( proc ) {
	proc.names =  proc.names ? 
						( Array.isArray(proc.names) ? proc.names : Array(proc.names) )  
						: [];
	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( params ) { 
	params = params || {};
	var req = params.req;
	var res = params.res;
	var finalFn = params.finalFn;
	var handler = params.handler;
	var endPrep = (params.endPrep && {fn: params.endPrep}) || []; //last preprocessor
 
	var currentItem = 0;
	var chain = [].concat(this.chain, endPrep);
	var totalItems = 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);
		}
	}
 
	var next = function(err) {
		//chain is taken from the closure
		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 ) {
			var idx = ++currentItem;
 
			if( handler && handler.name) {
				for(; idx < chain.length; idx++) {
					if( !chain[idx].names || ( ! chain[idx].names.length ) || ~chain[idx].names.indexOf(handler.name)) {
						break
					}
				}
			} 
 
			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, chain)
		firstItem.fn(req, res, next)
	} else {
		chain[0].fn(req, res, next )
	}
};
 
ProcessingChain.prototype.findFirstValidItem = function(name, chain) {
	if(!name) return chain[0]	
	return _.find(chain, function(item) { 
		if(item.names && Array.isArray(item.names) && item.names.length > 0) {
			return item.names.indexOf(name) != -1
		} else {
			return true
		}
	})
}