config-loader: deeply merge Array and Object vals

This commit is contained in:
Shelby Sanders 2014-08-13 22:07:10 -07:00 committed by Miroslav Bajtoš
parent abda37fee9
commit e1d870dced
3 changed files with 96 additions and 10 deletions

View File

@ -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
}

View File

@ -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() {

View File

@ -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);