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.
@@ -0,0 +1,376 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ # tc_interface.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 TestFasterCSVInterface < Test::Unit::TestCase
13
+ def setup
14
+ @path = File.join(File.dirname(__FILE__), "temp_test_data.csv")
15
+
16
+ File.open(@path, "w") do |file|
17
+ file << "1\t2\t3\r\n"
18
+ file << "4\t5\r\n"
19
+ end
20
+
21
+ @expected = [%w{1 2 3}, %w{4 5}]
22
+ end
23
+
24
+ def teardown
25
+ File.unlink(@path)
26
+ end
27
+
28
+ ### Test Read Interface ###
29
+
30
+ def test_foreach
31
+ FasterCSV.foreach(@path, :col_sep => "\t", :row_sep => "\r\n") do |row|
32
+ assert_equal(@expected.shift, row)
33
+ end
34
+ end
35
+
36
+ def test_open_and_close
37
+ csv = FasterCSV.open(@path, "r+", :col_sep => "\t", :row_sep => "\r\n")
38
+ assert_not_nil(csv)
39
+ assert_instance_of(FasterCSV, csv)
40
+ assert_equal(false, csv.closed?)
41
+ csv.close
42
+ assert(csv.closed?)
43
+
44
+ ret = FasterCSV.open(@path) do |csv|
45
+ assert_instance_of(FasterCSV, csv)
46
+ "Return value."
47
+ end
48
+ assert(csv.closed?)
49
+ assert_equal("Return value.", ret)
50
+ end
51
+
52
+ def test_parse
53
+ data = File.read(@path)
54
+ assert_equal( @expected,
55
+ FasterCSV.parse(data, :col_sep => "\t", :row_sep => "\r\n") )
56
+
57
+ FasterCSV.parse(data, :col_sep => "\t", :row_sep => "\r\n") do |row|
58
+ assert_equal(@expected.shift, row)
59
+ end
60
+ end
61
+
62
+ def test_parse_line
63
+ row = FasterCSV.parse_line("1;2;3", :col_sep => ";")
64
+ assert_not_nil(row)
65
+ assert_instance_of(Array, row)
66
+ assert_equal(%w{1 2 3}, row)
67
+
68
+ # shortcut interface
69
+ row = "1;2;3".parse_csv(:col_sep => ";")
70
+ assert_not_nil(row)
71
+ assert_instance_of(Array, row)
72
+ assert_equal(%w{1 2 3}, row)
73
+ end
74
+
75
+ def test_parse_line_with_empty_lines
76
+ assert_equal(nil, FasterCSV.parse_line("")) # to signal eof
77
+ assert_equal(Array.new, FasterCSV.parse_line("\n1,2,3"))
78
+ end
79
+
80
+ def test_read_and_readlines
81
+ assert_equal( @expected,
82
+ FasterCSV.read(@path, :col_sep => "\t", :row_sep => "\r\n") )
83
+ assert_equal( @expected,
84
+ FasterCSV.readlines( @path,
85
+ :col_sep => "\t", :row_sep => "\r\n") )
86
+
87
+
88
+ data = FasterCSV.open(@path, :col_sep => "\t", :row_sep => "\r\n") do |csv|
89
+ csv.read
90
+ end
91
+ assert_equal(@expected, data)
92
+ data = FasterCSV.open(@path, :col_sep => "\t", :row_sep => "\r\n") do |csv|
93
+ csv.readlines
94
+ end
95
+ assert_equal(@expected, data)
96
+ end
97
+
98
+ def test_table
99
+ table = FasterCSV.table(@path, :col_sep => "\t", :row_sep => "\r\n")
100
+ assert_instance_of(FasterCSV::Table, table)
101
+ assert_equal([[:"1", :"2", :"3"], [4, 5, nil]], table.to_a)
102
+ end
103
+
104
+ def test_shift # aliased as gets() and readline()
105
+ FasterCSV.open(@path, "r+", :col_sep => "\t", :row_sep => "\r\n") do |csv|
106
+ assert_equal(@expected.shift, csv.shift)
107
+ assert_equal(@expected.shift, csv.shift)
108
+ assert_equal(nil, csv.shift)
109
+ end
110
+ end
111
+
112
+ def test_long_line # ruby's regex parser may have problems with long rows
113
+ File.unlink(@path)
114
+
115
+ long_field_length = 2800
116
+ File.open(@path, "w") do |file|
117
+ file << "1\t2\t#{'3' * long_field_length}\r\n"
118
+ end
119
+ @expected = [%w{1 2} + ['3' * long_field_length]]
120
+ test_shift
121
+ end
122
+
123
+ ### Test Write Interface ###
124
+
125
+ def test_generate
126
+ str = FasterCSV.generate do |csv| # default empty String
127
+ assert_instance_of(FasterCSV, csv)
128
+ assert_equal(csv, csv << [1, 2, 3])
129
+ assert_equal(csv, csv << [4, nil, 5])
130
+ end
131
+ assert_not_nil(str)
132
+ assert_instance_of(String, str)
133
+ assert_equal("1,2,3\n4,,5\n", str)
134
+
135
+ FasterCSV.generate(str) do |csv| # appending to a String
136
+ assert_equal(csv, csv << ["last", %Q{"row"}])
137
+ end
138
+ assert_equal(%Q{1,2,3\n4,,5\nlast,"""row"""\n}, str)
139
+ end
140
+
141
+ def test_generate_line
142
+ line = FasterCSV.generate_line(%w{1 2 3}, :col_sep => ";")
143
+ assert_not_nil(line)
144
+ assert_instance_of(String, line)
145
+ assert_equal("1;2;3\n", line)
146
+
147
+ # shortcut interface
148
+ line = %w{1 2 3}.to_csv(:col_sep => ";")
149
+ assert_not_nil(line)
150
+ assert_instance_of(String, line)
151
+ assert_equal("1;2;3\n", line)
152
+ end
153
+
154
+ def test_write_header_detection
155
+ File.unlink(@path)
156
+
157
+ headers = %w{a b c}
158
+ FasterCSV.open(@path, "w", :headers => true) do |csv|
159
+ csv << headers
160
+ csv << %w{1 2 3}
161
+ assert_equal(headers, csv.instance_variable_get(:@headers))
162
+ end
163
+ end
164
+
165
+ def test_write_lineno
166
+ File.unlink(@path)
167
+
168
+ FasterCSV.open(@path, "w") do |csv|
169
+ lines = 20
170
+ lines.times { csv << %w{a b c} }
171
+ assert_equal(lines, csv.lineno)
172
+ end
173
+ end
174
+
175
+ def test_write_hash
176
+ File.unlink(@path)
177
+
178
+ lines = [{:a => 1, :b => 2, :c => 3}, {:a => 4, :b => 5, :c => 6}]
179
+ FasterCSV.open( @path, "w", :headers => true,
180
+ :header_converters => :symbol ) do |csv|
181
+ csv << lines.first.keys
182
+ lines.each { |line| csv << line }
183
+ end
184
+ FasterCSV.open( @path, "r", :headers => true,
185
+ :converters => :all,
186
+ :header_converters => :symbol ) do |csv|
187
+ csv.each { |line| assert_equal(lines.shift, line.to_hash) }
188
+ end
189
+ end
190
+
191
+ def test_write_hash_with_headers_array
192
+ File.unlink(@path)
193
+
194
+ lines = [{:a => 1, :b => 2, :c => 3}, {:a => 4, :b => 5, :c => 6}]
195
+ FasterCSV.open(@path, "w", :headers => [:b, :a, :c]) do |csv|
196
+ lines.each { |line| csv << line }
197
+ end
198
+
199
+ # test writing fields in the correct order
200
+ File.open(@path, "r") do |f|
201
+ assert_equal("2,1,3", f.gets.strip)
202
+ assert_equal("5,4,6", f.gets.strip)
203
+ end
204
+
205
+ # test reading CSV with headers
206
+ FasterCSV.open( @path, "r", :headers => [:b, :a, :c],
207
+ :converters => :all ) do |csv|
208
+ csv.each { |line| assert_equal(lines.shift, line.to_hash) }
209
+ end
210
+ end
211
+
212
+ def test_write_hash_with_headers_string
213
+ File.unlink(@path)
214
+
215
+ lines = [{"a" => 1, "b" => 2, "c" => 3}, {"a" => 4, "b" => 5, "c" => 6}]
216
+ FasterCSV.open( @path, "w", :headers => "b|a|c",
217
+ :col_sep => "|" ) do |csv|
218
+ lines.each { |line| csv << line }
219
+ end
220
+
221
+ # test writing fields in the correct order
222
+ File.open(@path, "r") do |f|
223
+ assert_equal("2|1|3", f.gets.strip)
224
+ assert_equal("5|4|6", f.gets.strip)
225
+ end
226
+
227
+ # test reading CSV with headers
228
+ FasterCSV.open( @path, "r", :headers => "b|a|c",
229
+ :col_sep => "|",
230
+ :converters => :all ) do |csv|
231
+ csv.each { |line| assert_equal(lines.shift, line.to_hash) }
232
+ end
233
+ end
234
+
235
+ def test_write_headers
236
+ File.unlink(@path)
237
+
238
+ lines = [{"a" => 1, "b" => 2, "c" => 3}, {"a" => 4, "b" => 5, "c" => 6}]
239
+ FasterCSV.open( @path, "w", :headers => "b|a|c",
240
+ :write_headers => true,
241
+ :col_sep => "|" ) do |csv|
242
+ lines.each { |line| csv << line }
243
+ end
244
+
245
+ # test writing fields in the correct order
246
+ File.open(@path, "r") do |f|
247
+ assert_equal("b|a|c", f.gets.strip)
248
+ assert_equal("2|1|3", f.gets.strip)
249
+ assert_equal("5|4|6", f.gets.strip)
250
+ end
251
+
252
+ # test reading CSV with headers
253
+ FasterCSV.open( @path, "r", :headers => true,
254
+ :col_sep => "|",
255
+ :converters => :all ) do |csv|
256
+ csv.each { |line| assert_equal(lines.shift, line.to_hash) }
257
+ end
258
+ end
259
+
260
+ def test_append # aliased add_row() and puts()
261
+ File.unlink(@path)
262
+
263
+ FasterCSV.open(@path, "w", :col_sep => "\t", :row_sep => "\r\n") do |csv|
264
+ @expected.each { |row| csv << row }
265
+ end
266
+
267
+ test_shift
268
+
269
+ # same thing using FasterCSV::Row objects
270
+ File.unlink(@path)
271
+
272
+ FasterCSV.open(@path, "w", :col_sep => "\t", :row_sep => "\r\n") do |csv|
273
+ @expected.each { |row| csv << FasterCSV::Row.new(Array.new, row) }
274
+ end
275
+
276
+ test_shift
277
+ end
278
+
279
+ ### Test Read and Write Interface ###
280
+
281
+ def test_filter
282
+ assert_respond_to(FasterCSV, :filter)
283
+
284
+ expected = [[1, 2, 3], [4, 5]]
285
+ FasterCSV.filter( "1;2;3\n4;5\n", (result = String.new),
286
+ :in_col_sep => ";", :out_col_sep => ",",
287
+ :converters => :all ) do |row|
288
+ assert_equal(row, expected.shift)
289
+ row.map! { |n| n * 2 }
290
+ row << "Added\r"
291
+ end
292
+ assert_equal("2,4,6,\"Added\r\"\n8,10,\"Added\r\"\n", result)
293
+ end
294
+
295
+ def test_instance
296
+ csv = String.new
297
+
298
+ first = nil
299
+ assert_nothing_raised(Exception) do
300
+ first = FasterCSV.instance(csv, :col_sep => ";")
301
+ first << %w{a b c}
302
+ end
303
+
304
+ assert_equal("a;b;c\n", csv)
305
+
306
+ second = nil
307
+ assert_nothing_raised(Exception) do
308
+ second = FasterCSV.instance(csv, :col_sep => ";")
309
+ second << [1, 2, 3]
310
+ end
311
+
312
+ assert_equal(first.object_id, second.object_id)
313
+ assert_equal("a;b;c\n1;2;3\n", csv)
314
+
315
+ # shortcuts
316
+ assert_equal(STDOUT, FasterCSV.instance.instance_eval { @io })
317
+ assert_equal(STDOUT, FasterCSV { |csv| csv.instance_eval { @io } })
318
+ assert_equal(STDOUT, FCSV.instance.instance_eval { @io })
319
+ assert_equal(STDOUT, FCSV { |csv| csv.instance_eval { @io } })
320
+ end
321
+
322
+ ### Test Alternate Interface ###
323
+
324
+ def test_csv_interface
325
+ require "csv"
326
+ data = ["Number", 42, "Tricky Field", 'This has embedded "quotes"!']
327
+ data_file = File.join(File.dirname(__FILE__), "temp_csv_data.csv")
328
+ CSV.open(data_file, "w") { |f| 10.times { f << data } }
329
+ csv = CSV.generate_line(data)
330
+ tests = { :foreach => Array.new,
331
+ :generate_line => csv,
332
+ :open => Array.new,
333
+ :parse => CSV.parse(csv),
334
+ :parse_w_block => Array.new,
335
+ :parse_line => CSV.parse_line(csv),
336
+ :readlines => CSV.readlines(data_file) }
337
+ CSV.foreach(data_file) { |row| tests[:foreach] << row }
338
+ CSV.open(data_file, "r") { |row| tests[:open] << row }
339
+ CSV.parse(([csv] * 3).join("\n")) { |row| tests[:parse_w_block] << row }
340
+ Object.send(:remove_const, :CSV)
341
+
342
+ assert_nothing_raised(Exception) do
343
+ FasterCSV.build_csv_interface
344
+ end
345
+
346
+ %w{ foreach
347
+ generate_line
348
+ open
349
+ parse
350
+ parse_line
351
+ readlines }.each do |meth|
352
+ assert_respond_to(::CSV, meth)
353
+ end
354
+
355
+ faster_csv = Array.new
356
+ CSV.foreach(data_file) { |row| faster_csv << row }
357
+ assert_equal(tests[:foreach], faster_csv)
358
+ assert_equal(tests[:generate_line], CSV.generate_line(data))
359
+ faster_csv.clear
360
+ CSV.open(data_file, "r") { |row| faster_csv << row }
361
+ assert_equal(tests[:open], faster_csv)
362
+ comp_file = data_file.sub("_csv_data", "_faster_csv_data")
363
+ CSV.open(comp_file, "w") { |f| 10.times { f << data } }
364
+ assert_equal(File.read(data_file), File.read(comp_file))
365
+ assert_equal(tests[:parse], CSV.parse(csv))
366
+ faster_csv.clear
367
+ CSV.parse(([csv] * 3).join("\n")) { |row| faster_csv << row }
368
+ assert_equal(tests[:parse_w_block], faster_csv)
369
+ assert_equal(tests[:parse_line], CSV.parse_line(csv))
370
+ assert_equal(tests[:readlines], CSV.readlines(data_file))
371
+
372
+ Object.send(:remove_const, :CSV)
373
+ load "csv.rb"
374
+ [data_file, comp_file].each { |file| File.unlink(file) }
375
+ end
376
+ end
data/test/tc_row.rb ADDED
@@ -0,0 +1,305 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ # tc_row.rb
4
+ #
5
+ # Created by James Edward Gray II on 2006-02-24.
6
+ # Copyright 2006 Gray Productions. All rights reserved.
7
+
8
+ require "test/unit"
9
+
10
+ require "faster_csv"
11
+
12
+ class TestFasterCSVRow < Test::Unit::TestCase
13
+ def setup
14
+ @row = FasterCSV::Row.new(%w{A B C A A}, [1, 2, 3, 4])
15
+ end
16
+
17
+ def test_initialize
18
+ # basic
19
+ row = FasterCSV::Row.new(%w{A B C}, [1, 2, 3])
20
+ assert_not_nil(row)
21
+ assert_instance_of(FasterCSV::Row, row)
22
+ assert_equal([["A", 1], ["B", 2], ["C", 3]], row.to_a)
23
+
24
+ # missing headers
25
+ row = FasterCSV::Row.new(%w{A}, [1, 2, 3])
26
+ assert_not_nil(row)
27
+ assert_instance_of(FasterCSV::Row, row)
28
+ assert_equal([["A", 1], [nil, 2], [nil, 3]], row.to_a)
29
+
30
+ # missing fields
31
+ row = FasterCSV::Row.new(%w{A B C}, [1, 2])
32
+ assert_not_nil(row)
33
+ assert_instance_of(FasterCSV::Row, row)
34
+ assert_equal([["A", 1], ["B", 2], ["C", nil]], row.to_a)
35
+ end
36
+
37
+ def test_row_type
38
+ # field rows
39
+ row = FasterCSV::Row.new(%w{A B C}, [1, 2, 3]) # implicit
40
+ assert(!row.header_row?)
41
+ assert(row.field_row?)
42
+ row = FasterCSV::Row.new(%w{A B C}, [1, 2, 3], false) # explicit
43
+ assert(!row.header_row?)
44
+ assert(row.field_row?)
45
+
46
+ # header row
47
+ row = FasterCSV::Row.new(%w{A B C}, [1, 2, 3], true)
48
+ assert(row.header_row?)
49
+ assert(!row.field_row?)
50
+ end
51
+
52
+ def test_headers
53
+ assert_equal(%w{A B C A A}, @row.headers)
54
+ end
55
+
56
+ def test_field
57
+ # by name
58
+ assert_equal(2, @row.field("B"))
59
+ assert_equal(2, @row["B"]) # alias
60
+
61
+ # by index
62
+ assert_equal(3, @row.field(2))
63
+
64
+ # missing
65
+ assert_nil(@row.field("Missing"))
66
+ assert_nil(@row.field(10))
67
+
68
+ # minimum index
69
+ assert_equal(1, @row.field("A"))
70
+ assert_equal(1, @row.field("A", 0))
71
+ assert_equal(4, @row.field("A", 1))
72
+ assert_equal(4, @row.field("A", 2))
73
+ assert_equal(4, @row.field("A", 3))
74
+ assert_equal(nil, @row.field("A", 4))
75
+ assert_equal(nil, @row.field("A", 5))
76
+ end
77
+
78
+ def test_set_field
79
+ # set field by name
80
+ assert_equal(100, @row["A"] = 100)
81
+
82
+ # set field by index
83
+ assert_equal(300, @row[3] = 300)
84
+
85
+ # set field by name and minimum index
86
+ assert_equal([:a, :b, :c], @row["A", 4] = [:a, :b, :c])
87
+
88
+ # verify the changes
89
+ assert_equal( [ ["A", 100],
90
+ ["B", 2],
91
+ ["C", 3],
92
+ ["A", 300],
93
+ ["A", [:a, :b, :c]] ], @row.to_a )
94
+
95
+ # assigning an index past the end
96
+ assert_equal("End", @row[10] = "End")
97
+ assert_equal( [ ["A", 100],
98
+ ["B", 2],
99
+ ["C", 3],
100
+ ["A", 300],
101
+ ["A", [:a, :b, :c]],
102
+ [nil, nil],
103
+ [nil, nil],
104
+ [nil, nil],
105
+ [nil, nil],
106
+ [nil, nil],
107
+ [nil, "End"] ], @row.to_a )
108
+
109
+ # assigning a new field by header
110
+ assert_equal("New", @row[:new] = "New")
111
+ assert_equal( [ ["A", 100],
112
+ ["B", 2],
113
+ ["C", 3],
114
+ ["A", 300],
115
+ ["A", [:a, :b, :c]],
116
+ [nil, nil],
117
+ [nil, nil],
118
+ [nil, nil],
119
+ [nil, nil],
120
+ [nil, nil],
121
+ [nil, "End"],
122
+ [:new, "New"] ], @row.to_a )
123
+ end
124
+
125
+ def test_append
126
+ # add a value
127
+ assert_equal(@row, @row << "Value")
128
+ assert_equal( [ ["A", 1],
129
+ ["B", 2],
130
+ ["C", 3],
131
+ ["A", 4],
132
+ ["A", nil],
133
+ [nil, "Value"] ], @row.to_a )
134
+
135
+ # add a pair
136
+ assert_equal(@row, @row << %w{Header Field})
137
+ assert_equal( [ ["A", 1],
138
+ ["B", 2],
139
+ ["C", 3],
140
+ ["A", 4],
141
+ ["A", nil],
142
+ [nil, "Value"],
143
+ %w{Header Field} ], @row.to_a )
144
+
145
+ # a pair with Hash syntax
146
+ assert_equal(@row, @row << {:key => :value})
147
+ assert_equal( [ ["A", 1],
148
+ ["B", 2],
149
+ ["C", 3],
150
+ ["A", 4],
151
+ ["A", nil],
152
+ [nil, "Value"],
153
+ %w{Header Field},
154
+ [:key, :value] ], @row.to_a )
155
+
156
+ # multiple fields at once
157
+ assert_equal(@row, @row.push(100, 200, [:last, 300]))
158
+ assert_equal( [ ["A", 1],
159
+ ["B", 2],
160
+ ["C", 3],
161
+ ["A", 4],
162
+ ["A", nil],
163
+ [nil, "Value"],
164
+ %w{Header Field},
165
+ [:key, :value],
166
+ [nil, 100],
167
+ [nil, 200],
168
+ [:last, 300] ], @row.to_a )
169
+ end
170
+
171
+ def test_delete
172
+ # by index
173
+ assert_equal(["B", 2], @row.delete(1))
174
+
175
+ # by header
176
+ assert_equal(["C", 3], @row.delete("C"))
177
+
178
+ # using a block
179
+ assert_equal(@row, @row.delete_if { |h, f| h == "A" and not f.nil? })
180
+ assert_equal([["A", nil]], @row.to_a)
181
+ end
182
+
183
+ def test_fields
184
+ # all fields
185
+ assert_equal([1, 2, 3, 4, nil], @row.fields)
186
+
187
+ # by header
188
+ assert_equal([1, 3], @row.fields("A", "C"))
189
+
190
+ # by index
191
+ assert_equal([2, 3, nil], @row.fields(1, 2, 10))
192
+
193
+ # by both
194
+ assert_equal([2, 3, 4], @row.fields("B", "C", 3))
195
+
196
+ # with minimum indices
197
+ assert_equal([2, 3, 4], @row.fields("B", "C", ["A", 3]))
198
+
199
+ # by header range
200
+ assert_equal([2, 3], @row.values_at("B".."C"))
201
+ end
202
+
203
+ def test_index
204
+ # basic usage
205
+ assert_equal(0, @row.index("A"))
206
+ assert_equal(1, @row.index("B"))
207
+ assert_equal(2, @row.index("C"))
208
+ assert_equal(nil, @row.index("Z"))
209
+
210
+ # with minimum index
211
+ assert_equal(0, @row.index("A"))
212
+ assert_equal(0, @row.index("A", 0))
213
+ assert_equal(3, @row.index("A", 1))
214
+ assert_equal(3, @row.index("A", 2))
215
+ assert_equal(3, @row.index("A", 3))
216
+ assert_equal(4, @row.index("A", 4))
217
+ assert_equal(nil, @row.index("A", 5))
218
+ end
219
+
220
+ def test_queries
221
+ # headers
222
+ assert(@row.header?("A"))
223
+ assert(@row.header?("C"))
224
+ assert(!@row.header?("Z"))
225
+ assert(@row.include?("A")) # alias
226
+
227
+ # fields
228
+ assert(@row.field?(4))
229
+ assert(@row.field?(nil))
230
+ assert(!@row.field?(10))
231
+ end
232
+
233
+ def test_each
234
+ # array style
235
+ ary = @row.to_a
236
+ @row.each do |pair|
237
+ assert_equal(ary.first.first, pair.first)
238
+ assert_equal(ary.shift.last, pair.last)
239
+ end
240
+
241
+ # hash style
242
+ ary = @row.to_a
243
+ @row.each do |header, field|
244
+ assert_equal(ary.first.first, header)
245
+ assert_equal(ary.shift.last, field)
246
+ end
247
+
248
+ # verify that we can chain the call
249
+ assert_equal(@row, @row.each { })
250
+ end
251
+
252
+ def test_enumerable
253
+ assert_equal( [["A", 1], ["A", 4], ["A", nil]],
254
+ @row.select { |pair| pair.first == "A" } )
255
+
256
+ assert_equal(10, @row.inject(0) { |sum, (header, n)| sum + (n || 0) })
257
+ end
258
+
259
+ def test_to_a
260
+ row = FasterCSV::Row.new(%w{A B C}, [1, 2, 3]).to_a
261
+ assert_instance_of(Array, row)
262
+ row.each do |pair|
263
+ assert_instance_of(Array, pair)
264
+ assert_equal(2, pair.size)
265
+ end
266
+ assert_equal([["A", 1], ["B", 2], ["C", 3]], row)
267
+ end
268
+
269
+ def test_to_hash
270
+ assert_equal({"A" => nil, "B" => 2, "C" => 3}, @row.to_hash)
271
+ end
272
+
273
+ def test_to_csv
274
+ # normal conversion
275
+ assert_equal("1,2,3,4,\n", @row.to_csv)
276
+ assert_equal("1,2,3,4,\n", @row.to_s) # alias
277
+
278
+ # with options
279
+ assert_equal( "1|2|3|4|\r\n",
280
+ @row.to_csv(:col_sep => "|", :row_sep => "\r\n") )
281
+ end
282
+
283
+ def test_array_delegation
284
+ assert(!@row.empty?, "Row was empty.")
285
+
286
+ assert_equal([@row.headers.size, @row.fields.size].max, @row.size)
287
+ end
288
+
289
+ def test_inspect_shows_header_field_pairs
290
+ str = @row.inspect
291
+ @row.each do |header, field|
292
+ assert( str.include?("#{header.inspect}:#{field.inspect}"),
293
+ "Header field pair not found." )
294
+ end
295
+ end
296
+
297
+ def test_inspect_shows_symbol_headers_as_bare_attributes
298
+ str = FasterCSV::Row.new( @row.headers.map { |h| h.to_sym },
299
+ @row.fields ).inspect
300
+ @row.each do |header, field|
301
+ assert( str.include?("#{header}:#{field.inspect}"),
302
+ "Header field pair not found." )
303
+ end
304
+ end
305
+ end