rw_fastercsv 1.5.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -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