rw_fastercsv 1.5.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/test/export.csv ADDED
@@ -0,0 +1,5 @@
1
+ Email Address,First Name,Last Name
2
+ "www@example.com",,
3
+ "bank@example.com","John J. Daw, Sr. and Mary Ann Daw","Daw"
4
+ "z@example.com",,
5
+
Binary file
@@ -0,0 +1,194 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ # tc_csv_parsing.rb
4
+ #
5
+ # Created by James Edward Gray II on 2005-10-31.
6
+ # Copyright 2005 Gray Productions. All rights reserved.
7
+
8
+ require "test/unit"
9
+
10
+ require "faster_csv"
11
+
12
+ #
13
+ # Following tests are my interpretation of the
14
+ # {CSV RCF}[http://www.ietf.org/rfc/rfc4180.txt]. I only deviate from that
15
+ # document in one place (intentionally) and that is to make the default row
16
+ # separator <tt>$/</tt>.
17
+ #
18
+ class TestCSVParsing < Test::Unit::TestCase
19
+ def test_mastering_regex_example
20
+ ex = %Q{Ten Thousand,10000, 2710 ,,"10,000","It's ""10 Grand"", baby",10K}
21
+ assert_equal( [ "Ten Thousand", "10000", " 2710 ", nil, "10,000",
22
+ "It's \"10 Grand\", baby", "10K" ],
23
+ FasterCSV.parse_line(ex) )
24
+ end
25
+
26
+ # Pulled from: http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/ruby/test/csv/test_csv.rb?rev=1.12.2.2;content-type=text%2Fplain
27
+ def test_std_lib_csv
28
+ [ ["\t", ["\t"]],
29
+ ["foo,\"\"\"\"\"\",baz", ["foo", "\"\"", "baz"]],
30
+ ["foo,\"\"\"bar\"\"\",baz", ["foo", "\"bar\"", "baz"]],
31
+ ["\"\"\"\n\",\"\"\"\n\"", ["\"\n", "\"\n"]],
32
+ ["foo,\"\r\n\",baz", ["foo", "\r\n", "baz"]],
33
+ ["\"\"", [""]],
34
+ ["foo,\"\"\"\",baz", ["foo", "\"", "baz"]],
35
+ ["foo,\"\r.\n\",baz", ["foo", "\r.\n", "baz"]],
36
+ ["foo,\"\r\",baz", ["foo", "\r", "baz"]],
37
+ ["foo,\"\",baz", ["foo", "", "baz"]],
38
+ ["\",\"", [","]],
39
+ ["foo", ["foo"]],
40
+ [",,", [nil, nil, nil]],
41
+ [",", [nil, nil]],
42
+ ["foo,\"\n\",baz", ["foo", "\n", "baz"]],
43
+ ["foo,,baz", ["foo", nil, "baz"]],
44
+ ["\"\"\"\r\",\"\"\"\r\"", ["\"\r", "\"\r"]],
45
+ ["\",\",\",\"", [",", ","]],
46
+ ["foo,bar,", ["foo", "bar", nil]],
47
+ [",foo,bar", [nil, "foo", "bar"]],
48
+ ["foo,bar", ["foo", "bar"]],
49
+ [";", [";"]],
50
+ ["\t,\t", ["\t", "\t"]],
51
+ ["foo,\"\r\n\r\",baz", ["foo", "\r\n\r", "baz"]],
52
+ ["foo,\"\r\n\n\",baz", ["foo", "\r\n\n", "baz"]],
53
+ ["foo,\"foo,bar\",baz", ["foo", "foo,bar", "baz"]],
54
+ [";,;", [";", ";"]] ].each do |csv_test|
55
+ assert_equal(csv_test.last, FasterCSV.parse_line(csv_test.first))
56
+ end
57
+
58
+ [ ["foo,\"\"\"\"\"\",baz", ["foo", "\"\"", "baz"]],
59
+ ["foo,\"\"\"bar\"\"\",baz", ["foo", "\"bar\"", "baz"]],
60
+ ["foo,\"\r\n\",baz", ["foo", "\r\n", "baz"]],
61
+ ["\"\"", [""]],
62
+ ["foo,\"\"\"\",baz", ["foo", "\"", "baz"]],
63
+ ["foo,\"\r.\n\",baz", ["foo", "\r.\n", "baz"]],
64
+ ["foo,\"\r\",baz", ["foo", "\r", "baz"]],
65
+ ["foo,\"\",baz", ["foo", "", "baz"]],
66
+ ["foo", ["foo"]],
67
+ [",,", [nil, nil, nil]],
68
+ [",", [nil, nil]],
69
+ ["foo,\"\n\",baz", ["foo", "\n", "baz"]],
70
+ ["foo,,baz", ["foo", nil, "baz"]],
71
+ ["foo,bar", ["foo", "bar"]],
72
+ ["foo,\"\r\n\n\",baz", ["foo", "\r\n\n", "baz"]],
73
+ ["foo,\"foo,bar\",baz", ["foo", "foo,bar", "baz"]] ].each do |csv_test|
74
+ assert_equal(csv_test.last, FasterCSV.parse_line(csv_test.first))
75
+ end
76
+ end
77
+
78
+ # From: http://ruby-talk.org/cgi-bin/scat.rb/ruby/ruby-core/6496
79
+ def test_aras_edge_cases
80
+ [ [%Q{a,b}, ["a", "b"]],
81
+ [%Q{a,"""b"""}, ["a", "\"b\""]],
82
+ [%Q{a,"""b"}, ["a", "\"b"]],
83
+ [%Q{a,"b"""}, ["a", "b\""]],
84
+ [%Q{a,"\nb"""}, ["a", "\nb\""]],
85
+ [%Q{a,"""\nb"}, ["a", "\"\nb"]],
86
+ [%Q{a,"""\nb\n"""}, ["a", "\"\nb\n\""]],
87
+ [%Q{a,"""\nb\n""",\nc}, ["a", "\"\nb\n\"", nil]],
88
+ [%Q{a,,,}, ["a", nil, nil, nil]],
89
+ [%Q{,}, [nil, nil]],
90
+ [%Q{"",""}, ["", ""]],
91
+ [%Q{""""}, ["\""]],
92
+ [%Q{"""",""}, ["\"",""]],
93
+ [%Q{,""}, [nil,""]],
94
+ [%Q{,"\r"}, [nil,"\r"]],
95
+ [%Q{"\r\n,"}, ["\r\n,"]],
96
+ [%Q{"\r\n,",}, ["\r\n,", nil]] ].each do |edge_case|
97
+ assert_equal(edge_case.last, FasterCSV.parse_line(edge_case.first))
98
+ end
99
+ end
100
+
101
+ def test_james_edge_cases
102
+ # A read at eof? should return nil.
103
+ assert_equal(nil, FasterCSV.parse_line(""))
104
+ #
105
+ # With CSV it's impossible to tell an empty line from a line containing a
106
+ # single +nil+ field. The standard CSV library returns <tt>[nil]</tt>
107
+ # in these cases, but <tt>Array.new</tt> makes more sense to me.
108
+ #
109
+ assert_equal(Array.new, FasterCSV.parse_line("\n1,2,3\n"))
110
+ end
111
+
112
+ def test_rob_edge_cases
113
+ [ [%Q{"a\nb"}, ["a\nb"]],
114
+ [%Q{"\n\n\n"}, ["\n\n\n"]],
115
+ [%Q{a,"b\n\nc"}, ['a', "b\n\nc"]],
116
+ [%Q{,"\r\n"}, [nil,"\r\n"]],
117
+ [%Q{,"\r\n."}, [nil,"\r\n."]],
118
+ [%Q{"a\na","one newline"}, ["a\na", 'one newline']],
119
+ [%Q{"a\n\na","two newlines"}, ["a\n\na", 'two newlines']],
120
+ [%Q{"a\r\na","one CRLF"}, ["a\r\na", 'one CRLF']],
121
+ [%Q{"a\r\n\r\na","two CRLFs"}, ["a\r\n\r\na", 'two CRLFs']],
122
+ [%Q{with blank,"start\n\nfinish"\n}, ['with blank', "start\n\nfinish"]],
123
+ ].each do |edge_case|
124
+ assert_equal(edge_case.last, FasterCSV.parse_line(edge_case.first))
125
+ end
126
+ end
127
+
128
+ def test_non_regex_edge_cases
129
+ # An early version of the non-regex parser fails this test
130
+ [["foo,\"foo,bar,baz,foo\",\"foo\"", ["foo", "foo,bar,baz,foo", "foo"]]].each do |edge_case|
131
+ assert_equal(edge_case.last, FasterCSV.parse_line(edge_case.first))
132
+ end
133
+
134
+ assert_raise(FasterCSV::MalformedCSVError) do
135
+ FasterCSV.parse_line("1,\"23\"4\"5\", 6")
136
+ end
137
+ end
138
+
139
+ def test_malformed_csv
140
+ assert_raise(FasterCSV::MalformedCSVError) do
141
+ FasterCSV.parse_line("1,2\r,3", :row_sep => "\n")
142
+ end
143
+
144
+ bad_data = <<-END_DATA.gsub(/^ +/, "")
145
+ line,1,abc
146
+ line,2,"def\nghi"
147
+
148
+ line,4,some\rjunk
149
+ line,5,jkl
150
+ END_DATA
151
+ lines = bad_data.to_a
152
+ assert_equal(6, lines.size)
153
+ assert_match(/\Aline,4/, lines.find { |l| l =~ /some\rjunk/ })
154
+
155
+ csv = FasterCSV.new(bad_data)
156
+ begin
157
+ loop do
158
+ assert_not_nil(csv.shift)
159
+ assert_send([csv.lineno, :<, 4])
160
+ end
161
+ rescue FasterCSV::MalformedCSVError
162
+ assert_equal( "Unquoted fields do not allow \\r or \\n (line 4).",
163
+ $!.message )
164
+ end
165
+
166
+ assert_nothing_raised(FasterCSV::MalformedCSVError) do
167
+ FasterCSV.parse_line('1,2,"3...',{:raise_exception => false})
168
+ end
169
+ assert_raise(FasterCSV::MalformedCSVError) do
170
+ FasterCSV.parse_line('1,2,"3...')
171
+ end
172
+
173
+ bad_data = <<-END_DATA.gsub(/^ +/, "")
174
+ line,1,abc
175
+ line,2,"def\nghi"
176
+
177
+ line,4,8'10"
178
+ line,5,jkl
179
+ END_DATA
180
+ lines = bad_data.to_a
181
+ assert_equal(6, lines.size)
182
+ assert_match(/\Aline,4/, lines.find { |l| l =~ /8'10"/ })
183
+
184
+ csv = FasterCSV.new(bad_data)
185
+ begin
186
+ loop do
187
+ assert_not_nil(csv.shift)
188
+ assert_send([csv.lineno, :<, 4])
189
+ end
190
+ rescue FasterCSV::MalformedCSVError
191
+ assert_equal("Illegal quoting on line 4.", $!.message)
192
+ end
193
+ end
194
+ end
@@ -0,0 +1,96 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ # tc_csv_writing.rb
4
+ #
5
+ # Created by James Edward Gray II on 2005-11-14.
6
+ # Copyright 2005 Gray Productions. All rights reserved.
7
+
8
+ require "test/unit"
9
+
10
+ require "faster_csv"
11
+
12
+ class TestFasterCSVWriting < Test::Unit::TestCase
13
+ def test_writing
14
+ [ ["\t", ["\t"]],
15
+ ["foo,\"\"\"\"\"\",baz", ["foo", "\"\"", "baz"]],
16
+ ["foo,\"\"\"bar\"\"\",baz", ["foo", "\"bar\"", "baz"]],
17
+ ["\"\"\"\n\",\"\"\"\n\"", ["\"\n", "\"\n"]],
18
+ ["foo,\"\r\n\",baz", ["foo", "\r\n", "baz"]],
19
+ ["\"\"", [""]],
20
+ ["foo,\"\"\"\",baz", ["foo", "\"", "baz"]],
21
+ ["foo,\"\r.\n\",baz", ["foo", "\r.\n", "baz"]],
22
+ ["foo,\"\r\",baz", ["foo", "\r", "baz"]],
23
+ ["foo,\"\",baz", ["foo", "", "baz"]],
24
+ ["\",\"", [","]],
25
+ ["foo", ["foo"]],
26
+ [",,", [nil, nil, nil]],
27
+ [",", [nil, nil]],
28
+ ["foo,\"\n\",baz", ["foo", "\n", "baz"]],
29
+ ["foo,,baz", ["foo", nil, "baz"]],
30
+ ["\"\"\"\r\",\"\"\"\r\"", ["\"\r", "\"\r"]],
31
+ ["\",\",\",\"", [",", ","]],
32
+ ["foo,bar,", ["foo", "bar", nil]],
33
+ [",foo,bar", [nil, "foo", "bar"]],
34
+ ["foo,bar", ["foo", "bar"]],
35
+ [";", [";"]],
36
+ ["\t,\t", ["\t", "\t"]],
37
+ ["foo,\"\r\n\r\",baz", ["foo", "\r\n\r", "baz"]],
38
+ ["foo,\"\r\n\n\",baz", ["foo", "\r\n\n", "baz"]],
39
+ ["foo,\"foo,bar\",baz", ["foo", "foo,bar", "baz"]],
40
+ [";,;", [";", ";"]],
41
+ ["foo,\"\"\"\"\"\",baz", ["foo", "\"\"", "baz"]],
42
+ ["foo,\"\"\"bar\"\"\",baz", ["foo", "\"bar\"", "baz"]],
43
+ ["foo,\"\r\n\",baz", ["foo", "\r\n", "baz"]],
44
+ ["\"\"", [""]],
45
+ ["foo,\"\"\"\",baz", ["foo", "\"", "baz"]],
46
+ ["foo,\"\r.\n\",baz", ["foo", "\r.\n", "baz"]],
47
+ ["foo,\"\r\",baz", ["foo", "\r", "baz"]],
48
+ ["foo,\"\",baz", ["foo", "", "baz"]],
49
+ ["foo", ["foo"]],
50
+ [",,", [nil, nil, nil]],
51
+ [",", [nil, nil]],
52
+ ["foo,\"\n\",baz", ["foo", "\n", "baz"]],
53
+ ["foo,,baz", ["foo", nil, "baz"]],
54
+ ["foo,bar", ["foo", "bar"]],
55
+ ["foo,\"\r\n\n\",baz", ["foo", "\r\n\n", "baz"]],
56
+ ["foo,\"foo,bar\",baz", ["foo", "foo,bar", "baz"]],
57
+ [%Q{a,b}, ["a", "b"]],
58
+ [%Q{a,"""b"""}, ["a", "\"b\""]],
59
+ [%Q{a,"""b"}, ["a", "\"b"]],
60
+ [%Q{a,"b"""}, ["a", "b\""]],
61
+ [%Q{a,"\nb"""}, ["a", "\nb\""]],
62
+ [%Q{a,"""\nb"}, ["a", "\"\nb"]],
63
+ [%Q{a,"""\nb\n"""}, ["a", "\"\nb\n\""]],
64
+ [%Q{a,"""\nb\n""",}, ["a", "\"\nb\n\"", nil]],
65
+ [%Q{a,,,}, ["a", nil, nil, nil]],
66
+ [%Q{,}, [nil, nil]],
67
+ [%Q{"",""}, ["", ""]],
68
+ [%Q{""""}, ["\""]],
69
+ [%Q{"""",""}, ["\"",""]],
70
+ [%Q{,""}, [nil,""]],
71
+ [%Q{,"\r"}, [nil,"\r"]],
72
+ [%Q{"\r\n,"}, ["\r\n,"]],
73
+ [%Q{"\r\n,",}, ["\r\n,", nil]] ].each do |test_case|
74
+ assert_equal( test_case.first + $/,
75
+ FasterCSV.generate_line(test_case.last) )
76
+ end
77
+ end
78
+
79
+ def test_col_sep
80
+ assert_equal( "a;b;;c\n", FasterCSV.generate_line( ["a", "b", nil, "c"],
81
+ :col_sep => ";" ) )
82
+ assert_equal( "a\tb\t\tc\n", FasterCSV.generate_line( ["a", "b", nil, "c"],
83
+ :col_sep => "\t" ) )
84
+ end
85
+
86
+ def test_row_sep
87
+ assert_equal( "a,b,,c\r\n", FasterCSV.generate_line( ["a", "b", nil, "c"],
88
+ :row_sep => "\r\n" ) )
89
+ end
90
+
91
+ def test_force_quotes
92
+ assert_equal( %Q{"1","b","","already ""quoted"""\n},
93
+ FasterCSV.generate_line( [1, "b", nil, %Q{already "quoted"}],
94
+ :force_quotes => true ) )
95
+ end
96
+ end
@@ -0,0 +1,260 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ # tc_data_converters.rb
4
+ #
5
+ # Created by James Edward Gray II on 2005-12-30.
6
+ # Copyright 2005 Gray Productions. All rights reserved.
7
+
8
+ require "test/unit"
9
+
10
+ require "faster_csv"
11
+
12
+ class TestDataConverters < Test::Unit::TestCase
13
+ def setup
14
+ @data = "Numbers,:integer,1,:float,3.015"
15
+ @parser = FasterCSV.new(@data)
16
+
17
+ @custom = lambda { |field| field =~ /\A:(\S.*?)\s*\Z/ ? $1.to_sym : field }
18
+
19
+ @win_safe_time_str = Time.now.strftime("%a %b %d %H:%M:%S %Y")
20
+ end
21
+
22
+ def test_builtin_integer_converter
23
+ # does convert
24
+ [-5, 1, 10000000000].each do |n|
25
+ assert_equal(n, FasterCSV::Converters[:integer][n.to_s])
26
+ end
27
+
28
+ # does not convert
29
+ (%w{junk 1.0} + [""]).each do |str|
30
+ assert_equal(str, FasterCSV::Converters[:integer][str])
31
+ end
32
+ end
33
+
34
+ def test_builtin_float_converter
35
+ # does convert
36
+ [-5.1234, 0, 2.3e-11].each do |n|
37
+ assert_equal(n, FasterCSV::Converters[:float][n.to_s])
38
+ end
39
+
40
+ # does not convert
41
+ (%w{junk 1..0 .015F} + [""]).each do |str|
42
+ assert_equal(str, FasterCSV::Converters[:float][str])
43
+ end
44
+ end
45
+
46
+ def test_builtin_date_converter
47
+ # does convert
48
+ assert_instance_of(
49
+ Date,
50
+ FasterCSV::Converters[:date][@win_safe_time_str.sub(/\d+:\d+:\d+ /, "")]
51
+ )
52
+
53
+ # does not convert
54
+ assert_instance_of(String, FasterCSV::Converters[:date]["junk"])
55
+ end
56
+
57
+ def test_builtin_date_time_converter
58
+ # does convert
59
+ assert_instance_of( DateTime,
60
+ FasterCSV::Converters[:date_time][@win_safe_time_str] )
61
+
62
+ # does not convert
63
+ assert_instance_of(String, FasterCSV::Converters[:date_time]["junk"])
64
+ end
65
+
66
+ def test_convert_with_builtin
67
+ # setup parser...
68
+ assert(@parser.respond_to?(:convert))
69
+ assert_nothing_raised(Exception) { @parser.convert(:integer) }
70
+
71
+ # and use
72
+ assert_equal(["Numbers", ":integer", 1, ":float", "3.015"], @parser.shift)
73
+
74
+ setup # reset
75
+
76
+ # setup parser...
77
+ assert_nothing_raised(Exception) { @parser.convert(:float) }
78
+
79
+ # and use
80
+ assert_equal(["Numbers", ":integer", 1.0, ":float", 3.015], @parser.shift)
81
+ end
82
+
83
+ def test_convert_order
84
+ # floats first, then integers...
85
+ assert_nothing_raised(Exception) do
86
+ @parser.convert(:float)
87
+ @parser.convert(:integer)
88
+ end
89
+
90
+ # gets us nothing but floats
91
+ assert_equal( [String, String, Float, String, Float],
92
+ @parser.shift.map { |field| field.class } )
93
+
94
+ setup # reset
95
+
96
+ # integers have precendance...
97
+ assert_nothing_raised(Exception) do
98
+ @parser.convert(:integer)
99
+ @parser.convert(:float)
100
+ end
101
+
102
+ # gives us proper number conversion
103
+ assert_equal( [String, String, Fixnum, String, Float],
104
+ @parser.shift.map { |field| field.class } )
105
+ end
106
+
107
+ def test_builtin_numeric_combo_converter
108
+ # setup parser...
109
+ assert_nothing_raised(Exception) { @parser.convert(:numeric) }
110
+
111
+ # and use
112
+ assert_equal( [String, String, Fixnum, String, Float],
113
+ @parser.shift.map { |field| field.class } )
114
+ end
115
+
116
+ def test_builtin_all_nested_combo_converter
117
+ # setup parser...
118
+ @data << ",#{@win_safe_time_str}" # add a DateTime field
119
+ @parser = FasterCSV.new(@data) # reset parser
120
+ assert_nothing_raised(Exception) { @parser.convert(:all) }
121
+
122
+ # and use
123
+ assert_equal( [String, String, Fixnum, String, Float, DateTime],
124
+ @parser.shift.map { |field| field.class } )
125
+ end
126
+
127
+ def test_convert_with_custom_code
128
+ # define custom converter...
129
+ assert_nothing_raised(Exception) do
130
+ @parser.convert { |field| field =~ /\A:(\S.*?)\s*\Z/ ? $1.to_sym : field }
131
+ end
132
+
133
+ # and use
134
+ assert_equal(["Numbers", :integer, "1", :float, "3.015"], @parser.shift)
135
+
136
+ setup # reset
137
+
138
+ # mix built-in and custom...
139
+ assert_nothing_raised(Exception) { @parser.convert(:numeric) }
140
+ assert_nothing_raised(Exception) { @parser.convert(&@custom) }
141
+
142
+ # and use
143
+ assert_equal(["Numbers", :integer, 1, :float, 3.015], @parser.shift)
144
+ end
145
+
146
+ def test_convert_with_custom_code_using_field_info
147
+ # define custom converter that uses field information...
148
+ assert_nothing_raised(Exception) do
149
+ @parser.convert do |field, info|
150
+ assert_equal(1, info.line)
151
+ info.index == 4 ? Float(field).floor : field
152
+ end
153
+ end
154
+
155
+ # and use
156
+ assert_equal(["Numbers", ":integer", "1", ":float", 3], @parser.shift)
157
+ end
158
+
159
+ def test_convert_with_custom_code_using_field_info_header
160
+ @parser = FasterCSV.new(@data, :headers => %w{one two three four five})
161
+
162
+ # define custom converter that uses field header information...
163
+ assert_nothing_raised(Exception) do
164
+ @parser.convert do |field, info|
165
+ info.header == "three" ? Integer(field) * 100 : field
166
+ end
167
+ end
168
+
169
+ # and use
170
+ assert_equal(["Numbers", ":integer", 100, ":float", "3.015"], @parser.shift.fields)
171
+ end
172
+
173
+ def test_shortcut_interface
174
+ assert_equal( ["Numbers", ":integer", 1, ":float", 3.015],
175
+ FasterCSV.parse_line(@data, :converters => :numeric) )
176
+
177
+ assert_equal( ["Numbers", ":integer", 1, ":float", 3.015],
178
+ FasterCSV.parse_line( @data, :converters => [ :integer,
179
+ :float ] ) )
180
+
181
+ assert_equal( ["Numbers", :integer, 1, :float, 3.015],
182
+ FasterCSV.parse_line( @data, :converters => [ :numeric,
183
+ @custom ] ) )
184
+ end
185
+
186
+ def test_unconverted_fields
187
+ [ [ @data,
188
+ ["Numbers", :integer, 1, :float, 3.015],
189
+ %w{Numbers :integer 1 :float 3.015} ],
190
+ ["\n", Array.new, Array.new] ].each do |test, fields, unconverted|
191
+ row = nil
192
+ assert_nothing_raised(Exception) do
193
+ row = FasterCSV.parse_line( test,
194
+ :converters => [:numeric, @custom],
195
+ :unconverted_fields => true )
196
+ end
197
+ assert_not_nil(row)
198
+ assert_equal(fields, row)
199
+ assert_respond_to(row, :unconverted_fields)
200
+ assert_equal(unconverted, row.unconverted_fields)
201
+ end
202
+
203
+ data = <<-END_CSV.gsub(/^\s+/, "")
204
+ first,second,third
205
+ 1,2,3
206
+ END_CSV
207
+ row = nil
208
+ assert_nothing_raised(Exception) do
209
+ row = FasterCSV.parse_line( data,
210
+ :converters => :numeric,
211
+ :unconverted_fields => true,
212
+ :headers => :first_row )
213
+ end
214
+ assert_not_nil(row)
215
+ assert_equal([["first", 1], ["second", 2], ["third", 3]], row.to_a)
216
+ assert_respond_to(row, :unconverted_fields)
217
+ assert_equal(%w{1 2 3}, row.unconverted_fields)
218
+
219
+ assert_nothing_raised(Exception) do
220
+ row = FasterCSV.parse_line( data,
221
+ :converters => :numeric,
222
+ :unconverted_fields => true,
223
+ :headers => :first_row,
224
+ :return_headers => true )
225
+ end
226
+ assert_not_nil(row)
227
+ assert_equal( [%w{first first}, %w{second second}, %w{third third}],
228
+ row.to_a )
229
+ assert_respond_to(row, :unconverted_fields)
230
+ assert_equal(%w{first second third}, row.unconverted_fields)
231
+
232
+ assert_nothing_raised(Exception) do
233
+ row = FasterCSV.parse_line( data,
234
+ :converters => :numeric,
235
+ :unconverted_fields => true,
236
+ :headers => :first_row,
237
+ :return_headers => true,
238
+ :header_converters => :symbol )
239
+ end
240
+ assert_not_nil(row)
241
+ assert_equal( [[:first, "first"], [:second, "second"], [:third, "third"]],
242
+ row.to_a )
243
+ assert_respond_to(row, :unconverted_fields)
244
+ assert_equal(%w{first second third}, row.unconverted_fields)
245
+
246
+ assert_nothing_raised(Exception) do
247
+ row = FasterCSV.parse_line( data,
248
+ :converters => :numeric,
249
+ :unconverted_fields => true,
250
+ :headers => %w{my new headers},
251
+ :return_headers => true,
252
+ :header_converters => :symbol )
253
+ end
254
+ assert_not_nil(row)
255
+ assert_equal( [[:my, "my"], [:new, "new"], [:headers, "headers"]],
256
+ row.to_a )
257
+ assert_respond_to(row, :unconverted_fields)
258
+ assert_equal(Array.new, row.unconverted_fields)
259
+ end
260
+ end