Skip to content

Commit

Permalink
1.3.0 - add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kaue committed Oct 6, 2016
1 parent 2a4f133 commit 26513e7
Show file tree
Hide file tree
Showing 4 changed files with 223 additions and 36 deletions.
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Changelog
# Usage

Installation command is `npm install jsonexport`.
Run tests with `npm test`.

```javascript
var jsonexport = require('jsonexport');
Expand Down Expand Up @@ -211,8 +212,6 @@ In order to get the most of out of this module, you can customize many parameter
- `handleNumber` - `Function` Use this to customize all `Numbers` in the CSV file.
- `handleBoolean` - `Function` Use this to customize all `Booleans` in the CSV file.
- `handleDate` - `Function` Use this to customize all `Dates` in the CSV file.
- `handleArray` - `Function` Use this to customize all `Arrays` in the CSV file.
- `handleObject` - `Function` Use this to customize all `Objects` in the CSV file.

### Handle Customization

Expand Down
63 changes: 33 additions & 30 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,6 @@
*/
var os = require('os');
var _ = require('underscore');
/**
* Default options
*/
var options = {
headerPathString: '.', // String
rowDelimiter: ',', // String
textDelimiter: '"', // String
arrayPathString: ';', // String
undefinedString: '', // String
endOfLine: null, // String
mainPathItem: null, // String
booleanTrueString: null, // String
booleanFalseString: null, // String
includeHeaders: true, // Boolean
orderHeaders: false, // Boolean
verticalOutput: true, // Boolean
//Handlers
handleString: null, // Function
handleNumber: null, // Function
handleBoolean: null, // Function
handleDate: null, // Function
handleArray: null, // Function
handleObject: null // Function
};
/**
* Main function that converts json to csv
*
Expand All @@ -50,6 +26,30 @@ module.exports = function(json,userOptions,callback) {
* @param {Options} userOptions
*/
function parseOptions(userOptions){
/**
* Default options
*/
var options = {
headerPathString: '.', // String
rowDelimiter: ',', // String
textDelimiter: '"', // String
arrayPathString: ';', // String
undefinedString: '', // String
endOfLine: null, // String
mainPathItem: null, // String
booleanTrueString: null, // String
booleanFalseString: null, // String
includeHeaders: true, // Boolean
orderHeaders: false, // Boolean
verticalOutput: true, // Boolean
//Handlers
handleString: null, // Function
handleNumber: null, // Function
handleBoolean: null, // Function
handleDate: null, // Function
//handleArray: null, // Function
//handleObject: null // Function
};
return _.extend(options, userOptions);
}
/**
Expand Down Expand Up @@ -113,13 +113,16 @@ function generateCsv(json, callback) {
else if(_.isObject(json)){
var fileRows = [];
var horizontalRows = [[],[]];
var textDelimiterRegex = new RegExp(options.textDelimiter, 'g');
var textDelimiterRegex = new RegExp("\\" + options.textDelimiter, 'g');
var endOfLine = options.endOfLine || os.EOL || '\n';
for(var prop in json){
var parseResult = checkType(json[prop], prop);
var prefix = "";
if(options.mainPathItem)
prefix = options.mainPathItem + options.headerPathString;
var parseResult = checkType(json[prop], prefix + prop);
parseResult.forEach(function (result) {

var value = result.value || options.undefinedString;
var value = result.value ? result.value.toString() : options.undefinedString;
// Escape the textDelimiters contained in the field
/*(https://tools.ietf.org/html/rfc4180)
7. If double-quotes are used to enclose fields, then a double-quote
Expand All @@ -128,7 +131,7 @@ function generateCsv(json, callback) {
For example: "aaa","b""bb","ccc"
*/
value = value.replace(textDelimiterRegex, options.textDelimiter+options.textDelimiter);
// Escape the whole field if it contains a rowDelimiter
// Escape the whole field if it contains a rowDelimiter or a linebreak
if (value.indexOf(options.rowDelimiter) >= 0 || value.indexOf(endOfLine) >= 0) {
value = options.textDelimiter + value + options.textDelimiter;
}
Expand Down Expand Up @@ -235,7 +238,7 @@ function checkType(element, item){
}
//Check if element is an Array
else if(_.isArray(element)){
var resultArray = options.handleArray ? options.handleArray(element, item) : handleArray(element, item);
var resultArray = handleArray(element, item);
resultArray.forEach(function (resultArrayElement) {
if(resultArrayElement.item != null && item){
resultArrayElement.item = item + options.headerPathString + resultArrayElement.item;
Expand All @@ -248,7 +251,7 @@ function checkType(element, item){
}
//Check if element is a Object
else if(_.isObject(element)){
var resultObject = options.handleObject ? options.handleObject(element, item) : handleObject(element, item);
var resultObject = handleObject(element, item);
resultObject.forEach(function (resultObjectElement) {
if(resultObjectElement.item != null && item) {
resultObjectElement.item = item + options.headerPathString + resultObjectElement.item;
Expand Down
24 changes: 20 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,32 @@
{
"name": "jsonexport",
"version": "1.2.2",
"version": "1.3.0",
"description": "Makes easy to convert JSON to CSV",
"main": "./lib",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "mocha tests/*.js tests/**/*.js"
},
"bin": {
"jsonexport": "bin/jsonexport.js"
"jsonexport": "bin/jsonexport.js"
},
"repository": {
"type": "git",
"url": "https://github.com/kauegimenes/jsonexport.git"
},
"keywords": ["export", "json", "to", "2", "csv", "converter", "output", "array", "object", "json-to-csv", "json2csv", "parse"],
"keywords": [
"export",
"json",
"to",
"2",
"csv",
"converter",
"output",
"array",
"object",
"json-to-csv",
"json2csv",
"parse"
],
"author": "Kauê Gimenes",
"license": "ISC",
"bugs": {
Expand All @@ -22,5 +35,8 @@
"homepage": "https://github.com/kauegimenes/jsonexport",
"dependencies": {
"underscore": "^1.8.3"
},
"devDependencies": {
"chai": "^3.5.0"
}
}
169 changes: 169 additions & 0 deletions tests/options.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
var chai = require('chai');
var expect = chai.expect; // we are using the "expect" style of Chai
var jsonexport = require('../lib/index');

const SIMPLE_OBJECT = {
lang: 'Node.js',
module: 'jsonexport'
};
const COMPLEX_OBJECT = {
cars: 12,
roads: 5,
traffic: 'slow',
speed: {
max: 123,
avg: 20,
min: 5
},
size: [10,20]
};
const SIMPLE_ARRAY = [{
name: 'Bob',
lastname: 'Smith'
},{
name: 'James',
lastname: 'David'
}];
const COMPLEX_ARRAY = [{
name: 'Bob',
lastname: 'Smith',
family: {
name: 'Peter',
type: 'Father'
}
},{
name: 'James',
lastname: 'David',
family:{
name: 'Julie',
type: 'Mother'
}
}];

describe('Options', () => {
it('headerPathString', () => {
jsonexport({a: {b: true}}, {
headerPathString: '|'
}, (err, csv) => {
expect(csv).to.have.string('a|b');
});
});
it('rowDelimiter', () => {
jsonexport({a: true, b: true}, {
rowDelimiter: '|'
}, (err, csv) => {
expect(csv).to.have.string('a|true');
});
});
it('textDelimiter with linebreak', () => {
jsonexport({a: '\n', b: true}, {
textDelimiter: '|'
}, (err, csv) => {
expect(csv).to.have.string('|\n|');
});
});
it('textDelimiter with double quote', () => {
jsonexport({a: '"', b: true}, {
textDelimiter: '"'
}, (err, csv) => {
expect(csv).to.have.string('a,""');
});
});
it('endOfLine', () => {
jsonexport({a: true, b: true}, {
endOfLine: '|'
}, (err, csv) => {
expect(csv).to.have.string('a,true|b,true');
});
});
it('mainPathItem', () => {
// Object
jsonexport({a: true, b: true}, {
mainPathItem: 'main'
}, (err, csv) => {
expect(csv).to.have.string('main.a,true\nmain.b,true');
});
// Array
jsonexport([{a: true}, {b: true}], {
mainPathItem: 'main'
}, (err, csv) => {
expect(csv).to.have.string('main.a,main.b');
});
});
it('mainPathItem', () => {
jsonexport({a: [1, 2], b: true}, {
arrayPathString: '|'
}, (err, csv) => {
expect(csv).to.have.string('a,1|2');
});
});
it('booleanTrueString', () => {
jsonexport({a: true, b: true}, {
booleanTrueString: 'test'
}, (err, csv) => {
expect(csv).to.have.string('a,test');
});
});
it('booleanFalseString', () => {
jsonexport({a: false, b: true}, {
booleanFalseString: 'test'
}, (err, csv) => {
expect(csv).to.have.string('a,test');
});
});
it('includeHeaders', () => {
jsonexport([{a: true}, {a: false}], {
includeHeaders: false
}, (err, csv) => {
expect(csv).to.have.string('true\nfalse');
});
});
it('orderHeaders', () => {
jsonexport([{b: false}, {a: true}, {a: true}], {
orderHeaders: true
}, (err, csv) => {
expect(csv).to.have.string('a,b');
});
jsonexport([{b: false}, {a: true}, {a: true}], {
orderHeaders: false
}, (err, csv) => {
expect(csv).to.have.string('b,a');
});
});
it('verticalOutput', () => {
jsonexport({a: true, b: true}, {
verticalOutput: false
}, (err, csv) => {
expect(csv).to.have.string('a,b');
});
});
it('handleString', () => {
jsonexport({a: 'test', b: true}, {
handleString: (value, name) => value + "|||"
}, (err, csv) => {
expect(csv).to.have.string('a,test|||');
});
});
it('handleNumber', () => {
jsonexport({a: 1, b: true}, {
handleNumber: (value, name) => value + "|||"
}, (err, csv) => {
expect(csv).to.have.string('a,1|||');
});
});
it('handleBoolean', () => {
jsonexport({a: true, b: true}, {
handleBoolean: (value, name) => value + "|||"
}, (err, csv) => {
expect(csv).to.have.string('a,true|||');
});
});
it('handleDate', () => {
var date = new Date();
jsonexport({a: date, b: true}, {
handleDate: (value, name) => value + "|||"
}, (err, csv) => {
expect(csv).to.have.string('a,' + date + '|||');
});
});
})

0 comments on commit 26513e7

Please sign in to comment.