Skip to content

Commit 95b84b6

Browse files
committed
SmarterCSV::Writer bugfix for quote_headers:true
1 parent 927486a commit 95b84b6

4 files changed

Lines changed: 27 additions & 3 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11

22
# SmarterCSV 1.x Change Log
33

4+
## 1.14.2 (2025-04-10)
5+
* bugfix: SmarterCSV::Writer fixing corner case with `quote_headers: true`
6+
47
## 1.14.1 (2025-04-09)
58
* bugfix: SmarterCSV::Writer empty hash results in a blank line ([issue 299](https://github.com/tilo/smarter_csv/issues/299))
69
* bugfix: SmarterCSV::Writer need to automatically quote problematic headers ([issue #300](https://github.com/tilo/smarter_csv/issues/300))

lib/smarter_csv/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# frozen_string_literal: true
22

33
module SmarterCSV
4-
VERSION = "1.14.1"
4+
VERSION = "1.14.2"
55
end

lib/smarter_csv/writer.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ def <<(data)
9090
def finalize
9191
mapped_headers = @headers.map { |header| @map_headers[header] || header }
9292
force_quotes = @quote_headers || @force_quotes
93+
9394
mapped_headers = mapped_headers.map { |x| escape_csv_field(x, force_quotes) }
9495

9596
@temp_file.rewind
@@ -136,7 +137,7 @@ def map_all_values(key, value)
136137

137138
def escape_csv_field(field, force_quotes = false)
138139
str = field.to_s
139-
return str if @disable_auto_quoting
140+
return str if @disable_auto_quoting && !force_quotes
140141

141142
# double-quote fields if we force that, or if the field contains the comma, new-line, or quote character
142143
contains_special_char = str.to_s.match(@quote_regex)

spec/smarter_csv/writer_spec.rb

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,25 @@
384384
end
385385
end
386386

387+
context 'when force_quotes is true, even with auto-quoting disabled' do
388+
let(:options) do
389+
{
390+
force_quotes: true,
391+
disable_auto_quoting: true, # works even then
392+
}
393+
end
394+
395+
it 'quotes all the headers and data fields' do
396+
writer = SmarterCSV::Writer.new(file_path, options)
397+
writer << data
398+
writer.finalize
399+
output = File.read(file_path)
400+
401+
expect(output).to include("\"name\",\"age\",\"city\"#{row_sep}")
402+
expect(output).to include("\"John\",\"30\",\"New York\"#{row_sep}")
403+
end
404+
end
405+
387406
context 'when quote_headers is true' do
388407
let(:options) { {quote_headers: true} }
389408

@@ -446,6 +465,7 @@
446465
describe 'when doing advanced mapping' do
447466
let(:options) do
448467
{
468+
quote_headers: true,
449469
disable_auto_quoting: true, # ⚠️ Important: turn off auto-quoting because we're messing with it below
450470
value_converters: {
451471
active: ->(v) { v ? '✅' : '❌' },
@@ -470,7 +490,7 @@
470490
writer.finalize
471491

472492
output = File.read(file_path)
473-
expect(output).to include("name,age,active,balance#{row_sep}")
493+
expect(output).to include("\"name\",\"age\",\"active\",\"balance\"#{row_sep}")
474494
expect(output).to include("\"Alice\",42,\"\",\"$234.24\"#{row_sep}")
475495
expect(output).to include("\"Joe\",53,\"\",\"$32100\"#{row_sep}")
476496
end

0 commit comments

Comments
 (0)