From 77c1fd3a5d862b3a14b7f4a04490ec173a1c3494 Mon Sep 17 00:00:00 2001 From: Juanjo Diaz Date: Wed, 27 Jan 2021 20:25:07 +0100 Subject: [PATCH] fix: properly escape quotes when using excel mode --- lib/JSON2CSVBase.js | 6 +++--- test/CLI.js | 11 ++++++++++ test/JSON2CSVAsyncParser.js | 16 ++++++++++++++ test/JSON2CSVParser.js | 12 +++++++++++ test/JSON2CSVTransform.js | 21 +++++++++++++++++++ .../csv/excelStringsWithEscapedQuoted.csv | 3 +++ 6 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 test/fixtures/csv/excelStringsWithEscapedQuoted.csv diff --git a/lib/JSON2CSVBase.js b/lib/JSON2CSVBase.js index 708054ef..4444fe9d 100644 --- a/lib/JSON2CSVBase.js +++ b/lib/JSON2CSVBase.js @@ -172,10 +172,10 @@ class JSON2CSVBase { value = value.replace(new RegExp(this.opts.quote, 'g'), this.opts.escapedQuote); } - value = `${this.opts.quote}${value}${this.opts.quote}`; - if (this.opts.excelStrings) { - value = `"="${value}""`; + value = `"=""${value.replace(new RegExp(this.opts.quote, 'g'), this.opts.escapedQuote)}"""`; + } else { + value = `${this.opts.quote}${value}${this.opts.quote}`; } } diff --git a/test/CLI.js b/test/CLI.js index 0db7fe17..36df846c 100644 --- a/test/CLI.js +++ b/test/CLI.js @@ -443,6 +443,17 @@ module.exports = (testRunner, jsonFixtures, csvFixtures) => { }); }); + testRunner.add('should format strings to force excel to view the values as strings with escaped quotes', (t) => { + const opts = '--excel-strings'; + + exec(`${cli} -i "${getFixturePath('/json/quotes.json')}" ${opts}`, (err, stdout, stderr) => { + t.notOk(stderr); + const csv = stdout; + t.equal(csv, csvFixtures.excelStringsWithEscapedQuoted); + t.end(); + }); + }); + // Escaping and preserving values testRunner.add('should parse JSON values with trailing backslashes', (t) => { diff --git a/test/JSON2CSVAsyncParser.js b/test/JSON2CSVAsyncParser.js index 8b004676..fe06a4aa 100644 --- a/test/JSON2CSVAsyncParser.js +++ b/test/JSON2CSVAsyncParser.js @@ -787,6 +787,22 @@ module.exports = (testRunner, jsonFixtures, csvFixtures, inMemoryJsonFixtures) = t.end(); }); + testRunner.add('should format strings to force excel to view the values as strings with escaped quotes', async (t) => { + const opts = { + excelStrings:true + }; + const parser = new AsyncParser(opts); + + try { + const csv = await parser.fromInput(jsonFixtures.quotes()).promise(); + t.equal(csv, csvFixtures.excelStringsWithEscapedQuoted); + } catch(err) { + t.fail(err.message); + } + + t.end(); + }); + // Escaping and preserving values testRunner.add('should parse JSON values with trailing backslashes', async (t) => { diff --git a/test/JSON2CSVParser.js b/test/JSON2CSVParser.js index 542c1613..8d1b2f10 100644 --- a/test/JSON2CSVParser.js +++ b/test/JSON2CSVParser.js @@ -530,6 +530,18 @@ module.exports = (testRunner, jsonFixtures, csvFixtures) => { t.end(); }); + testRunner.add('should format strings to force excel to view the values as strings with escaped quotes', (t) => { + const opts = { + excelStrings:true + }; + + const parser = new Json2csvParser(opts); + const csv = parser.parse(jsonFixtures.quotes); + + t.equal(csv, csvFixtures.excelStringsWithEscapedQuoted); + t.end(); + }); + // Escaping and preserving values testRunner.add('should parse JSON values with trailing backslashes', (t) => { diff --git a/test/JSON2CSVTransform.js b/test/JSON2CSVTransform.js index b9771a73..a7868c57 100644 --- a/test/JSON2CSVTransform.js +++ b/test/JSON2CSVTransform.js @@ -866,6 +866,27 @@ module.exports = (testRunner, jsonFixtures, csvFixtures, inMemoryJsonFixtures) = }); }); + testRunner.add('should format strings to force excel to view the values as strings with escaped quotes', (t) => { + const opts = { + excelStrings:true + }; + + const transform = new Json2csvTransform(opts); + const processor = jsonFixtures.quotes().pipe(transform); + + let csv = ''; + processor + .on('data', chunk => (csv += chunk.toString())) + .on('end', () => { + t.equal(csv, csvFixtures.excelStringsWithEscapedQuoted); + t.end(); + }) + .on('error', err => { + t.fail(err.message); + t.end(); + }); + }); + // Escaping and preserving values testRunner.add('should parse JSON values with trailing backslashes', (t) => { diff --git a/test/fixtures/csv/excelStringsWithEscapedQuoted.csv b/test/fixtures/csv/excelStringsWithEscapedQuoted.csv new file mode 100644 index 00000000..e8045c12 --- /dev/null +++ b/test/fixtures/csv/excelStringsWithEscapedQuoted.csv @@ -0,0 +1,3 @@ +"=""a string""" +"=""with a description""" +"=""with a description and """"quotes""""""" \ No newline at end of file