Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option includeEmptyRows, defaults to false #120 #122

Merged
merged 1 commit into from
Jun 21, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ or [use it from the CLI](https://github.com/zemirco/json2csv#command-line-interf
- `newLine` - String, overrides the default OS line ending (i.e. `\n` on Unix and `\r\n` on Windows).
- `flatten` - Boolean, flattens nested JSON using [flat]. Defaults to `false`.
- `excelStrings` - Boolean, converts string data into normalized Excel style data.
- `includeEmptyRows` - Boolean, includes empty rows. Defaults to `false`.
- `callback` - **Required**; `function (error, csvString) {}`. To create a promise, you can use `var toCSV = Bluebird.promisify(json2csv)`, see [Bluebird] docs.

#### Example `fields` option
Expand Down
3 changes: 2 additions & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@ declare namespace json2csv {
newLine?: string;
flatten?: boolean;
excelStrings?: boolean;
includeEmptyRows?: boolean;
}

interface ICallback {
(error: Error, csv: string): void;
}

export function json2csv(options: IOptions, callback: ICallback): string;
}

Expand Down
7 changes: 5 additions & 2 deletions lib/json2csv.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ function checkParams(params, callback) {
//#check hasCSVColumnTitle, if it is not explicitly set to false then true.
params.hasCSVColumnTitle = params.hasCSVColumnTitle !== false;

//#check include empty rows, defaults to false
params.includeEmptyRows = params.includeEmptyRows || false;

callback(null);
}

Expand Down Expand Up @@ -150,8 +153,8 @@ function replaceQuotationMarks(stringifiedElement, quotes) {
*/
function createColumnContent(params, str) {
params.data.forEach(function (dataElement) {
//if null or empty object do nothing
if (dataElement && Object.getOwnPropertyNames(dataElement).length > 0) {
//if null do nothing, if empty object without includeEmptyRows do nothing
if (dataElement && (Object.getOwnPropertyNames(dataElement).length > 0 || params.includeEmptyRows)) {
var line = '';
var eol = params.newLine || os.EOL || '\n';

Expand Down
5 changes: 5 additions & 0 deletions test/fixtures/csv/emptyRow.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"carModel","price","color"
"Audi",0,"blue"
,,
"Mercedes",20000,"yellow"
"Porsche",30000,"green"
5 changes: 5 additions & 0 deletions test/fixtures/csv/emptyRowDefaultValues.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"carModel","price","color"
"Audi",0,"blue"
"NULL",1,"NULL"
"Mercedes",20000,"yellow"
"Porsche",30000,"green"
4 changes: 4 additions & 0 deletions test/fixtures/csv/emptyRowNotIncluded.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
"carModel","price","color"
"Audi",0,"blue"
"Mercedes",20000,"yellow"
"Porsche",30000,"green"
6 changes: 6 additions & 0 deletions test/fixtures/json/emptyRow.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[
{ "carModel": "Audi", "price": 0, "color": "blue" },
{},
{ "carModel": "Mercedes", "price": 20000, "color": "yellow" },
{ "carModel": "Porsche", "price": 30000, "color": "green" }
]
3 changes: 3 additions & 0 deletions test/helpers/load-fixtures.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ var fixtures = [
'excelStrings',
'newLineCellContent',
'overriddenDefaultValue',
'emptyRow',
'emptyRowNotIncluded',
'emptyRowDefaultValues',
];

/*eslint-disable no-console*/
Expand Down
126 changes: 126 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ var jsonDefaultValueEmpty = require('./fixtures/json/defaultValueEmpty');
var jsonTrailingBackslash = require('./fixtures/json/trailingBackslash');
var jsonNewlines = require('./fixtures/json/newlines');
var jsonOverriddenDefaultValue = require('./fixtures/json/overridenDefaultValue');
var jsonEmptyRow = require('./fixtures/json/emptyRow');
var csvFixtures = {};

async.parallel(loadFixtures(csvFixtures), function (err) {
Expand Down Expand Up @@ -448,4 +449,129 @@ async.parallel(loadFixtures(csvFixtures), function (err) {
t.end();
});
});

test('should include empty rows when options.includeEmptyRows is true', function (t) {
json2csv({
data: jsonEmptyRow,
fields: [
{
value: 'carModel',
},
{
label: 'price',
value: function (row) {
return row.price;
},
},
{
label: 'color',
value: function (row) {
return row.color;
},
}
],
includeEmptyRows: true,
}, function (error, csv) {
t.error(error);
t.equal(csv, csvFixtures.emptyRow);
t.end();
});
});

test('should not include empty rows when options.includeEmptyRows is false', function (t) {
json2csv({
data: jsonEmptyRow,
fields: [
{
value: 'carModel',
},
{
label: 'price',
value: function (row) {
return row.price;
},
},
{
label: 'color',
value: function (row) {
return row.color;
},
}
],
includeEmptyRows: false,
}, function (error, csv) {
t.error(error);
t.equal(csv, csvFixtures.emptyRowNotIncluded);
t.end();
});
});

test('should not include empty rows when options.includeEmptyRows is not specified', function (t) {
json2csv({
data: jsonEmptyRow,
fields: [
{
value: 'carModel',
},
{
label: 'price',
value: function (row) {
return row.price;
},
},
{
label: 'color',
value: function (row) {
return row.color;
},
}
],
}, function (error, csv) {
t.error(error);
t.equal(csv, csvFixtures.emptyRowNotIncluded);
t.end();
});
});

test('should include empty rows when options.includeEmptyRows is true, with default values', function (t) {
json2csv({
data: jsonEmptyRow,
fields: [
{
value: 'carModel',
},
{
label: 'price',
value: function (row) {
return row.price;
},
default: 1
},
{
label: 'color',
value: function (row) {
return row.color;
},
}
],
defaultValue: 'NULL',
includeEmptyRows: true,
}, function (error, csv) {
t.error(error);
t.equal(csv, csvFixtures.emptyRowDefaultValues);
t.end();
});
});

test('should parse data:[null] to csv with only column title, despite options.includeEmptyRows', function (t) {
json2csv({
data: [null],
fields: ['carModel', 'price', 'color'],
includeEmptyRows: true,
}, function (error, csv) {
t.error(error);
t.equal(csv, '"carModel","price","color"');
t.end();
});
});
});