From 5c1941a9be56a979c27d740370b781882d344f79 Mon Sep 17 00:00:00 2001 From: hsbt Date: Wed, 9 May 2018 04:39:16 +0000 Subject: Merge csv-1.0.2 from upstream. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63364 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- test/csv/test_csv_parsing.rb | 16 ++++-- test/csv/test_csv_writing.rb | 5 +- test/csv/test_data_converters.rb | 69 +++++++++++++++++++++++--- test/csv/test_encodings.rb | 20 ++++++-- test/csv/test_features.rb | 18 +++---- test/csv/test_headers.rb | 4 +- test/csv/test_interface.rb | 56 +++++++++++++++++++-- test/csv/test_row.rb | 50 +++++++++++++++++-- test/csv/test_table.rb | 103 +++++++++++++++++++++++++++++++++++++-- test/csv/ts_all.rb | 4 +- 10 files changed, 302 insertions(+), 43 deletions(-) (limited to 'test') diff --git a/test/csv/test_csv_parsing.rb b/test/csv/test_csv_parsing.rb index 547e70e933..ab8e97f4bb 100755 --- a/test/csv/test_csv_parsing.rb +++ b/test/csv/test_csv_parsing.rb @@ -4,9 +4,7 @@ # tc_csv_parsing.rb # -# Created by James Edward Gray II on 2005-10-31. -# Copyright 2005 James Edward Gray II. You can redistribute or modify this code -# under the terms of Ruby's license. +# Created by James Edward Gray II on 2005-10-31. require "timeout" @@ -168,7 +166,7 @@ class TestCSV::Parsing < TestCSV assert_send([csv.lineno, :<, 4]) end rescue CSV::MalformedCSVError - assert_equal( "Unquoted fields do not allow \\r or \\n (line 4).", + assert_equal( "Unquoted fields do not allow \\r or \\n in line 4.", $!.message ) end @@ -231,6 +229,16 @@ class TestCSV::Parsing < TestCSV 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 + private def assert_parse_errors_out(*args) diff --git a/test/csv/test_csv_writing.rb b/test/csv/test_csv_writing.rb index de82dae244..e1c02c1fb9 100755 --- a/test/csv/test_csv_writing.rb +++ b/test/csv/test_csv_writing.rb @@ -4,10 +4,7 @@ # tc_csv_writing.rb # -# Created by James Edward Gray II on 2005-10-31. -# Copyright 2005 James Edward Gray II. You can redistribute or modify this code -# under the terms of Ruby's license. - +# Created by James Edward Gray II on 2005-10-31. require_relative "base" class TestCSV::Writing < TestCSV diff --git a/test/csv/test_data_converters.rb b/test/csv/test_data_converters.rb index 0786ca6d0f..04970cd461 100755 --- a/test/csv/test_data_converters.rb +++ b/test/csv/test_data_converters.rb @@ -4,9 +4,7 @@ # tc_data_converters.rb # -# Created by James Edward Gray II on 2005-10-31. -# Copyright 2005 James Edward Gray II. You can redistribute or modify this code -# under the terms of Ruby's license. +# Created by James Edward Gray II on 2005-10-31. require_relative "base" @@ -67,6 +65,55 @@ class TestCSV::DataConverters < TestCSV assert_instance_of(String, CSV::Converters[:date_time]["junk"]) end + def test_builtin_date_time_converter_iso8601_date + iso8601_string = "2018-01-14" + datetime = DateTime.new(2018, 1, 14) + assert_equal(datetime, + CSV::Converters[:date_time][iso8601_string]) + end + + def test_builtin_date_time_converter_iso8601_minute + iso8601_string = "2018-01-14T22:25" + datetime = DateTime.new(2018, 1, 14, 22, 25) + assert_equal(datetime, + CSV::Converters[:date_time][iso8601_string]) + end + + def test_builtin_date_time_converter_iso8601_second + iso8601_string = "2018-01-14T22:25:19" + datetime = DateTime.new(2018, 1, 14, 22, 25, 19) + assert_equal(datetime, + CSV::Converters[:date_time][iso8601_string]) + end + + def test_builtin_date_time_converter_iso8601_under_second + iso8601_string = "2018-01-14T22:25:19.1" + datetime = DateTime.new(2018, 1, 14, 22, 25, 19.1) + assert_equal(datetime, + CSV::Converters[:date_time][iso8601_string]) + end + + def test_builtin_date_time_converter_iso8601_under_second_offset + iso8601_string = "2018-01-14T22:25:19.1+09:00" + datetime = DateTime.new(2018, 1, 14, 22, 25, 19.1, "+9") + assert_equal(datetime, + CSV::Converters[:date_time][iso8601_string]) + end + + def test_builtin_date_time_converter_iso8601_offset + iso8601_string = "2018-01-14T22:25:19+09:00" + datetime = DateTime.new(2018, 1, 14, 22, 25, 19, "+9") + assert_equal(datetime, + CSV::Converters[:date_time][iso8601_string]) + end + + def test_builtin_date_time_converter_iso8601_utc + iso8601_string = "2018-01-14T22:25:19Z" + datetime = DateTime.new(2018, 1, 14, 22, 25, 19) + assert_equal(datetime, + CSV::Converters[:date_time][iso8601_string]) + end + def test_convert_with_builtin_integer # setup parser... assert_respond_to(@parser, :convert) @@ -105,7 +152,7 @@ class TestCSV::DataConverters < TestCSV end # gives us proper number conversion - assert_equal( [String, String, Integer, String, Float], + assert_equal( [String, String, 0.class, String, Float], @parser.shift.map { |field| field.class } ) end @@ -114,7 +161,7 @@ class TestCSV::DataConverters < TestCSV assert_nothing_raised(Exception) { @parser.convert(:numeric) } # and use - assert_equal( [String, String, Integer, String, Float], + assert_equal( [String, String, 0.class, String, Float], @parser.shift.map { |field| field.class } ) end @@ -125,7 +172,7 @@ class TestCSV::DataConverters < TestCSV assert_nothing_raised(Exception) { @parser.convert(:all) } # and use - assert_equal( [String, String, Integer, String, Float, DateTime], + assert_equal( [String, String, 0.class, String, Float, DateTime], @parser.shift.map { |field| field.class } ) end @@ -270,4 +317,14 @@ class TestCSV::DataConverters < TestCSV 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 diff --git a/test/csv/test_encodings.rb b/test/csv/test_encodings.rb index 7460a3ff34..fcad90e007 100755 --- a/test/csv/test_encodings.rb +++ b/test/csv/test_encodings.rb @@ -4,9 +4,7 @@ # tc_encodings.rb # -# Created by James Edward Gray II on 2008-09-13. -# Copyright 2008 James Edward Gray II. You can redistribute or modify this code -# under the terms of Ruby's license. +# Created by James Edward Gray II on 2005-10-31. require_relative "base" @@ -256,6 +254,22 @@ class TestCSV::Encodings < TestCSV assert_equal(["foo,\u3042\n".encode(Encoding::Windows_31J), Encoding::Windows_31J], [s, s.encoding], bug9766) end + def test_row_separator_detection_with_invalid_encoding + csv = CSV.new("invalid,\xF8\r\nvalid,x\r\n".force_encoding("UTF-8"), + encoding: "UTF-8") + assert_equal("\r\n", csv.row_sep) + end + + def test_invalid_encoding_row_error + csv = CSV.new("invalid,\xF8\r\nvalid,x\r\n".force_encoding("UTF-8"), + encoding: "UTF-8") + error = assert_raise(CSV::MalformedCSVError) do + csv.shift + end + assert_equal("Invalid byte sequence in UTF-8 in line 1.", + error.message) + end + private def assert_parses(fields, encoding, options = { }) diff --git a/test/csv/test_features.rb b/test/csv/test_features.rb index 6dc6d34d46..a851c908f0 100755 --- a/test/csv/test_features.rb +++ b/test/csv/test_features.rb @@ -4,9 +4,7 @@ # tc_features.rb # -# Created by James Edward Gray II on 2005-10-31. -# Copyright 2005 James Edward Gray II. You can redistribute or modify this code -# under the terms of Ruby's license. +# Created by James Edward Gray II on 2005-10-31. begin require "zlib" @@ -313,7 +311,7 @@ class TestCSV::Features < TestCSV def test_inspect_encoding_is_ascii_compatible csv = CSV.new("one,two,three\n1,2,3\n".encode("UTF-16BE")) assert_send([Encoding, :compatible?, - Encoding.find("US-ASCII"), csv.inspect.encoding], + Encoding.find("US-ASCII"), csv.inspect.encoding], "inspect() was not ASCII compatible.") end @@ -321,7 +319,7 @@ class TestCSV::Features < TestCSV assert_not_nil(CSV::VERSION) assert_instance_of(String, CSV::VERSION) assert_predicate(CSV::VERSION, :frozen?) - assert_match(/\A\d\.\d\.\d\Z/, CSV::VERSION) + assert_match(/\A\d\.\d\.\d\z/, CSV::VERSION) end def test_accepts_comment_skip_lines_option @@ -352,11 +350,13 @@ class TestCSV::Features < TestCSV end def test_comment_rows_are_ignored_with_heredoc - c = CSV.new(<<~EOL, skip_lines: ".") - 1,foo - .2,bar - 3,baz + sample_data = <<~EOL + 1,foo + .2,bar + 3,baz EOL + + c = CSV.new(sample_data, skip_lines: ".") assert_equal [["1", "foo"], ["3", "baz"]], c.each.to_a end diff --git a/test/csv/test_headers.rb b/test/csv/test_headers.rb index 5ec8932d95..94f4359671 100755 --- a/test/csv/test_headers.rb +++ b/test/csv/test_headers.rb @@ -4,9 +4,7 @@ # tc_headers.rb # -# Created by James Edward Gray II on 2005-10-31. -# Copyright 2005 James Edward Gray II. You can redistribute or modify this code -# under the terms of Ruby's license. +# Created by James Edward Gray II on 2005-10-31. require_relative "base" diff --git a/test/csv/test_interface.rb b/test/csv/test_interface.rb index be27fcd616..912e2ec7f5 100755 --- a/test/csv/test_interface.rb +++ b/test/csv/test_interface.rb @@ -4,9 +4,7 @@ # tc_interface.rb # -# Created by James Edward Gray II on 2005-10-31. -# Copyright 2005 James Edward Gray II. You can redistribute or modify this code -# under the terms of Ruby's license. +# Created by James Edward Gray II on 2005-10-31. require_relative "base" require "tempfile" @@ -64,6 +62,55 @@ class TestCSV::Interface < TestCSV assert_equal("Return value.", ret) end + def test_open_encoding_valid + # U+1F600 GRINNING FACE + # U+1F601 GRINNING FACE WITH SMILING EYES + File.open(@path, "w") do |file| + file << "\u{1F600},\u{1F601}" + end + CSV.open(@path, encoding: "utf-8") do |csv| + assert_equal([["\u{1F600}", "\u{1F601}"]], + csv.to_a) + end + end + + def test_open_encoding_invalid + # U+1F600 GRINNING FACE + # U+1F601 GRINNING FACE WITH SMILING EYES + File.open(@path, "w") do |file| + file << "\u{1F600},\u{1F601}" + end + CSV.open(@path, encoding: "EUC-JP") do |csv| + error = assert_raise(CSV::MalformedCSVError) do + csv.shift + end + assert_equal("Invalid byte sequence in EUC-JP in line 1.", + error.message) + end + end + + def test_open_encoding_nonexistent + _output, error = capture_io do + CSV.open(@path, encoding: "nonexistent") do + end + end + assert_equal("path:0: warning: Unsupported encoding nonexistent ignored\n", + error.gsub(/\A.+:\d+: /, "path:0: ")) + end + + def test_open_encoding_utf_8_with_bom + # U+FEFF ZERO WIDTH NO-BREAK SPACE, BOM + # U+1F600 GRINNING FACE + # U+1F601 GRINNING FACE WITH SMILING EYES + File.open(@path, "w") do |file| + file << "\u{FEFF}\u{1F600},\u{1F601}" + end + CSV.open(@path, encoding: "bom|utf-8") do |csv| + assert_equal([["\u{1F600}", "\u{1F601}"]], + csv.to_a) + end + end + def test_parse data = File.binread(@path) assert_equal( @expected, @@ -161,6 +208,9 @@ class TestCSV::Interface < TestCSV assert_equal(csv, csv << ["last", %Q{"row"}]) end assert_equal(%Q{1,2,3\n4,,5\nlast,"""row"""\n}, str) + + out = CSV.generate("test") { |csv| csv << ["row"] } + assert_equal("testrow\n", out) end def test_generate_line diff --git a/test/csv/test_row.rb b/test/csv/test_row.rb index 1cb851b027..23df4d4fe6 100755 --- a/test/csv/test_row.rb +++ b/test/csv/test_row.rb @@ -4,9 +4,7 @@ # tc_row.rb # -# Created by James Edward Gray II on 2005-10-31. -# Copyright 2005 James Edward Gray II. You can redistribute or modify this code -# under the terms of Ruby's license. +# Created by James Edward Gray II on 2005-10-31. require_relative "base" @@ -304,6 +302,17 @@ class TestCSV::Row < TestCSV end end + def test_each_pair + assert_equal([ + ["A", 1], + ["B", 2], + ["C", 3], + ["A", 4], + ["A", nil], + ], + @row.each_pair.to_a) + end + def test_enumerable assert_equal( [["A", 1], ["A", 4], ["A", nil]], @row.select { |pair| pair.first == "A" } ) @@ -323,7 +332,7 @@ class TestCSV::Row < TestCSV def test_to_hash hash = @row.to_hash - assert_equal({"A" => nil, "B" => 2, "C" => 3}, hash) + assert_equal({"A" => @row["A"], "B" => @row["B"], "C" => @row["C"]}, hash) hash.keys.each_with_index do |string_key, h| assert_predicate(string_key, :frozen?) assert_same(string_key, @row.headers[h]) @@ -377,4 +386,37 @@ class TestCSV::Row < TestCSV r = @row == [] assert_equal false, r end + + def test_dig_by_index + assert_equal(2, @row.dig(1)) + + assert_nil(@row.dig(100)) + end + + def test_dig_by_header + assert_equal(2, @row.dig("B")) + + assert_nil(@row.dig("Missing")) + end + + def test_dig_cell + row = CSV::Row.new(%w{A}, [["foo", ["bar", ["baz"]]]]) + + assert_equal("foo", row.dig(0, 0)) + assert_equal("bar", row.dig(0, 1, 0)) + + assert_equal("foo", row.dig("A", 0)) + assert_equal("bar", row.dig("A", 1, 0)) + end + + def test_dig_cell_no_dig + row = CSV::Row.new(%w{A}, ["foo"]) + + assert_raise(TypeError) do + row.dig(0, 0) + end + assert_raise(TypeError) do + row.dig("A", 0) + end + end end diff --git a/test/csv/test_table.rb b/test/csv/test_table.rb index 25ef11a772..34ea2c5c6b 100755 --- a/test/csv/test_table.rb +++ b/test/csv/test_table.rb @@ -4,9 +4,7 @@ # tc_table.rb # -# Created by James Edward Gray II on 2005-10-31. -# Copyright 2005 James Edward Gray II. You can redistribute or modify this code -# under the terms of Ruby's license. +# Created by James Edward Gray II on 2005-10-31. require_relative "base" @@ -263,6 +261,15 @@ class TestCSV::Table < TestCSV @table.each { |row| assert_instance_of(CSV::Row, row) } end + def test_each_split + yielded_values = [] + @table.each do |column1, column2, column3| + yielded_values << [column1, column2, column3] + end + assert_equal(@rows.collect(&:to_a), + yielded_values) + end + def test_enumerable assert_equal( @rows.values_at(0, 2), @table.select { |row| (row["B"] % 2).zero? } ) @@ -312,7 +319,7 @@ class TestCSV::Table < TestCSV assert_equal(CSV::Row.new(%w[A B C], [13, 14, 15]), @table[-1]) end - def test_delete_mixed + def test_delete_mixed_one ################## ### Mixed Mode ### ################## @@ -330,6 +337,28 @@ class TestCSV::Table < TestCSV END_RESULT end + def test_delete_mixed_multiple + ################## + ### Mixed Mode ### + ################## + # delete row and col + second_row = @rows[1] + a_col = @rows.map { |row| row["A"] } + a_col_without_second_row = a_col[0..0] + a_col[2..-1] + assert_equal([ + second_row, + a_col_without_second_row, + ], + @table.delete(1, "A")) + + # verify resulting table + assert_equal(<<-END_RESULT.gsub(/^\s+/, ""), @table.to_csv) + B,C + 2,3 + 8,9 + END_RESULT + end + def test_delete_column ################### ### Column Mode ### @@ -494,4 +523,70 @@ class TestCSV::Table < TestCSV @table.inspect.encoding], "inspect() was not ASCII compatible." ) end + + def test_dig_mixed + # by row + assert_equal(@rows[0], @table.dig(0)) + assert_nil(@table.dig(100)) # empty row + + # by col + assert_equal([2, 5, 8], @table.dig("B")) + assert_equal([nil] * @rows.size, @table.dig("Z")) # empty col + + # by row then col + assert_equal(2, @table.dig(0, 1)) + assert_equal(6, @table.dig(1, "C")) + + # by col then row + assert_equal(5, @table.dig("B", 1)) + assert_equal(9, @table.dig("C", 2)) + end + + def test_dig_by_column + @table.by_col! + + assert_equal([2, 5, 8], @table.dig(1)) + assert_equal([2, 5, 8], @table.dig("B")) + + # by col then row + assert_equal(5, @table.dig("B", 1)) + assert_equal(9, @table.dig("C", 2)) + end + + def test_dig_by_row + @table.by_row! + + assert_equal(@rows[1], @table.dig(1)) + assert_raise(TypeError) { @table.dig("B") } + + # by row then col + assert_equal(2, @table.dig(0, 1)) + assert_equal(6, @table.dig(1, "C")) + end + + def test_dig_cell + table = CSV::Table.new([CSV::Row.new(["A"], [["foo", ["bar", ["baz"]]]])]) + + # by row, col then cell + assert_equal("foo", table.dig(0, "A", 0)) + assert_equal(["baz"], table.dig(0, "A", 1, 1)) + + # by col, row then cell + assert_equal("foo", table.dig("A", 0, 0)) + assert_equal(["baz"], table.dig("A", 0, 1, 1)) + end + + def test_dig_cell_no_dig + table = CSV::Table.new([CSV::Row.new(["A"], ["foo"])]) + + # by row, col then cell + assert_raise(TypeError) do + table.dig(0, "A", 0) + end + + # by col, row then cell + assert_raise(TypeError) do + table.dig("A", 0, 0) + end + end end diff --git a/test/csv/ts_all.rb b/test/csv/ts_all.rb index 9eadf12918..f632c8195f 100644 --- a/test/csv/ts_all.rb +++ b/test/csv/ts_all.rb @@ -4,9 +4,7 @@ # ts_all.rb # -# Created by James Edward Gray II on 2005-10-31. -# Copyright 2005 James Edward Gray II. You can redistribute or modify this code -# under the terms of Ruby's license. +# Created by James Edward Gray II on 2005-10-31. require "test/unit" -- cgit v1.2.3