Skip to content

Commit 203c5e0

Browse files
BurdetteLamarkou
andauthored
Fix CSV.filter to preserve headers (#174)
Co-authored-by: Sutou Kouhei <kou@clear-code.com>
1 parent 99956c6 commit 203c5e0

File tree

2 files changed

+86
-2
lines changed

2 files changed

+86
-2
lines changed

lib/csv.rb

+20-1
Original file line numberDiff line numberDiff line change
@@ -1057,10 +1057,29 @@ def filter(input=nil, output=nil, **options)
10571057
out_options[key] = value
10581058
end
10591059
end
1060+
10601061
# build input and output wrappers
1061-
input = new(input || ARGF, **in_options)
1062+
input = new(input || ARGF, **in_options)
10621063
output = new(output || $stdout, **out_options)
10631064

1065+
# process headers
1066+
need_manual_header_output =
1067+
(in_options[:headers] and
1068+
out_options[:headers] == true and
1069+
out_options[:write_headers])
1070+
if need_manual_header_output
1071+
first_row = input.shift
1072+
if first_row
1073+
if first_row.is_a?(Row)
1074+
headers = first_row.headers
1075+
yield headers
1076+
output << headers
1077+
end
1078+
yield first_row
1079+
output << first_row
1080+
end
1081+
end
1082+
10641083
# read, yield, write
10651084
input.each do |row|
10661085
yield row

test/csv/interface/test_read_write.rb

+66-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ class TestCSVInterfaceReadWrite < Test::Unit::TestCase
66
extend DifferentOFS
77

88
def test_filter
9-
input = <<-CSV
9+
input = <<-CSV.freeze
1010
1;2;3
1111
4;5
1212
CSV
@@ -24,6 +24,71 @@ def test_filter
2424
CSV
2525
end
2626

27+
def test_filter_headers_true
28+
input = <<-CSV.freeze
29+
Name,Value
30+
foo,0
31+
bar,1
32+
baz,2
33+
CSV
34+
output = ""
35+
CSV.filter(input, output, headers: true) do |row|
36+
row[0] += "X"
37+
row[1] = row[1].to_i + 1
38+
end
39+
assert_equal(<<-CSV, output)
40+
fooX,1
41+
barX,2
42+
bazX,3
43+
CSV
44+
end
45+
46+
def test_filter_headers_true_write_headers
47+
input = <<-CSV.freeze
48+
Name,Value
49+
foo,0
50+
bar,1
51+
baz,2
52+
CSV
53+
output = ""
54+
CSV.filter(input, output, headers: true, out_write_headers: true) do |row|
55+
if row.is_a?(Array)
56+
row[0] += "X"
57+
row[1] += "Y"
58+
else
59+
row[0] += "X"
60+
row[1] = row[1].to_i + 1
61+
end
62+
end
63+
assert_equal(<<-CSV, output)
64+
NameX,ValueY
65+
fooX,1
66+
barX,2
67+
bazX,3
68+
CSV
69+
end
70+
71+
def test_filter_headers_array_write_headers
72+
input = <<-CSV.freeze
73+
foo,0
74+
bar,1
75+
baz,2
76+
CSV
77+
output = ""
78+
CSV.filter(input, output,
79+
headers: ["Name", "Value"],
80+
out_write_headers: true) do |row|
81+
row[0] += "X"
82+
row[1] = row[1].to_i + 1
83+
end
84+
assert_equal(<<-CSV, output)
85+
Name,Value
86+
fooX,1
87+
barX,2
88+
bazX,3
89+
CSV
90+
end
91+
2792
def test_instance_same
2893
data = ""
2994
assert_equal(CSV.instance(data, col_sep: ";").object_id,

0 commit comments

Comments
 (0)