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

Fixing issue #4950
  • Loading branch information
leonardlabat committed Mar 27, 2020
1 parent cceaf0f commit cf5cab8
Show file tree
Hide file tree
Showing 4 changed files with 127 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 @@ -17,6 +17,7 @@ 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 { parseQS } from './url.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 @@ -255,7 +256,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
24 changes: 24 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -1348,3 +1348,27 @@ export function compareOn(property) {
return 0;
}
}

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 @@ -175,7 +175,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 @@ -212,7 +212,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 @@ -221,14 +221,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 @@ -930,4 +930,101 @@ describe('Utils', function () {
});
});
});

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 cf5cab8

Please sign in to comment.