[ruby/csv] Ensuring StringIO's encoding in CSV.generate (#111)

https://github.com/ruby/csv/commit/dbf55ef008
This commit is contained in:
Seiei Miyagi 2019-11-25 10:06:59 +09:00 committed by Nobuyoshi Nakada
parent d57bc03ba9
commit 3c5b67e0db
No known key found for this signature in database
GPG Key ID: 7CD2805BFA3770C6
Notes: git 2020-07-20 03:35:47 +09:00
4 changed files with 38 additions and 25 deletions

View File

@ -531,12 +531,13 @@ class CSV
# plan to output non-ASCII compatible data. # plan to output non-ASCII compatible data.
# #
def generate(str=nil, **options) def generate(str=nil, **options)
encoding = options[:encoding]
# add a default empty String, if none was given # add a default empty String, if none was given
if str if str
str = StringIO.new(str) str = StringIO.new(str)
str.seek(0, IO::SEEK_END) str.seek(0, IO::SEEK_END)
str.set_encoding(encoding) if encoding
else else
encoding = options[:encoding]
str = +"" str = +""
str.force_encoding(encoding) if encoding str.force_encoding(encoding) if encoding
end end

View File

@ -15,4 +15,28 @@ module Helper
ENV["CSV_PARSER_SCANNER_TEST_CHUNK_SIZE"] = chunk_size_keep ENV["CSV_PARSER_SCANNER_TEST_CHUNK_SIZE"] = chunk_size_keep
end end
end end
def with_verbose(verbose)
original = $VERBOSE
begin
$VERBOSE = verbose
yield
ensure
$VERBOSE = original
end
end
def with_default_internal(encoding)
original = Encoding.default_internal
begin
with_verbose(false) do
Encoding.default_internal = encoding
end
yield
ensure
with_verbose(false) do
Encoding.default_internal = original
end
end
end
end end

View File

@ -5,6 +5,7 @@ require_relative "helper"
class TestCSVEncodings < Test::Unit::TestCase class TestCSVEncodings < Test::Unit::TestCase
extend DifferentOFS extend DifferentOFS
include Helper
def setup def setup
super super
@ -249,6 +250,15 @@ class TestCSVEncodings < Test::Unit::TestCase
assert_equal(["foo,\u3042\n".encode(Encoding::Windows_31J), Encoding::Windows_31J], [s, s.encoding], bug9766) assert_equal(["foo,\u3042\n".encode(Encoding::Windows_31J), Encoding::Windows_31J], [s, s.encoding], bug9766)
end end
def test_encoding_with_default_internal
with_default_internal(Encoding::UTF_8) do
s = CSV.generate(String.new(encoding: Encoding::Big5), encoding: Encoding::Big5) do |csv|
csv << ["漢字"]
end
assert_equal(["漢字\n".encode(Encoding::Big5), Encoding::Big5], [s, s.encoding])
end
end
def test_row_separator_detection_with_invalid_encoding def test_row_separator_detection_with_invalid_encoding
csv = CSV.new("invalid,\xF8\r\nvalid,x\r\n".force_encoding("UTF-8"), csv = CSV.new("invalid,\xF8\r\nvalid,x\r\n".force_encoding("UTF-8"),
encoding: "UTF-8") encoding: "UTF-8")

View File

@ -4,6 +4,8 @@
require_relative "../helper" require_relative "../helper"
module TestCSVWriteGeneral module TestCSVWriteGeneral
include Helper
def test_tab def test_tab
assert_equal("\t#{$INPUT_RECORD_SEPARATOR}", assert_equal("\t#{$INPUT_RECORD_SEPARATOR}",
generate_line(["\t"])) generate_line(["\t"]))
@ -221,30 +223,6 @@ module TestCSVWriteGeneral
generate_line(row)) generate_line(row))
end end
end end
def with_verbose(verbose)
original = $VERBOSE
begin
$VERBOSE = verbose
yield
ensure
$VERBOSE = original
end
end
def with_default_internal(encoding)
original = Encoding.default_internal
begin
with_verbose(false) do
Encoding.default_internal = encoding
end
yield
ensure
with_verbose(false) do
Encoding.default_internal = original
end
end
end
end end
class TestCSVWriteGeneralGenerateLine < Test::Unit::TestCase class TestCSVWriteGeneralGenerateLine < Test::Unit::TestCase