Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Write method now accept an array; Transform may return an integer; Ca…

…tch and handle errors in transform callback
  • Loading branch information...
commit 3e8f199e6532670b7605acd3fff989e6a9885a7e 1 parent 2030bfd
@wdavidw authored
View
36 lib/csv.js
@@ -101,7 +101,7 @@ module.exports = function(){
}catch(e){
self.emit('error', e);
// Destroy the input stream
- this.destroy();
+ readStream.destroy();
}
});
readStream.on('error', function(error) { self.emit('error', error) });
@@ -129,6 +129,9 @@ module.exports = function(){
CSV.prototype.write = function(data, preserve){
if(typeof data === 'string' && !preserve){
return parse(data);
+ }else if(Array.isArray(data) && !transforming){
+ state.line = data;
+ return flush();
}
write(data, preserve);
if(!transforming && !preserve){
@@ -318,7 +321,10 @@ module.exports = function(){
}
}
- // Called by the `parse` function on each line. It will then call `write`
+ /**
+ * Called by the `parse` function on each line. It is responsible for
+ * transforming the data and finally calling `write`.
+ */
function flush(){
if(csv.readOptions.columns){
if(state.count === 0 && csv.readOptions.columns === true){
@@ -338,7 +344,14 @@ module.exports = function(){
var line;
if(csv.transformer){
transforming = true;
- line = csv.transformer(state.line, state.count);
+ try{
+ line = csv.transformer(state.line, state.count);
+ }catch(e){
+ error(e);
+ // csv.emit('error', e);
+ // // Destroy the input stream
+ // if(csv.readStream) csv.readStream.destroy();
+ }
if (csv.writeOptions.newColumns && !csv.writeOptions.columns && typeof line === 'object' && !Array.isArray(line)) {
Object.keys(line)
@@ -372,9 +385,10 @@ module.exports = function(){
try {
csv.emit('data', line, state.count);
}catch(e){
- csv.emit('error', e);
- csv.readable = false;
- csv.writable = false;
+ error(e);
+ // csv.emit('error', e);
+ // csv.readable = false;
+ // csv.writable = false;
}
}
if(typeof line === 'object'){
@@ -435,6 +449,8 @@ module.exports = function(){
}
line = newLine;
}
+ }else if(typeof line == 'number'){
+ line = ''+line;
}
if(state.buffer){
if(state.bufferPosition + Buffer.byteLength(line,'utf8') > csv.readOptions.bufferSize){
@@ -449,6 +465,14 @@ module.exports = function(){
}
return true;
}
+
+ function error(e){
+ csv.emit('error', e);
+ csv.readable = false;
+ csv.writable = false;
+ // Destroy the input stream
+ if(csv.readStream) csv.readStream.destroy();
+ }
return csv;
};
View
1  readme.md
@@ -247,6 +247,7 @@ Contributors
* jonseymour : <https://github.com/jonseymour>
* pascalopitz : <https://github.com/pascalopitz>
* Josh Pschorr : <https://github.com/jpschorr>
+* Elad Ben-Israel: <https://github.com/eladb>
Related projects
----------------
View
5 test/reader.coffee
@@ -10,8 +10,9 @@ describe 'reader', ->
test = csv()
.toPath( "#{__dirname}/write/write_array.tmp" )
.on 'data', (data, index) ->
- throw new Error 'Error in data' if index % 10 is 0
- .on 'error', ->
+ throw new Error "Error in data #{index}" if index % 10 is 0
+ .on 'error', (e) ->
+ e.message.should.equal 'Error in data 0'
next()
.on 'end', ->
false.should.be.ok
View
76 test/transform.coffee
@@ -6,7 +6,7 @@ should = require 'should'
csv = require '..'
describe 'transform', ->
- it 'Test reorder fields', ->
+ it 'Test reorder fields', (next) ->
count = 0
csv()
.fromPath("#{__dirname}/transform/reorder.in")
@@ -21,8 +21,8 @@ describe 'transform', ->
expect = fs.readFileSync("#{__dirname}/transform/reorder.out").toString()
result = fs.readFileSync("#{__dirname}/transform/reorder.tmp").toString()
result.should.eql expect
- fs.unlink "#{__dirname}/transform/reorder.tmp"
- it 'Test return undefined - skip all lines', ->
+ fs.unlink "#{__dirname}/transform/reorder.tmp", next
+ it 'should skip all lines where transform return undefined', (next) ->
count = 0
csv()
.fromPath("#{__dirname}/transform/undefined.in")
@@ -36,8 +36,8 @@ describe 'transform', ->
expect = fs.readFileSync("#{__dirname}/transform/undefined.out").toString()
result = fs.readFileSync("#{__dirname}/transform/undefined.tmp").toString()
result.should.eql expect
- fs.unlink "#{__dirname}/transform/undefined.tmp"
- it 'Test return null - skip one of two lines', ->
+ fs.unlink "#{__dirname}/transform/undefined.tmp", next
+ it 'should skip all lines where transform return null', (next) ->
count = 0
csv()
.fromPath("#{__dirname}/transform/null.in")
@@ -51,8 +51,8 @@ describe 'transform', ->
expect = fs.readFileSync("#{__dirname}/transform/null.out").toString()
result = fs.readFileSync("#{__dirname}/transform/null.tmp").toString()
result.should.eql expect
- fs.unlink "#{__dirname}/transform/null.tmp"
- it 'Test return object', ->
+ fs.unlink "#{__dirname}/transform/null.tmp", next
+ it 'Test return object', (next) ->
# we don't define columns
# recieve and array and return an object
# also see the columns test
@@ -66,8 +66,8 @@ describe 'transform', ->
expect = fs.readFileSync("#{__dirname}/transform/object.out").toString()
result = fs.readFileSync("#{__dirname}/transform/object.tmp").toString()
result.should.eql expect
- fs.unlink("#{__dirname}/transform/object.tmp")
- it 'Test return string', ->
+ fs.unlink "#{__dirname}/transform/object.tmp", next
+ it 'should accept a returned string', (next) ->
csv()
.fromPath("#{__dirname}/transform/string.in")
.toPath("#{__dirname}/transform/string.tmp")
@@ -78,8 +78,21 @@ describe 'transform', ->
expect = fs.readFileSync("#{__dirname}/transform/string.out").toString()
result = fs.readFileSync("#{__dirname}/transform/string.tmp").toString()
result.should.eql expect
- fs.unlink("#{__dirname}/transform/string.tmp")
- it 'Test types', ->
+ fs.unlink "#{__dirname}/transform/string.tmp", next
+ it 'should accept a returned integer', (next) ->
+ result = ''
+ test = csv()
+ .transform (data, index) ->
+ data[1]
+ .on 'data', (data) ->
+ result += data
+ .on 'end', ->
+ result.should.eql '210'
+ next()
+ for i in [2..0]
+ test.write ['Test '+i, i, '"']
+ test.end()
+ it 'should accept a returned array with different types', (next) ->
# Test date, int and float
csv()
.fromPath(__dirname+'/transform/types.in')
@@ -92,7 +105,46 @@ describe 'transform', ->
expect = fs.readFileSync("#{__dirname}/transform/types.out").toString()
result = fs.readFileSync("#{__dirname}/transform/types.tmp").toString()
result.should.eql expect
- fs.unlink("#{__dirname}/transform/types.tmp")
+ fs.unlink "#{__dirname}/transform/types.tmp", next
+
+ it 'should catch error thrown in transform callback', (next) ->
+ count = 0
+ error = false
+ test = csv()
+ .toPath( "#{__dirname}/write/write_array.tmp" )
+ .transform (data, index) ->
+ throw new Error "Error in data #{index}" if index is 10
+ data
+ .on 'error', (e) ->
+ error = true
+ e.message.should.equal 'Error in data 10'
+ next()
+ .on 'data', (data) ->
+ data[1].should.be.below 10
+ .on 'end', ->
+ false.should.be.ok
+ next()
+ for i in [0...1000]
+ test.write ['Test '+i, i, '"'] unless error
+ # it 'should catch error thrown in transform callback', (next) ->
+ # console.log 'sart'
+ # test = csv()
+ # .toPath( "#{__dirname}/write/write_array.tmp" )
+ # .transform (data, index) ->
+ # console.log 'ok'
+ # # throw new Error 'diable' # if index is 2
+ # data
+ # .on 'error', ->
+ # console.log 'error'
+ # next()
+ # .on 'end', ->
+ # # false.should.be.ok
+ # next()
+ # for i in [0...1000]
+ # test.write ['Test '+i, i, '"']
+
+
+
View
29 test/write.coffee
@@ -6,7 +6,7 @@ should = require 'should'
csv = require '..'
describe 'write', ->
- it 'Test write array', ->
+ it 'Test write array', (next) ->
count = 0;
test = csv()
.toPath( "#{__dirname}/write/write_array.tmp" )
@@ -19,11 +19,11 @@ describe 'write', ->
expect = fs.readFileSync( "#{__dirname}/write/write.out" ).toString()
result = fs.readFileSync( "#{__dirname}/write/write_array.tmp" ).toString()
result.should.eql expect
- fs.unlinkSync "#{__dirname}/write/write_array.tmp"
+ fs.unlink "#{__dirname}/write/write_array.tmp", next
for i in [0...1000]
test.write ["Test #{i}", i, '"']
test.end()
- it 'Test write object with column options', ->
+ it 'Test write object with column options', (next) ->
count = 0
test = csv()
.toPath( "#{__dirname}/write/write_object.tmp", columns: ['name','value','escape'] )
@@ -37,11 +37,11 @@ describe 'write', ->
expect = fs.readFileSync( "#{__dirname}/write/write.out").toString()
result = fs.readFileSync( "#{__dirname}/write/write_object.tmp").toString()
result.should.eql expect
- fs.unlinkSync "#{__dirname}/write/write_object.tmp"
+ fs.unlink "#{__dirname}/write/write_object.tmp", next
for i in [0...1000]
test.write {name: "Test #{i}", value:i, escape: '"', ovni: "ET #{i}"}
test.end()
- it 'Test write string', ->
+ it 'Test write string', (next) ->
count = 0
test = csv()
.toPath( "#{__dirname}/write/write_string.tmp" )
@@ -54,7 +54,7 @@ describe 'write', ->
expect = fs.readFileSync("#{__dirname}/write/write.out").toString()
result = fs.readFileSync("#{__dirname}/write/write_string.tmp").toString()
result.should.eql expect
- fs.unlinkSync "#{__dirname}/write/write_string.tmp"
+ fs.unlink "#{__dirname}/write/write_string.tmp", next
buffer = ''
for i in [0...1000]
buffer += ''.concat "Test #{i}", ',', i, ',', '""""', "\r"
@@ -63,7 +63,7 @@ describe 'write', ->
buffer = buffer.substr 250
test.write buffer
test.end()
- it 'Test write string with preserve', ->
+ it 'Test write string with preserve', (next) ->
count = 0
test = csv()
.toPath( "#{__dirname}/write/string_preserve.tmp" )
@@ -80,7 +80,7 @@ describe 'write', ->
expect = fs.readFileSync("#{__dirname}/write/string_preserve.out").toString()
result = fs.readFileSync("#{__dirname}/write/string_preserve.tmp").toString()
result.should.eql expect
- fs.unlinkSync "#{__dirname}/write/string_preserve.tmp"
+ fs.unlink "#{__dirname}/write/string_preserve.tmp", next
test.write '# This line should not be parsed', true
test.write '\n', true
buffer = ''
@@ -93,6 +93,19 @@ describe 'write', ->
test.write '\n', true
test.write '# This one as well', true
test.end()
+ it 'should transform data provided by write as an array', (next) ->
+ # Fix bug in which transform callback was called by flush and not write
+ count = 0
+ test = csv()
+ .toPath( "#{__dirname}/write/write_array.tmp" )
+ .transform (data, index) ->
+ count++
+ .on 'end', ->
+ count.should.eql 1000
+ next()
+ for i in [0...1000]
+ test.write ['Test '+i, i, '"']
+ test.end()
Please sign in to comment.
Something went wrong with that request. Please try again.