Skip to content

Commit

Permalink
fix: unwind of nested fields (#357)
Browse files Browse the repository at this point in the history
juanjoDiaz authored and knownasilya committed Feb 22, 2019

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent c910c35 commit 2d69281
Showing 9 changed files with 298 additions and 3,477 deletions.
21 changes: 9 additions & 12 deletions lib/JSON2CSVBase.js
Original file line number Diff line number Diff line change
@@ -2,7 +2,13 @@

const os = require('os');
const lodashGet = require('lodash.get');
const lodashSet = require('lodash.set');

const setProp = (obj, path, value) => {
const pathArray = Array.isArray(path) ? path : path.split('.');
const key = pathArray[0];
const newValue = pathArray.length > 1 ? setProp(obj[key] || {}, pathArray.slice(1), value) : value;
return Object.assign({}, obj, { [key]: newValue });
};

class JSON2CSVBase {
constructor(opts) {
@@ -255,15 +261,6 @@ class JSON2CSVBase {
*/
unwindData(dataRow, unwindPaths) {
const unwind = (rows, unwindPath) => {
const pathAndField = unwindPath.split(/\.(?=[^.]+$)/);
const setUnwoundValue = pathAndField.length === 2
? (() => {
const parentPath = pathAndField[0];
const unwindField = pathAndField[1];
return (row, value) => lodashSet(Object.assign({}, row), parentPath, Object.assign({}, lodashGet(row, parentPath), { [unwindField]: value }));
})()
: (row, value) => Object.assign({}, row, { [unwindPath]: value });

return rows
.map(row => {
const unwindArray = lodashGet(row, unwindPath);
@@ -273,15 +270,15 @@ class JSON2CSVBase {
}

if (!unwindArray.length) {
return setUnwoundValue(row, undefined);
return setProp(row, unwindPath, undefined);
}

return unwindArray.map((unwindRow, index) => {
const clonedRow = (this.opts.unwindBlank && index > 0)
? {}
: row;

return setUnwoundValue(clonedRow, unwindRow);
return setProp(clonedRow, unwindPath, unwindRow);
});
})
.reduce((a, e) => a.concat(e), []);
3,649 changes: 235 additions & 3,414 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -41,8 +41,7 @@
"dependencies": {
"commander": "^2.15.1",
"jsonparse": "^1.3.1",
"lodash.get": "^4.4.2",
"lodash.set": "^4.3.2"
"lodash.get": "^4.4.2"
},
"devDependencies": {
"babel-core": "^6.26.3",
8 changes: 4 additions & 4 deletions test/CLI.js
Original file line number Diff line number Diff line change
@@ -301,8 +301,8 @@ module.exports = (testRunner, jsonFixtures, csvFixtures) => {
});

testRunner.add('should support multi-level unwind', (t) => {
const opts = ' --fields carModel,price,items.name,items.color,items.items.position,items.items.color'
+ ' --unwind items,items.items';
const opts = ' --fields carModel,price,extras.items.name,extras.items.color,extras.items.items.position,extras.items.items.color'
+ ' --unwind extras.items,extras.items.items';

child_process.exec(cli + '-i ' + getFixturePath('/json/unwind2.json') + opts, (err, stdout, stderr) => {
t.notOk(stderr);
@@ -313,8 +313,8 @@ module.exports = (testRunner, jsonFixtures, csvFixtures) => {
});

testRunner.add('hould unwind and blank out repeated data', (t) => {
const opts = ' --fields carModel,price,items.name,items.color,items.items.position,items.items.color'
+ ' --unwind items,items.items --unwind-blank';
const opts = ' --fields carModel,price,extras.items.name,extras.items.color,extras.items.items.position,extras.items.items.color'
+ ' --unwind extras.items,extras.items.items --unwind-blank';

child_process.exec(cli + '-i ' + getFixturePath('/json/unwind2.json') + opts, (err, stdout, stderr) => {
t.notOk(stderr);
8 changes: 4 additions & 4 deletions test/JSON2CSVParser.js
Original file line number Diff line number Diff line change
@@ -339,8 +339,8 @@ module.exports = (testRunner, jsonFixtures, csvFixtures) => {

testRunner.add('should support multi-level unwind', (t) => {
const opts = {
fields: ['carModel', 'price', 'items.name', 'items.color', 'items.items.position', 'items.items.color'],
unwind: ['items', 'items.items']
fields: ['carModel', 'price', 'extras.items.name', 'extras.items.color', 'extras.items.items.position', 'extras.items.items.color'],
unwind: ['extras.items', 'extras.items.items']
};

const parser = new Json2csvParser(opts);
@@ -352,8 +352,8 @@ module.exports = (testRunner, jsonFixtures, csvFixtures) => {

testRunner.add('should unwind and blank out repeated data', (t) => {
const opts = {
fields: ['carModel', 'price', 'items.name', 'items.color', 'items.items.position', 'items.items.color'],
unwind: ['items', 'items.items'],
fields: ['carModel', 'price', 'extras.items.name', 'extras.items.color', 'extras.items.items.position', 'extras.items.items.color'],
unwind: ['extras.items', 'extras.items.items'],
unwindBlank: true
};

8 changes: 4 additions & 4 deletions test/JSON2CSVTransform.js
Original file line number Diff line number Diff line change
@@ -499,8 +499,8 @@ module.exports = (testRunner, jsonFixtures, csvFixtures, inMemoryJsonFixtures) =

testRunner.add('should support multi-level unwind', (t) => {
const opts = {
fields: ['carModel', 'price', 'items.name', 'items.color', 'items.items.position', 'items.items.color'],
unwind: ['items', 'items.items']
fields: ['carModel', 'price', 'extras.items.name', 'extras.items.color', 'extras.items.items.position', 'extras.items.items.color'],
unwind: ['extras.items', 'extras.items.items']
};

const transform = new Json2csvTransform(opts);
@@ -520,8 +520,8 @@ module.exports = (testRunner, jsonFixtures, csvFixtures, inMemoryJsonFixtures) =

testRunner.add('should unwind and blank out repeated data', (t) => {
const opts = {
fields: ['carModel', 'price', 'items.name', 'items.color', 'items.items.position', 'items.items.color'],
unwind: ['items', 'items.items'],
fields: ['carModel', 'price', 'extras.items.name', 'extras.items.color', 'extras.items.items.position', 'extras.items.items.color'],
unwind: ['extras.items', 'extras.items.items'],
unwindBlank: true
};

2 changes: 1 addition & 1 deletion test/fixtures/csv/unwind2.csv
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"carModel","price","items.name","items.color","items.items.position","items.items.color"
"carModel","price","extras.items.name","extras.items.color","extras.items.items.position","extras.items.items.color"
"BMW",15000,"airbag","white",,
"BMW",15000,"dashboard","black",,
"Porsche",30000,"airbag",,"left","white"
2 changes: 1 addition & 1 deletion test/fixtures/csv/unwind2Blank.csv
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"carModel","price","items.name","items.color","items.items.position","items.items.color"
"carModel","price","extras.items.name","extras.items.color","extras.items.items.position","extras.items.items.color"
"BMW",15000,"airbag","white",,
,,"dashboard","black",,
"Porsche",30000,"airbag",,"left","white"
74 changes: 39 additions & 35 deletions test/fixtures/json/unwind2.json
Original file line number Diff line number Diff line change
@@ -2,43 +2,47 @@
{
"carModel": "BMW",
"price": 15000,
"items": [
{
"name": "airbag",
"color": "white"
}, {
"name": "dashboard",
"color": "black"
}
]
"extras": {
"items": [
{
"name": "airbag",
"color": "white"
}, {
"name": "dashboard",
"color": "black"
}
]
}
}, {
"carModel": "Porsche",
"price": 30000,
"items": [
{
"name": "airbag",
"items": [
{
"position": "left",
"color": "white"
}, {
"position": "right",
"color": "gray"
}
]
},
{
"name": "dashboard",
"items": [
{
"position": "left",
"color": "gray"
}, {
"position": "right",
"color": "black"
}
]
}
]
"extras": {
"items": [
{
"name": "airbag",
"items": [
{
"position": "left",
"color": "white"
}, {
"position": "right",
"color": "gray"
}
]
},
{
"name": "dashboard",
"items": [
{
"position": "left",
"color": "gray"
}, {
"position": "right",
"color": "black"
}
]
}
]
}
}
]

0 comments on commit 2d69281

Please sign in to comment.