diff --git a/packages/csv-stringify/lib/api/index.js b/packages/csv-stringify/lib/api/index.js index 5b785875e..7d2b82e5d 100644 --- a/packages/csv-stringify/lib/api/index.js +++ b/packages/csv-stringify/lib/api/index.js @@ -126,7 +126,22 @@ const stringifier = function(options, state, info){ return [Error(`Invalid Casting Value: returned value must return a string, an object, null or undefined, got ${JSON.stringify(value)}`)]; } const {delimiter, escape, quote, quoted, quoted_empty, quoted_string, quoted_match, record_delimiter} = options; - if(value){ + if('' === value && '' === field){ + let quotedMatch = quoted_match && quoted_match.filter(quoted_match => { + if(typeof quoted_match === 'string'){ + return value.indexOf(quoted_match) !== -1; + }else{ + return quoted_match.test(value); + } + }); + quotedMatch = quotedMatch && quotedMatch.length > 0; + const shouldQuote = quotedMatch || true === quoted_empty || + (true === quoted_string && false !== quoted_empty); + if(shouldQuote === true){ + value = quote + value + quote; + } + csvrecord += value; + }else if(value){ if(typeof value !== 'string'){ return [Error(`Formatter must return a string, null or undefined, got ${JSON.stringify(value)}`)]; } diff --git a/packages/csv-stringify/test/option.quoted_match.coffee b/packages/csv-stringify/test/option.quoted_match.coffee index e52d27248..4387fb28d 100644 --- a/packages/csv-stringify/test/option.quoted_match.coffee +++ b/packages/csv-stringify/test/option.quoted_match.coffee @@ -35,3 +35,58 @@ describe 'Option `quoted_match`', -> ab,"cd","efg" ''' unless err next err + + it 'an empty string regex with no other "quoted" options (#344)', (next) -> + count = 0 + data = '' + stringifier = stringify [ + ['a', null, undefined, '', 'b'] + ], quoted_match: /^$/, eof: false, (err, data) -> + data.should.eql ''' + a,,,"",b + ''' unless err + next err + + it 'an empty string regex with all other "quoted" options set to false (#344)', (next) -> + count = 0 + data = '' + stringifier = stringify [ + ['a', null, undefined, '', 'b'] + ], quoted: false, quoted_empty: false, quoted_string: false, quoted_match: /^$/, eof: false, (err, data) -> + data.should.eql ''' + a,,,"",b + ''' unless err + next err + + it 'an empty string regex has higher priority than the "quoted" option', (next) -> + count = 0 + data = '' + stringifier = stringify [ + ['a', null, undefined, '', 'b'] + ], quoted: true, quoted_match: /^$/, eof: false, (err, data) -> + data.should.eql ''' + "a",,,"","b" + ''' unless err + next err + + it "an empty string regex does not conflict with quoted_string set to true", (next) -> + count = 0 + data = '' + stringifier = stringify [ + ['a', null, undefined, '', 'b'] + ], quoted_string: true, quoted_match: /^$/, eof: false, (err, data) -> + data.should.eql ''' + "a",,,"","b" + ''' unless err + next err + + it "an empty string regex does not conflict with quoted_empty set to true", (next) -> + count = 0 + data = '' + stringifier = stringify [ + ['a', null, undefined, '' , 'b'] + ], quoted_empty: true, quoted_match: /^$/, eof: false, (err, data) -> + data.should.eql ''' + a,"","","",b + ''' unless err + next err