-
Notifications
You must be signed in to change notification settings - Fork 102
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Make stamp factory to accept refs not props. Make the props safely me…
…rged into the refs when possible.
- Loading branch information
Showing
3 changed files
with
62 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,12 +3,13 @@ var forOwn = require('lodash/object/forOwn'); | |
var forIn = require('lodash/object/forIn'); | ||
var deepClone = require('lodash/lang/cloneDeep'); | ||
var isObject = require('lodash/lang/isObject'); | ||
var isUndefined = require('lodash/lang/isUndefined'); | ||
var isFunction = require('lodash/lang/isFunction'); | ||
|
||
/** | ||
* Creates mixin functions of all kinds. | ||
* @param {object} opts Options. | ||
* @param {function(object, string)} opts.filter Function which filters value and key. | ||
* @param {function(object, object)} opts.filter Function which filters value and key. | ||
* @param {boolean} opts.chain Loop through prototype properties too. | ||
* @param {function(object)} opts.getTarget Converts an object object to a target. | ||
* @param {function(object, object)} opts.getValue Converts src and dst values to a new value. | ||
|
@@ -30,11 +31,14 @@ var mixer = function (opts) { | |
target = opts.getTarget ? opts.getTarget(target) : target; | ||
This comment has been minimized.
Sorry, something went wrong. |
||
|
||
var mergeValue = function mergeValue(val, key) { | ||
if (opts.filter && !opts.filter(val, key)) { | ||
if (opts.filter && !opts.filter(val, this[key])) { | ||
This comment has been minimized.
Sorry, something went wrong.
unstoppablecarl
Contributor
|
||
return; | ||
} | ||
|
||
this[key] = opts.getValue ? opts.getValue(val, this[key]) : val; | ||
if (this[key] === 'should not be merged') { | ||
console.log('got ya'); | ||
} | ||
}; | ||
|
||
while (++i < n) { | ||
|
@@ -51,7 +55,6 @@ var mixer = function (opts) { | |
}; | ||
|
||
var merge = mixer({ | ||
getTarget: deepClone, | ||
/* jshint ignore:start */ | ||
getValue: mergeSourceToTarget | ||
/* jshint ignore:end */ | ||
|
@@ -94,6 +97,32 @@ module.exports.mixinChainFunctions = mixer({ | |
*/ | ||
module.exports.merge = merge; | ||
|
||
|
||
var mergeUnique = mixer({ | ||
filter: function (srcVal, targetVal) { | ||
return isUndefined(targetVal) || (isObject(srcVal) && isObject(targetVal)); | ||
}, | ||
/* jshint ignore:start */ | ||
getValue: mergeUniqueSourceToTarget | ||
/* jshint ignore:end */ | ||
}); | ||
|
||
function mergeUniqueSourceToTarget(srcVal, targetVal) { | ||
if ((isObject(srcVal) && isObject(targetVal))) { | ||
// inception, deep merge objects | ||
return mergeUnique(targetVal, srcVal); | ||
} else { | ||
// make sure arrays, regexp, date, objects are cloned | ||
return deepClone(srcVal); | ||
} | ||
} | ||
|
||
/** | ||
* Just like regular object merge, but do not override destination object data. | ||
*/ | ||
module.exports.mergeUnique = mergeUnique; | ||
|
||
|
||
/** | ||
* merge objects including prototype chain properties. | ||
*/ | ||
|
@@ -103,3 +132,13 @@ module.exports.mergeChainNonFunctions = mixer({ | |
getValue: mergeSourceToTarget, | ||
chain: true | ||
}); | ||
|
||
/** | ||
* merge unique properties of objects including prototype chain properties. | ||
*/ | ||
module.exports.mergeChainNonFunctions = mixer({ | ||
filter: function (val) { return !isFunction(val); }, | ||
getTarget: deepClone, | ||
getValue: mergeUniqueSourceToTarget, | ||
chain: true | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,27 +26,22 @@ test('Stamp props deep cloned for object created', function (t) { | |
t.end(); | ||
}); | ||
|
||
test('stamp(props) deep merge into object created', function (t) { | ||
var deep = { foo: 'foo', bar: 'bar' }; | ||
var stamp1 = stampit().props({ deep: deep, foo: 'foo', bar: 'bar' }); | ||
var stamp2 = stampit({ props: { deep: deep, foo: 'foo', bar: 'bar' } }); | ||
test('stamp(refs) deep merges props into refs', function (t) { | ||
var deepInProps = { deepProp1: 'should not be merged', deepProp2: 'merge me!' }; | ||
var stamp1 = stampit().props({ deep: deepInProps, shallow1: 'should not be merged', shallow2: 'merge me!' }); | ||
var stamp2 = stampit({ props: { deep: deepInProps, shallow1: 'should not be merged', shallow2: 'merge me!' } }); | ||
|
||
var deep2 = { foo: 'override', baz: 'baz' }; | ||
var o1 = stamp1({ deep: deep2, foo: 'override', baz: 'baz' }); | ||
var o2 = stamp2({ deep: deep2, foo: 'override', baz: 'baz' }); | ||
var o1 = stamp1({ deep: { deepProp1: 'leave me as is' }, shallow1: 'leave me as is' }); | ||
var o2 = stamp2({ deep: { deepProp1: 'leave me as is' }, shallow1: 'leave me as is' }); | ||
|
||
t.equal(o1.foo, 'override'); | ||
t.equal(o1.bar, 'bar'); | ||
t.equal(o1.baz, 'baz'); | ||
t.equal(o2.foo, 'override'); | ||
t.equal(o2.bar, 'bar'); | ||
t.equal(o2.baz, 'baz'); | ||
t.equal(o1.deep.foo, 'override'); | ||
t.equal(o1.deep.bar, 'bar'); | ||
t.equal(o1.deep.baz, 'baz'); | ||
t.equal(o2.deep.foo, 'override'); | ||
t.equal(o2.deep.bar, 'bar'); | ||
t.equal(o2.deep.baz, 'baz'); | ||
t.equal(o1.shallow1, 'leave me as is'); | ||
This comment has been minimized.
Sorry, something went wrong.
ericelliott
Contributor
|
||
t.equal(o1.shallow2, 'merge me!'); | ||
t.equal(o2.shallow1, 'leave me as is'); | ||
t.equal(o2.shallow2, 'merge me!'); | ||
t.equal(o1.deep.deepProp1, 'leave me as is', 'Deep property in refs should not be touched by props'); | ||
t.equal(o1.deep.deepProp2, 'merge me!'); | ||
t.equal(o2.deep.deepProp1, 'leave me as is', 'Deep property in refs should not be touched by props'); | ||
t.equal(o2.deep.deepProp2, 'merge me!'); | ||
|
||
t.end(); | ||
}); | ||
|
use vars for opts to decrease cognitive load
use
target
instead ofthis