csv
Advanced tools
Comparing version 0.0.9 to 0.0.10
771
lib/csv.js
@@ -5,376 +5,411 @@ | ||
var EventEmitter = require('events').EventEmitter, | ||
fs = require('fs'); | ||
fs = require('fs'); | ||
// Utils function | ||
var merge = function(obj1,obj2){ | ||
var r = obj1||{}; | ||
for(var key in obj2){ | ||
r[key] = obj2[key]; | ||
} | ||
return r; | ||
var r = obj1||{}; | ||
for(var key in obj2){ | ||
r[key] = obj2[key]; | ||
} | ||
return r; | ||
} | ||
module.exports = function(){ | ||
var state = { | ||
count: 0, | ||
countWriten: 0, | ||
field: '', | ||
line: [], | ||
lastC: '', | ||
quoted: false, | ||
commented: false, | ||
buffer: null, | ||
bufferPosition: 0 | ||
} | ||
// Defined Class | ||
var CSV = function(){ | ||
// Set options | ||
this.readOptions = { | ||
delimiter: ',', | ||
quote: '"', | ||
escape: '"', | ||
columns: null, | ||
flags: 'r', | ||
encoding: 'utf8', | ||
bufferSize: 8 * 1024 * 1024, | ||
trim: false, | ||
ltrim: false, | ||
rtrim: false | ||
}; | ||
this.writeOptions = { | ||
delimiter: null, | ||
quote: null, | ||
escape: null, | ||
lineBreaks: null, | ||
flags: 'w', | ||
encoding: 'utf8', | ||
bufferSize: null, | ||
end: true | ||
}; | ||
} | ||
CSV.prototype.__proto__ = EventEmitter.prototype; | ||
// Reading API | ||
CSV.prototype.from = function(data,options){ | ||
if(options) merge(this.readOptions,options); | ||
var self = this; | ||
process.nextTick(function(){ | ||
if(data instanceof Array){ | ||
if( csv.writeOptions.lineBreaks === null ){ | ||
csv.writeOptions.lineBreaks = "\r\n"; | ||
} | ||
data.forEach(function(line){ | ||
state.line = line; | ||
flush(); | ||
}) | ||
}else{ | ||
try{ | ||
parse(data); | ||
}catch(e){ | ||
self.emit('error', e); | ||
return; | ||
} | ||
} | ||
self.end(); | ||
}); | ||
return this; | ||
} | ||
CSV.prototype.fromStream = function(readStream, options){ | ||
if(options) merge(this.readOptions,options); | ||
var self = this; | ||
readStream.on('data', function(data) { | ||
try{ | ||
parse(data); | ||
}catch(e){ | ||
self.emit('error', e); | ||
this.destroy(); | ||
} | ||
}); | ||
readStream.on('error', function(error) { self.emit('error', error) }); | ||
readStream.on('end', function() { | ||
self.end(); | ||
}); | ||
this.readStream = readStream; | ||
return this; | ||
} | ||
CSV.prototype.fromPath = function(path, options){ | ||
if(options) merge(this.readOptions,options); | ||
var stream = fs.createReadStream(path, this.readOptions); | ||
stream.setEncoding(this.readOptions.encoding); | ||
return this.fromStream(stream, null); | ||
} | ||
// Writting API | ||
CSV.prototype.write = function(line,preserve){ | ||
if(typeof line === 'string' && !preserve){ | ||
return parse(line); | ||
} | ||
write(line,preserve); | ||
} | ||
CSV.prototype.end = function(){ | ||
if (state.quoted) { | ||
csv.emit('error', new Error('Quoted field not terminated')); | ||
} else { | ||
// dump open record | ||
if (state.field) { | ||
if(csv.readOptions.trim || csv.readOptions.rtrim){ | ||
state.field = state.field.trimRight(); | ||
} | ||
state.line.push(state.field); | ||
state.field = ''; | ||
} | ||
if (state.line.length > 0) { | ||
flush(); | ||
} | ||
if(csv.writeStream){ | ||
if(state.bufferPosition !== 0){ | ||
csv.writeStream.write(state.buffer.slice(0, state.bufferPosition)); | ||
} | ||
if(this.writeOptions.end){ | ||
csv.writeStream.end(); | ||
}else{ | ||
csv.emit('end', state.count); | ||
} | ||
}else{ | ||
csv.emit('end', state.count); | ||
} | ||
} | ||
} | ||
CSV.prototype.toStream = function(writeStream, options){ | ||
if(options) merge(this.writeOptions,options); | ||
var self = this; | ||
switch(this.writeOptions.lineBreaks){ | ||
case 'auto': | ||
this.writeOptions.lineBreaks = null; | ||
break; | ||
case 'unix': | ||
this.writeOptions.lineBreaks = "\n"; | ||
break; | ||
case 'mac': | ||
this.writeOptions.lineBreaks = "\r"; | ||
break; | ||
case 'windows': | ||
this.writeOptions.lineBreaks = "\r\n"; | ||
break; | ||
case 'unicode': | ||
this.writeOptions.lineBreaks = "\u2028"; | ||
break; | ||
} | ||
writeStream.on('close', function(){ | ||
self.emit('end',state.count); | ||
}) | ||
this.writeStream = writeStream; | ||
state.buffer = new Buffer(this.writeOptions.bufferSize||this.readOptions.bufferSize); | ||
state.bufferPosition = 0; | ||
return this; | ||
} | ||
CSV.prototype.toPath = function(path, options){ | ||
// Merge user provided options | ||
if(options) merge(this.writeOptions,options); | ||
// clone options | ||
var options = merge({},this.writeOptions); | ||
// Delete end property which otherwise overwrite `WriteStream.end()` | ||
delete options.end; | ||
// Create the write stream | ||
var stream = fs.createWriteStream(path, options); | ||
return this.toStream(stream, null); | ||
} | ||
// Transform API | ||
CSV.prototype.transform = function(callback){ | ||
this.transformer = callback; | ||
return this; | ||
} | ||
var csv = new CSV(); | ||
// Private API | ||
function write(line,preserve){ | ||
if(typeof line === 'undefined' || line === null){ | ||
return; | ||
} | ||
if(!preserve){ | ||
csv.emit('data',line,state.count); | ||
} | ||
if(typeof line === 'object'){ | ||
if(!(line instanceof Array)){ | ||
var columns = csv.writeOptions.columns || csv.readOptions.columns; | ||
var _line = []; | ||
if(columns){ | ||
columns.forEach(function(column, i){ | ||
_line[i] = (typeof line[column] === 'undefined' || line[column] === null) ? '' : line[column]; | ||
}) | ||
}else{ | ||
for(var column in line){ | ||
_line.push(line[column]); | ||
} | ||
} | ||
line = _line; | ||
_line = null; | ||
} | ||
if(line instanceof Array){ | ||
var newLine = state.countWriten ? csv.writeOptions.lineBreaks || "\r" : ''; | ||
line.forEach(function(field,i){ | ||
if(typeof field == 'string'){ | ||
// fine 99% of the cases, keep going | ||
}else if(typeof field == 'number'){ | ||
field = '' + field; | ||
}else if(field instanceof Date){ | ||
field = '' + field.getTime(); | ||
} | ||
if(field){ | ||
var containsdelimiter = field.indexOf(csv.writeOptions.delimiter || csv.readOptions.delimiter) >= 0; | ||
var containsQuote = field.indexOf(csv.writeOptions.quote || csv.readOptions.quote) >= 0; | ||
var containsLinebreak = field.indexOf("\r") >= 0 || field.indexOf("\n") >= 0; | ||
if(containsQuote){ | ||
field = field.replace( | ||
new RegExp(csv.writeOptions.quote || csv.readOptions.quote,'g') | ||
, (csv.writeOptions.escape || csv.readOptions.escape) | ||
+ (csv.writeOptions.quote || csv.readOptions.quote)); | ||
} | ||
if(containsQuote || containsdelimiter || containsLinebreak){ | ||
field = (csv.writeOptions.quote || csv.readOptions.quote) + field + (csv.writeOptions.quote || csv.readOptions.quote); | ||
} | ||
newLine += field; | ||
} | ||
if(i!==line.length-1){ | ||
newLine += csv.writeOptions.delimiter || csv.readOptions.delimiter; | ||
} | ||
}); | ||
line = newLine; | ||
} | ||
} | ||
if(state.buffer){ | ||
if(state.bufferPosition + Buffer.byteLength(line,'utf8') > csv.readOptions.bufferSize){ | ||
csv.writeStream.write(state.buffer.slice(0, state.bufferPosition)); | ||
state.buffer = new Buffer(csv.readOptions.bufferSize); | ||
state.bufferPosition = 0; | ||
} | ||
state.bufferPosition += state.buffer.write(line, state.bufferPosition,'utf8'); | ||
} | ||
if(!preserve){ | ||
state.countWriten++; | ||
} | ||
} | ||
function parse(chars){ | ||
chars = '' + chars; | ||
for (var i = 0, l = chars.length; i < l; i++) { | ||
var c = chars.charAt(i); | ||
switch (c) { | ||
case csv.readOptions.escape: | ||
case csv.readOptions.quote: | ||
if( state.commented ) break; | ||
var isEscape = false; | ||
if (c === csv.readOptions.escape) { | ||
// Make sure the escape is really here for escaping: | ||
// if escape is same as quote, and escape is first char of a field and it's not quoted, then it is a quote | ||
// next char should be an escape or a quote | ||
var nextChar = chars.charAt(i + 1); | ||
if( !( csv.readOptions.escape === csv.readOptions.quote && !state.field && !state.quoted ) | ||
&& ( nextChar === csv.readOptions.escape || nextChar === csv.readOptions.quote ) ) { | ||
i++; | ||
isEscape = true; | ||
c = chars.charAt(i); | ||
state.field += c; | ||
} | ||
} | ||
if (!isEscape && (c === csv.readOptions.quote)) { | ||
if (state.field && !state.quoted) { | ||
// Treat quote as a regular character | ||
state.field += c; | ||
break; | ||
} | ||
if (state.quoted) { | ||
// Make sure a closing quote is followed by a delimiter | ||
var nextChar = chars.charAt(i + 1); | ||
if (nextChar && nextChar != '\r' && nextChar != '\n' && nextChar !== csv.readOptions.delimiter) { | ||
throw new Error('Invalid closing quote; found "' + nextChar + '" instead of delimiter "' + csv.readOptions.delimiter + '"'); | ||
} | ||
state.quoted = false; | ||
} else if (state.field === '') { | ||
state.quoted = true; | ||
} | ||
} | ||
break; | ||
case csv.readOptions.delimiter: | ||
if( state.commented ) break; | ||
if( state.quoted ) { | ||
state.field += c; | ||
}else{ | ||
if(csv.readOptions.trim || csv.readOptions.rtrim){ | ||
state.field = state.field.trimRight(); | ||
} | ||
state.line.push(state.field); | ||
state.field = ''; | ||
} | ||
break; | ||
case '\n': | ||
if(state.quoted) { | ||
state.field += c; | ||
break; | ||
} | ||
if( !csv.readOptions.quoted && state.lastC === '\r' ){ | ||
break; | ||
} | ||
case '\r': | ||
if(state.quoted) { | ||
state.field += c; | ||
break; | ||
} | ||
if( csv.writeOptions.lineBreaks === null ){ | ||
// Auto-discovery of linebreaks | ||
csv.writeOptions.lineBreaks = c + ( c === '\r' && chars.charAt(i+1) === '\n' ? '\n' : '' ); | ||
} | ||
if(csv.readOptions.trim || csv.readOptions.rtrim){ | ||
state.field = state.field.trimRight(); | ||
} | ||
state.line.push(state.field); | ||
state.field = ''; | ||
flush(); | ||
break; | ||
case ' ': | ||
case '\t': | ||
if(state.quoted || (!csv.readOptions.trim && !csv.readOptions.ltrim ) || state.field) { | ||
state.field += c; | ||
break; | ||
} | ||
break; | ||
default: | ||
if(state.commented) break; | ||
state.field += c; | ||
} | ||
state.lastC = c; | ||
} | ||
} | ||
function flush(){ | ||
if(csv.readOptions.columns){ | ||
if(state.count === 0 && csv.readOptions.columns === true){ | ||
csv.readOptions.columns = state.line; | ||
state.line = []; | ||
state.lastC = ''; | ||
return; | ||
} | ||
var line = {}; | ||
csv.readOptions.columns.forEach(function(column, i){ | ||
line[column] = state.line[i]||null; | ||
}) | ||
state.line = line; | ||
line = null; | ||
} | ||
var line = csv.transformer ? csv.transformer(state.line, state.count) : state.line; | ||
write(line); | ||
state.count++; | ||
state.line = []; | ||
state.lastC = ''; | ||
} | ||
return csv; | ||
var state = { | ||
count: 0, | ||
countWriten: 0, | ||
field: '', | ||
line: [], | ||
lastC: '', | ||
quoted: false, | ||
commented: false, | ||
buffer: null, | ||
bufferPosition: 0 | ||
} | ||
// Are we currently inside the transform callback? If so, | ||
// we shouldn't increment `state.count` which count provided lines | ||
var transforming = false; | ||
// Defined Class | ||
var CSV = function(){ | ||
// Set options | ||
this.readOptions = { | ||
delimiter: ',', | ||
quote: '"', | ||
escape: '"', | ||
columns: null, | ||
flags: 'r', | ||
encoding: 'utf8', | ||
bufferSize: 8 * 1024 * 1024, | ||
trim: false, | ||
ltrim: false, | ||
rtrim: false | ||
}; | ||
this.writeOptions = { | ||
delimiter: null, | ||
quote: null, | ||
escape: null, | ||
lineBreaks: null, | ||
flags: 'w', | ||
encoding: 'utf8', | ||
bufferSize: null, | ||
end: true | ||
}; | ||
} | ||
CSV.prototype.__proto__ = EventEmitter.prototype; | ||
// Reading API | ||
CSV.prototype.from = function(data,options){ | ||
if(options) merge(this.readOptions,options); | ||
var self = this; | ||
process.nextTick(function(){ | ||
if(data instanceof Array){ | ||
if( csv.writeOptions.lineBreaks === null ){ | ||
csv.writeOptions.lineBreaks = "\r\n"; | ||
} | ||
data.forEach(function(line){ | ||
state.line = line; | ||
flush(); | ||
}) | ||
}else{ | ||
try{ | ||
parse(data); | ||
}catch(e){ | ||
self.emit('error', e); | ||
return; | ||
} | ||
} | ||
self.end(); | ||
}); | ||
return this; | ||
} | ||
CSV.prototype.fromStream = function(readStream, options){ | ||
if(options) merge(this.readOptions,options); | ||
var self = this; | ||
readStream.on('data', function(data) { | ||
try{ | ||
parse(data); | ||
}catch(e){ | ||
self.emit('error', e); | ||
this.destroy(); | ||
} | ||
}); | ||
readStream.on('error', function(error) { self.emit('error', error) }); | ||
readStream.on('end', function() { | ||
self.end(); | ||
}); | ||
this.readStream = readStream; | ||
return this; | ||
} | ||
CSV.prototype.fromPath = function(path, options){ | ||
if(options) merge(this.readOptions,options); | ||
var stream = fs.createReadStream(path, this.readOptions); | ||
stream.setEncoding(this.readOptions.encoding); | ||
return this.fromStream(stream, null); | ||
} | ||
// Writting API | ||
/** | ||
* Write data. | ||
* Data may be string in which case it could span multiple lines. If data | ||
* is an object or an array, it must represent a single line. | ||
* Preserve is for line which are not considered as CSV data. | ||
*/ | ||
CSV.prototype.write = function(data, preserve){ | ||
if(typeof data === 'string' && !preserve){ | ||
return parse(data); | ||
} | ||
write(data, preserve); | ||
if(!transforming && !preserve){ | ||
state.count++; | ||
} | ||
} | ||
CSV.prototype.end = function(){ | ||
if (state.quoted) { | ||
csv.emit('error', new Error('Quoted field not terminated')); | ||
} else { | ||
// dump open record | ||
if (state.field) { | ||
if(csv.readOptions.trim || csv.readOptions.rtrim){ | ||
state.field = state.field.trimRight(); | ||
} | ||
state.line.push(state.field); | ||
state.field = ''; | ||
} | ||
if (state.line.length > 0) { | ||
flush(); | ||
} | ||
if(csv.writeStream){ | ||
if(state.bufferPosition !== 0){ | ||
csv.writeStream.write(state.buffer.slice(0, state.bufferPosition)); | ||
} | ||
if(this.writeOptions.end){ | ||
csv.writeStream.end(); | ||
}else{ | ||
csv.emit('end', state.count); | ||
} | ||
}else{ | ||
csv.emit('end', state.count); | ||
} | ||
} | ||
} | ||
CSV.prototype.toStream = function(writeStream, options){ | ||
if(options) merge(this.writeOptions,options); | ||
var self = this; | ||
switch(this.writeOptions.lineBreaks){ | ||
case 'auto': | ||
this.writeOptions.lineBreaks = null; | ||
break; | ||
case 'unix': | ||
this.writeOptions.lineBreaks = "\n"; | ||
break; | ||
case 'mac': | ||
this.writeOptions.lineBreaks = "\r"; | ||
break; | ||
case 'windows': | ||
this.writeOptions.lineBreaks = "\r\n"; | ||
break; | ||
case 'unicode': | ||
this.writeOptions.lineBreaks = "\u2028"; | ||
break; | ||
} | ||
writeStream.on('close', function(){ | ||
self.emit('end',state.count); | ||
}) | ||
this.writeStream = writeStream; | ||
state.buffer = new Buffer(this.writeOptions.bufferSize||this.readOptions.bufferSize); | ||
state.bufferPosition = 0; | ||
return this; | ||
} | ||
CSV.prototype.toPath = function(path, options){ | ||
// Merge user provided options | ||
if(options) merge(this.writeOptions,options); | ||
// clone options | ||
var options = merge({},this.writeOptions); | ||
// Delete end property which otherwise overwrite `WriteStream.end()` | ||
delete options.end; | ||
// Create the write stream | ||
var stream = fs.createWriteStream(path, options); | ||
return this.toStream(stream, null); | ||
} | ||
// Transform API | ||
CSV.prototype.transform = function(callback){ | ||
this.transformer = callback; | ||
return this; | ||
} | ||
var csv = new CSV(); | ||
// Private API | ||
/** | ||
* Write a line to the written stream. | ||
* Line may be an object, an array or a string | ||
* Preserve is for line which are not considered as CSV data | ||
*/ | ||
function write(line, preserve){ | ||
if(typeof line === 'undefined' || line === null){ | ||
return; | ||
} | ||
if(!preserve){ | ||
csv.emit('data', line, state.count); | ||
} | ||
if(typeof line === 'object'){ | ||
if(!(line instanceof Array)){ | ||
var columns = csv.writeOptions.columns || csv.readOptions.columns; | ||
var _line = []; | ||
if(columns){ | ||
columns.forEach(function(column, i){ | ||
_line[i] = (typeof line[column] === 'undefined' || line[column] === null) ? '' : line[column]; | ||
}) | ||
}else{ | ||
for(var column in line){ | ||
_line.push(line[column]); | ||
} | ||
} | ||
line = _line; | ||
_line = null; | ||
} | ||
if(line instanceof Array){ | ||
var newLine = state.countWriten ? csv.writeOptions.lineBreaks || "\r" : ''; | ||
line.forEach(function(field,i){ | ||
if(typeof field === 'string'){ | ||
// fine 99% of the cases, keep going | ||
}else if(typeof field === 'number'){ | ||
// Cast number to string | ||
field = '' + field; | ||
}else if(field instanceof Date){ | ||
// Cast date to timestamp string | ||
field = '' + field.getTime(); | ||
} | ||
if(field){ | ||
var containsdelimiter = field.indexOf(csv.writeOptions.delimiter || csv.readOptions.delimiter) >= 0; | ||
var containsQuote = field.indexOf(csv.writeOptions.quote || csv.readOptions.quote) >= 0; | ||
var containsLinebreak = field.indexOf("\r") >= 0 || field.indexOf("\n") >= 0; | ||
if(containsQuote){ | ||
field = field.replace( | ||
new RegExp(csv.writeOptions.quote || csv.readOptions.quote,'g') | ||
, (csv.writeOptions.escape || csv.readOptions.escape) | ||
+ (csv.writeOptions.quote || csv.readOptions.quote)); | ||
} | ||
if(containsQuote || containsdelimiter || containsLinebreak){ | ||
field = (csv.writeOptions.quote || csv.readOptions.quote) + field + (csv.writeOptions.quote || csv.readOptions.quote); | ||
} | ||
newLine += field; | ||
} | ||
if(i!==line.length-1){ | ||
newLine += csv.writeOptions.delimiter || csv.readOptions.delimiter; | ||
} | ||
}); | ||
line = newLine; | ||
} | ||
} | ||
if(state.buffer){ | ||
if(state.bufferPosition + Buffer.byteLength(line,'utf8') > csv.readOptions.bufferSize){ | ||
csv.writeStream.write(state.buffer.slice(0, state.bufferPosition)); | ||
state.buffer = new Buffer(csv.readOptions.bufferSize); | ||
state.bufferPosition = 0; | ||
} | ||
state.bufferPosition += state.buffer.write(line, state.bufferPosition,'utf8'); | ||
} | ||
if(!preserve){ | ||
state.countWriten++; | ||
} | ||
} | ||
/** | ||
* Parse a string which may hold multiple lines. | ||
* Private state object is enriched on each charactere until | ||
* flush is called on a new line | ||
*/ | ||
function parse(chars){ | ||
chars = '' + chars; | ||
for (var i = 0, l = chars.length; i < l; i++) { | ||
var c = chars.charAt(i); | ||
switch (c) { | ||
case csv.readOptions.escape: | ||
case csv.readOptions.quote: | ||
if( state.commented ) break; | ||
var isEscape = false; | ||
if (c === csv.readOptions.escape) { | ||
// Make sure the escape is really here for escaping: | ||
// if escape is same as quote, and escape is first char of a field and it's not quoted, then it is a quote | ||
// next char should be an escape or a quote | ||
var nextChar = chars.charAt(i + 1); | ||
if( !( csv.readOptions.escape === csv.readOptions.quote && !state.field && !state.quoted ) | ||
&& ( nextChar === csv.readOptions.escape || nextChar === csv.readOptions.quote ) ) { | ||
i++; | ||
isEscape = true; | ||
c = chars.charAt(i); | ||
state.field += c; | ||
} | ||
} | ||
if (!isEscape && (c === csv.readOptions.quote)) { | ||
if (state.field && !state.quoted) { | ||
// Treat quote as a regular character | ||
state.field += c; | ||
break; | ||
} | ||
if (state.quoted) { | ||
// Make sure a closing quote is followed by a delimiter | ||
var nextChar = chars.charAt(i + 1); | ||
if (nextChar && nextChar != '\r' && nextChar != '\n' && nextChar !== csv.readOptions.delimiter) { | ||
throw new Error('Invalid closing quote; found "' + nextChar + '" instead of delimiter "' + csv.readOptions.delimiter + '"'); | ||
} | ||
state.quoted = false; | ||
} else if (state.field === '') { | ||
state.quoted = true; | ||
} | ||
} | ||
break; | ||
case csv.readOptions.delimiter: | ||
if( state.commented ) break; | ||
if( state.quoted ) { | ||
state.field += c; | ||
}else{ | ||
if(csv.readOptions.trim || csv.readOptions.rtrim){ | ||
state.field = state.field.trimRight(); | ||
} | ||
state.line.push(state.field); | ||
state.field = ''; | ||
} | ||
break; | ||
case '\n': | ||
if(state.quoted) { | ||
state.field += c; | ||
break; | ||
} | ||
if( !csv.readOptions.quoted && state.lastC === '\r' ){ | ||
break; | ||
} | ||
case '\r': | ||
if(state.quoted) { | ||
state.field += c; | ||
break; | ||
} | ||
if( csv.writeOptions.lineBreaks === null ){ | ||
// Auto-discovery of linebreaks | ||
csv.writeOptions.lineBreaks = c + ( c === '\r' && chars.charAt(i+1) === '\n' ? '\n' : '' ); | ||
} | ||
if(csv.readOptions.trim || csv.readOptions.rtrim){ | ||
state.field = state.field.trimRight(); | ||
} | ||
state.line.push(state.field); | ||
state.field = ''; | ||
flush(); | ||
break; | ||
case ' ': | ||
case '\t': | ||
if(state.quoted || (!csv.readOptions.trim && !csv.readOptions.ltrim ) || state.field) { | ||
state.field += c; | ||
break; | ||
} | ||
break; | ||
default: | ||
if(state.commented) break; | ||
state.field += c; | ||
} | ||
state.lastC = c; | ||
} | ||
} | ||
function flush(){ | ||
if(csv.readOptions.columns){ | ||
if(state.count === 0 && csv.readOptions.columns === true){ | ||
csv.readOptions.columns = state.line; | ||
state.line = []; | ||
state.lastC = ''; | ||
return; | ||
} | ||
var line = {}; | ||
csv.readOptions.columns.forEach(function(column, i){ | ||
line[column] = state.line[i]||null; | ||
}) | ||
state.line = line; | ||
line = null; | ||
} | ||
//var line = csv.transformer ? csv.transformer(state.line, state.count) : state.line; | ||
var line; | ||
if(csv.transformer){ | ||
transforming = true; | ||
line = csv.transformer(state.line, state.count); | ||
transforming = false; | ||
}else{ | ||
line = state.line; | ||
} | ||
write(line); | ||
state.count++; | ||
state.line = []; | ||
state.lastC = ''; | ||
} | ||
return csv; | ||
}; |
{ "name": "csv" | ||
, "version": "0.0.9" | ||
, "version": "0.0.10" | ||
, "description": "CSV parser with simple api, full of options and tested against large datasets." | ||
@@ -4,0 +4,0 @@ , "author": "David Worms <david@adaltas.com>" |
@@ -144,3 +144,3 @@ <pre> | ||
- *flag* | ||
- *flags* | ||
Default to 'w', 'w' to create or overwrite an file, 'a' to append to a file. Apply when using the `toPath` method. | ||
@@ -161,3 +161,3 @@ | ||
When the returned value is an array, the fields are merge in order. When the returned value is an object, it will search for the `columns` property in the write or in the read options and smartly order the values. If no `columns` options are found, it will merge the values in their order of appearance. When the returned value is a string, it directly sent to the destination source and it is your responsibility to delimit, quote, escape or define line breaks. | ||
When the returned value is an array, the fields are merge in order. When the returned value is an object, it will search for the `columns` property in the write or in the read options and smartly order the values. If no `columns` options are found, it will merge the values in their order of appearance. When the returned value is a string, it is directly sent to the destination source and it is your responsibility to delimit, quote, escape or define line breaks. | ||
@@ -246,2 +246,3 @@ Example of transform returning a string | ||
* pascalopitz : <https://github.com/pascalopitz> | ||
* Josh Pschorr : <https://github.com/jpschorr> | ||
@@ -248,0 +249,0 @@ Related projects |
// CSV sample - Copyright David Worms <open@adaltas.com> (MIT Licensed) | ||
// node samples/column.js | ||
var csv = require('csv'); | ||
csv() | ||
.fromPath(__dirname+'/columns.in',{ | ||
columns: true | ||
}) | ||
.toStream(process.stdout,{ | ||
columns: ['id', 'name'] | ||
}) | ||
.transform(function(data){ | ||
data.name = data.firstname + ' ' + data.lastname | ||
return data; | ||
}); | ||
// Will print sth like: | ||
// 82,Zbigniew Preisner | ||
// 94,Serge Gainsbourg | ||
// node samples/column.js | ||
var csv = require('csv'); | ||
csv() | ||
.fromPath(__dirname+'/columns.in',{ | ||
columns: true | ||
}) | ||
.toStream(process.stdout,{ | ||
columns: ['id', 'name'] | ||
}) | ||
.transform(function(data){ | ||
data.name = data.firstname + ' ' + data.lastname | ||
return data; | ||
}); | ||
// Will print sth like: | ||
// 82,Zbigniew Preisner | ||
// 94,Serge Gainsbourg |
@@ -13,23 +13,23 @@ // CSV sample - Copyright jon seymour jon.seymour@gmail.com | ||
var csv = require('csv'), | ||
header; | ||
process.stdin.resume(); | ||
csv() | ||
.fromStream(process.stdin) | ||
.toStream(process.stdout, {end: false}) | ||
.transform(function(data){ | ||
if (header) { | ||
this.write(header); | ||
} else { | ||
header=data; | ||
return null; | ||
} | ||
return data; | ||
}) | ||
.on('end',function(error){ | ||
process.stdout.write("\n"); | ||
}) | ||
.on('error',function(error){ | ||
console.log(error.message); | ||
}); | ||
var csv = require('csv'), | ||
header; | ||
process.stdin.resume(); | ||
csv() | ||
.fromStream(process.stdin) | ||
.toStream(process.stdout, {end: false}) | ||
.transform(function(data){ | ||
if (header) { | ||
this.write(header); | ||
} else { | ||
header=data; | ||
return null; | ||
} | ||
return data; | ||
}) | ||
.on('end',function(error){ | ||
process.stdout.write("\n"); | ||
}) | ||
.on('error',function(error){ | ||
console.log(error.message); | ||
}); | ||
@@ -36,0 +36,0 @@ // |
@@ -5,25 +5,25 @@ | ||
var csv = require('csv'); | ||
var csv = require('csv'); | ||
process.stdin.resume(); | ||
csv() | ||
.fromStream(process.stdin) | ||
.toPath(__dirname+'/sample.out') | ||
.transform(function(data){ | ||
data.unshift(data.pop()); | ||
return data; | ||
}) | ||
.on('data',function(data,index){ | ||
console.log('#'+index+' '+JSON.stringify(data)); | ||
}) | ||
.on('end',function(count){ | ||
console.log('Number of lines: '+count); | ||
}) | ||
.on('error',function(error){ | ||
console.log(error.message); | ||
}); | ||
// Print sth like: | ||
// #0 ["2000-01-01","20322051544","1979.0","8.8017226E7","ABC","45"] | ||
// #1 ["2050-11-27","28392898392","1974.0","8.8392926E7","DEF","23"] | ||
// Number of lines: 2 | ||
csv() | ||
.fromStream(process.stdin) | ||
.toPath(__dirname+'/sample.out') | ||
.transform(function(data){ | ||
data.unshift(data.pop()); | ||
return data; | ||
}) | ||
.on('data',function(data,index){ | ||
console.log('#'+index+' '+JSON.stringify(data)); | ||
}) | ||
.on('end',function(count){ | ||
console.log('Number of lines: '+count); | ||
}) | ||
.on('error',function(error){ | ||
console.log(error.message); | ||
}); | ||
// Print sth like: | ||
// #0 ["2000-01-01","20322051544","1979.0","8.8017226E7","ABC","45"] | ||
// #1 ["2050-11-27","28392898392","1974.0","8.8392926E7","DEF","23"] | ||
// Number of lines: 2 |
// CSV sample - Copyright David Worms <open@adaltas.com> (MIT Licensed) | ||
// node samples/sample.js | ||
var csv = require('csv'); | ||
csv() | ||
.fromPath(__dirname+'/sample.in') | ||
.toPath(__dirname+'/sample.out') | ||
.transform(function(data){ | ||
data.unshift(data.pop()); | ||
return data; | ||
}) | ||
.on('data',function(data,index){ | ||
console.log('#'+index+' '+JSON.stringify(data)); | ||
}) | ||
.on('end',function(count){ | ||
console.log('Number of lines: '+count); | ||
}) | ||
.on('error',function(error){ | ||
console.log(error.message); | ||
}); | ||
// Print sth like: | ||
// #0 ["2000-01-01","20322051544","1979.0","8.8017226E7","ABC","45"] | ||
// #1 ["2050-11-27","28392898392","1974.0","8.8392926E7","DEF","23"] | ||
// Number of lines: 2 | ||
// node samples/sample.js | ||
var csv = require('csv'); | ||
csv() | ||
.fromPath(__dirname+'/sample.in') | ||
.toPath(__dirname+'/sample.out') | ||
.transform(function(data){ | ||
data.unshift(data.pop()); | ||
return data; | ||
}) | ||
.on('data',function(data,index){ | ||
console.log('#'+index+' '+JSON.stringify(data)); | ||
}) | ||
.on('end',function(count){ | ||
console.log('Number of lines: '+count); | ||
}) | ||
.on('error',function(error){ | ||
console.log(error.message); | ||
}); | ||
// Print sth like: | ||
// #0 ["2000-01-01","20322051544","1979.0","8.8017226E7","ABC","45"] | ||
// #1 ["2050-11-27","28392898392","1974.0","8.8392926E7","DEF","23"] | ||
// Number of lines: 2 |
// CSV sample - Copyright David Worms <open@adaltas.com> (MIT Licensed) | ||
// node samples/transform.js | ||
var csv = require('csv'); | ||
csv() | ||
.fromPath(__dirname+'/transform.in') | ||
.toStream(process.stdout) | ||
.transform(function(data,index){ | ||
return (index>0 ? ',' : '') + data[0] + ":" + data[2] + ' ' + data[1]; | ||
}); | ||
// Print sth like: | ||
// 82:Zbigniew Preisner,94:Serge Gainsbourg | ||
// node samples/transform.js | ||
var csv = require('csv'); | ||
csv() | ||
.fromPath(__dirname+'/transform.in') | ||
.toStream(process.stdout) | ||
.transform(function(data,index){ | ||
return (index>0 ? ',' : '') + data[0] + ":" + data[2] + ' ' + data[1]; | ||
}); | ||
// Print sth like: | ||
// 82:Zbigniew Preisner,94:Serge Gainsbourg |
@@ -5,31 +5,31 @@ | ||
var fs = require('fs'), | ||
assert = require('assert'), | ||
csv = require('csv'); | ||
assert = require('assert'), | ||
csv = require('csv'); | ||
module.exports = { | ||
'Test empty value': function(){ | ||
csv() | ||
.fromPath(__dirname+'/delimiter/empty_value.in') | ||
.toPath(__dirname+'/delimiter/empty_value.tmp') | ||
.transform(function(data,index){ | ||
assert.strictEqual(5,data.length); | ||
if(index===0){ | ||
assert.strictEqual('',data[1]); | ||
assert.strictEqual('',data[4]); | ||
}else if(index===1){ | ||
assert.strictEqual('',data[0]); | ||
assert.strictEqual('',data[3]); | ||
assert.strictEqual('',data[4]); | ||
} | ||
return data; | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(2,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/delimiter/empty_value.out').toString(), | ||
fs.readFileSync(__dirname+'/delimiter/empty_value.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/delimiter/empty_value.tmp'); | ||
}); | ||
} | ||
'Test empty value': function(){ | ||
csv() | ||
.fromPath(__dirname+'/delimiter/empty_value.in') | ||
.toPath(__dirname+'/delimiter/empty_value.tmp') | ||
.transform(function(data,index){ | ||
assert.strictEqual(5,data.length); | ||
if(index===0){ | ||
assert.strictEqual('',data[1]); | ||
assert.strictEqual('',data[4]); | ||
}else if(index===1){ | ||
assert.strictEqual('',data[0]); | ||
assert.strictEqual('',data[3]); | ||
assert.strictEqual('',data[4]); | ||
} | ||
return data; | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(2,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/delimiter/empty_value.out').toString(), | ||
fs.readFileSync(__dirname+'/delimiter/empty_value.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/delimiter/empty_value.tmp'); | ||
}); | ||
} | ||
} |
@@ -5,48 +5,48 @@ | ||
var fs = require('fs'), | ||
assert = require('assert'), | ||
csv = require('csv'); | ||
assert = require('assert'), | ||
csv = require('csv'); | ||
module.exports = { | ||
// Note: we only escape quote and escape character | ||
'Test default': function(){ | ||
csv() | ||
.fromPath(__dirname+'/escape/default.in',{ | ||
escape: '"' | ||
}) | ||
.toPath(__dirname+'/escape/default.tmp') | ||
.on('data',function(data,index){ | ||
if(index===0){ | ||
assert.equal('19"79.0',data[1]); | ||
assert.equal('A"B"C',data[3]); | ||
} | ||
}) | ||
.on('end',function(){ | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/escape/default.out').toString(), | ||
fs.readFileSync(__dirname+'/escape/default.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/escape/default.tmp'); | ||
}); | ||
}, | ||
'Test backslash': function(){ | ||
csv() | ||
.fromPath(__dirname+'/escape/backslash.in',{ | ||
escape: '\\' | ||
}) | ||
.toPath(__dirname+'/escape/backslash.tmp') | ||
.on('data',function(data,index){ | ||
if(index===0){ | ||
assert.equal('19"79.0',data[1]); | ||
assert.equal('A"B"C',data[3]); | ||
} | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(2,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/escape/backslash.out').toString(), | ||
fs.readFileSync(__dirname+'/escape/backslash.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/escape/backslash.tmp'); | ||
}); | ||
} | ||
// Note: we only escape quote and escape character | ||
'Test default': function(){ | ||
csv() | ||
.fromPath(__dirname+'/escape/default.in',{ | ||
escape: '"' | ||
}) | ||
.toPath(__dirname+'/escape/default.tmp') | ||
.on('data',function(data,index){ | ||
if(index===0){ | ||
assert.equal('19"79.0',data[1]); | ||
assert.equal('A"B"C',data[3]); | ||
} | ||
}) | ||
.on('end',function(){ | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/escape/default.out').toString(), | ||
fs.readFileSync(__dirname+'/escape/default.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/escape/default.tmp'); | ||
}); | ||
}, | ||
'Test backslash': function(){ | ||
csv() | ||
.fromPath(__dirname+'/escape/backslash.in',{ | ||
escape: '\\' | ||
}) | ||
.toPath(__dirname+'/escape/backslash.tmp') | ||
.on('data',function(data,index){ | ||
if(index===0){ | ||
assert.equal('19"79.0',data[1]); | ||
assert.equal('A"B"C',data[3]); | ||
} | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(2,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/escape/backslash.out').toString(), | ||
fs.readFileSync(__dirname+'/escape/backslash.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/escape/backslash.tmp'); | ||
}); | ||
} | ||
} |
@@ -5,114 +5,114 @@ | ||
var fs = require('fs'), | ||
assert = require('assert'), | ||
csv = require('csv'); | ||
assert = require('assert'), | ||
csv = require('csv'); | ||
module.exports = { | ||
'Test fs stream': function(){ | ||
csv() | ||
.fromStream(fs.createReadStream(__dirname+'/fromto/sample.in',{flags:'r'})) | ||
.toStream(fs.createWriteStream(__dirname+'/fromto/sample.tmp',{flags:'w'})) | ||
.on('end',function(count){ | ||
assert.strictEqual(2,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/fromto/sample.out').toString(), | ||
fs.readFileSync(__dirname+'/fromto/sample.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/fromto/sample.tmp'); | ||
}); | ||
}, | ||
'Test string without destination': function(){ | ||
csv() | ||
.from(fs.readFileSync(__dirname+'/fromto/sample.in').toString()) | ||
.on('data',function(data,index){ | ||
assert.ok(index<2); | ||
if(index===0){ | ||
assert.strictEqual('20322051544',data[0]) | ||
}else if(index===1){ | ||
assert.strictEqual('28392898392',data[0]) | ||
} | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(2,count); | ||
}); | ||
}, | ||
'Test string to stream': function(){ | ||
csv() | ||
.from(fs.readFileSync(__dirname+'/fromto/string_to_stream.in').toString()) | ||
.toPath(__dirname+'/fromto/string_to_stream.tmp') | ||
.on('data',function(data,index){ | ||
assert.ok(index<2); | ||
if(index===0){ | ||
assert.strictEqual('20322051544',data[0]) | ||
}else if(index===1){ | ||
assert.strictEqual('28392898392',data[0]) | ||
} | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(2,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/fromto/string_to_stream.out').toString(), | ||
fs.readFileSync(__dirname+'/fromto/string_to_stream.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/fromto/string_to_stream.tmp'); | ||
}); | ||
}, | ||
'Test array to stream': function(){ | ||
// note: destination line breaks is windows styled because we can't guess it | ||
var data = [ | ||
["20322051544","1979.0","8.8017226E7","ABC","45","2000-01-01"], | ||
["28392898392","1974.0","8.8392926E7","DEF","23","2050-11-27"] | ||
]; | ||
csv() | ||
.from(data) | ||
.toPath(__dirname+'/fromto/array_to_stream.tmp') | ||
.on('data',function(data,index){ | ||
assert.ok(index<2); | ||
if(index===0){ | ||
assert.strictEqual('20322051544',data[0]); | ||
}else if(index===1){ | ||
assert.strictEqual('28392898392',data[0]); | ||
} | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(2,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/fromto/array_to_stream.out').toString(), | ||
fs.readFileSync(__dirname+'/fromto/array_to_stream.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/fromto/array_to_stream.tmp'); | ||
}); | ||
}, | ||
'Test null': function(){ | ||
// note: destination line breaks is windows styled because we can't guess it | ||
var data = [ | ||
["20322051544",null,"8.8017226E7","ABC","45","2000-01-01"], | ||
["28392898392","1974.0","8.8392926E7","DEF","23",null] | ||
]; | ||
csv() | ||
.from(data) | ||
.transform(function(data){ | ||
data[0] = null; | ||
data[3] = null; | ||
return data; | ||
}) | ||
.toPath(__dirname+'/fromto/null.tmp') | ||
.on('data',function(data,index){ | ||
assert.ok(index<2); | ||
assert.strictEqual(null,data[0]); | ||
assert.strictEqual(null,data[3]); | ||
if(index===0){ | ||
assert.strictEqual(null,data[1]); | ||
}else if(index===1){ | ||
assert.strictEqual(null,data[5]); | ||
} | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(2,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/fromto/null.out').toString(), | ||
fs.readFileSync(__dirname+'/fromto/null.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/fromto/null.tmp'); | ||
}); | ||
} | ||
'Test fs stream': function(){ | ||
csv() | ||
.fromStream(fs.createReadStream(__dirname+'/fromto/sample.in',{flags:'r'})) | ||
.toStream(fs.createWriteStream(__dirname+'/fromto/sample.tmp',{flags:'w'})) | ||
.on('end',function(count){ | ||
assert.strictEqual(2,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/fromto/sample.out').toString(), | ||
fs.readFileSync(__dirname+'/fromto/sample.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/fromto/sample.tmp'); | ||
}); | ||
}, | ||
'Test string without destination': function(){ | ||
csv() | ||
.from(fs.readFileSync(__dirname+'/fromto/sample.in').toString()) | ||
.on('data',function(data,index){ | ||
assert.ok(index<2); | ||
if(index===0){ | ||
assert.strictEqual('20322051544',data[0]) | ||
}else if(index===1){ | ||
assert.strictEqual('28392898392',data[0]) | ||
} | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(2,count); | ||
}); | ||
}, | ||
'Test string to stream': function(){ | ||
csv() | ||
.from(fs.readFileSync(__dirname+'/fromto/string_to_stream.in').toString()) | ||
.toPath(__dirname+'/fromto/string_to_stream.tmp') | ||
.on('data',function(data,index){ | ||
assert.ok(index<2); | ||
if(index===0){ | ||
assert.strictEqual('20322051544',data[0]) | ||
}else if(index===1){ | ||
assert.strictEqual('28392898392',data[0]) | ||
} | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(2,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/fromto/string_to_stream.out').toString(), | ||
fs.readFileSync(__dirname+'/fromto/string_to_stream.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/fromto/string_to_stream.tmp'); | ||
}); | ||
}, | ||
'Test array to stream': function(){ | ||
// note: destination line breaks is windows styled because we can't guess it | ||
var data = [ | ||
["20322051544","1979.0","8.8017226E7","ABC","45","2000-01-01"], | ||
["28392898392","1974.0","8.8392926E7","DEF","23","2050-11-27"] | ||
]; | ||
csv() | ||
.from(data) | ||
.toPath(__dirname+'/fromto/array_to_stream.tmp') | ||
.on('data',function(data,index){ | ||
assert.ok(index<2); | ||
if(index===0){ | ||
assert.strictEqual('20322051544',data[0]); | ||
}else if(index===1){ | ||
assert.strictEqual('28392898392',data[0]); | ||
} | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(2,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/fromto/array_to_stream.out').toString(), | ||
fs.readFileSync(__dirname+'/fromto/array_to_stream.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/fromto/array_to_stream.tmp'); | ||
}); | ||
}, | ||
'Test null': function(){ | ||
// note: destination line breaks is windows styled because we can't guess it | ||
var data = [ | ||
["20322051544",null,"8.8017226E7","ABC","45","2000-01-01"], | ||
["28392898392","1974.0","8.8392926E7","DEF","23",null] | ||
]; | ||
csv() | ||
.from(data) | ||
.transform(function(data){ | ||
data[0] = null; | ||
data[3] = null; | ||
return data; | ||
}) | ||
.toPath(__dirname+'/fromto/null.tmp') | ||
.on('data',function(data,index){ | ||
assert.ok(index<2); | ||
assert.strictEqual(null,data[0]); | ||
assert.strictEqual(null,data[3]); | ||
if(index===0){ | ||
assert.strictEqual(null,data[1]); | ||
}else if(index===1){ | ||
assert.strictEqual(null,data[5]); | ||
} | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(2,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/fromto/null.out').toString(), | ||
fs.readFileSync(__dirname+'/fromto/null.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/fromto/null.tmp'); | ||
}); | ||
} | ||
} |
@@ -5,86 +5,86 @@ | ||
var fs = require('fs'), | ||
assert = require('assert'), | ||
csv = require('csv'); | ||
assert = require('assert'), | ||
csv = require('csv'); | ||
module.exports = { | ||
'Test line breaks custom': function(){ | ||
csv() | ||
.fromPath(__dirname+'/lineBreaks/lineBreaks.in',{ | ||
}) | ||
.toPath(__dirname+'/lineBreaks/custom.tmp',{ | ||
lineBreaks: "::" | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(2,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/lineBreaks/custom.out').toString(), | ||
fs.readFileSync(__dirname+'/lineBreaks/custom.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/lineBreaks/custom.tmp'); | ||
}); | ||
}, | ||
'Test line breaks unix': function(){ | ||
csv() | ||
.fromPath(__dirname+'/lineBreaks/lineBreaks.in',{ | ||
}) | ||
.toPath(__dirname+'/lineBreaks/unix.tmp',{ | ||
lineBreaks: "unix" | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(2,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/lineBreaks/unix.out').toString(), | ||
fs.readFileSync(__dirname+'/lineBreaks/unix.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/lineBreaks/unix.tmp'); | ||
}); | ||
}, | ||
'Test line breaks unicode': function(){ | ||
csv() | ||
.fromPath(__dirname+'/lineBreaks/lineBreaks.in',{ | ||
}) | ||
.toPath(__dirname+'/lineBreaks/unicode.tmp',{ | ||
lineBreaks: "unicode" | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(2,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/lineBreaks/unicode.out').toString(), | ||
fs.readFileSync(__dirname+'/lineBreaks/unicode.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/lineBreaks/unicode.tmp'); | ||
}); | ||
}, | ||
'Test line breaks mac': function(){ | ||
csv() | ||
.fromPath(__dirname+'/lineBreaks/lineBreaks.in',{ | ||
}) | ||
.toPath(__dirname+'/lineBreaks/mac.tmp',{ | ||
lineBreaks: "mac" | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(2,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/lineBreaks/mac.out').toString(), | ||
fs.readFileSync(__dirname+'/lineBreaks/mac.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/lineBreaks/mac.tmp'); | ||
}); | ||
}, | ||
'Test line breaks windows': function(){ | ||
csv() | ||
.fromPath(__dirname+'/lineBreaks/lineBreaks.in',{ | ||
}) | ||
.toPath(__dirname+'/lineBreaks/windows.tmp',{ | ||
lineBreaks: "windows" | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(2,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/lineBreaks/windows.out').toString(), | ||
fs.readFileSync(__dirname+'/lineBreaks/windows.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/lineBreaks/windows.tmp'); | ||
}); | ||
} | ||
'Test line breaks custom': function(){ | ||
csv() | ||
.fromPath(__dirname+'/lineBreaks/lineBreaks.in',{ | ||
}) | ||
.toPath(__dirname+'/lineBreaks/custom.tmp',{ | ||
lineBreaks: "::" | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(2,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/lineBreaks/custom.out').toString(), | ||
fs.readFileSync(__dirname+'/lineBreaks/custom.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/lineBreaks/custom.tmp'); | ||
}); | ||
}, | ||
'Test line breaks unix': function(){ | ||
csv() | ||
.fromPath(__dirname+'/lineBreaks/lineBreaks.in',{ | ||
}) | ||
.toPath(__dirname+'/lineBreaks/unix.tmp',{ | ||
lineBreaks: "unix" | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(2,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/lineBreaks/unix.out').toString(), | ||
fs.readFileSync(__dirname+'/lineBreaks/unix.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/lineBreaks/unix.tmp'); | ||
}); | ||
}, | ||
'Test line breaks unicode': function(){ | ||
csv() | ||
.fromPath(__dirname+'/lineBreaks/lineBreaks.in',{ | ||
}) | ||
.toPath(__dirname+'/lineBreaks/unicode.tmp',{ | ||
lineBreaks: "unicode" | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(2,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/lineBreaks/unicode.out').toString(), | ||
fs.readFileSync(__dirname+'/lineBreaks/unicode.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/lineBreaks/unicode.tmp'); | ||
}); | ||
}, | ||
'Test line breaks mac': function(){ | ||
csv() | ||
.fromPath(__dirname+'/lineBreaks/lineBreaks.in',{ | ||
}) | ||
.toPath(__dirname+'/lineBreaks/mac.tmp',{ | ||
lineBreaks: "mac" | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(2,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/lineBreaks/mac.out').toString(), | ||
fs.readFileSync(__dirname+'/lineBreaks/mac.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/lineBreaks/mac.tmp'); | ||
}); | ||
}, | ||
'Test line breaks windows': function(){ | ||
csv() | ||
.fromPath(__dirname+'/lineBreaks/lineBreaks.in',{ | ||
}) | ||
.toPath(__dirname+'/lineBreaks/windows.tmp',{ | ||
lineBreaks: "windows" | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(2,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/lineBreaks/windows.out').toString(), | ||
fs.readFileSync(__dirname+'/lineBreaks/windows.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/lineBreaks/windows.tmp'); | ||
}); | ||
} | ||
} |
@@ -5,162 +5,162 @@ | ||
var fs = require('fs'), | ||
assert = require('assert'), | ||
csv = require('csv'); | ||
assert = require('assert'), | ||
csv = require('csv'); | ||
module.exports = { | ||
'Test regular quotes': function(){ | ||
csv() | ||
.fromPath(__dirname+'/quotes/regular.in',{ | ||
}) | ||
.toPath(__dirname+'/quotes/regular.tmp',{ | ||
}) | ||
.on('end',function(){ | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/quotes/regular.out').toString(), | ||
fs.readFileSync(__dirname+'/quotes/regular.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/quotes/regular.tmp'); | ||
}); | ||
}, | ||
'Test quotes with delimiter': function(){ | ||
csv() | ||
.fromPath(__dirname+'/quotes/delimiter.in',{ | ||
}) | ||
.toPath(__dirname+'/quotes/delimiter.tmp',{ | ||
}) | ||
.on('end',function(){ | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/quotes/delimiter.out').toString(), | ||
fs.readFileSync(__dirname+'/quotes/delimiter.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/quotes/delimiter.tmp'); | ||
}); | ||
}, | ||
'Test quotes inside field': function(){ | ||
csv() | ||
.fromPath(__dirname+'/quotes/in_field.in',{ | ||
}) | ||
.toPath(__dirname+'/quotes/in_field.tmp',{ | ||
}) | ||
.on('end',function(){ | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/quotes/in_field.out').toString(), | ||
fs.readFileSync(__dirname+'/quotes/in_field.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/quotes/in_field.tmp'); | ||
}); | ||
}, | ||
'Test empty value': function(){ | ||
csv() | ||
.fromPath(__dirname+'/quotes/empty_value.in',{ | ||
quote: '"', | ||
escape: '"', | ||
}) | ||
.toPath(__dirname+'/quotes/empty_value.tmp') | ||
.on('end',function(){ | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/quotes/empty_value.out').toString(), | ||
fs.readFileSync(__dirname+'/quotes/empty_value.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/quotes/empty_value.tmp'); | ||
}); | ||
}, | ||
'Test quoted quote': function(){ | ||
csv() | ||
.fromPath(__dirname+'/quotes/quoted.in',{ | ||
quote: '"', | ||
escape: '"', | ||
}) | ||
.toPath(__dirname+'/quotes/quoted.tmp') | ||
.on('data',function(data,index){ | ||
assert.strictEqual(5,data.length); | ||
if(index===0){ | ||
assert.strictEqual('"',data[1]); | ||
assert.strictEqual('"ok"',data[4]); | ||
} | ||
}) | ||
.on('end',function(){ | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/quotes/quoted.out').toString(), | ||
fs.readFileSync(__dirname+'/quotes/quoted.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/quotes/quoted.tmp'); | ||
}); | ||
}, | ||
'Test quoted linebreak': function(){ | ||
csv() | ||
.fromPath(__dirname+'/quotes/linebreak.in',{ | ||
quote: '"', | ||
escape: '"', | ||
}) | ||
.toPath(__dirname+'/quotes/linebreak.tmp') | ||
.on('data',function(data,index){ | ||
assert.strictEqual(5,data.length); | ||
}) | ||
.on('end',function(){ | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/quotes/linebreak.out').toString(), | ||
fs.readFileSync(__dirname+'/quotes/linebreak.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/quotes/linebreak.tmp'); | ||
}); | ||
}, | ||
'Test unclosed quote': function(beforeExit){ | ||
var n = 0; | ||
csv() | ||
.fromPath(__dirname+'/quotes/unclosed.in',{ | ||
quote: '"', | ||
escape: '"', | ||
}) | ||
.toPath(__dirname+'/quotes/unclosed.tmp') | ||
.on('end',function(){ | ||
assert.ok(false, 'end was raised'); | ||
}) | ||
.on('error',function(){ | ||
++n; | ||
}); | ||
beforeExit(function() { | ||
assert.equal(1, n, 'error was not raised'); | ||
fs.unlink(__dirname+'/quotes/unclosed.tmp'); | ||
}); | ||
}, | ||
'Test invalid quotes': function(beforeExit){ | ||
var n = 0; | ||
csv() | ||
.on('error',function(e){ | ||
assert.equal(e.message.split(';')[0], 'Invalid closing quote'); | ||
++n; | ||
}) | ||
.fromPath(__dirname+'/quotes/invalid.in',{ | ||
quote: '"', | ||
escape: '"', | ||
}) | ||
.toPath(__dirname+'/quotes/invalid.tmp') | ||
.on('end',function(){ | ||
assert.ok(false, 'end was raised'); | ||
}); | ||
beforeExit(function() { | ||
assert.equal(1, n, 'error was not raised'); | ||
fs.unlink(__dirname+'/quotes/invalid.tmp'); | ||
}); | ||
}, | ||
'Test invalid quotes from string': function(beforeExit){ | ||
var n = 0; | ||
csv() | ||
.on('error',function(e){ | ||
assert.equal(e.message.split(';')[0], 'Invalid closing quote'); | ||
++n; | ||
}) | ||
.from('"",1974,8.8392926E7,""t,""',{ | ||
quote: '"', | ||
escape: '"', | ||
}) | ||
.toPath(__dirname+'/quotes/invalidstring.tmp') | ||
.on('end',function(){ | ||
assert.ok(false, 'end was raised'); | ||
}); | ||
beforeExit(function() { | ||
assert.equal(1, n); | ||
fs.unlink(__dirname+'/quotes/invalidstring.tmp'); | ||
}); | ||
} | ||
'Test regular quotes': function(){ | ||
csv() | ||
.fromPath(__dirname+'/quotes/regular.in',{ | ||
}) | ||
.toPath(__dirname+'/quotes/regular.tmp',{ | ||
}) | ||
.on('end',function(){ | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/quotes/regular.out').toString(), | ||
fs.readFileSync(__dirname+'/quotes/regular.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/quotes/regular.tmp'); | ||
}); | ||
}, | ||
'Test quotes with delimiter': function(){ | ||
csv() | ||
.fromPath(__dirname+'/quotes/delimiter.in',{ | ||
}) | ||
.toPath(__dirname+'/quotes/delimiter.tmp',{ | ||
}) | ||
.on('end',function(){ | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/quotes/delimiter.out').toString(), | ||
fs.readFileSync(__dirname+'/quotes/delimiter.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/quotes/delimiter.tmp'); | ||
}); | ||
}, | ||
'Test quotes inside field': function(){ | ||
csv() | ||
.fromPath(__dirname+'/quotes/in_field.in',{ | ||
}) | ||
.toPath(__dirname+'/quotes/in_field.tmp',{ | ||
}) | ||
.on('end',function(){ | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/quotes/in_field.out').toString(), | ||
fs.readFileSync(__dirname+'/quotes/in_field.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/quotes/in_field.tmp'); | ||
}); | ||
}, | ||
'Test empty value': function(){ | ||
csv() | ||
.fromPath(__dirname+'/quotes/empty_value.in',{ | ||
quote: '"', | ||
escape: '"', | ||
}) | ||
.toPath(__dirname+'/quotes/empty_value.tmp') | ||
.on('end',function(){ | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/quotes/empty_value.out').toString(), | ||
fs.readFileSync(__dirname+'/quotes/empty_value.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/quotes/empty_value.tmp'); | ||
}); | ||
}, | ||
'Test quoted quote': function(){ | ||
csv() | ||
.fromPath(__dirname+'/quotes/quoted.in',{ | ||
quote: '"', | ||
escape: '"', | ||
}) | ||
.toPath(__dirname+'/quotes/quoted.tmp') | ||
.on('data',function(data,index){ | ||
assert.strictEqual(5,data.length); | ||
if(index===0){ | ||
assert.strictEqual('"',data[1]); | ||
assert.strictEqual('"ok"',data[4]); | ||
} | ||
}) | ||
.on('end',function(){ | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/quotes/quoted.out').toString(), | ||
fs.readFileSync(__dirname+'/quotes/quoted.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/quotes/quoted.tmp'); | ||
}); | ||
}, | ||
'Test quoted linebreak': function(){ | ||
csv() | ||
.fromPath(__dirname+'/quotes/linebreak.in',{ | ||
quote: '"', | ||
escape: '"', | ||
}) | ||
.toPath(__dirname+'/quotes/linebreak.tmp') | ||
.on('data',function(data,index){ | ||
assert.strictEqual(5,data.length); | ||
}) | ||
.on('end',function(){ | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/quotes/linebreak.out').toString(), | ||
fs.readFileSync(__dirname+'/quotes/linebreak.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/quotes/linebreak.tmp'); | ||
}); | ||
}, | ||
'Test unclosed quote': function(beforeExit){ | ||
var n = 0; | ||
csv() | ||
.fromPath(__dirname+'/quotes/unclosed.in',{ | ||
quote: '"', | ||
escape: '"', | ||
}) | ||
.toPath(__dirname+'/quotes/unclosed.tmp') | ||
.on('end',function(){ | ||
assert.ok(false, 'end was raised'); | ||
}) | ||
.on('error',function(){ | ||
++n; | ||
}); | ||
beforeExit(function() { | ||
assert.equal(1, n, 'error was not raised'); | ||
fs.unlink(__dirname+'/quotes/unclosed.tmp'); | ||
}); | ||
}, | ||
'Test invalid quotes': function(beforeExit){ | ||
var n = 0; | ||
csv() | ||
.on('error',function(e){ | ||
assert.equal(e.message.split(';')[0], 'Invalid closing quote'); | ||
++n; | ||
}) | ||
.fromPath(__dirname+'/quotes/invalid.in',{ | ||
quote: '"', | ||
escape: '"', | ||
}) | ||
.toPath(__dirname+'/quotes/invalid.tmp') | ||
.on('end',function(){ | ||
assert.ok(false, 'end was raised'); | ||
}); | ||
beforeExit(function() { | ||
assert.equal(1, n, 'error was not raised'); | ||
fs.unlink(__dirname+'/quotes/invalid.tmp'); | ||
}); | ||
}, | ||
'Test invalid quotes from string': function(beforeExit){ | ||
var n = 0; | ||
csv() | ||
.on('error',function(e){ | ||
assert.equal(e.message.split(';')[0], 'Invalid closing quote'); | ||
++n; | ||
}) | ||
.from('"",1974,8.8392926E7,""t,""',{ | ||
quote: '"', | ||
escape: '"', | ||
}) | ||
.toPath(__dirname+'/quotes/invalidstring.tmp') | ||
.on('end',function(){ | ||
assert.ok(false, 'end was raised'); | ||
}); | ||
beforeExit(function() { | ||
assert.equal(1, n); | ||
fs.unlink(__dirname+'/quotes/invalidstring.tmp'); | ||
}); | ||
} | ||
} |
@@ -5,116 +5,116 @@ | ||
var fs = require('fs'), | ||
assert = require('assert'), | ||
csv = require('csv'); | ||
assert = require('assert'), | ||
csv = require('csv'); | ||
module.exports = { | ||
'Test reorder fields': function(){ | ||
var count = 0; | ||
csv() | ||
.fromPath(__dirname+'/transform/reorder.in') | ||
.toPath(__dirname+'/transform/reorder.tmp') | ||
.transform(function(data,index){ | ||
assert.strictEqual(count,index); | ||
count++; | ||
data.unshift(data.pop()); | ||
return data; | ||
}) | ||
.on('end',function(){ | ||
assert.strictEqual(2,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/transform/reorder.out').toString(), | ||
fs.readFileSync(__dirname+'/transform/reorder.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/transform/reorder.tmp'); | ||
}); | ||
}, | ||
'Test return undefined - skip all lines': function(){ | ||
var count = 0; | ||
csv() | ||
.fromPath(__dirname+'/transform/undefined.in') | ||
.toPath(__dirname+'/transform/undefined.tmp') | ||
.transform(function(data,index){ | ||
assert.strictEqual(count,index); | ||
count++; | ||
}) | ||
.on('end',function(){ | ||
assert.strictEqual(2,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/transform/undefined.out').toString(), | ||
fs.readFileSync(__dirname+'/transform/undefined.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/transform/undefined.tmp'); | ||
}); | ||
}, | ||
'Test return null - skip one of two lines': function(){ | ||
var count = 0; | ||
csv() | ||
.fromPath(__dirname+'/transform/null.in') | ||
.toPath(__dirname+'/transform/null.tmp') | ||
.transform(function(data,index){ | ||
assert.strictEqual(count,index); | ||
count++; | ||
return index%2 ? data : null; | ||
}) | ||
.on('end',function(){ | ||
assert.strictEqual(6,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/transform/null.out').toString(), | ||
fs.readFileSync(__dirname+'/transform/null.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/transform/null.tmp'); | ||
}); | ||
}, | ||
'Test return object': function(){ | ||
// we don't define columns | ||
// recieve and array and return an object | ||
// also see the columns test | ||
csv() | ||
.fromPath(__dirname+'/transform/object.in') | ||
.toPath(__dirname+'/transform/object.tmp') | ||
.transform(function(data,index){ | ||
return {field_1:data[4],field_2:data[3]}; | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(2,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/transform/object.out').toString(), | ||
fs.readFileSync(__dirname+'/transform/object.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/transform/object.tmp'); | ||
}); | ||
}, | ||
'Test return string': function(){ | ||
csv() | ||
.fromPath(__dirname+'/transform/string.in') | ||
.toPath(__dirname+'/transform/string.tmp') | ||
.transform(function(data,index){ | ||
return (index>0 ? ',' : '') + data[4] + ":" + data[3]; | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(2,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/transform/string.out').toString(), | ||
fs.readFileSync(__dirname+'/transform/string.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/transform/string.tmp'); | ||
}); | ||
}, | ||
'Test types': function(){ | ||
// Test date, int and float | ||
csv() | ||
.fromPath(__dirname+'/transform/types.in') | ||
.toPath(__dirname+'/transform/types.tmp') | ||
.transform(function(data,index){ | ||
data[3] = data[3].split('-'); | ||
return [parseInt(data[0]),parseFloat(data[1]),parseFloat(data[2]),Date.UTC(data[3][0],data[3][1],data[3][2])]; | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(2,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/transform/types.out').toString(), | ||
fs.readFileSync(__dirname+'/transform/types.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/transform/types.tmp'); | ||
}); | ||
} | ||
'Test reorder fields': function(){ | ||
var count = 0; | ||
csv() | ||
.fromPath(__dirname+'/transform/reorder.in') | ||
.toPath(__dirname+'/transform/reorder.tmp') | ||
.transform(function(data,index){ | ||
assert.strictEqual(count,index); | ||
count++; | ||
data.unshift(data.pop()); | ||
return data; | ||
}) | ||
.on('end',function(){ | ||
assert.strictEqual(2,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/transform/reorder.out').toString(), | ||
fs.readFileSync(__dirname+'/transform/reorder.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/transform/reorder.tmp'); | ||
}); | ||
}, | ||
'Test return undefined - skip all lines': function(){ | ||
var count = 0; | ||
csv() | ||
.fromPath(__dirname+'/transform/undefined.in') | ||
.toPath(__dirname+'/transform/undefined.tmp') | ||
.transform(function(data,index){ | ||
assert.strictEqual(count,index); | ||
count++; | ||
}) | ||
.on('end',function(){ | ||
assert.strictEqual(2,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/transform/undefined.out').toString(), | ||
fs.readFileSync(__dirname+'/transform/undefined.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/transform/undefined.tmp'); | ||
}); | ||
}, | ||
'Test return null - skip one of two lines': function(){ | ||
var count = 0; | ||
csv() | ||
.fromPath(__dirname+'/transform/null.in') | ||
.toPath(__dirname+'/transform/null.tmp') | ||
.transform(function(data,index){ | ||
assert.strictEqual(count,index); | ||
count++; | ||
return index%2 ? data : null; | ||
}) | ||
.on('end',function(){ | ||
assert.strictEqual(6,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/transform/null.out').toString(), | ||
fs.readFileSync(__dirname+'/transform/null.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/transform/null.tmp'); | ||
}); | ||
}, | ||
'Test return object': function(){ | ||
// we don't define columns | ||
// recieve and array and return an object | ||
// also see the columns test | ||
csv() | ||
.fromPath(__dirname+'/transform/object.in') | ||
.toPath(__dirname+'/transform/object.tmp') | ||
.transform(function(data,index){ | ||
return {field_1:data[4],field_2:data[3]}; | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(2,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/transform/object.out').toString(), | ||
fs.readFileSync(__dirname+'/transform/object.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/transform/object.tmp'); | ||
}); | ||
}, | ||
'Test return string': function(){ | ||
csv() | ||
.fromPath(__dirname+'/transform/string.in') | ||
.toPath(__dirname+'/transform/string.tmp') | ||
.transform(function(data,index){ | ||
return (index>0 ? ',' : '') + data[4] + ":" + data[3]; | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(2,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/transform/string.out').toString(), | ||
fs.readFileSync(__dirname+'/transform/string.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/transform/string.tmp'); | ||
}); | ||
}, | ||
'Test types': function(){ | ||
// Test date, int and float | ||
csv() | ||
.fromPath(__dirname+'/transform/types.in') | ||
.toPath(__dirname+'/transform/types.tmp') | ||
.transform(function(data,index){ | ||
data[3] = data[3].split('-'); | ||
return [parseInt(data[0]),parseFloat(data[1]),parseFloat(data[2]),Date.UTC(data[3][0],data[3][1],data[3][2])]; | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(2,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/transform/types.out').toString(), | ||
fs.readFileSync(__dirname+'/transform/types.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/transform/types.tmp'); | ||
}); | ||
} | ||
} |
140
test/trim.js
@@ -5,74 +5,74 @@ | ||
var fs = require('fs'), | ||
assert = require('assert'), | ||
csv = require('csv'); | ||
assert = require('assert'), | ||
csv = require('csv'); | ||
module.exports = { | ||
'Test ignoring whitespace immediately following the delimiter': function(){ | ||
csv() | ||
.fromPath(__dirname+'/trim/ltrim.in', {ltrim: true}) | ||
.toPath(__dirname+'/trim/ltrim.tmp') | ||
.transform(function(data,index){ | ||
return data; | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(3,count); | ||
// console.log(''); | ||
// console.log(fs.readFileSync(__dirname+'/trim/ltrim.tmp').toString()); | ||
// console.log(''); | ||
// console.log(fs.readFileSync(__dirname+'/trim/ltrim.out').toString()); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/trim/ltrim.out').toString(), | ||
fs.readFileSync(__dirname+'/trim/ltrim.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/trim/ltrim.tmp'); | ||
}); | ||
}, | ||
'Test rtrim - ignoring whitespace immediately preceding the delimiter': function(){ | ||
csv() | ||
.fromPath(__dirname+'/trim/rtrim.in', {rtrim: true}) | ||
.toPath(__dirname+'/trim/rtrim.tmp') | ||
.transform(function(data,index){ | ||
return data; | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(3,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/trim/rtrim.out').toString(), | ||
fs.readFileSync(__dirname+'/trim/rtrim.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/trim/rtrim.tmp'); | ||
}); | ||
}, | ||
'Test trim - ignoring whitespace both immediately preceding and following the delimiter': function(){ | ||
csv() | ||
.fromPath(__dirname+'/trim/trim.in', {trim: true}) | ||
.toPath(__dirname+'/trim/trim.tmp') | ||
.transform(function(data,index){ | ||
return data; | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(3,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/trim/trim.out').toString(), | ||
fs.readFileSync(__dirname+'/trim/trim.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/trim/trim.tmp'); | ||
}); | ||
}, | ||
'Test no trim': function(){ | ||
csv() | ||
.fromPath(__dirname+'/trim/notrim.in') | ||
.toPath(__dirname+'/trim/notrim.tmp') | ||
.transform(function(data,index){ | ||
return data; | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(3,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/trim/notrim.out').toString(), | ||
fs.readFileSync(__dirname+'/trim/notrim.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/trim/notrim.tmp'); | ||
}); | ||
} | ||
'Test ignoring whitespace immediately following the delimiter': function(){ | ||
csv() | ||
.fromPath(__dirname+'/trim/ltrim.in', {ltrim: true}) | ||
.toPath(__dirname+'/trim/ltrim.tmp') | ||
.transform(function(data,index){ | ||
return data; | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(3,count); | ||
// console.log(''); | ||
// console.log(fs.readFileSync(__dirname+'/trim/ltrim.tmp').toString()); | ||
// console.log(''); | ||
// console.log(fs.readFileSync(__dirname+'/trim/ltrim.out').toString()); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/trim/ltrim.out').toString(), | ||
fs.readFileSync(__dirname+'/trim/ltrim.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/trim/ltrim.tmp'); | ||
}); | ||
}, | ||
'Test rtrim - ignoring whitespace immediately preceding the delimiter': function(){ | ||
csv() | ||
.fromPath(__dirname+'/trim/rtrim.in', {rtrim: true}) | ||
.toPath(__dirname+'/trim/rtrim.tmp') | ||
.transform(function(data,index){ | ||
return data; | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(3,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/trim/rtrim.out').toString(), | ||
fs.readFileSync(__dirname+'/trim/rtrim.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/trim/rtrim.tmp'); | ||
}); | ||
}, | ||
'Test trim - ignoring whitespace both immediately preceding and following the delimiter': function(){ | ||
csv() | ||
.fromPath(__dirname+'/trim/trim.in', {trim: true}) | ||
.toPath(__dirname+'/trim/trim.tmp') | ||
.transform(function(data,index){ | ||
return data; | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(3,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/trim/trim.out').toString(), | ||
fs.readFileSync(__dirname+'/trim/trim.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/trim/trim.tmp'); | ||
}); | ||
}, | ||
'Test no trim': function(){ | ||
csv() | ||
.fromPath(__dirname+'/trim/notrim.in') | ||
.toPath(__dirname+'/trim/notrim.tmp') | ||
.transform(function(data,index){ | ||
return data; | ||
}) | ||
.on('end',function(count){ | ||
assert.strictEqual(3,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/trim/notrim.out').toString(), | ||
fs.readFileSync(__dirname+'/trim/notrim.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/trim/notrim.tmp'); | ||
}); | ||
} | ||
} |
@@ -5,119 +5,119 @@ | ||
var fs = require('fs'), | ||
assert = require('assert'), | ||
csv = require('csv'); | ||
assert = require('assert'), | ||
csv = require('csv'); | ||
module.exports = { | ||
// 'Test write array': function(){ | ||
// var count = 0; | ||
// var test = csv() | ||
// .toPath(__dirname+'/write/write_array.tmp') | ||
// .on('data', function(data, index){ | ||
// assert.ok(Array.isArray(data)); | ||
// assert.eql(count,index); | ||
// count++; | ||
// }) | ||
// .on('end',function(){ | ||
// assert.eql(1000,count); | ||
// assert.equal( | ||
// fs.readFileSync(__dirname+'/write/write.out').toString(), | ||
// fs.readFileSync(__dirname+'/write/write_array.tmp').toString() | ||
// ); | ||
// fs.unlink(__dirname+'/write/write_array.tmp'); | ||
// }); | ||
// for(var i=0; i<1000; i++){ | ||
// test.write(['Test '+i,i,'"']); | ||
// } | ||
// test.end(); | ||
// }, | ||
// 'Test write object with column options': function(){ | ||
// var count = 0; | ||
// var test = csv() | ||
// .toPath(__dirname+'/write/write_object.tmp',{ | ||
// columns: ['name','value','escape'] | ||
// }) | ||
// .on('data', function(data, index){ | ||
// assert.ok(typeof data === 'object'); | ||
// assert.ok(!Array.isArray(data)); | ||
// assert.eql(count,index); | ||
// count++; | ||
// }) | ||
// .on('end',function(){ | ||
// assert.eql(1000,count); | ||
// assert.equal( | ||
// fs.readFileSync(__dirname+'/write/write.out').toString(), | ||
// fs.readFileSync(__dirname+'/write/write_object.tmp').toString() | ||
// ); | ||
// fs.unlink(__dirname+'/write/write_object.tmp'); | ||
// }); | ||
// for(var i=0; i<1000; i++){ | ||
// test.write({name: 'Test '+i, value:i, escape: '"', ovni: 'ET '+i}); | ||
// } | ||
// test.end(); | ||
// }, | ||
// 'Test write string': function(){ | ||
// var count = 0; | ||
// var test = csv() | ||
// .toPath(__dirname+'/write/write_string.tmp') | ||
// .on('data', function(data, index){ | ||
// assert.ok(Array.isArray(data)); | ||
// assert.eql(count,index); | ||
// count++; | ||
// }) | ||
// .on('end',function(){ | ||
// assert.eql(1000,count); | ||
// assert.equal( | ||
// fs.readFileSync(__dirname+'/write/write.out').toString(), | ||
// fs.readFileSync(__dirname+'/write/write_string.tmp').toString() | ||
// ); | ||
// fs.unlink(__dirname+'/write/write_string.tmp'); | ||
// }); | ||
// var buffer = ''; | ||
// for(var i=0; i<1000; i++){ | ||
// buffer += ''.concat('Test '+i,',',i,',','""""',"\r"); | ||
// if(buffer.length > 250){ | ||
// test.write(buffer.substr(0,250)); | ||
// buffer = buffer.substr(250); | ||
// } | ||
// } | ||
// test.write(buffer); | ||
// test.end(); | ||
// }, | ||
'Test write string with preserve': function(){ | ||
var count = 0; | ||
var test = csv() | ||
.toPath(__dirname+'/write/string_preserve.tmp') | ||
.transform(function(data, index){ | ||
if(index===0){ | ||
test.write('--------------------\n',true); | ||
} | ||
test.write(data); | ||
test.write('\n--------------------',true); | ||
assert.ok(Array.isArray(data)); | ||
assert.eql(count,index); | ||
count ++; | ||
return null; | ||
}) | ||
.on('end',function(){ | ||
// assert.eql(4,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/write/string_preserve.out').toString(), | ||
fs.readFileSync(__dirname+'/write/string_preserve.tmp').toString() | ||
); | ||
fs.unlink(__dirname+'/write/write_string.tmp'); | ||
}); | ||
test.write('# This line should not be parsed',true); | ||
test.write('\n',true); | ||
var buffer = ''; | ||
for(var i=0; i<2; i++){ | ||
buffer += ''.concat('Test '+i,',',i,',','""""',"\n"); | ||
if(buffer.length > 250){ | ||
test.write(buffer.substr(0,250)); | ||
buffer = buffer.substr(250); | ||
} | ||
} | ||
test.write(buffer); | ||
test.write('\n',true); | ||
test.write('# This one as well',true); | ||
test.end(); | ||
} | ||
'Test write array': function(){ | ||
var count = 0; | ||
var test = csv() | ||
.toPath(__dirname+'/write/write_array.tmp') | ||
.on('data', function(data, index){ | ||
assert.ok(Array.isArray(data)); | ||
assert.eql(count,index); | ||
count++; | ||
}) | ||
.on('end',function(){ | ||
assert.eql(1000,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/write/write.out').toString(), | ||
fs.readFileSync(__dirname+'/write/write_array.tmp').toString() | ||
); | ||
fs.unlinkSync(__dirname+'/write/write_array.tmp'); | ||
}); | ||
for(var i=0; i<1000; i++){ | ||
test.write(['Test '+i,i,'"']); | ||
} | ||
test.end(); | ||
}, | ||
'Test write object with column options': function(){ | ||
var count = 0; | ||
var test = csv() | ||
.toPath(__dirname+'/write/write_object.tmp',{ | ||
columns: ['name','value','escape'] | ||
}) | ||
.on('data', function(data, index){ | ||
assert.ok(typeof data === 'object'); | ||
assert.ok(!Array.isArray(data)); | ||
assert.eql(count, index); | ||
count++; | ||
}) | ||
.on('end',function(){ | ||
assert.eql(1000,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/write/write.out').toString(), | ||
fs.readFileSync(__dirname+'/write/write_object.tmp').toString() | ||
); | ||
fs.unlinkSync(__dirname+'/write/write_object.tmp'); | ||
}); | ||
for(var i=0; i<1000; i++){ | ||
test.write({name: 'Test '+i, value:i, escape: '"', ovni: 'ET '+i}); | ||
} | ||
test.end(); | ||
}, | ||
'Test write string': function(){ | ||
var count = 0; | ||
var test = csv() | ||
.toPath(__dirname+'/write/write_string.tmp') | ||
.on('data', function(data, index){ | ||
assert.ok(Array.isArray(data)); | ||
assert.eql(count,index); | ||
count++; | ||
}) | ||
.on('end',function(){ | ||
assert.eql(1000,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/write/write.out').toString(), | ||
fs.readFileSync(__dirname+'/write/write_string.tmp').toString() | ||
); | ||
fs.unlinkSync(__dirname+'/write/write_string.tmp'); | ||
}); | ||
var buffer = ''; | ||
for(var i=0; i<1000; i++){ | ||
buffer += ''.concat('Test '+i,',',i,',','""""',"\r"); | ||
if(buffer.length > 250){ | ||
test.write(buffer.substr(0,250)); | ||
buffer = buffer.substr(250); | ||
} | ||
} | ||
test.write(buffer); | ||
test.end(); | ||
}, | ||
'Test write string with preserve': function(){ | ||
var count = 0; | ||
var test = csv() | ||
.toPath(__dirname+'/write/string_preserve.tmp') | ||
.transform(function(data, index){ | ||
if(index===0){ | ||
test.write('--------------------\n',true); | ||
} | ||
test.write(data); | ||
test.write('\n--------------------',true); | ||
assert.ok(Array.isArray(data)); | ||
assert.eql(count,index); | ||
count ++; | ||
return null; | ||
}) | ||
.on('end',function(){ | ||
// assert.eql(4,count); | ||
assert.equal( | ||
fs.readFileSync(__dirname+'/write/string_preserve.out').toString(), | ||
fs.readFileSync(__dirname+'/write/string_preserve.tmp').toString() | ||
); | ||
fs.unlinkSync(__dirname+'/write/string_preserve.tmp'); | ||
}); | ||
test.write('# This line should not be parsed',true); | ||
test.write('\n',true); | ||
var buffer = ''; | ||
for(var i=0; i<2; i++){ | ||
buffer += ''.concat('Test '+i,',',i,',','""""',"\n"); | ||
if(buffer.length > 250){ | ||
test.write(buffer.substr(0,250)); | ||
buffer = buffer.substr(250); | ||
} | ||
} | ||
test.write(buffer); | ||
test.write('\n',true); | ||
test.write('# This one as well',true); | ||
test.end(); | ||
} | ||
} |
114083
252
10
89
1767