Skip to content
This repository has been archived by the owner on Jan 9, 2018. It is now read-only.

added a csv.generate function #11

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
10 changes: 10 additions & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,16 @@ res.csv([ { name: "joe", id: 1 }]
//=> "joe", 1
```

csv also expose a generate() function that generate a csv string from an array, E.g:

```js
var csvString = csv.generate([
["a", "b", "c"]
, ["d", "e", "f"]
]);
// => csvString = '"a", "b", "c"\n"d", "e", "f"'
```

## License

The MIT License
Expand Down
24 changes: 18 additions & 6 deletions lib/express-csv.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,23 @@ function objToArray(obj) {
return result;
}

/**
* Generate a csv string fom an object
*
* @param {Array} obj
* @return {String}
*/

exports.generate = function(obj) {
var str = '';
obj.forEach(function(item) {
if (!(item instanceof Array)) item = objToArray(item);
str += item.map(escape).join(exports.separator) + '\r\n';
});
return str;
};


/**
* Send CSV response with `obj`, optional `headers`, and optional `status`.
*
Expand All @@ -93,16 +110,11 @@ function objToArray(obj) {
*/

res.csv = function(obj, headers, status) {
var body = '';
var body = exports.generate(obj);

this.charset = this.charset || 'utf-8';
this.header('Content-Type', 'text/csv');

obj.forEach(function(item) {
if (!(item instanceof Array)) item = objToArray(item);
body += item.map(escape).join(exports.separator) + '\r\n';
});

return this.send(body, headers, status);
};

146 changes: 127 additions & 19 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,35 @@ var express = require('express')
, csv = require('../')
, app = express.createServer();

var test1Data = [
['a', 'b', 'c']
, ['d', 'e', 'f']
]
, test2Data = [
[ 'a', 'b', null ]
]
, test3Data = [
[ 'a', 'b', undefined ]
]
, testObjectArrayData = [
{ stringProp: "a", nullProp: null, undefinedProp: undefined },
{ stringProp: "b", nullProp: null, undefinedProp: undefined }
];

app.get('/test/1', function(req, res) {
res.csv([
['a', 'b', 'c']
, ['d', 'e', 'f']
]);
res.csv(test1Data);
});

app.get('/test/2', function(req, res) {
res.csv([
[ 'a', 'b', null ]
]);
res.csv(test2Data);
});

app.get('/test/3', function(req, res) {
res.csv([
[ 'a', 'b', undefined ]
]);
res.csv(test3Data);
});

app.get('/test/objectArray', function(req, res) {
res.csv([
{ stringProp: "a", nullProp: null, undefinedProp: undefined },
{ stringProp: "b", nullProp: null, undefinedProp: undefined }
]);
res.csv(testObjectArrayData);
});

app.listen(8383);
Expand All @@ -37,28 +42,131 @@ describe('express-csv', function() {
});

it('should expose .separator', function() {
csv.separator.should.be.a('string');
csv.separator.should.be.type('string');
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After running npm install, I got an erro while trying to run the test, saying that a is not a function... I checked shouldjs documentation, "be.type" seems a valid way of testing the type.

});

it('should expose .preventCast', function() {
csv.preventCast.should.be.a('boolean');
csv.preventCast.should.be.type('boolean');
});

it('should expose .ignoreNullOrUndefined', function() {
csv.ignoreNullOrUndefined.should.be.a('boolean');
csv.ignoreNullOrUndefined.should.be.type('boolean');
});

it('should expose .generate()', function() {
csv.generate.should.be.type('function');
});

it('should extend res.csv', function() {
if (express.version.match(/^2\.[0-9]+\.[0-9]+$/)) {
// express 2.x
require('http').ServerResponse.prototype.csv.should.be.a('function');
require('http').ServerResponse.prototype.csv.should.be.type('function');
} else {
// express 3.x
require('express').response.csv.should.be.a('function');
require('express').response.csv.should.be.type('function');
}
});
});

describe('csv.generate()', function() {
describe('when given an array of objects', function() {
describe('and ignoreNullOrUndefined is true', function() {
var rows;

beforeEach(function() {
console.log(csv.generate(testObjectArrayData));
rows = csv.generate(testObjectArrayData).split("\r\n");
});

it('should include values that exist', function() {
rows[0].split(",")[0].should.equal('"a"');
rows[1].split(",")[0].should.equal('"b"');
});

it('should exclude null', function() {
rows[0].split(",")[1].should.equal('');
rows[0].split(",")[2].should.equal('');
});

it('should exclude undefined', function() {
rows[0].split(",")[2].should.equal('');
rows[1].split(",")[2].should.equal('');
});


describe('and ignoreNullOrUndefined is false', function() {
var rows;

beforeEach(function() {
csv.ignoreNullOrUndefined = false;
rows = csv.generate(testObjectArrayData).split("\r\n");
});

afterEach(function() {
csv.ignoreNullOrUndefined = true;
});

it('should include values that exist', function() {
rows[0].split(",")[0].should.equal('"a"');
rows[1].split(",")[0].should.equal('"b"');
});

it('should include null', function() {
rows[0].split(",")[1].should.equal('"null"');
rows[1].split(",")[1].should.equal('"null"');
});

it('should include undefined', function() {
rows[0].split(",")[2].should.equal('"undefined"');
rows[1].split(",")[2].should.equal('"undefined"');
});
});
});
});

it('should return csv', function() {
csv.generate(test1Data).should.equal('"a","b","c"\r\n"d","e","f"\r\n');
});

it('should generate a csv that ignores null', function() {
csv.generate(test2Data).should.equal('"a","b",\r\n');
});

it('should generate a csv that ignores undefined', function() {
csv.generate(test3Data).should.equal('"a","b",\r\n');
});

it('should generate a csv that include null', function() {
var prevOption = csv.ignoreNullOrUndefined;
csv.ignoreNullOrUndefined = false;
csv.generate(test2Data).should.equal('"a","b","null"\r\n');
csv.ignoreNullOrUndefined = prevOption;
});

it('should generate a csv that includes undefined', function() {
var prevOption = csv.ignoreNullOrUndefined;
csv.ignoreNullOrUndefined = false;

csv.generate(test3Data).should.equal('"a","b","undefined"\r\n');
csv.ignoreNullOrUndefined = prevOption;
});

it('should generate a tsv', function() {
var prevSeparator = csv.separator;
csv.separator = '\t';
csv.generate(test1Data).should.equal('"a"\t"b"\t"c"\r\n"d"\t"e"\t"f"\r\n');
csv.separator = prevSeparator;
});

it('should generate a quoted csv', function() {
var prevSetting = csv.preventCast;
csv.preventCast = true;
csv.generate(test1Data).should.equal('="a",="b",="c"\r\n="d",="e",="f"\r\n');
csv.preventCast = prevSetting;
});
});


describe('res.csv()', function() {

describe('when given an array of objects', function() {
Expand Down