Skip to content

Commit

Permalink
Use a deepmerge function to merge both globa level config & bidder sp…
Browse files Browse the repository at this point in the history
…ecific config (prebid#5039)

Fixing issue prebid#4950
  • Loading branch information
leonardlabat authored and iggyfisk committed Jun 22, 2020
1 parent e52688b commit c528da6
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 5 deletions.
3 changes: 2 additions & 1 deletion src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { isValidPriceConfig } from './cpmBucketManager.js';
import find from 'core-js/library/fn/array/find.js';
import includes from 'core-js/library/fn/array/includes.js';
import Set from 'core-js/library/fn/set.js';
import { mergeDeep } from './utils.js';

const from = require('core-js/library/fn/array/from.js');
const utils = require('./utils.js');
Expand Down Expand Up @@ -254,7 +255,7 @@ export function newConfig() {
memo[topic] = currBidderConfig[topic];
} else {
if (utils.isPlainObject(currBidderConfig[topic])) {
memo[topic] = Object.assign({}, config[topic], currBidderConfig[topic]);
memo[topic] = mergeDeep({}, config[topic], currBidderConfig[topic]);
} else {
memo[topic] = currBidderConfig[topic];
}
Expand Down
28 changes: 28 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,10 @@ function decorateLog(args, prefix) {
return args;
}

export function hasConsoleLogger() {
return consoleLogExists;
}

export function debugTurnedOn() {
return !!config.getConfig('debug');
}
Expand Down Expand Up @@ -1166,3 +1170,27 @@ export function buildUrl(obj) {
export function deepEqual(obj1, obj2) {
return deepequal(obj1, obj2);
}

export function mergeDeep(target, ...sources) {
if (!sources.length) return target;
const source = sources.shift();

if (isPlainObject(target) && isPlainObject(source)) {
for (const key in source) {
if (isPlainObject(source[key])) {
if (!target[key]) Object.assign(target, { [key]: {} });
mergeDeep(target[key], source[key]);
} else if (isArray(source[key])) {
if (!target[key]) {
Object.assign(target, { [key]: source[key] });
} else if (isArray(target[key])) {
target[key] = target[key].concat(source[key]);
}
} else {
Object.assign(target, { [key]: source[key] });
}
}
}

return mergeDeep(target, ...sources);
}
8 changes: 4 additions & 4 deletions test/spec/unit/core/adapterManager_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ describe('adapterManager tests', function () {
buildRequests: {
data: 1
},
test1: { speedy: true },
test1: { speedy: true, fun: { test: true } },
interpretResponse: 'baseInterpret',
afterInterpretResponse: 'anotherBaseInterpret'
});
Expand Down Expand Up @@ -253,7 +253,7 @@ describe('adapterManager tests', function () {
data: 1,
test: 2
},
{ fun: { safe: true, cheap: false }, speedy: true },
{ fun: { safe: true, cheap: false, test: true }, speedy: true },
{ amazing: true },
'appnexusInterpret',
'anotherBaseInterpret'
Expand All @@ -262,14 +262,14 @@ describe('adapterManager tests', function () {
{
data: 1
},
{ speedy: true },
{ fun: { test: true }, speedy: true },
undefined,
'baseInterpret',
'anotherBaseInterpret'
],
'rubicon': [
'rubiconBuild',
{ speedy: true },
{ fun: { test: true }, speedy: true },
{ amazing: true },
null,
'anotherBaseInterpret'
Expand Down
97 changes: 97 additions & 0 deletions test/spec/utils_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1018,4 +1018,101 @@ describe('Utils', function () {
expect(utils.isSafariBrowser()).to.equal(false);
});
});

describe('mergeDeep', function() {
it('properly merge objects that share same property names', function() {
const object1 = {
propA: {
subPropA: 'abc'
}
};
const object2 = {
propA: {
subPropB: 'def'
}
};

const resultWithoutMergeDeep = Object.assign({}, object1, object2);
expect(resultWithoutMergeDeep).to.deep.equal({
propA: {
subPropB: 'def'
}
});

const resultWithMergeDeep = utils.mergeDeep({}, object1, object2);
expect(resultWithMergeDeep).to.deep.equal({
propA: {
subPropA: 'abc',
subPropB: 'def'
}
});
});

it('properly merge objects that have different depths', function() {
const object1 = {
depth0_A: {
depth1_A: {
depth2_A: 123
}
}
};
const object2 = {
depth0_A: {
depth1_A: {
depth2_B: {
depth3_A: {
depth4_A: 'def'
}
}
},
depth1_B: 'abc'
}
};
const object3 = {
depth0_B: 456
};

const result = utils.mergeDeep({}, object1, object2, object3);
expect(result).to.deep.equal({
depth0_A: {
depth1_A: {
depth2_A: 123,
depth2_B: {
depth3_A: {
depth4_A: 'def'
}
}
},
depth1_B: 'abc'
},
depth0_B: 456
});
});

it('properly merge objects with various property types', function() {
const object1 = {
depth0_A: {
depth1_A: ['a', 'b', 'c'],
depth1_B: 'abc',
depth1_C: 123
}
};
const object2 = {
depth0_A: {
depth1_A: ['d', 'e', 'f'],
depth1_D: true,
}
};

const result = utils.mergeDeep({}, object1, object2);
expect(result).to.deep.equal({
depth0_A: {
depth1_A: ['a', 'b', 'c', 'd', 'e', 'f'],
depth1_B: 'abc',
depth1_C: 123,
depth1_D: true,
}
});
});
});
});

0 comments on commit c528da6

Please sign in to comment.