Skip to content

Commit 5bf6873

Browse files
authored
Add invalid: :replace for CSV.open (#130)
This PR adds `invalid: :replace` for `CSV.open`. It is a PR similar to #129.
1 parent a4b528c commit 5bf6873

File tree

2 files changed

+35
-2
lines changed

2 files changed

+35
-2
lines changed

lib/csv.rb

+5-2
Original file line numberDiff line numberDiff line change
@@ -962,8 +962,10 @@ def generate_line(row, **options)
962962
#
963963
# possible options elements:
964964
# hash form:
965-
# :undef => :replace # replace undefined conversion
966-
# :replace => string # replacement string ("?" or "\uFFFD" if not specified)
965+
# :invalid => nil # raise error on invalid byte sequence (default)
966+
# :invalid => :replace # replace invalid byte sequence
967+
# :undef => :replace # replace undefined conversion
968+
# :replace => string # replacement string ("?" or "\uFFFD" if not specified)
967969
#
968970
# This method opens an IO object, and wraps that with CSV. This is intended
969971
# as the primary interface for writing a CSV file.
@@ -1026,6 +1028,7 @@ def open(filename, mode="r", **options)
10261028
# wrap a File opened with the remaining +args+ with no newline
10271029
# decorator
10281030
file_opts = {universal_newline: false}.merge(options)
1031+
options.delete(:invalid)
10291032
options.delete(:undef)
10301033
options.delete(:replace)
10311034

test/csv/interface/test_read.rb

+30
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,36 @@ def test_open_invalid_byte_sequence_in_utf_8
135135
end
136136
end
137137

138+
def test_open_with_invalid_nil
139+
CSV.open(@input.path, "w", encoding: Encoding::CP932, invalid: nil) do |rows|
140+
error = assert_raise(Encoding::InvalidByteSequenceError) do
141+
rows << ["\x82\xa0"]
142+
end
143+
assert_equal('"\x82" on UTF-8',
144+
error.message)
145+
end
146+
end
147+
148+
def test_open_with_invalid_replace
149+
CSV.open(@input.path, "w", encoding: Encoding::CP932, invalid: :replace) do |rows|
150+
rows << ["\x82\xa0".force_encoding(Encoding::UTF_8)]
151+
end
152+
CSV.open(@input.path, encoding: Encoding::CP932) do |csv|
153+
assert_equal([["??"]],
154+
csv.to_a)
155+
end
156+
end
157+
158+
def test_open_with_invalid_replace_and_replace_string
159+
CSV.open(@input.path, "w", encoding: Encoding::CP932, invalid: :replace, replace: "X") do |rows|
160+
rows << ["\x82\xa0".force_encoding(Encoding::UTF_8)]
161+
end
162+
CSV.open(@input.path, encoding: Encoding::CP932) do |csv|
163+
assert_equal([["XX"]],
164+
csv.to_a)
165+
end
166+
end
167+
138168
def test_open_with_undef_replace
139169
# U+00B7 Middle Dot
140170
CSV.open(@input.path, "w", encoding: Encoding::CP932, undef: :replace) do |rows|

0 commit comments

Comments
 (0)