mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Upgrade CSV to 3.0.4
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66922 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
cdca14e75e
commit
24b57b102c
27 changed files with 908 additions and 565 deletions
5
NEWS
5
NEWS
|
@ -26,6 +26,11 @@ sufficient information, see the ChangeLog file or Redmine
|
|||
|
||||
=== Stdlib updates (outstanding ones only)
|
||||
|
||||
[CSV]
|
||||
|
||||
* Upgrade to 3.0.4.
|
||||
See https://github.com/ruby/csv/blob/master/NEWS.md.
|
||||
|
||||
[RSS]
|
||||
|
||||
* Upgrade to RSS 0.2.8.
|
||||
|
|
21
lib/csv.rb
21
lib/csv.rb
|
@ -397,6 +397,7 @@ class CSV
|
|||
# <b><tt>:force_quotes</tt></b>:: +false+
|
||||
# <b><tt>:skip_lines</tt></b>:: +nil+
|
||||
# <b><tt>:liberal_parsing</tt></b>:: +false+
|
||||
# <b><tt>:quote_empty</tt></b>:: +true+
|
||||
#
|
||||
DEFAULT_OPTIONS = {
|
||||
col_sep: ",",
|
||||
|
@ -412,6 +413,7 @@ class CSV
|
|||
force_quotes: false,
|
||||
skip_lines: nil,
|
||||
liberal_parsing: false,
|
||||
quote_empty: true,
|
||||
}.freeze
|
||||
|
||||
#
|
||||
|
@ -534,7 +536,7 @@ class CSV
|
|||
str.seek(0, IO::SEEK_END)
|
||||
else
|
||||
encoding = options[:encoding]
|
||||
str = String.new
|
||||
str = +""
|
||||
str.force_encoding(encoding) if encoding
|
||||
end
|
||||
csv = new(str, options) # wrap
|
||||
|
@ -557,11 +559,11 @@ class CSV
|
|||
#
|
||||
def self.generate_line(row, **options)
|
||||
options = {row_sep: $INPUT_RECORD_SEPARATOR}.merge(options)
|
||||
str = String.new
|
||||
str = +""
|
||||
if options[:encoding]
|
||||
str.force_encoding(options[:encoding])
|
||||
elsif field = row.find { |f| not f.nil? }
|
||||
str.force_encoding(String(field).encoding)
|
||||
elsif field = row.find {|f| f.is_a?(String)}
|
||||
str.force_encoding(field.encoding)
|
||||
end
|
||||
(new(str, options) << row).string
|
||||
end
|
||||
|
@ -882,6 +884,7 @@ class CSV
|
|||
# <b><tt>:empty_value</tt></b>:: When set an object, any values of a
|
||||
# blank string field is replaced by
|
||||
# the set object.
|
||||
# <b><tt>:quote_empty</tt></b>:: TODO
|
||||
#
|
||||
# See CSV::DEFAULT_OPTIONS for the default settings.
|
||||
#
|
||||
|
@ -907,7 +910,8 @@ class CSV
|
|||
external_encoding: nil,
|
||||
encoding: nil,
|
||||
nil_value: nil,
|
||||
empty_value: "")
|
||||
empty_value: "",
|
||||
quote_empty: true)
|
||||
raise ArgumentError.new("Cannot parse nil as CSV") if data.nil?
|
||||
|
||||
# create the IO object we will read from
|
||||
|
@ -947,6 +951,7 @@ class CSV
|
|||
column_separator: col_sep,
|
||||
row_separator: row_sep,
|
||||
quote_character: quote_char,
|
||||
quote_empty: quote_empty,
|
||||
}
|
||||
|
||||
@writer = nil
|
||||
|
@ -1178,9 +1183,8 @@ class CSV
|
|||
#
|
||||
def read
|
||||
rows = to_a
|
||||
headers = parser.headers
|
||||
if headers
|
||||
Table.new(rows, headers: headers)
|
||||
if parser.use_headers?
|
||||
Table.new(rows, headers: parser.headers)
|
||||
else
|
||||
rows
|
||||
end
|
||||
|
@ -1240,7 +1244,6 @@ class CSV
|
|||
end
|
||||
end
|
||||
_headers = headers
|
||||
_headers = headers
|
||||
str << " headers:" << _headers.inspect if _headers
|
||||
str << ">"
|
||||
begin
|
||||
|
|
|
@ -38,6 +38,6 @@ Gem::Specification.new do |spec|
|
|||
|
||||
spec.add_development_dependency "bundler"
|
||||
spec.add_development_dependency "rake"
|
||||
spec.add_development_dependency "benchmark-ips"
|
||||
spec.add_development_dependency "benchmark_driver"
|
||||
spec.add_development_dependency "simplecov"
|
||||
end
|
||||
|
|
|
@ -170,6 +170,7 @@ class CSV
|
|||
@input = input
|
||||
@options = options
|
||||
@samples = []
|
||||
@parsed = false
|
||||
|
||||
prepare
|
||||
end
|
||||
|
@ -229,6 +230,8 @@ class CSV
|
|||
def parse(&block)
|
||||
return to_enum(__method__) unless block_given?
|
||||
|
||||
return if @parsed
|
||||
|
||||
if @return_headers and @headers
|
||||
headers = Row.new(@headers, @raw_headers, true)
|
||||
if @unconverted_fields
|
||||
|
@ -262,10 +265,10 @@ class CSV
|
|||
skip_needless_lines
|
||||
start_row
|
||||
elsif @scanner.eos?
|
||||
return if row.empty? and value.nil?
|
||||
break if row.empty? and value.nil?
|
||||
row << value
|
||||
emit_row(row, &block)
|
||||
return
|
||||
break
|
||||
else
|
||||
if @quoted_column_value
|
||||
message = "Do not allow except col_sep_split_separator " +
|
||||
|
@ -287,6 +290,12 @@ class CSV
|
|||
message = "Invalid byte sequence in #{@encoding}"
|
||||
raise MalformedCSVError.new(message, @lineno + 1)
|
||||
end
|
||||
|
||||
@parsed = true
|
||||
end
|
||||
|
||||
def use_headers?
|
||||
@use_headers
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -300,7 +309,18 @@ class CSV
|
|||
|
||||
def prepare_variable
|
||||
@encoding = @options[:encoding]
|
||||
@liberal_parsing = @options[:liberal_parsing]
|
||||
liberal_parsing = @options[:liberal_parsing]
|
||||
if liberal_parsing
|
||||
@liberal_parsing = true
|
||||
if liberal_parsing.is_a?(Hash)
|
||||
@double_quote_outside_quote =
|
||||
liberal_parsing[:double_quote_outside_quote]
|
||||
else
|
||||
@double_quote_outside_quote = false
|
||||
end
|
||||
else
|
||||
@liberal_parsing = false
|
||||
end
|
||||
@unconverted_fields = @options[:unconverted_fields]
|
||||
@field_size_limit = @options[:field_size_limit]
|
||||
@skip_blanks = @options[:skip_blanks]
|
||||
|
@ -318,6 +338,7 @@ class CSV
|
|||
end
|
||||
|
||||
escaped_column_separator = Regexp.escape(@column_separator)
|
||||
escaped_first_column_separator = Regexp.escape(@column_separator[0])
|
||||
escaped_row_separator = Regexp.escape(@row_separator)
|
||||
escaped_quote_character = Regexp.escape(@quote_character)
|
||||
|
||||
|
@ -341,8 +362,11 @@ class CSV
|
|||
@column_ends = @column_separator.each_char.collect do |char|
|
||||
Regexp.new(Regexp.escape(char))
|
||||
end
|
||||
@first_column_separators = Regexp.new(escaped_first_column_separator +
|
||||
"+".encode(@encoding))
|
||||
else
|
||||
@column_ends = nil
|
||||
@first_column_separators = nil
|
||||
end
|
||||
@row_end = Regexp.new(escaped_row_separator)
|
||||
if @row_separator.size > 1
|
||||
|
@ -359,12 +383,12 @@ class CSV
|
|||
"]+".encode(@encoding))
|
||||
if @liberal_parsing
|
||||
@unquoted_value = Regexp.new("[^".encode(@encoding) +
|
||||
escaped_column_separator +
|
||||
escaped_first_column_separator +
|
||||
"\r\n]+".encode(@encoding))
|
||||
else
|
||||
@unquoted_value = Regexp.new("[^".encode(@encoding) +
|
||||
escaped_quote_character +
|
||||
escaped_column_separator +
|
||||
escaped_first_column_separator +
|
||||
"\r\n]+".encode(@encoding))
|
||||
end
|
||||
@cr_or_lf = Regexp.new("[\r\n]".encode(@encoding))
|
||||
|
@ -583,6 +607,13 @@ class CSV
|
|||
if quoted_value
|
||||
unquoted_value = parse_unquoted_column_value
|
||||
if unquoted_value
|
||||
if @double_quote_outside_quote
|
||||
unquoted_value = unquoted_value.gsub(@quote_character * 2,
|
||||
@quote_character)
|
||||
if quoted_value.empty? # %Q{""...} case
|
||||
return @quote_character + unquoted_value
|
||||
end
|
||||
end
|
||||
@quote_character + quoted_value + @quote_character + unquoted_value
|
||||
else
|
||||
quoted_value
|
||||
|
@ -601,7 +632,25 @@ class CSV
|
|||
|
||||
def parse_unquoted_column_value
|
||||
value = @scanner.scan_all(@unquoted_value)
|
||||
@unquoted_column_value = true if value
|
||||
return nil unless value
|
||||
|
||||
@unquoted_column_value = true
|
||||
if @first_column_separators
|
||||
while true
|
||||
@scanner.keep_start
|
||||
is_column_end = @column_ends.all? do |column_end|
|
||||
@scanner.scan(column_end)
|
||||
end
|
||||
@scanner.keep_back
|
||||
break if is_column_end
|
||||
sub_separator = @scanner.scan_all(@first_column_separators)
|
||||
break if sub_separator.nil?
|
||||
value << sub_separator
|
||||
sub_value = @scanner.scan_all(@unquoted_value)
|
||||
break if sub_value.nil?
|
||||
value << sub_value
|
||||
end
|
||||
end
|
||||
value
|
||||
end
|
||||
|
||||
|
|
|
@ -130,6 +130,7 @@ class CSV
|
|||
alias_method :include?, :has_key?
|
||||
alias_method :key?, :has_key?
|
||||
alias_method :member?, :has_key?
|
||||
alias_method :header?, :has_key?
|
||||
|
||||
#
|
||||
# :call-seq:
|
||||
|
@ -286,12 +287,6 @@ class CSV
|
|||
index.nil? ? nil : index + minimum_index
|
||||
end
|
||||
|
||||
# Returns +true+ if +name+ is a header for this row, and +false+ otherwise.
|
||||
def header?(name)
|
||||
headers.include? name
|
||||
end
|
||||
alias_method :include?, :header?
|
||||
|
||||
#
|
||||
# Returns +true+ if +data+ matches a field in this row, and +false+
|
||||
# otherwise.
|
||||
|
|
|
@ -19,7 +19,7 @@ class CSV
|
|||
# The optional +headers+ parameter can be set to Array of headers.
|
||||
# If headers aren't set, headers are fetched from CSV::Row objects.
|
||||
# Otherwise, headers() method will return headers being set in
|
||||
# headers arugument.
|
||||
# headers argument.
|
||||
#
|
||||
# A CSV::Table object supports the following Array methods through
|
||||
# delegation:
|
||||
|
@ -133,10 +133,15 @@ class CSV
|
|||
|
||||
#
|
||||
# Returns the headers for the first row of this table (assumed to match all
|
||||
# other rows). An empty Array is returned for empty tables.
|
||||
# other rows). The headers Array passed to CSV::Table.new is returned for
|
||||
# empty tables.
|
||||
#
|
||||
def headers
|
||||
if @table.empty?
|
||||
@headers.dup
|
||||
else
|
||||
@table.first.headers
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
|
||||
class CSV
|
||||
# The version of the installed library.
|
||||
VERSION = "3.0.2"
|
||||
VERSION = "3.0.4"
|
||||
end
|
||||
|
|
|
@ -31,7 +31,10 @@ class CSV
|
|||
@headers ||= row if @use_headers
|
||||
@lineno += 1
|
||||
|
||||
line = row.collect(&@quote).join(@column_separator) + @row_separator
|
||||
converted_row = row.collect do |field|
|
||||
quote(field)
|
||||
end
|
||||
line = converted_row.join(@column_separator) + @row_separator
|
||||
if @output_encoding
|
||||
line = line.encode(@output_encoding)
|
||||
end
|
||||
|
@ -90,37 +93,16 @@ class CSV
|
|||
else
|
||||
@row_separator = row_separator.to_s.encode(@encoding)
|
||||
end
|
||||
quote_character = @options[:quote_character]
|
||||
quote = lambda do |field|
|
||||
field = String(field)
|
||||
encoded_quote_character = quote_character.encode(field.encoding)
|
||||
encoded_quote_character +
|
||||
field.gsub(encoded_quote_character,
|
||||
encoded_quote_character * 2) +
|
||||
encoded_quote_character
|
||||
end
|
||||
if @options[:force_quotes]
|
||||
@quote = quote
|
||||
else
|
||||
quotable_pattern =
|
||||
@quote_character = @options[:quote_character]
|
||||
@force_quotes = @options[:force_quotes]
|
||||
unless @force_quotes
|
||||
@quotable_pattern =
|
||||
Regexp.new("[\r\n".encode(@encoding) +
|
||||
Regexp.escape(@column_separator) +
|
||||
Regexp.escape(quote_character.encode(@encoding)) +
|
||||
Regexp.escape(@quote_character.encode(@encoding)) +
|
||||
"]".encode(@encoding))
|
||||
@quote = lambda do |field|
|
||||
if field.nil? # represent +nil+ fields as empty unquoted fields
|
||||
""
|
||||
else
|
||||
field = String(field) # Stringify fields
|
||||
# represent empty fields as empty quoted fields
|
||||
if field.empty? or quotable_pattern.match?(field)
|
||||
quote.call(field)
|
||||
else
|
||||
field # unquoted field
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@quote_empty = @options.fetch(:quote_empty, true)
|
||||
end
|
||||
|
||||
def prepare_output
|
||||
|
@ -140,5 +122,32 @@ class CSV
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
def quote_field(field)
|
||||
field = String(field)
|
||||
encoded_quote_character = @quote_character.encode(field.encoding)
|
||||
encoded_quote_character +
|
||||
field.gsub(encoded_quote_character,
|
||||
encoded_quote_character * 2) +
|
||||
encoded_quote_character
|
||||
end
|
||||
|
||||
def quote(field)
|
||||
if @force_quotes
|
||||
quote_field(field)
|
||||
else
|
||||
if field.nil? # represent +nil+ fields as empty unquoted fields
|
||||
""
|
||||
else
|
||||
field = String(field) # Stringify fields
|
||||
# represent empty fields as empty quoted fields
|
||||
if (@quote_empty and field.empty?) or @quotable_pattern.match?(field)
|
||||
quote_field(field)
|
||||
else
|
||||
field # unquoted field
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
# frozen_string_literal: false
|
||||
require "test/unit"
|
||||
|
||||
require "csv"
|
||||
|
||||
require_relative "../lib/with_different_ofs.rb"
|
||||
|
||||
class TestCSV < Test::Unit::TestCase
|
||||
end
|
40
test/csv/parse/test_column_separator.rb
Normal file
40
test/csv/parse/test_column_separator.rb
Normal file
|
@ -0,0 +1,40 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# frozen_string_literal: false
|
||||
|
||||
require_relative "../helper"
|
||||
|
||||
class TestCSVParseColumnSeparator < Test::Unit::TestCase
|
||||
extend DifferentOFS
|
||||
|
||||
def test_comma
|
||||
assert_equal([["a", "b", nil, "d"]],
|
||||
CSV.parse("a,b,,d", col_sep: ","))
|
||||
end
|
||||
|
||||
def test_space
|
||||
assert_equal([["a", "b", nil, "d"]],
|
||||
CSV.parse("a b d", col_sep: " "))
|
||||
end
|
||||
|
||||
def test_tab
|
||||
assert_equal([["a", "b", nil, "d"]],
|
||||
CSV.parse("a\tb\t\td", col_sep: "\t"))
|
||||
end
|
||||
|
||||
def test_multiple_characters_include_sub_separator
|
||||
assert_equal([["a b", nil, "d"]],
|
||||
CSV.parse("a b d", col_sep: " "))
|
||||
end
|
||||
|
||||
def test_multiple_characters_leading_empty_fields
|
||||
data = <<-CSV
|
||||
<=><=>A<=>B<=>C
|
||||
1<=>2<=>3
|
||||
CSV
|
||||
assert_equal([
|
||||
[nil, nil, "A", "B", "C"],
|
||||
["1", "2", "3"],
|
||||
],
|
||||
CSV.parse(data, col_sep: "<=>"))
|
||||
end
|
||||
end
|
110
test/csv/parse/test_convert.rb
Normal file
110
test/csv/parse/test_convert.rb
Normal file
|
@ -0,0 +1,110 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# frozen_string_literal: false
|
||||
|
||||
require_relative "../helper"
|
||||
|
||||
class TestCSVParseConvert < Test::Unit::TestCase
|
||||
extend DifferentOFS
|
||||
|
||||
def setup
|
||||
super
|
||||
@data = "Numbers,:integer,1,:float,3.015"
|
||||
@parser = CSV.new(@data)
|
||||
|
||||
@custom = lambda {|field| /\A:(\S.*?)\s*\Z/ =~ field ? $1.to_sym : field}
|
||||
|
||||
@time = Time.utc(2018, 12, 30, 6, 41, 29)
|
||||
@windows_safe_time_data = @time.strftime("%a %b %d %H:%M:%S %Y")
|
||||
end
|
||||
|
||||
def test_integer
|
||||
@parser.convert(:integer)
|
||||
assert_equal(["Numbers", ":integer", 1, ":float", "3.015"],
|
||||
@parser.shift)
|
||||
end
|
||||
|
||||
def test_float
|
||||
@parser.convert(:float)
|
||||
assert_equal(["Numbers", ":integer", 1.0, ":float", 3.015],
|
||||
@parser.shift)
|
||||
end
|
||||
|
||||
def test_float_integer
|
||||
@parser.convert(:float)
|
||||
@parser.convert(:integer)
|
||||
assert_equal(["Numbers", ":integer", 1.0, ":float", 3.015],
|
||||
@parser.shift)
|
||||
end
|
||||
|
||||
def test_integer_float
|
||||
@parser.convert(:integer)
|
||||
@parser.convert(:float)
|
||||
assert_equal(["Numbers", ":integer", 1, ":float", 3.015],
|
||||
@parser.shift)
|
||||
end
|
||||
|
||||
def test_numberic
|
||||
@parser.convert(:numeric)
|
||||
assert_equal(["Numbers", ":integer", 1, ":float", 3.015],
|
||||
@parser.shift)
|
||||
end
|
||||
|
||||
def test_all
|
||||
@data << ",#{@windows_safe_time_data}"
|
||||
@parser = CSV.new(@data)
|
||||
@parser.convert(:all)
|
||||
assert_equal(["Numbers", ":integer", 1, ":float", 3.015, @time.to_datetime],
|
||||
@parser.shift)
|
||||
end
|
||||
|
||||
def test_custom
|
||||
@parser.convert do |field|
|
||||
/\A:(\S.*?)\s*\Z/ =~ field ? $1.to_sym : field
|
||||
end
|
||||
assert_equal(["Numbers", :integer, "1", :float, "3.015"],
|
||||
@parser.shift)
|
||||
end
|
||||
|
||||
def test_builtin_custom
|
||||
@parser.convert(:numeric)
|
||||
@parser.convert(&@custom)
|
||||
assert_equal(["Numbers", :integer, 1, :float, 3.015],
|
||||
@parser.shift)
|
||||
end
|
||||
|
||||
def test_custom_field_info_line
|
||||
@parser.convert do |field, info|
|
||||
assert_equal(1, info.line)
|
||||
info.index == 4 ? Float(field).floor : field
|
||||
end
|
||||
assert_equal(["Numbers", ":integer", "1", ":float", 3],
|
||||
@parser.shift)
|
||||
end
|
||||
|
||||
def test_custom_field_info_header
|
||||
headers = ["one", "two", "three", "four", "five"]
|
||||
@parser = CSV.new(@data, headers: headers)
|
||||
@parser.convert do |field, info|
|
||||
info.header == "three" ? Integer(field) * 100 : field
|
||||
end
|
||||
assert_equal(CSV::Row.new(headers,
|
||||
["Numbers", ":integer", 100, ":float", "3.015"]),
|
||||
@parser.shift)
|
||||
end
|
||||
|
||||
def test_custom_blank_field
|
||||
converter = lambda {|field| field.nil?}
|
||||
row = CSV.parse_line('nil,', converters: converter)
|
||||
assert_equal([false, true], row)
|
||||
end
|
||||
|
||||
def test_nil_value
|
||||
assert_equal(["nil", "", "a"],
|
||||
CSV.parse_line(',"",a', nil_value: "nil"))
|
||||
end
|
||||
|
||||
def test_empty_value
|
||||
assert_equal([nil, "empty", "a"],
|
||||
CSV.parse_line(',"",a', empty_value: "empty"))
|
||||
end
|
||||
end
|
23
test/csv/parse/test_each.rb
Normal file
23
test/csv/parse/test_each.rb
Normal file
|
@ -0,0 +1,23 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# frozen_string_literal: false
|
||||
|
||||
require_relative "../helper"
|
||||
|
||||
class TestCSVParseEach < Test::Unit::TestCase
|
||||
extend DifferentOFS
|
||||
|
||||
def test_twice
|
||||
data = <<-CSV
|
||||
Ruby,2.6.0,script
|
||||
CSV
|
||||
csv = CSV.new(data)
|
||||
assert_equal([
|
||||
[["Ruby", "2.6.0", "script"]],
|
||||
[],
|
||||
],
|
||||
[
|
||||
csv.to_a,
|
||||
csv.to_a,
|
||||
])
|
||||
end
|
||||
end
|
28
test/csv/test_csv_parsing.rb → test/csv/parse/test_general.rb
Executable file → Normal file
28
test/csv/test_csv_parsing.rb → test/csv/parse/test_general.rb
Executable file → Normal file
|
@ -1,14 +1,9 @@
|
|||
#!/usr/bin/env ruby -w
|
||||
# encoding: UTF-8
|
||||
# -*- coding: utf-8 -*-
|
||||
# frozen_string_literal: false
|
||||
|
||||
# tc_csv_parsing.rb
|
||||
#
|
||||
# Created by James Edward Gray II on 2005-10-31.
|
||||
|
||||
require "timeout"
|
||||
|
||||
require_relative "base"
|
||||
require_relative "../helper"
|
||||
|
||||
#
|
||||
# Following tests are my interpretation of the
|
||||
|
@ -16,7 +11,7 @@ require_relative "base"
|
|||
# document in one place (intentionally) and that is to make the default row
|
||||
# separator <tt>$/</tt>.
|
||||
#
|
||||
class TestCSV::Parsing < TestCSV
|
||||
class TestCSVParseGeneral < Test::Unit::TestCase
|
||||
extend DifferentOFS
|
||||
|
||||
BIG_DATA = "123456789\n" * 1024
|
||||
|
@ -226,16 +221,6 @@ line,5,jkl
|
|||
assert_parse_errors_out(data, field_size_limit: 5)
|
||||
end
|
||||
|
||||
def test_col_sep_comma
|
||||
assert_equal([["a", "b", nil, "d"]],
|
||||
CSV.parse("a,b,,d", col_sep: ","))
|
||||
end
|
||||
|
||||
def test_col_sep_space
|
||||
assert_equal([["a", "b", nil, "d"]],
|
||||
CSV.parse("a b d", col_sep: " "))
|
||||
end
|
||||
|
||||
def test_row_sep_auto_cr
|
||||
assert_equal([["a"]], CSV.parse("a\r"))
|
||||
end
|
||||
|
@ -248,14 +233,7 @@ line,5,jkl
|
|||
assert_equal([["a"]], CSV.parse("a\r\n"))
|
||||
end
|
||||
|
||||
def test_headers_empty_line
|
||||
assert_equal(CSV::Table.new([CSV::Row.new(["header1"], [])],
|
||||
headers: ["header1"]),
|
||||
CSV.parse("\n", headers: "header1"))
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def assert_parse_errors_out(*args)
|
||||
assert_raise(CSV::MalformedCSVError) do
|
||||
Timeout.timeout(0.2) do
|
33
test/csv/test_headers.rb → test/csv/parse/test_header.rb
Executable file → Normal file
33
test/csv/test_headers.rb → test/csv/parse/test_header.rb
Executable file → Normal file
|
@ -1,14 +1,9 @@
|
|||
#!/usr/bin/env ruby -w
|
||||
# encoding: UTF-8
|
||||
# -*- coding: utf-8 -*-
|
||||
# frozen_string_literal: false
|
||||
|
||||
# tc_headers.rb
|
||||
#
|
||||
# Created by James Edward Gray II on 2005-10-31.
|
||||
require_relative "../helper"
|
||||
|
||||
require_relative "base"
|
||||
|
||||
class TestCSV::Headers < TestCSV
|
||||
class TestCSVHeaders < Test::Unit::TestCase
|
||||
extend DifferentOFS
|
||||
|
||||
def setup
|
||||
|
@ -315,4 +310,26 @@ A
|
|||
assert_equal([["A"], [nil]],
|
||||
[row.headers, row.fields])
|
||||
end
|
||||
|
||||
def test_parse_empty
|
||||
assert_equal(CSV::Table.new([], {}),
|
||||
CSV.parse("", headers: true))
|
||||
end
|
||||
|
||||
def test_parse_empty_line
|
||||
assert_equal(CSV::Table.new([], {}),
|
||||
CSV.parse("\n", headers: true))
|
||||
end
|
||||
|
||||
def test_specified_empty
|
||||
assert_equal(CSV::Table.new([],
|
||||
headers: ["header1"]),
|
||||
CSV.parse("", headers: ["header1"]))
|
||||
end
|
||||
|
||||
def test_specified_empty_line
|
||||
assert_equal(CSV::Table.new([CSV::Row.new(["header1"], [])],
|
||||
headers: ["header1"]),
|
||||
CSV.parse("\n", headers: ["header1"]))
|
||||
end
|
||||
end
|
93
test/csv/parse/test_liberal_parsing.rb
Normal file
93
test/csv/parse/test_liberal_parsing.rb
Normal file
|
@ -0,0 +1,93 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# frozen_string_literal: false
|
||||
|
||||
require_relative "../helper"
|
||||
|
||||
class TestCSVParseLiberalParsing < Test::Unit::TestCase
|
||||
extend DifferentOFS
|
||||
|
||||
def test_middle_quote_start
|
||||
input = '"Johnson, Dwayne",Dwayne "The Rock" Johnson'
|
||||
error = assert_raise(CSV::MalformedCSVError) do
|
||||
CSV.parse_line(input)
|
||||
end
|
||||
assert_equal("Illegal quoting in line 1.",
|
||||
error.message)
|
||||
assert_equal(["Johnson, Dwayne", 'Dwayne "The Rock" Johnson'],
|
||||
CSV.parse_line(input, liberal_parsing: true))
|
||||
end
|
||||
|
||||
def test_middle_quote_end
|
||||
input = '"quoted" field'
|
||||
error = assert_raise(CSV::MalformedCSVError) do
|
||||
CSV.parse_line(input)
|
||||
end
|
||||
assert_equal("Do not allow except col_sep_split_separator " +
|
||||
"after quoted fields in line 1.",
|
||||
error.message)
|
||||
assert_equal(['"quoted" field'],
|
||||
CSV.parse_line(input, liberal_parsing: true))
|
||||
end
|
||||
|
||||
def test_quote_after_column_separator
|
||||
error = assert_raise(CSV::MalformedCSVError) do
|
||||
CSV.parse_line('is,this "three," or four,fields', liberal_parsing: true)
|
||||
end
|
||||
assert_equal("Unclosed quoted field in line 1.",
|
||||
error.message)
|
||||
end
|
||||
|
||||
def test_quote_before_column_separator
|
||||
assert_equal(["is", 'this "three', ' or four"', "fields"],
|
||||
CSV.parse_line('is,this "three, or four",fields',
|
||||
liberal_parsing: true))
|
||||
end
|
||||
|
||||
def test_backslash_quote
|
||||
assert_equal([
|
||||
"1",
|
||||
"\"Hamlet says, \\\"Seems",
|
||||
"\\\" madam! Nay it is; I know not \\\"seems.\\\"\"",
|
||||
],
|
||||
CSV.parse_line('1,' +
|
||||
'"Hamlet says, \"Seems,' +
|
||||
'\" madam! Nay it is; I know not \"seems.\""',
|
||||
liberal_parsing: true))
|
||||
end
|
||||
|
||||
def test_space_quote
|
||||
input = <<~CSV
|
||||
Los Angeles, 34°03'N, 118°15'W
|
||||
New York City, 40°42'46"N, 74°00'21"W
|
||||
Paris, 48°51'24"N, 2°21'03"E
|
||||
CSV
|
||||
assert_equal(
|
||||
[
|
||||
["Los Angeles", " 34°03'N", " 118°15'W"],
|
||||
["New York City", " 40°42'46\"N", " 74°00'21\"W"],
|
||||
["Paris", " 48°51'24\"N", " 2°21'03\"E"],
|
||||
],
|
||||
CSV.parse(input, liberal_parsing: true))
|
||||
end
|
||||
|
||||
def test_double_quote_outside_quote
|
||||
data = %Q{a,""b""}
|
||||
error = assert_raise(CSV::MalformedCSVError) do
|
||||
CSV.parse(data)
|
||||
end
|
||||
assert_equal("Do not allow except col_sep_split_separator " +
|
||||
"after quoted fields in line 1.",
|
||||
error.message)
|
||||
assert_equal([
|
||||
[["a", %Q{""b""}]],
|
||||
[["a", %Q{"b"}]],
|
||||
],
|
||||
[
|
||||
CSV.parse(data, liberal_parsing: true),
|
||||
CSV.parse(data,
|
||||
liberal_parsing: {
|
||||
double_quote_outside_quote: true,
|
||||
}),
|
||||
])
|
||||
end
|
||||
end
|
40
test/csv/parse/test_rewind.rb
Normal file
40
test/csv/parse/test_rewind.rb
Normal file
|
@ -0,0 +1,40 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# frozen_string_literal: false
|
||||
|
||||
require_relative "../helper"
|
||||
|
||||
class TestCSVParseRewind < Test::Unit::TestCase
|
||||
extend DifferentOFS
|
||||
|
||||
def parse(data, options={})
|
||||
csv = CSV.new(data, options)
|
||||
records = csv.to_a
|
||||
csv.rewind
|
||||
[records, csv.to_a]
|
||||
end
|
||||
|
||||
def test_default
|
||||
data = <<-CSV
|
||||
Ruby,2.6.0,script
|
||||
CSV
|
||||
assert_equal([
|
||||
[["Ruby", "2.6.0", "script"]],
|
||||
[["Ruby", "2.6.0", "script"]],
|
||||
],
|
||||
parse(data))
|
||||
end
|
||||
|
||||
def test_have_headers
|
||||
data = <<-CSV
|
||||
Language,Version,Type
|
||||
Ruby,2.6.0,script
|
||||
CSV
|
||||
assert_equal([
|
||||
[CSV::Row.new(["Language", "Version", "Type"],
|
||||
["Ruby", "2.6.0", "script"])],
|
||||
[CSV::Row.new(["Language", "Version", "Type"],
|
||||
["Ruby", "2.6.0", "script"])],
|
||||
],
|
||||
parse(data, headers: true))
|
||||
end
|
||||
end
|
117
test/csv/parse/test_unconverted_fields.rb
Normal file
117
test/csv/parse/test_unconverted_fields.rb
Normal file
|
@ -0,0 +1,117 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# frozen_string_literal: false
|
||||
|
||||
require_relative "../helper"
|
||||
|
||||
class TestCSVParseUnconvertedFields < Test::Unit::TestCase
|
||||
extend DifferentOFS
|
||||
|
||||
def setup
|
||||
super
|
||||
@custom = lambda {|field| /\A:(\S.*?)\s*\Z/ =~ field ? $1.to_sym : field}
|
||||
|
||||
@headers = ["first", "second", "third"]
|
||||
@data = <<-CSV
|
||||
first,second,third
|
||||
1,2,3
|
||||
CSV
|
||||
end
|
||||
|
||||
|
||||
def test_custom
|
||||
row = CSV.parse_line("Numbers,:integer,1,:float,3.015",
|
||||
converters: [:numeric, @custom],
|
||||
unconverted_fields: true)
|
||||
assert_equal([
|
||||
["Numbers", :integer, 1, :float, 3.015],
|
||||
["Numbers", ":integer", "1", ":float", "3.015"],
|
||||
],
|
||||
[
|
||||
row,
|
||||
row.unconverted_fields,
|
||||
])
|
||||
end
|
||||
|
||||
def test_no_fields
|
||||
row = CSV.parse_line("\n",
|
||||
converters: [:numeric, @custom],
|
||||
unconverted_fields: true)
|
||||
assert_equal([
|
||||
[],
|
||||
[],
|
||||
],
|
||||
[
|
||||
row,
|
||||
row.unconverted_fields,
|
||||
])
|
||||
end
|
||||
|
||||
def test_parsed_header
|
||||
row = CSV.parse_line(@data,
|
||||
converters: :numeric,
|
||||
unconverted_fields: true,
|
||||
headers: :first_row)
|
||||
assert_equal([
|
||||
CSV::Row.new(@headers,
|
||||
[1, 2, 3]),
|
||||
["1", "2", "3"],
|
||||
],
|
||||
[
|
||||
row,
|
||||
row.unconverted_fields,
|
||||
])
|
||||
end
|
||||
|
||||
def test_return_headers
|
||||
row = CSV.parse_line(@data,
|
||||
converters: :numeric,
|
||||
unconverted_fields: true,
|
||||
headers: :first_row,
|
||||
return_headers: true)
|
||||
assert_equal([
|
||||
CSV::Row.new(@headers,
|
||||
@headers),
|
||||
@headers,
|
||||
],
|
||||
[
|
||||
row,
|
||||
row.unconverted_fields,
|
||||
])
|
||||
end
|
||||
|
||||
def test_header_converters
|
||||
row = CSV.parse_line(@data,
|
||||
converters: :numeric,
|
||||
unconverted_fields: true,
|
||||
headers: :first_row,
|
||||
return_headers: true,
|
||||
header_converters: :symbol)
|
||||
assert_equal([
|
||||
CSV::Row.new(@headers.collect(&:to_sym),
|
||||
@headers),
|
||||
@headers,
|
||||
],
|
||||
[
|
||||
row,
|
||||
row.unconverted_fields,
|
||||
])
|
||||
end
|
||||
|
||||
def test_specified_headers
|
||||
row = CSV.parse_line("\n",
|
||||
converters: :numeric,
|
||||
unconverted_fields: true,
|
||||
headers: %w{my new headers},
|
||||
return_headers: true,
|
||||
header_converters: :symbol)
|
||||
assert_equal([
|
||||
CSV::Row.new([:my, :new, :headers],
|
||||
["my", "new", "headers"]),
|
||||
[],
|
||||
],
|
||||
[
|
||||
row,
|
||||
row.unconverted_fields,
|
||||
])
|
||||
end
|
||||
end
|
|
@ -1,95 +0,0 @@
|
|||
#!/usr/bin/env ruby -w
|
||||
# encoding: UTF-8
|
||||
# frozen_string_literal: false
|
||||
|
||||
# tc_csv_writing.rb
|
||||
#
|
||||
# Created by James Edward Gray II on 2005-10-31.
|
||||
require_relative "base"
|
||||
|
||||
class TestCSV::Writing < TestCSV
|
||||
extend DifferentOFS
|
||||
|
||||
def test_writing
|
||||
[ ["\t", ["\t"]],
|
||||
["foo,\"\"\"\"\"\",baz", ["foo", "\"\"", "baz"]],
|
||||
["foo,\"\"\"bar\"\"\",baz", ["foo", "\"bar\"", "baz"]],
|
||||
["\"\"\"\n\",\"\"\"\n\"", ["\"\n", "\"\n"]],
|
||||
["foo,\"\r\n\",baz", ["foo", "\r\n", "baz"]],
|
||||
["\"\"", [""]],
|
||||
["foo,\"\"\"\",baz", ["foo", "\"", "baz"]],
|
||||
["foo,\"\r.\n\",baz", ["foo", "\r.\n", "baz"]],
|
||||
["foo,\"\r\",baz", ["foo", "\r", "baz"]],
|
||||
["foo,\"\",baz", ["foo", "", "baz"]],
|
||||
["\",\"", [","]],
|
||||
["foo", ["foo"]],
|
||||
[",,", [nil, nil, nil]],
|
||||
[",", [nil, nil]],
|
||||
["foo,\"\n\",baz", ["foo", "\n", "baz"]],
|
||||
["foo,,baz", ["foo", nil, "baz"]],
|
||||
["\"\"\"\r\",\"\"\"\r\"", ["\"\r", "\"\r"]],
|
||||
["\",\",\",\"", [",", ","]],
|
||||
["foo,bar,", ["foo", "bar", nil]],
|
||||
[",foo,bar", [nil, "foo", "bar"]],
|
||||
["foo,bar", ["foo", "bar"]],
|
||||
[";", [";"]],
|
||||
["\t,\t", ["\t", "\t"]],
|
||||
["foo,\"\r\n\r\",baz", ["foo", "\r\n\r", "baz"]],
|
||||
["foo,\"\r\n\n\",baz", ["foo", "\r\n\n", "baz"]],
|
||||
["foo,\"foo,bar\",baz", ["foo", "foo,bar", "baz"]],
|
||||
[";,;", [";", ";"]],
|
||||
["foo,\"\"\"\"\"\",baz", ["foo", "\"\"", "baz"]],
|
||||
["foo,\"\"\"bar\"\"\",baz", ["foo", "\"bar\"", "baz"]],
|
||||
["foo,\"\r\n\",baz", ["foo", "\r\n", "baz"]],
|
||||
["\"\"", [""]],
|
||||
["foo,\"\"\"\",baz", ["foo", "\"", "baz"]],
|
||||
["foo,\"\r.\n\",baz", ["foo", "\r.\n", "baz"]],
|
||||
["foo,\"\r\",baz", ["foo", "\r", "baz"]],
|
||||
["foo,\"\",baz", ["foo", "", "baz"]],
|
||||
["foo", ["foo"]],
|
||||
[",,", [nil, nil, nil]],
|
||||
[",", [nil, nil]],
|
||||
["foo,\"\n\",baz", ["foo", "\n", "baz"]],
|
||||
["foo,,baz", ["foo", nil, "baz"]],
|
||||
["foo,bar", ["foo", "bar"]],
|
||||
["foo,\"\r\n\n\",baz", ["foo", "\r\n\n", "baz"]],
|
||||
["foo,\"foo,bar\",baz", ["foo", "foo,bar", "baz"]],
|
||||
[%Q{a,b}, ["a", "b"]],
|
||||
[%Q{a,"""b"""}, ["a", "\"b\""]],
|
||||
[%Q{a,"""b"}, ["a", "\"b"]],
|
||||
[%Q{a,"b"""}, ["a", "b\""]],
|
||||
[%Q{a,"\nb"""}, ["a", "\nb\""]],
|
||||
[%Q{a,"""\nb"}, ["a", "\"\nb"]],
|
||||
[%Q{a,"""\nb\n"""}, ["a", "\"\nb\n\""]],
|
||||
[%Q{a,"""\nb\n""",}, ["a", "\"\nb\n\"", nil]],
|
||||
[%Q{a,,,}, ["a", nil, nil, nil]],
|
||||
[%Q{,}, [nil, nil]],
|
||||
[%Q{"",""}, ["", ""]],
|
||||
[%Q{""""}, ["\""]],
|
||||
[%Q{"""",""}, ["\"",""]],
|
||||
[%Q{,""}, [nil,""]],
|
||||
[%Q{,"\r"}, [nil,"\r"]],
|
||||
[%Q{"\r\n,"}, ["\r\n,"]],
|
||||
[%Q{"\r\n,",}, ["\r\n,", nil]] ].each do |test_case|
|
||||
assert_equal(test_case.first + $/, CSV.generate_line(test_case.last))
|
||||
end
|
||||
end
|
||||
|
||||
def test_col_sep
|
||||
assert_equal( "a;b;;c\n", CSV.generate_line( ["a", "b", nil, "c"],
|
||||
col_sep: ";" ) )
|
||||
assert_equal( "a\tb\t\tc\n", CSV.generate_line( ["a", "b", nil, "c"],
|
||||
col_sep: "\t" ) )
|
||||
end
|
||||
|
||||
def test_row_sep
|
||||
assert_equal( "a,b,,c\r\n", CSV.generate_line( ["a", "b", nil, "c"],
|
||||
row_sep: "\r\n" ) )
|
||||
end
|
||||
|
||||
def test_force_quotes
|
||||
assert_equal( %Q{"1","b","","already ""quoted"""\n},
|
||||
CSV.generate_line( [1, "b", nil, %Q{already "quoted"}],
|
||||
force_quotes: true ) )
|
||||
end
|
||||
end
|
|
@ -1,23 +1,13 @@
|
|||
#!/usr/bin/env ruby -w
|
||||
# encoding: UTF-8
|
||||
# -*- coding: utf-8 -*-
|
||||
# frozen_string_literal: false
|
||||
|
||||
# tc_data_converters.rb
|
||||
#
|
||||
# Created by James Edward Gray II on 2005-10-31.
|
||||
require_relative "helper"
|
||||
|
||||
require_relative "base"
|
||||
|
||||
class TestCSV::DataConverters < TestCSV
|
||||
class TestCSVDataConverters < Test::Unit::TestCase
|
||||
extend DifferentOFS
|
||||
|
||||
def setup
|
||||
super
|
||||
@data = "Numbers,:integer,1,:float,3.015"
|
||||
@parser = CSV.new(@data)
|
||||
|
||||
@custom = lambda { |field| field =~ /\A:(\S.*?)\s*\Z/ ? $1.to_sym : field }
|
||||
|
||||
@win_safe_time_str = Time.now.strftime("%a %b %d %H:%M:%S %Y")
|
||||
end
|
||||
|
||||
|
@ -113,230 +103,4 @@ class TestCSV::DataConverters < TestCSV
|
|||
assert_equal(datetime,
|
||||
CSV::Converters[:date_time][iso8601_string])
|
||||
end
|
||||
|
||||
def test_convert_with_builtin_integer
|
||||
# setup parser...
|
||||
assert_respond_to(@parser, :convert)
|
||||
assert_nothing_raised(Exception) { @parser.convert(:integer) }
|
||||
|
||||
# and use
|
||||
assert_equal(["Numbers", ":integer", 1, ":float", "3.015"], @parser.shift)
|
||||
end
|
||||
|
||||
def test_convert_with_builtin_float
|
||||
# setup parser...
|
||||
assert_respond_to(@parser, :convert)
|
||||
assert_nothing_raised(Exception) { @parser.convert(:float) }
|
||||
|
||||
# and use
|
||||
assert_equal(["Numbers", ":integer", 1.0, ":float", 3.015], @parser.shift)
|
||||
end
|
||||
|
||||
def test_convert_order_float_integer
|
||||
# floats first, then integers...
|
||||
assert_nothing_raised(Exception) do
|
||||
@parser.convert(:float)
|
||||
@parser.convert(:integer)
|
||||
end
|
||||
|
||||
# gets us nothing but floats
|
||||
assert_equal( [String, String, Float, String, Float],
|
||||
@parser.shift.map { |field| field.class } )
|
||||
end
|
||||
|
||||
def test_convert_order_integer_float
|
||||
# integers have precendance...
|
||||
assert_nothing_raised(Exception) do
|
||||
@parser.convert(:integer)
|
||||
@parser.convert(:float)
|
||||
end
|
||||
|
||||
# gives us proper number conversion
|
||||
assert_equal( [String, String, 0.class, String, Float],
|
||||
@parser.shift.map { |field| field.class } )
|
||||
end
|
||||
|
||||
def test_builtin_numeric_combo_converter
|
||||
# setup parser...
|
||||
assert_nothing_raised(Exception) { @parser.convert(:numeric) }
|
||||
|
||||
# and use
|
||||
assert_equal( [String, String, 0.class, String, Float],
|
||||
@parser.shift.map { |field| field.class } )
|
||||
end
|
||||
|
||||
def test_builtin_all_nested_combo_converter
|
||||
# setup parser...
|
||||
@data << ",#{@win_safe_time_str}" # add a DateTime field
|
||||
@parser = CSV.new(@data) # reset parser
|
||||
assert_nothing_raised(Exception) { @parser.convert(:all) }
|
||||
|
||||
# and use
|
||||
assert_equal( [String, String, 0.class, String, Float, DateTime],
|
||||
@parser.shift.map { |field| field.class } )
|
||||
end
|
||||
|
||||
def test_convert_with_custom_code
|
||||
# define custom converter...
|
||||
assert_nothing_raised(Exception) do
|
||||
@parser.convert { |field| field =~ /\A:(\S.*?)\s*\Z/ ? $1.to_sym : field }
|
||||
end
|
||||
|
||||
# and use
|
||||
assert_equal(["Numbers", :integer, "1", :float, "3.015"], @parser.shift)
|
||||
end
|
||||
|
||||
def test_convert_with_custom_code_mix
|
||||
# mix built-in and custom...
|
||||
assert_nothing_raised(Exception) { @parser.convert(:numeric) }
|
||||
assert_nothing_raised(Exception) { @parser.convert(&@custom) }
|
||||
|
||||
# and use
|
||||
assert_equal(["Numbers", :integer, 1, :float, 3.015], @parser.shift)
|
||||
end
|
||||
|
||||
def test_convert_with_custom_code_using_field_info
|
||||
# define custom converter that uses field information...
|
||||
assert_nothing_raised(Exception) do
|
||||
@parser.convert do |field, info|
|
||||
assert_equal(1, info.line)
|
||||
info.index == 4 ? Float(field).floor : field
|
||||
end
|
||||
end
|
||||
|
||||
# and use
|
||||
assert_equal(["Numbers", ":integer", "1", ":float", 3], @parser.shift)
|
||||
end
|
||||
|
||||
def test_convert_with_custom_code_using_field_info_header
|
||||
@parser = CSV.new(@data, headers: %w{one two three four five})
|
||||
|
||||
# define custom converter that uses field header information...
|
||||
assert_nothing_raised(Exception) do
|
||||
@parser.convert do |field, info|
|
||||
info.header == "three" ? Integer(field) * 100 : field
|
||||
end
|
||||
end
|
||||
|
||||
# and use
|
||||
assert_equal( ["Numbers", ":integer", 100, ":float", "3.015"],
|
||||
@parser.shift.fields )
|
||||
end
|
||||
|
||||
def test_custom_converter_with_blank_field
|
||||
converter = lambda { |field| field.nil? }
|
||||
row = nil
|
||||
assert_nothing_raised(Exception) do
|
||||
row = CSV.parse_line('nil,', converters: converter)
|
||||
end
|
||||
assert_equal([false, true], row);
|
||||
end
|
||||
|
||||
def test_shortcut_interface
|
||||
assert_equal( ["Numbers", ":integer", 1, ":float", 3.015],
|
||||
CSV.parse_line(@data, converters: :numeric) )
|
||||
|
||||
assert_equal( ["Numbers", ":integer", 1, ":float", 3.015],
|
||||
CSV.parse_line(@data, converters: [:integer, :float]) )
|
||||
|
||||
assert_equal( ["Numbers", :integer, 1, :float, 3.015],
|
||||
CSV.parse_line(@data, converters: [:numeric, @custom]) )
|
||||
end
|
||||
|
||||
def test_unconverted_fields_number
|
||||
row = CSV.parse_line(@data,
|
||||
converters: [:numeric, @custom],
|
||||
unconverted_fields: true)
|
||||
assert_equal([
|
||||
["Numbers", :integer, 1, :float, 3.015],
|
||||
["Numbers", ":integer", "1", ":float", "3.015"],
|
||||
],
|
||||
[
|
||||
row,
|
||||
row.unconverted_fields,
|
||||
])
|
||||
end
|
||||
|
||||
def test_unconverted_fields_empty_line
|
||||
row = CSV.parse_line("\n",
|
||||
converters: [:numeric, @custom],
|
||||
unconverted_fields: true)
|
||||
assert_equal([
|
||||
[],
|
||||
[],
|
||||
],
|
||||
[
|
||||
row,
|
||||
row.unconverted_fields,
|
||||
])
|
||||
end
|
||||
|
||||
def test_unconverted_fields
|
||||
data = <<-CSV
|
||||
first,second,third
|
||||
1,2,3
|
||||
CSV
|
||||
row = nil
|
||||
assert_nothing_raised(Exception) do
|
||||
row = CSV.parse_line( data,
|
||||
converters: :numeric,
|
||||
unconverted_fields: true,
|
||||
headers: :first_row )
|
||||
end
|
||||
assert_not_nil(row)
|
||||
assert_equal([["first", 1], ["second", 2], ["third", 3]], row.to_a)
|
||||
assert_respond_to(row, :unconverted_fields)
|
||||
assert_equal(%w{1 2 3}, row.unconverted_fields)
|
||||
|
||||
assert_nothing_raised(Exception) do
|
||||
row = CSV.parse_line( data,
|
||||
converters: :numeric,
|
||||
unconverted_fields: true,
|
||||
headers: :first_row,
|
||||
return_headers: true )
|
||||
end
|
||||
assert_not_nil(row)
|
||||
assert_equal( [%w{first first}, %w{second second}, %w{third third}],
|
||||
row.to_a )
|
||||
assert_respond_to(row, :unconverted_fields)
|
||||
assert_equal(%w{first second third}, row.unconverted_fields)
|
||||
|
||||
assert_nothing_raised(Exception) do
|
||||
row = CSV.parse_line( data,
|
||||
converters: :numeric,
|
||||
unconverted_fields: true,
|
||||
headers: :first_row,
|
||||
return_headers: true,
|
||||
header_converters: :symbol )
|
||||
end
|
||||
assert_not_nil(row)
|
||||
assert_equal( [[:first, "first"], [:second, "second"], [:third, "third"]],
|
||||
row.to_a )
|
||||
assert_respond_to(row, :unconverted_fields)
|
||||
assert_equal(%w{first second third}, row.unconverted_fields)
|
||||
|
||||
assert_nothing_raised(Exception) do
|
||||
row = CSV.parse_line( data,
|
||||
converters: :numeric,
|
||||
unconverted_fields: true,
|
||||
headers: %w{my new headers},
|
||||
return_headers: true,
|
||||
header_converters: :symbol )
|
||||
end
|
||||
assert_not_nil(row)
|
||||
assert_equal( [[:my, "my"], [:new, "new"], [:headers, "headers"]],
|
||||
row.to_a )
|
||||
assert_respond_to(row, :unconverted_fields)
|
||||
assert_equal(Array.new, row.unconverted_fields)
|
||||
end
|
||||
|
||||
def test_nil_value
|
||||
assert_equal(["nil", "", "a"],
|
||||
CSV.parse_line(',"",a', nil_value: "nil"))
|
||||
end
|
||||
|
||||
def test_empty_value
|
||||
assert_equal([nil, "empty", "a"],
|
||||
CSV.parse_line(',"",a', empty_value: "empty"))
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,14 +1,9 @@
|
|||
#!/usr/bin/env ruby -w
|
||||
# encoding: UTF-8
|
||||
# -*- coding: utf-8 -*-
|
||||
# frozen_string_literal: false
|
||||
|
||||
# tc_encodings.rb
|
||||
#
|
||||
# Created by James Edward Gray II on 2005-10-31.
|
||||
require_relative "helper"
|
||||
|
||||
require_relative "base"
|
||||
|
||||
class TestCSV::Encodings < TestCSV
|
||||
class TestCSVEncodings < Test::Unit::TestCase
|
||||
extend DifferentOFS
|
||||
|
||||
def setup
|
||||
|
|
|
@ -1,20 +1,15 @@
|
|||
#!/usr/bin/env ruby -w
|
||||
# encoding: UTF-8
|
||||
# -*- coding: utf-8 -*-
|
||||
# frozen_string_literal: false
|
||||
|
||||
# tc_features.rb
|
||||
#
|
||||
# Created by James Edward Gray II on 2005-10-31.
|
||||
|
||||
begin
|
||||
require "zlib"
|
||||
rescue LoadError
|
||||
end
|
||||
|
||||
require_relative "base"
|
||||
require_relative "helper"
|
||||
require "tempfile"
|
||||
|
||||
class TestCSV::Features < TestCSV
|
||||
class TestCSVFeatures < Test::Unit::TestCase
|
||||
extend DifferentOFS
|
||||
|
||||
TEST_CASES = [ [%Q{a,b}, ["a", "b"]],
|
||||
|
@ -168,70 +163,6 @@ line,4,jkl
|
|||
assert_equal(3, count)
|
||||
end
|
||||
|
||||
def test_liberal_parsing_middle_quote_start
|
||||
input = '"Johnson, Dwayne",Dwayne "The Rock" Johnson'
|
||||
error = assert_raise(CSV::MalformedCSVError) do
|
||||
CSV.parse_line(input)
|
||||
end
|
||||
assert_equal("Illegal quoting in line 1.",
|
||||
error.message)
|
||||
assert_equal(["Johnson, Dwayne", 'Dwayne "The Rock" Johnson'],
|
||||
CSV.parse_line(input, liberal_parsing: true))
|
||||
end
|
||||
|
||||
def test_liberal_parsing_middle_quote_end
|
||||
input = '"quoted" field'
|
||||
error = assert_raise(CSV::MalformedCSVError) do
|
||||
CSV.parse_line(input)
|
||||
end
|
||||
assert_equal("Do not allow except col_sep_split_separator " +
|
||||
"after quoted fields in line 1.",
|
||||
error.message)
|
||||
assert_equal(['"quoted" field'],
|
||||
CSV.parse_line(input, liberal_parsing: true))
|
||||
end
|
||||
|
||||
def test_liberal_parsing_quote_after_column_separator
|
||||
error = assert_raise(CSV::MalformedCSVError) do
|
||||
CSV.parse_line('is,this "three," or four,fields', liberal_parsing: true)
|
||||
end
|
||||
assert_equal("Unclosed quoted field in line 1.",
|
||||
error.message)
|
||||
end
|
||||
|
||||
def test_liberal_parsing_quote_before_column_separator
|
||||
assert_equal(["is", 'this "three', ' or four"', "fields"],
|
||||
CSV.parse_line('is,this "three, or four",fields',
|
||||
liberal_parsing: true))
|
||||
end
|
||||
|
||||
def test_liberal_parsing_backslash_quote
|
||||
assert_equal([
|
||||
"1",
|
||||
"\"Hamlet says, \\\"Seems",
|
||||
"\\\" madam! Nay it is; I know not \\\"seems.\\\"\"",
|
||||
],
|
||||
CSV.parse_line('1,' +
|
||||
'"Hamlet says, \"Seems,' +
|
||||
'\" madam! Nay it is; I know not \"seems.\""',
|
||||
liberal_parsing: true))
|
||||
end
|
||||
|
||||
def test_liberal_parsing_space_quote
|
||||
input = <<~CSV
|
||||
Los Angeles, 34°03'N, 118°15'W
|
||||
New York City, 40°42'46"N, 74°00'21"W
|
||||
Paris, 48°51'24"N, 2°21'03"E
|
||||
CSV
|
||||
assert_equal(
|
||||
[
|
||||
["Los Angeles", " 34°03'N", " 118°15'W"],
|
||||
["New York City", " 40°42'46\"N", " 74°00'21\"W"],
|
||||
["Paris", " 48°51'24\"N", " 2°21'03\"E"],
|
||||
],
|
||||
CSV.parse(input, liberal_parsing: true))
|
||||
end
|
||||
|
||||
def test_csv_behavior_readers
|
||||
%w[ unconverted_fields return_headers write_headers
|
||||
skip_blanks force_quotes ].each do |behavior|
|
||||
|
@ -289,16 +220,6 @@ line,4,jkl
|
|||
csv.each {|row| assert_predicate row, :header_row?}
|
||||
end
|
||||
|
||||
# reported by Dave Burt
|
||||
def test_leading_empty_fields_with_multibyte_col_sep
|
||||
data = <<-CSV
|
||||
<=><=>A<=>B<=>C
|
||||
1<=>2<=>3
|
||||
CSV
|
||||
parsed = CSV.parse(data, col_sep: "<=>")
|
||||
assert_equal([[nil, nil, "A", "B", "C"], ["1", "2", "3"]], parsed)
|
||||
end
|
||||
|
||||
def test_gzip_reader
|
||||
zipped = nil
|
||||
assert_nothing_raised(NoMethodError) do
|
||||
|
|
|
@ -1,15 +1,10 @@
|
|||
#!/usr/bin/env ruby -w
|
||||
# encoding: UTF-8
|
||||
# -*- coding: utf-8 -*-
|
||||
# frozen_string_literal: false
|
||||
|
||||
# tc_interface.rb
|
||||
#
|
||||
# Created by James Edward Gray II on 2005-10-31.
|
||||
|
||||
require_relative "base"
|
||||
require_relative "helper"
|
||||
require "tempfile"
|
||||
|
||||
class TestCSV::Interface < TestCSV
|
||||
class TestCSVInterface < Test::Unit::TestCase
|
||||
extend DifferentOFS
|
||||
|
||||
def setup
|
||||
|
|
|
@ -1,14 +1,9 @@
|
|||
#!/usr/bin/env ruby -w
|
||||
# encoding: UTF-8
|
||||
# -*- coding: utf-8 -*-
|
||||
# frozen_string_literal: false
|
||||
|
||||
# tc_row.rb
|
||||
#
|
||||
# Created by James Edward Gray II on 2005-10-31.
|
||||
require_relative "helper"
|
||||
|
||||
require_relative "base"
|
||||
|
||||
class TestCSV::Row < TestCSV
|
||||
class TestCSVRow < Test::Unit::TestCase
|
||||
extend DifferentOFS
|
||||
|
||||
def setup
|
||||
|
@ -105,6 +100,19 @@ class TestCSV::Row < TestCSV
|
|||
def test_has_key?
|
||||
assert_equal(true, @row.has_key?('B'))
|
||||
assert_equal(false, @row.has_key?('foo'))
|
||||
|
||||
# aliases
|
||||
assert_equal(true, @row.header?('B'))
|
||||
assert_equal(false, @row.header?('foo'))
|
||||
|
||||
assert_equal(true, @row.include?('B'))
|
||||
assert_equal(false, @row.include?('foo'))
|
||||
|
||||
assert_equal(true, @row.member?('B'))
|
||||
assert_equal(false, @row.member?('foo'))
|
||||
|
||||
assert_equal(true, @row.key?('B'))
|
||||
assert_equal(false, @row.key?('foo'))
|
||||
end
|
||||
|
||||
def test_set_field
|
||||
|
@ -261,12 +269,6 @@ class TestCSV::Row < TestCSV
|
|||
end
|
||||
|
||||
def test_queries
|
||||
# headers
|
||||
assert_send([@row, :header?, "A"])
|
||||
assert_send([@row, :header?, "C"])
|
||||
assert_not_send([@row, :header?, "Z"])
|
||||
assert_send([@row, :include?, "A"]) # alias
|
||||
|
||||
# fields
|
||||
assert(@row.field?(4))
|
||||
assert(@row.field?(nil))
|
||||
|
|
|
@ -1,14 +1,9 @@
|
|||
#!/usr/bin/env ruby -w
|
||||
# encoding: UTF-8
|
||||
# -*- coding: utf-8 -*-
|
||||
# frozen_string_literal: false
|
||||
|
||||
# tc_table.rb
|
||||
#
|
||||
# Created by James Edward Gray II on 2005-10-31.
|
||||
require_relative "helper"
|
||||
|
||||
require_relative "base"
|
||||
|
||||
class TestCSV::Table < TestCSV
|
||||
class TestCSVTable < Test::Unit::TestCase
|
||||
extend DifferentOFS
|
||||
|
||||
def setup
|
||||
|
@ -69,6 +64,13 @@ class TestCSV::Table < TestCSV
|
|||
assert_equal(%w[A B C], @header_only_table.headers)
|
||||
end
|
||||
|
||||
def test_headers_modified_by_row
|
||||
table = CSV::Table.new([], headers: ["A", "B"])
|
||||
table << ["a", "b"]
|
||||
table.first << {"C" => "c"}
|
||||
assert_equal(["A", "B", "C"], table.headers)
|
||||
end
|
||||
|
||||
def test_index
|
||||
##################
|
||||
### Mixed Mode ###
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
#!/usr/bin/env ruby -w
|
||||
# encoding: UTF-8
|
||||
# frozen_string_literal: false
|
||||
|
||||
# ts_all.rb
|
||||
#
|
||||
# Created by James Edward Gray II on 2005-10-31.
|
||||
|
||||
require "test/unit"
|
||||
|
||||
require "test_csv_parsing"
|
||||
require "test_features"
|
||||
require "test_interface"
|
||||
require "test_csv_writing"
|
||||
require "test_data_converters"
|
||||
require "test_row"
|
||||
require "test_table"
|
||||
require "test_headers"
|
||||
require "test_encodings"
|
228
test/csv/write/test_general.rb
Normal file
228
test/csv/write/test_general.rb
Normal file
|
@ -0,0 +1,228 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# frozen_string_literal: false
|
||||
|
||||
require_relative "../helper"
|
||||
|
||||
module TestCSVWriteGeneral
|
||||
def test_tab
|
||||
assert_equal("\t#{$INPUT_RECORD_SEPARATOR}",
|
||||
generate_line(["\t"]))
|
||||
end
|
||||
|
||||
def test_quote_character
|
||||
assert_equal(%Q[foo,"""",baz#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line(["foo", %Q["], "baz"]))
|
||||
end
|
||||
|
||||
def test_quote_character_double
|
||||
assert_equal(%Q[foo,"""""",baz#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line(["foo", %Q[""], "baz"]))
|
||||
end
|
||||
|
||||
def test_quote
|
||||
assert_equal(%Q[foo,"""bar""",baz#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line(["foo", %Q["bar"], "baz"]))
|
||||
end
|
||||
|
||||
def test_quote_lf
|
||||
assert_equal(%Q["""\n","""\n"#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line([%Q["\n], %Q["\n]]))
|
||||
end
|
||||
|
||||
def test_quote_cr
|
||||
assert_equal(%Q["""\r","""\r"#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line([%Q["\r], %Q["\r]]))
|
||||
end
|
||||
|
||||
def test_quote_last
|
||||
assert_equal(%Q[foo,"bar"""#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line(["foo", %Q[bar"]]))
|
||||
end
|
||||
|
||||
def test_quote_lf_last
|
||||
assert_equal(%Q[foo,"\nbar"""#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line(["foo", %Q[\nbar"]]))
|
||||
end
|
||||
|
||||
def test_quote_lf_value_lf
|
||||
assert_equal(%Q[foo,"""\nbar\n"""#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line(["foo", %Q["\nbar\n"]]))
|
||||
end
|
||||
|
||||
def test_quote_lf_value_lf_nil
|
||||
assert_equal(%Q[foo,"""\nbar\n""",#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line(["foo", %Q["\nbar\n"], nil]))
|
||||
end
|
||||
|
||||
def test_cr
|
||||
assert_equal(%Q[foo,"\r",baz#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line(["foo", "\r", "baz"]))
|
||||
end
|
||||
|
||||
def test_lf
|
||||
assert_equal(%Q[foo,"\n",baz#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line(["foo", "\n", "baz"]))
|
||||
end
|
||||
|
||||
def test_cr_lf
|
||||
assert_equal(%Q[foo,"\r\n",baz#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line(["foo", "\r\n", "baz"]))
|
||||
end
|
||||
|
||||
def test_cr_dot_lf
|
||||
assert_equal(%Q[foo,"\r.\n",baz#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line(["foo", "\r.\n", "baz"]))
|
||||
end
|
||||
|
||||
def test_cr_lf_cr
|
||||
assert_equal(%Q[foo,"\r\n\r",baz#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line(["foo", "\r\n\r", "baz"]))
|
||||
end
|
||||
|
||||
def test_cr_lf_lf
|
||||
assert_equal(%Q[foo,"\r\n\n",baz#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line(["foo", "\r\n\n", "baz"]))
|
||||
end
|
||||
|
||||
def test_cr_lf_comma
|
||||
assert_equal(%Q["\r\n,"#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line(["\r\n,"]))
|
||||
end
|
||||
|
||||
def test_cr_lf_comma_nil
|
||||
assert_equal(%Q["\r\n,",#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line(["\r\n,", nil]))
|
||||
end
|
||||
|
||||
def test_comma
|
||||
assert_equal(%Q[","#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line([","]))
|
||||
end
|
||||
|
||||
def test_comma_double
|
||||
assert_equal(%Q[",",","#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line([",", ","]))
|
||||
end
|
||||
|
||||
def test_comma_and_value
|
||||
assert_equal(%Q[foo,"foo,bar",baz#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line(["foo", "foo,bar", "baz"]))
|
||||
end
|
||||
|
||||
def test_one_element
|
||||
assert_equal(%Q[foo#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line(["foo"]))
|
||||
end
|
||||
|
||||
def test_nil_values_only
|
||||
assert_equal(%Q[,,#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line([nil, nil, nil]))
|
||||
end
|
||||
|
||||
def test_nil_double_only
|
||||
assert_equal(%Q[,#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line([nil, nil]))
|
||||
end
|
||||
|
||||
def test_nil_values
|
||||
assert_equal(%Q[foo,,,#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line(["foo", nil, nil, nil]))
|
||||
end
|
||||
|
||||
def test_nil_value_first
|
||||
assert_equal(%Q[,foo,baz#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line([nil, "foo", "baz"]))
|
||||
end
|
||||
|
||||
def test_nil_value_middle
|
||||
assert_equal(%Q[foo,,baz#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line(["foo", nil, "baz"]))
|
||||
end
|
||||
|
||||
def test_nil_value_last
|
||||
assert_equal(%Q[foo,baz,#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line(["foo", "baz", nil]))
|
||||
end
|
||||
|
||||
def test_nil_empty
|
||||
assert_equal(%Q[,""#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line([nil, ""]))
|
||||
end
|
||||
|
||||
def test_nil_cr
|
||||
assert_equal(%Q[,"\r"#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line([nil, "\r"]))
|
||||
end
|
||||
|
||||
def test_values
|
||||
assert_equal(%Q[foo,bar#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line(["foo", "bar"]))
|
||||
end
|
||||
|
||||
def test_semi_colon
|
||||
assert_equal(%Q[;#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line([";"]))
|
||||
end
|
||||
|
||||
def test_semi_colon_values
|
||||
assert_equal(%Q[;,;#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line([";", ";"]))
|
||||
end
|
||||
|
||||
def test_tab_values
|
||||
assert_equal(%Q[\t,\t#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line(["\t", "\t"]))
|
||||
end
|
||||
|
||||
def test_col_sep
|
||||
assert_equal(%Q[a;b;;c#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line(["a", "b", nil, "c"],
|
||||
col_sep: ";"))
|
||||
assert_equal(%Q[a\tb\t\tc#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line(["a", "b", nil, "c"],
|
||||
col_sep: "\t"))
|
||||
end
|
||||
|
||||
def test_row_sep
|
||||
assert_equal(%Q[a,b,,c\r\n],
|
||||
generate_line(["a", "b", nil, "c"],
|
||||
row_sep: "\r\n"))
|
||||
end
|
||||
|
||||
def test_force_quotes
|
||||
assert_equal(%Q["1","b","","already ""quoted"""#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line([1, "b", nil, %Q{already "quoted"}],
|
||||
force_quotes: true))
|
||||
end
|
||||
|
||||
def test_encoding_utf8
|
||||
assert_equal(%Q[あ,い,う#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line(["あ" , "い", "う"]))
|
||||
end
|
||||
|
||||
def test_encoding_euc_jp
|
||||
row = ["あ", "い", "う"].collect {|field| field.encode("EUC-JP")}
|
||||
assert_equal(%Q[あ,い,う#{$INPUT_RECORD_SEPARATOR}].encode("EUC-JP"),
|
||||
generate_line(row))
|
||||
end
|
||||
end
|
||||
|
||||
class TestCSVWriteGeneralGenerateLine < Test::Unit::TestCase
|
||||
include TestCSVWriteGeneral
|
||||
extend DifferentOFS
|
||||
|
||||
def generate_line(row, **kwargs)
|
||||
CSV.generate_line(row, **kwargs)
|
||||
end
|
||||
end
|
||||
|
||||
class TestCSVWriteGeneralGenerate < Test::Unit::TestCase
|
||||
include TestCSVWriteGeneral
|
||||
extend DifferentOFS
|
||||
|
||||
def generate_line(row, **kwargs)
|
||||
CSV.generate(**kwargs) do |csv|
|
||||
csv << row
|
||||
end
|
||||
end
|
||||
end
|
70
test/csv/write/test_quote_empty.rb
Normal file
70
test/csv/write/test_quote_empty.rb
Normal file
|
@ -0,0 +1,70 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# frozen_string_literal: false
|
||||
|
||||
require_relative "../helper"
|
||||
|
||||
module TestCSVWriteQuoteEmpty
|
||||
def test_quote_empty_default
|
||||
assert_equal(%Q["""",""#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line([%Q["], ""]))
|
||||
end
|
||||
|
||||
def test_quote_empty_false
|
||||
assert_equal(%Q["""",#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line([%Q["], ""],
|
||||
quote_empty: false))
|
||||
end
|
||||
|
||||
def test_empty_default
|
||||
assert_equal(%Q[foo,"",baz#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line(["foo", "", "baz"]))
|
||||
end
|
||||
|
||||
def test_empty_false
|
||||
assert_equal(%Q[foo,,baz#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line(["foo", "", "baz"],
|
||||
quote_empty: false))
|
||||
end
|
||||
|
||||
def test_empty_only_default
|
||||
assert_equal(%Q[""#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line([""]))
|
||||
end
|
||||
|
||||
def test_empty_only_false
|
||||
assert_equal(%Q[#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line([""],
|
||||
quote_empty: false))
|
||||
end
|
||||
|
||||
def test_empty_double_default
|
||||
assert_equal(%Q["",""#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line(["", ""]))
|
||||
end
|
||||
|
||||
def test_empty_double_false
|
||||
assert_equal(%Q[,#{$INPUT_RECORD_SEPARATOR}],
|
||||
generate_line(["", ""],
|
||||
quote_empty: false))
|
||||
end
|
||||
end
|
||||
|
||||
class TestCSVWriteQuoteEmptyGenerateLine < Test::Unit::TestCase
|
||||
include TestCSVWriteQuoteEmpty
|
||||
extend DifferentOFS
|
||||
|
||||
def generate_line(row, **kwargs)
|
||||
CSV.generate_line(row, **kwargs)
|
||||
end
|
||||
end
|
||||
|
||||
class TestCSVWriteQuoteEmptyGenerate < Test::Unit::TestCase
|
||||
include TestCSVWriteQuoteEmpty
|
||||
extend DifferentOFS
|
||||
|
||||
def generate_line(row, **kwargs)
|
||||
CSV.generate(**kwargs) do |csv|
|
||||
csv << row
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue