Skip to content

Commit

Permalink
Add a destination node object as an argument of a converter
Browse files Browse the repository at this point in the history
  • Loading branch information
sttk committed Apr 1, 2017
1 parent e68e793 commit 25b2ddc
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 20 deletions.
26 changes: 24 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,27 @@ Usage
// => { a: 'A', b: 'b', c: null }
```

* You can operate the parent node object directly in converter.

```js
var src = { a: 1, b: 2 };
var dst = {};
copyProps(src, dst, function(srcval, srckey, dstkey, dstval, dstParent) {
var key = dstkey.split('.').pop();
Object.defineProperty(dstParent, key, {
writable: false,
enumerable: true,
configurable: false,
value: srcval * 2
})
}); // => { a: 2, b: 4 }
dst // => { a: 2, b: 4 }
dst.a = 9
dst // -> { a: 2, b: 4 }
```

API
---

Expand Down Expand Up @@ -145,7 +166,7 @@ copyProps(src, dst, {

#### *API of converter*

**<u>converter(srcValue, srcKeychain, dstKeyChain, dstValue) => any</u>**
**<u>converter(srcValue, srcKeychain, dstKeyChain, dstValue, dstParent) => any</u>**

*converter* is a function to convert terminal values of propeerties of *src*.

Expand All @@ -155,8 +176,9 @@ copyProps(src, dst, {
* **srcKeychain** [string] : a source property key string concatenated with dots.
* **dstKeychain** [string] : a destination property key string concatenated with dots.
* **dstValue** [any] : a destination property value before copying.
* **dstParent** [object] : the destination node object which has the copied property.

* **Return:** [any] : converted value to be set as a destination property value.
* **Return:** [any] : converted value to be set as a destination property value. If this value is undefined, the destination property is not set to the destination node object.

License
-------
Expand Down
11 changes: 6 additions & 5 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,9 @@ function copyWithFromto(value, keyChain, nodeInfo) {
}

for (var i = 0, n = dstKeyChains.length; i < n; i++) {
setDeep(nodeInfo.dest, dstKeyChains[i], function(dstValue) {
return nodeInfo.convert(value, keyChain, dstKeyChains[i], dstValue);
setDeep(nodeInfo.dest, dstKeyChains[i], function(dstValue, dstParent) {
return nodeInfo.convert(value, keyChain, dstKeyChains[i], dstValue,
dstParent);
});
}
}
Expand All @@ -99,8 +100,8 @@ function copyWithoutFromto(value, keyChain, nodeInfo) {
return;
}

setDeep(nodeInfo.dest, keyChain, function(dstValue) {
return nodeInfo.convert(value, keyChain, keyChain, dstValue);
setDeep(nodeInfo.dest, keyChain, function(dstValue, dstParent) {
return nodeInfo.convert(value, keyChain, keyChain, dstValue, dstParent);
});
}

Expand Down Expand Up @@ -153,7 +154,7 @@ function setDeep(obj, keyChain, valueCreator) {
function _setDeep(obj, keyElems, valueCreator) {
var key = keyElems.shift();
if (!keyElems.length) {
var value = valueCreator(obj[key]);
var value = valueCreator(obj[key], obj);
if (value !== undefined) {
obj[key] = value;
}
Expand Down
35 changes: 29 additions & 6 deletions test/copy-props-proc.js
Original file line number Diff line number Diff line change
Expand Up @@ -256,30 +256,34 @@ describe('Processing', function() {
it('When converter returns undefined', function(done) {
var src = { a: 1, b: { c: 2, d: 3, e: 4 } };
var dst = { a: 'A', b: { e: 'E' } };
function fn(value, keyChain, dstKeyChain, dstValue) {
function fn(value, keyChain, dstKeyChain, dstValue, dstParent) {
switch (keyChain) {
case 'a': {
expect(value).to.equal(1);
expect(dstKeyChain).to.equal(keyChain);
expect(dstValue).to.equal('A');
expect(dstParent).to.equal(dst);
break;
}
case 'b.c': {
expect(value).to.equal(2);
expect(dstKeyChain).to.equal(keyChain);
expect(dstValue).to.be.undefined;
expect(dstParent).to.equal(dst.b);
break;
}
case 'b.d': {
expect(value).to.equal(3);
expect(dstKeyChain).to.equal(keyChain);
expect(dstValue).to.be.undefined;
expect(dstParent).to.equal(dst.b);
break;
}
case 'b.e': {
expect(value).to.equal(4);
expect(dstKeyChain).to.equal(keyChain);
expect(dstValue).to.equal('E');
expect(dstParent).to.equal(dst.b);
break;
}
default: {
Expand All @@ -298,24 +302,27 @@ describe('Processing', function() {
it('When converter returns null', function(done) {
var src = { a: 1, b: { c: 2, d: 3 } };
var dst = {};
function fn(value, keyChain, dstKeyChain, dstValue) {
function fn(value, keyChain, dstKeyChain, dstValue, dstParent) {
switch (keyChain) {
case 'a': {
expect(value).to.equal(1);
expect(dstKeyChain).to.equal(keyChain);
expect(dstValue).to.be.undefined;
expect(dstParent).to.equal(dst);
break;
}
case 'b.c': {
expect(value).to.equal(2);
expect(dstKeyChain).to.equal(keyChain);
expect(dstValue).to.be.undefined;
expect(dstParent).to.equal(dst.b);
break;
}
case 'b.d': {
expect(value).to.equal(3);
expect(dstKeyChain).to.equal(keyChain);
expect(dstValue).to.be.undefined;
expect(dstParent).to.equal(dst.b);
break;
}
default: {
Expand Down Expand Up @@ -351,24 +358,28 @@ describe('Processing', function() {

src = { a: 1, b: { c: 2, d: 3 } };
dst = { a: 'A', b: { c: 'C', d: 'D' } };
var converter = function(value, keyChain, dstKeyChain, dstValue) {
var converter = function(value, keyChain, dstKeyChain, dstValue,
dstParent) {
switch (keyChain) {
case 'a': {
expect(value).to.equal('A');
expect(dstKeyChain).to.equal(keyChain);
expect(dstValue).to.equal(1);
expect(dstParent).to.equal(src);
break;
}
case 'b.c': {
expect(value).to.equal('C');
expect(dstKeyChain).to.equal(keyChain);
expect(dstValue).to.equal(2);
expect(dstParent).to.equal(src.b);
break;
}
case 'b.d': {
expect(value).to.equal('D');
expect(dstKeyChain).to.equal(keyChain);
expect(dstValue).to.equal(3);
expect(dstParent).to.equal(src.b);
break;
}
default: {
Expand All @@ -389,30 +400,34 @@ describe('Processing', function() {
src = { a: 1, b: { c: 2, d: 3 } };
dst = { a: 'A', b: { c: 'C', d: 'D', e: 'E', f: 'F' } };
fromto = ['a', 'b.c', 'b.d', 'b.e'];
converter = function(value, keyChain, dstKeyChain, dstValue) {
converter = function(value, keyChain, dstKeyChain, dstValue, dstParent) {
switch (keyChain) {
case 'a': {
expect(value).to.equal('A');
expect(dstKeyChain).to.equal(keyChain);
expect(dstValue).to.equal(1);
expect(dstParent).to.equal(src);
break;
}
case 'b.c': {
expect(value).to.equal('C');
expect(dstKeyChain).to.equal(keyChain);
expect(dstValue).to.equal(2);
expect(dstParent).to.equal(src.b);
break;
}
case 'b.d': {
expect(value).to.equal('D');
expect(dstKeyChain).to.equal(keyChain);
expect(dstValue).to.equal(3);
expect(dstParent).to.equal(src.b);
break;
}
case 'b.e': {
expect(value).to.equal('E');
expect(dstKeyChain).to.equal(keyChain);
expect(dstValue).to.be.undefined;
expect(dstParent).to.equal(src.b);
break;
}
default: {
Expand Down Expand Up @@ -448,24 +463,28 @@ describe('Processing', function() {

src = { a: 1, b: { c: 2, d: 3 } };
dst = { a: 'A', b: { c: 'C', d: 'D' } };
var converter = function(value, keyChain, dstKeyChain, dstValue) {
var converter = function(value, keyChain, dstKeyChain, dstValue,
dstParent) {
switch (keyChain) {
case 'a': {
expect(value).to.equal(1);
expect(dstKeyChain).to.equal(keyChain);
expect(dstValue).to.equal('A');
expect(dstParent).to.equal(dst);
break;
}
case 'b.c': {
expect(value).to.equal(2);
expect(dstKeyChain).to.equal(keyChain);
expect(dstValue).to.equal('C');
expect(dstParent).to.equal(dst.b);
break;
}
case 'b.d': {
expect(value).to.equal(3);
expect(dstKeyChain).to.equal(keyChain);
expect(dstValue).to.equal('D');
expect(dstParent).to.equal(dst.b);
break;
}
default: {
Expand All @@ -486,30 +505,34 @@ describe('Processing', function() {
src = { a: 1, b: { c: 2, d: 3 } };
dst = { a: 'A', b: { c: 'C', d: 'D', e: 'E', f: 'F' } };
fromto = ['a', 'b.c', 'b.d', 'b.e'];
converter = function(value, keyChain, dstKeyChain, dstValue) {
converter = function(value, keyChain, dstKeyChain, dstValue, dstParent) {
switch (keyChain) {
case 'a': {
expect(value).to.equal(1);
expect(dstKeyChain).to.equal(keyChain);
expect(dstValue).to.equal('A');
expect(dstParent).to.equal(dst);
break;
}
case 'b.c': {
expect(value).to.equal(2);
expect(dstKeyChain).to.equal(keyChain);
expect(dstValue).to.equal('C');
expect(dstParent).to.equal(dst.b);
break;
}
case 'b.d': {
expect(value).to.equal(3);
expect(dstKeyChain).to.equal(keyChain);
expect(dstValue).to.equal('D');
expect(dstParent).to.equal(dst.b);
break;
}
case 'b.e': {
expect(value).to.be.undefined;
expect(dstKeyChain).to.equal(keyChain);
expect(dstValue).to.equal('E');
expect(dstParent).to.equal(dst.b);
break;
}
default: {
Expand Down
Loading

0 comments on commit 25b2ddc

Please sign in to comment.