diff --git a/lib/vatican.js b/lib/vatican.js index 735c9b8..696e17e 100644 --- a/lib/vatican.js +++ b/lib/vatican.js @@ -5,35 +5,44 @@ var http = require("http"), handlerParser = require("./handlerParser"), processingChain = require("./processingChain"), mongoose = require("mongoose"), - _ = require("lodash"); + _ = require("lodash"), + path = require("path"); +(function(version) { + if( version[1] < 11 || (version[1] == 11 && version[2] < 2) ) { + path.isAbsolute = function(pth) { + return path.resolve(pth) == pth; + } + } + } +)(process.version.match(/^v\d+\.(\d+)\.(\d+)/)); module.exports = Vatican; -var CONFIG_FILE_PATH = process.cwd() + "/vatican-conf.json"; var DEFAULT_CONFIG = { cors: false, db: { host: 'localhost', dbname: 'vatican-project' - } + }, + requestParser: __dirname + '/defaultRequestParser', } -function Vatican(options) { - var config = null; - this.dbconn = null - try { - config = (options) ? options : require(CONFIG_FILE_PATH); - } catch(ex) { - logger.error("Error loading config file '" + CONFIG_FILE_PATH + "': " + ex); - return; +function Vatican(context, options) { + this.dbconn = null; + + if(arguments.length < 2 && typeof context != 'string') { + options = context; + context = undefined; } - this.options = _.defaults( config, DEFAULT_CONFIG); + + this.context = this.getContext(context); + + this.options = _.defaults(options ? options : this.getConfig(), DEFAULT_CONFIG); this.checkOptions(); - this.requestParser = config.requestParser ? require(config.requestParser) : require("./defaultRequestParser"); + this.requestParser = require(path.resolve(this.context, this.options.requestParser)); this.handlers = {}; - this.parseHandlers(); this.paths = []; this.server = null; @@ -63,6 +72,38 @@ Vatican.prototype.parseHandlers = function(cb) { }) }; +Vatican.prototype.getConfig = function() { + var confPath = this.context + "/vatican-conf.json"; + try { + return require( confPath ); + } catch(ex) { + logger.error("Error loading config file '" + confPath + "': " + ex); + throw new Error( "Error loading config file '" + confPath ); + } +} + +Vatican.prototype.getContext = function(context) { + if( ! context ) { + context = process.cwd(); + } else { + if( !path.isAbsolute( context ) ) { + logger.error("Context specified is not an absolute path, throwing error!"); + throw new Error("Context specified specified is not an absolute path"); + } + + try { + fs.readdirSync( context ); + } catch (e) { + logger.error("Context specified can not be treated as directory, throwing error!"); + throw new Error("Context specified can not be treated as directory"); + + throw e; + } + } + + return context; +} + /** Makes sure that the required options are there */ @@ -75,6 +116,8 @@ Vatican.prototype.checkOptions = function() { if( !this.options.handlers ) { logger.error("Handlers folder not specified, throwing error!"); throw new Error("Handlers folder not specified"); + } else { + this.options.handlers = path.resolve(this.context, this.options.handlers); } }; @@ -148,7 +191,7 @@ Vatican.prototype.requestHandler = function (req, res) { } else { try { var request = this.createRequest(req); - var hdlr = this.loadHandler(process.cwd() + "/" + methodFound.handlerPath); + var hdlr = this.loadHandler(path.resolve(this.context, methodFound.handlerPath)); res = vaticanResp.improveResponse(res, request, this.options, this.postprocessors); //Parse the request to grab the parameters this.parseRequest(request, methodFound.url, req, function(newRequest) { @@ -255,4 +298,3 @@ Vatican.prototype.loadDbModels = function(folder, cb) { cb(null, models) }) } - diff --git a/test/fixtures/vatican/vatican-conf.json b/test/fixtures/vatican/vatican-conf.json new file mode 100644 index 0000000..776b5a7 --- /dev/null +++ b/test/fixtures/vatican/vatican-conf.json @@ -0,0 +1 @@ +{"port":5000,"handlers":"./handlers"} diff --git a/test/vatican.js b/test/vatican.js index 798e3cd..ddf6bf6 100644 --- a/test/vatican.js +++ b/test/vatican.js @@ -1,20 +1,78 @@ var should = require('should'); //for mocha tests var Vatican = require("../lib/vatican") var _ = require('lodash'); +var path = require('path'); describe("Vatican methods", function() { - var vatican = new Vatican({ - handlers: __dirname + '/fixtures/vatican/handlers', - port: 88 - }) + var vatican = new Vatican( + __dirname, + { + handlers: 'fixtures/vatican/handlers', + port: 88 + } + ); var matchFound = null + describe("@Vatican constructor", function() { + //the case new Vatican() without any params I did not analyzed because mocha can't support this case + it("(context)", function() { + var context = __dirname + "/fixtures/vatican"; + var v = new Vatican(context); + + v.context.should.be.equal(context); + v.options.handlers.should.be.equal(context + "/handlers"); + v.options.port.should.be.equal(5000); + }); + + it("(options)", function() { + var absPath = __dirname + "/fixtures/vatican/handlers"; + var v = new Vatican({ handlers: absPath, port: 88}); + + v.context.should.be.equal(process.cwd()); + v.options.handlers.should.be.equal(absPath); + v.options.port.should.be.equal(88); + }); + + it("(context, options)", function() { + var context = __dirname + "/fixtures/vatican"; + var absPath = __dirname + "/fixtures/vatican/handlers"; + var v = new Vatican(context, { handlers: absPath, port: 88}); + + v.context.should.be.equal(context); + v.options.handlers.should.be.equal(absPath); + v.options.port.should.be.equal(88); + }); + }); + + describe("@getContext", function() { + it("() should return process.cwd()", function() { + Vatican.prototype.getContext().should.be.equal(process.cwd()); + }); + + it("(absPath) should return absPath", function() { + var absPath = process.cwd(); + Vatican.prototype.getContext(absPath).should.be.equal(absPath); + }); + + it("(relPath) should throw error", function() { + (function(){ + var v = new Vatican("./ok"); + }).should.throw("Context specified specified is not an absolute path"); + }); + + it("(notDir) should throw error", function() { + (function(){ + var v = new Vatican(path.resolve(process.cwd(), "wrong_file.txt")); + }).should.throw("Context specified can not be treated as directory"); + }); + }); + describe("@checkOptions", function(){ it("should throw an error if no port is specified", function() { (function() { - v = new Vatican({handlers: ''}) + var v = new Vatican({handlers: ''}) }).should.throw("Port not specified") }) it("should throw an error if no handlers folder is specified", function() { @@ -24,6 +82,7 @@ describe("Vatican methods", function() { }) }) + describe("@preprocess", function() { it("should add a processor to the pre-processors chain", function() { vatican.preprocess(function(req, res, next) { @@ -99,10 +158,13 @@ describe("Vatican methods", function() { describe("@close", function() { it('should close server', function() { - var app = new Vatican({ - handlers: __dirname + '/fixtures/vatican/handlers', - port: 8888 - }) + var app = new Vatican( + __dirname, + { + handlers: 'fixtures/vatican/handlers', + port: 8888 + } + ); app.start(); @@ -114,10 +176,13 @@ describe("Vatican methods", function() { }); it('should call callback on close', function( done ) { - var app = new Vatican({ - handlers: __dirname + '/fixtures/vatican/handlers', - port: 8888 - }) + var app = new Vatican( + __dirname, + { + handlers: __dirname + '/fixtures/vatican/handlers', + port: 8888 + } + ); app.start(); app.close(function() {