fastcsv 0.0.2 → 0.0.3

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