fastcsv 0.0.2 → 0.0.3

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,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