diff --git a/lib/config.js b/lib/config.js index e6ddc6f9..0269f82f 100644 --- a/lib/config.js +++ b/lib/config.js @@ -105,10 +105,14 @@ function walkConfig(level) { return level; } -exports.loadObject = function(config, currentEnv) { +exports.loadObject = function(_config, currentEnv) { var out = new Config(); + // do not overwrite the users config + var config = JSON.parse(JSON.stringify(_config)); for (var env in config) { + + if (config[env].ENV) { if(!process.env[config[env].ENV]) log.verbose('Environment variable ' + config[env].ENV + ' is empty!'); @@ -122,6 +126,42 @@ exports.loadObject = function(config, currentEnv) { config[env] = walkConfig(config[env]); out[env] = config[env]; } + + if(typeof(config[env].url) === 'string') { + + config[env] = Object.assign( + config[env], + exports.loadUrl(config[env].url, env)[env] + ); + delete config[env].url; + } + else if(config[env].url && config[env].url.value) { + + config[env].url = config[env].url.value; + } + + if(config[env].overwrite || config[env].addIfNotExists) { + + var overwrite = config[env].overwrite || {}; + + if(config[env].addIfNotExists) { + + var addIfNotExists = config[env].addIfNotExists; + Object.keys(addIfNotExists).filter(function(key) { + return !overwrite[key] && !config[env][key]; + }).forEach(function(key) { + config[env][key] = addIfNotExists[key]; + }); + + delete config[env].addIfNotExists; + } + + Object.keys(overwrite).forEach(function(key) { + config[env][key] = overwrite[key]; + }); + + delete config[env].overwrite; + } } if(currentEnv) { diff --git a/test/config_test.js b/test/config_test.js index a73638dd..6abbde1a 100644 --- a/test/config_test.js +++ b/test/config_test.js @@ -3,6 +3,7 @@ var Lab = require('lab'); var lab = exports.lab = Lab.script(); var config = require('../lib/config'); var path = require('path'); +var sinon = require('sinon'); var _configLoad = config.load; var _configLoadUrl = config.loadUrl; @@ -160,13 +161,7 @@ lab.experiment('config', function() { config.load = _configLoad; config.loadUrl = _configLoadUrl; - lab.test('should something', function(done, cleanup) { - - cleanup(function(next) { - - delete require.cache[require.resolve('../lib/config')]; - next(); - }); + lab.test('should something', function(done) { Code.expect( config.load.bind(this, configPath, 'dev') @@ -174,4 +169,176 @@ lab.experiment('config', function() { done(); }); }); + + lab.experiment('loading a url from url property', function() { + + + lab.test('should export a valid config', + function(done) { + + var databaseUrl = { + 'dev': { + 'url': 'postgres://uname:pw@server.com/dbname' + } + }; + var cfg = config.loadObject(databaseUrl, 'dev'); + + Code.expect(cfg.getCurrent).to.exists(); + var current = cfg.getCurrent(); + Code.expect(current.env).to.equal('dev'); + Code.expect(current.settings.url).to.not.exists(); + Code.expect(current.settings.driver).to.equal('postgres'); + Code.expect(current.settings.user).to.equal('uname'); + Code.expect(current.settings.password).to.equal('pw'); + Code.expect(current.settings.host).to.equal('server.com'); + Code.expect(current.settings.database).to.equal('dbname'); + + done(); + }); + + lab.test('should export the value if specified in suboject', + function(done) { + + var databaseUrl = { + 'dev': { + 'url': { + 'value': 'http://example.com' + } + } + }; + var cfg = config.loadObject(databaseUrl, 'dev'); + + Code.expect(cfg.getCurrent).to.exists(); + var current = cfg.getCurrent(); + Code.expect(current.env).to.equal('dev'); + Code.expect(current.settings.url).to.equal('http://example.com'); + + done(); + }); + }); + + lab.experiment('loading from an URL and overwriting it', function() { + + var databaseUrl = { + 'dev': { + 'url': 'postgres://uname:pw@server.com/dbname', + 'overwrite': { + 'ssl': true + } + } + }; + + var cfg = config.loadObject(databaseUrl, 'dev'); + + lab.test('should export the settings as the current environment', function(done) { + + Code.expect(cfg.dev).to.exists(); + done(); + }); + + lab.test('should export a getCurrent function with all current environment settings', + function(done) { + + Code.expect(cfg.getCurrent).to.exists(); + var current = cfg.getCurrent(); + Code.expect(current.env).to.equal('dev'); + Code.expect(current.settings.url).to.not.exists(); + Code.expect(current.settings.overwrite).to.not.exists(); + Code.expect(current.settings.driver).to.equal('postgres'); + Code.expect(current.settings.user).to.equal('uname'); + Code.expect(current.settings.password).to.equal('pw'); + Code.expect(current.settings.host).to.equal('server.com'); + Code.expect(current.settings.database).to.equal('dbname'); + Code.expect(current.settings.ssl).to.equal(true); + + done(); + }); + }); + + lab.experiment('loading from an ENV URL within the object and overwriting it', + function() { + + lab.test('should export a getCurrent function with all current environment settings', + function(done, cleanup) { + + process.env.DATABASE_URL = 'postgres://uname:pw@server.com/dbname'; + var databaseUrl = { + 'dev': { + 'url': { 'ENV': 'DATABASE_URL' }, + 'overwrite': { + 'ssl': true + } + } + }; + var cfg = config.loadObject(databaseUrl, 'dev'); + + cleanup(function(next) { + delete process.env.DATABASE_URL; + next(); + }); + + Code.expect(cfg.getCurrent).to.exists(); + var current = cfg.getCurrent(); + Code.expect(current.env).to.equal('dev'); + Code.expect(current.settings.url).to.not.exists(); + Code.expect(current.settings.overwrite).to.not.exists(); + Code.expect(current.settings.driver).to.equal('postgres'); + Code.expect(current.settings.user).to.equal('uname'); + Code.expect(current.settings.password).to.equal('pw'); + Code.expect(current.settings.host).to.equal('server.com'); + Code.expect(current.settings.database).to.equal('dbname'); + Code.expect(current.settings.ssl).to.equal(true); + + done(); + }); + }); + + lab.experiment('loading from an ENV URL within the object and extending it from the ENV', + function() { + + lab.test('', function(done, cleanup) { + + process.env.DATABASE_URL = 'postgres://uname:pw@server.com/dbname?ssl=false&testing=false'; + var databaseUrl = { + 'dev': { + 'url': { + 'ENV': 'DATABASE_URL', + }, + 'overwrite': { + 'ssl': true, + 'cache': false + }, + 'addIfNotExists': { + 'native': true, // this on is new + 'cache': true, // overwrite should have higher priority + 'testing': true // already in config do not overwrite + } + } + }; + var cfg = config.loadObject(databaseUrl, 'dev'); + + cleanup(function(next) { + delete process.env.DATABASE_URL; + next(); + }); + + Code.expect(cfg.getCurrent).to.exists(); + var current = cfg.getCurrent(); + Code.expect(current.env).to.equal('dev'); + Code.expect(current.settings.url).to.not.exists(); + Code.expect(current.settings.overwrite).to.not.exists(); + Code.expect(current.settings.addIfNotExists).to.not.exists(); + Code.expect(current.settings.driver).to.equal('postgres'); + Code.expect(current.settings.user).to.equal('uname'); + Code.expect(current.settings.password).to.equal('pw'); + Code.expect(current.settings.host).to.equal('server.com'); + Code.expect(current.settings.database).to.equal('dbname'); + Code.expect(current.settings.native).to.equal(true); + Code.expect(current.settings.testing).to.equal('false'); + Code.expect(current.settings.cache).to.equal(false); + Code.expect(current.settings.ssl).to.equal(true); + + done(); + }); + }); });