From ae917c709a3bbaed2603bae303a7c0cf5e48db0f Mon Sep 17 00:00:00 2001 From: Shelby Sanders Date: Wed, 13 Aug 2014 22:05:33 -0700 Subject: [PATCH 1/3] Corrected lint line-length error --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index f7f0953..bf59c74 100644 --- a/index.js +++ b/index.js @@ -68,7 +68,7 @@ var addInstructionsToBrowserify = require('./lib/bundler'); * for files containing model definitions. * @property {Array.} [bootDirs] List of directories where to look * for boot scripts. - * @property {Array.} [bootScripts] List of script files to execute on boot. + * @property {Array.} [bootScripts] List of script files to execute * @end * * @header boot(app, [options]) From add944704cd1ab49dd50783c620acc2f2fc70f22 Mon Sep 17 00:00:00 2001 From: Shelby Sanders Date: Wed, 13 Aug 2014 22:06:12 -0700 Subject: [PATCH 2/3] Corrected path to jshint to be relative in order to avoid global installs --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 8fbb725..f251541 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "main": "index.js", "browser": "browser.js", "scripts": { - "pretest": "jshint .", + "pretest": "node_modules/.bin/jshint .", "test": "mocha" }, "license": { @@ -31,6 +31,7 @@ "underscore": "^1.6.0" }, "devDependencies": { + "jshint": "^2.5.2", "loopback": "^1.5.0", "mocha": "^1.19.0", "must": "^0.12.0", From 16ad57ac27ced90e1bd9d169c093306f39822593 Mon Sep 17 00:00:00 2001 From: Shelby Sanders Date: Wed, 13 Aug 2014 22:07:10 -0700 Subject: [PATCH 3/3] Added support for merging nested and complex data structures in configuration files --- .gitignore | 1 + lib/config-loader.js | 24 ++++++++++++-- test/compiler.test.js | 72 ++++++++++++++++++++++++++++++++++++++---- test/helpers/appdir.js | 10 ++++++ 4 files changed, 97 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index bff8718..ec7a8f1 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ *.pid *.swp *.swo +*.iml node_modules checkstyle.xml loopback-boot-*.tgz diff --git a/lib/config-loader.js b/lib/config-loader.js index d9b503f..f43fac7 100644 --- a/lib/config-loader.js +++ b/lib/config-loader.js @@ -129,10 +129,28 @@ function mergeAppConfig(target, config, fileName) { function applyCustomConfig(target, config) { for (var key in config) { var value = config[key]; - if (typeof value === 'object') { - return 'override for the option `' + key + '` is not a value type.'; + if (target[key]) { + if (Array.isArray(target[key]) && Array.isArray(value)) { + if (target[key].length == value.length) { + for (var valueIdx in value) { + if (typeof value[valueIdx] === 'object') { + applyCustomConfig(target[key][valueIdx], value[valueIdx]); + } else { + target[key][valueIdx] = value[valueIdx]; + } + } + } else { + return 'override for the option `' + key + + '` is an array and lengths mismatch.'; + } + } else if (typeof target[key] === 'object' && typeof value === 'object') { + applyCustomConfig(target[key], value); + } else { + target[key] = value; + } + } else { + target[key] = value; } - target[key] = value; } return null; // no error } diff --git a/test/compiler.test.js b/test/compiler.test.js index ee712d1..d5c18cc 100644 --- a/test/compiler.test.js +++ b/test/compiler.test.js @@ -125,24 +125,82 @@ describe('compiler', function() { expect(db).to.have.property('fromJs', true); }); - it('refuses to merge Object properties', function() { + it('merges Object properties', function() { + var nestedValue = { key: 'value' }; appdir.createConfigFilesSync(); appdir.writeConfigFileSync('datasources.local.json', { - db: { nested: { key: 'value' } } + db: { nested: nestedValue } }); - expect(function() { boot.compile(appdir.PATH); }) - .to.throw(/`nested` is not a value type/); + var instructions = boot.compile(appdir.PATH); + + var db = instructions.dataSources.db; + expect(db).to.have.property('nested'); + expect(db.nested).to.eql(nestedValue); }); - it('refuses to merge Array properties', function() { + it('merges nested Object properties', function() { + var nestedValue = 'http://api.test.com'; appdir.createConfigFilesSync(); appdir.writeConfigFileSync('datasources.local.json', { - db: { nested: ['value'] } + rest: { + operations: [ + { + template: { + url: nestedValue + } + } + ] + } + }); + + var instructions = boot.compile(appdir.PATH); + + var rest = instructions.dataSources.rest; + expect(rest).to.have.property('operations'); + expect(rest.operations[0]).to.have.property('template'); + expect(rest.operations[0].template).to.have.property('url'); + expect(rest.operations[0].template.method).to.eql('POST'); + expect(rest.operations[0].template.url).to.eql(nestedValue); + }); + + it('merges Array properties', function() { + var nestedValue = ['value']; + appdir.createConfigFilesSync(); + appdir.writeConfigFileSync('datasources.local.json', { + db: { nested: nestedValue } + }); + + var instructions = boot.compile(appdir.PATH); + + var db = instructions.dataSources.db; + expect(db).to.have.property('nested'); + expect(db.nested).to.eql(nestedValue); + }); + + it('errors on mismatched arrays', function() { + var nestedValue = 'http://api.test.com'; + appdir.createConfigFilesSync(); + appdir.writeConfigFileSync('datasources.local.json', { + rest: { + operations: [ + { + template: { + url: nestedValue + } + }, + { + template: { + method: 'GET', + url: nestedValue + } + } + ] + } }); expect(function() { boot.compile(appdir.PATH); }) - .to.throw(/`nested` is not a value type/); + .to.throw(/an array and lengths mismatch/); }); it('merges app configs from multiple files', function() { diff --git a/test/helpers/appdir.js b/test/helpers/appdir.js index 1a31be5..579e675 100644 --- a/test/helpers/appdir.js +++ b/test/helpers/appdir.js @@ -28,6 +28,16 @@ appdir.createConfigFilesSync = function(appConfig, dataSources, models) { db: { connector: 'memory', defaultForType: 'db' + }, + rest: { + connector: 'rest', + operations: [ + { + template: { + method: 'POST' + } + } + ] } }, dataSources); appdir.writeConfigFileSync ('datasources.json', dataSources);