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,45 @@
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 TestFasterCSVRPCases < Test::Unit::TestCase
13
+ def setup
14
+ @path = File.join(File.dirname(__FILE__), "export.csv")
15
+ end
16
+
17
+ def teardown
18
+ # File.unlink(@path)
19
+ end
20
+
21
+ #RPBS-2760
22
+ def test_failed_export
23
+ lines = []
24
+ csv = FasterCSV.open(@path, :raise_exception => true)
25
+ assert_raise(FasterCSV::MalformedCSVError) do
26
+ while line = csv.gets
27
+ lines<<line
28
+ end
29
+ end
30
+ assert_equal(4,lines.size)
31
+ end
32
+
33
+ def test_success_export
34
+ lines = []
35
+ csv = FasterCSV.open(@path, :raise_exception => false)
36
+ assert_nothing_raised do
37
+ while line = csv.gets
38
+ lines<<line
39
+ end
40
+ end
41
+ assert_equal(5,lines.size)
42
+ end
43
+
44
+
45
+ end
@@ -0,0 +1,154 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ # tc_serialization.rb
4
+ #
5
+ # Created by James Edward Gray II on 2006-03-28.
6
+ # Copyright 2006 Gray Productions. All rights reserved.
7
+
8
+ require "test/unit"
9
+
10
+ require "faster_csv"
11
+
12
+ # An example of how to provide custom CSV serialization.
13
+ class Hash
14
+ def self.csv_load( meta, headers, fields )
15
+ self[*headers.zip(fields).flatten.map { |e| eval(e) }]
16
+ end
17
+
18
+ def csv_headers
19
+ keys.map { |key| key.inspect }
20
+ end
21
+
22
+ def csv_dump( headers )
23
+ headers.map { |header| fetch(eval(header)).inspect }
24
+ end
25
+ end
26
+
27
+ class TestSerialization < Test::Unit::TestCase
28
+
29
+ ### Classes Used to Test Serialization ###
30
+
31
+ class ReadOnlyName
32
+ def initialize( first, last )
33
+ @first, @last = first, last
34
+ end
35
+
36
+ attr_reader :first, :last
37
+
38
+ def ==( other )
39
+ %w{first last}.all? { |att| send(att) == other.send(att) }
40
+ end
41
+ end
42
+
43
+ Name = Struct.new(:first, :last)
44
+
45
+ class FullName < Name
46
+ def initialize( first, last, suffix = nil )
47
+ super(first, last)
48
+
49
+ @suffix = suffix
50
+ end
51
+
52
+ attr_accessor :suffix
53
+
54
+ def ==( other )
55
+ %w{first last suffix}.all? { |att| send(att) == other.send(att) }
56
+ end
57
+ end
58
+
59
+ ### Tests ###
60
+
61
+ def test_class_dump
62
+ @names = [ %w{James Gray},
63
+ %w{Dana Gray},
64
+ %w{Greg Brown} ].map do |first, last|
65
+ ReadOnlyName.new(first, last)
66
+ end
67
+
68
+ assert_nothing_raised(Exception) do
69
+ @data = FasterCSV.dump(@names)
70
+ end
71
+ assert_equal(<<-END_CLASS_DUMP.gsub(/^\s*/, ""), @data)
72
+ class,TestSerialization::ReadOnlyName
73
+ @first,@last
74
+ James,Gray
75
+ Dana,Gray
76
+ Greg,Brown
77
+ END_CLASS_DUMP
78
+ end
79
+
80
+ def test_struct_dump
81
+ @names = [ %w{James Gray},
82
+ %w{Dana Gray},
83
+ %w{Greg Brown} ].map do |first, last|
84
+ Name.new(first, last)
85
+ end
86
+
87
+ assert_nothing_raised(Exception) do
88
+ @data = FasterCSV.dump(@names)
89
+ end
90
+ assert_equal(<<-END_STRUCT_DUMP.gsub(/^\s*/, ""), @data)
91
+ class,TestSerialization::Name
92
+ first=,last=
93
+ James,Gray
94
+ Dana,Gray
95
+ Greg,Brown
96
+ END_STRUCT_DUMP
97
+ end
98
+
99
+ def test_inherited_struct_dump
100
+ @names = [ %w{James Gray II},
101
+ %w{Dana Gray},
102
+ %w{Greg Brown} ].map do |first, last, suffix|
103
+ FullName.new(first, last, suffix)
104
+ end
105
+
106
+ assert_nothing_raised(Exception) do
107
+ @data = FasterCSV.dump(@names)
108
+ end
109
+ assert_equal(<<-END_STRUCT_DUMP.gsub(/^\s*/, ""), @data)
110
+ class,TestSerialization::FullName
111
+ @suffix,first=,last=
112
+ II,James,Gray
113
+ ,Dana,Gray
114
+ ,Greg,Brown
115
+ END_STRUCT_DUMP
116
+ end
117
+
118
+ def test_load
119
+ %w{ test_class_dump
120
+ test_struct_dump
121
+ test_inherited_struct_dump }.each do |test|
122
+ send(test)
123
+ FasterCSV.load(@data).each do |loaded|
124
+ assert_instance_of(@names.first.class, loaded)
125
+ assert_equal(@names.shift, loaded)
126
+ end
127
+ end
128
+ end
129
+
130
+ def test_io
131
+ test_class_dump
132
+
133
+ data_file = File.join(File.dirname(__FILE__), "temp_test_data.csv")
134
+ FasterCSV.dump(@names, File.open(data_file, "w"))
135
+
136
+ assert(File.exist?(data_file))
137
+ assert_equal(<<-END_IO_DUMP.gsub(/^\s*/, ""), File.read(data_file))
138
+ class,TestSerialization::ReadOnlyName
139
+ @first,@last
140
+ James,Gray
141
+ Dana,Gray
142
+ Greg,Brown
143
+ END_IO_DUMP
144
+
145
+ assert_equal(@names, FasterCSV.load(File.open(data_file)))
146
+
147
+ File.unlink(data_file)
148
+ end
149
+
150
+ def test_custom_dump_and_load
151
+ obj = {1 => "simple", :test => Hash}
152
+ assert_equal(obj, FasterCSV.load(FasterCSV.dump([obj])).first)
153
+ end
154
+ end
data/test/tc_speed.rb ADDED
@@ -0,0 +1,65 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ # tc_speed.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
+ require "timeout"
10
+
11
+ require "faster_csv"
12
+ require "csv"
13
+
14
+ class TestFasterCSVSpeed < Test::Unit::TestCase
15
+ PATH = File.join(File.dirname(__FILE__), "test_data.csv")
16
+ BIG_DATA = "123456789\n" * 1024
17
+
18
+ def test_that_we_are_doing_the_same_work
19
+ FasterCSV.open(PATH) do |csv|
20
+ CSV.foreach(PATH) do |row|
21
+ assert_equal(row, csv.shift)
22
+ end
23
+ end
24
+ end
25
+
26
+ def test_speed_vs_csv
27
+ csv_time = Time.now
28
+ CSV.foreach(PATH) do |row|
29
+ # do nothing, we're just timing a read...
30
+ end
31
+ csv_time = Time.now - csv_time
32
+
33
+ faster_csv_time = Time.now
34
+ FasterCSV.foreach(PATH) do |row|
35
+ # do nothing, we're just timing a read...
36
+ end
37
+ faster_csv_time = Time.now - faster_csv_time
38
+
39
+ assert(faster_csv_time < csv_time / 3)
40
+ end
41
+
42
+ def test_the_parse_fails_fast_when_it_can_for_unquoted_fields
43
+ assert_parse_errors_out('valid,fields,bad start"' + BIG_DATA)
44
+ end
45
+
46
+ def test_the_parse_fails_fast_when_it_can_for_unescaped_quotes
47
+ assert_parse_errors_out('valid,fields,"bad start"unescaped' + BIG_DATA)
48
+ end
49
+
50
+ def test_field_size_limit_controls_lookahead
51
+ assert_parse_errors_out( 'valid,fields,"' + BIG_DATA + '"',
52
+ :field_size_limit => 2048 )
53
+ end
54
+
55
+ private
56
+
57
+ def assert_parse_errors_out(*args)
58
+ assert_raise(FasterCSV::MalformedCSVError) do
59
+ Timeout.timeout(0.2) do
60
+ FasterCSV.parse(*args)
61
+ fail("Parse didn't error out")
62
+ end
63
+ end
64
+ end
65
+ end
data/test/tc_table.rb ADDED
@@ -0,0 +1,408 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ # tc_table.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 TestFasterCSVTable < Test::Unit::TestCase
13
+ def setup
14
+ @rows = [ FasterCSV::Row.new(%w{A B C}, [1, 2, 3]),
15
+ FasterCSV::Row.new(%w{A B C}, [4, 5, 6]),
16
+ FasterCSV::Row.new(%w{A B C}, [7, 8, 9]) ]
17
+ @table = FasterCSV::Table.new(@rows)
18
+
19
+ @header_table = FasterCSV::Table.new(
20
+ [FasterCSV::Row.new(%w{A B C}, %w{A B C}, true)] + @rows
21
+ )
22
+ end
23
+
24
+ def test_initialze
25
+ assert_not_nil(@table)
26
+ assert_instance_of(FasterCSV::Table, @table)
27
+ end
28
+
29
+ def test_modes
30
+ assert_equal(:col_or_row, @table.mode)
31
+
32
+ # non-destructive changes, intended for one shot calls
33
+ cols = @table.by_col
34
+ assert_equal(:col_or_row, @table.mode)
35
+ assert_equal(:col, cols.mode)
36
+ assert_equal(@table, cols)
37
+
38
+ rows = @table.by_row
39
+ assert_equal(:col_or_row, @table.mode)
40
+ assert_equal(:row, rows.mode)
41
+ assert_equal(@table, rows)
42
+
43
+ # destructive mode changing calls
44
+ assert_equal(@table, @table.by_row!)
45
+ assert_equal(:row, @table.mode)
46
+ assert_equal(@table, @table.by_col_or_row!)
47
+ assert_equal(:col_or_row, @table.mode)
48
+ end
49
+
50
+ def test_headers
51
+ assert_equal(@rows.first.headers, @table.headers)
52
+ end
53
+
54
+ def test_index
55
+ ##################
56
+ ### Mixed Mode ###
57
+ ##################
58
+ # by row
59
+ @rows.each_index { |i| assert_equal(@rows[i], @table[i]) }
60
+ assert_equal(nil, @table[100]) # empty row
61
+
62
+ # by col
63
+ @rows.first.headers.each do |header|
64
+ assert_equal(@rows.map { |row| row[header] }, @table[header])
65
+ end
66
+ assert_equal([nil] * @rows.size, @table["Z"]) # empty col
67
+
68
+ # by cell, row then col
69
+ assert_equal(2, @table[0][1])
70
+ assert_equal(6, @table[1]["C"])
71
+
72
+ # by cell, col then row
73
+ assert_equal(5, @table["B"][1])
74
+ assert_equal(9, @table["C"][2])
75
+
76
+ # with headers (by col)
77
+ assert_equal(["B", 2, 5, 8], @header_table["B"])
78
+
79
+ ###################
80
+ ### Column Mode ###
81
+ ###################
82
+ @table.by_col!
83
+
84
+ assert_equal([2, 5, 8], @table[1])
85
+ assert_equal([2, 5, 8], @table["B"])
86
+
87
+ ################
88
+ ### Row Mode ###
89
+ ################
90
+ @table.by_row!
91
+
92
+ assert_equal(@rows[1], @table[1])
93
+ assert_raise(TypeError) { @table["B"] }
94
+
95
+ ############################
96
+ ### One Shot Mode Change ###
97
+ ############################
98
+ assert_equal(@rows[1], @table[1])
99
+ assert_equal([2, 5, 8], @table.by_col[1])
100
+ assert_equal(@rows[1], @table[1])
101
+ end
102
+
103
+ def test_set_row_or_column
104
+ ##################
105
+ ### Mixed Mode ###
106
+ ##################
107
+ # set row
108
+ @table[2] = [10, 11, 12]
109
+ assert_equal([%w[A B C], [1, 2, 3], [4, 5, 6], [10, 11, 12]], @table.to_a)
110
+
111
+ @table[3] = FasterCSV::Row.new(%w[A B C], [13, 14, 15])
112
+ assert_equal( [%w[A B C], [1, 2, 3], [4, 5, 6], [10, 11, 12], [13, 14, 15]],
113
+ @table.to_a )
114
+
115
+ # set col
116
+ @table["Type"] = "data"
117
+ assert_equal( [ %w[A B C Type],
118
+ [1, 2, 3, "data"],
119
+ [4, 5, 6, "data"],
120
+ [10, 11, 12, "data"],
121
+ [13, 14, 15, "data"] ],
122
+ @table.to_a )
123
+
124
+ @table["Index"] = [1, 2, 3]
125
+ assert_equal( [ %w[A B C Type Index],
126
+ [1, 2, 3, "data", 1],
127
+ [4, 5, 6, "data", 2],
128
+ [10, 11, 12, "data", 3],
129
+ [13, 14, 15, "data", nil] ],
130
+ @table.to_a )
131
+
132
+ @table["B"] = [100, 200]
133
+ assert_equal( [ %w[A B C Type Index],
134
+ [1, 100, 3, "data", 1],
135
+ [4, 200, 6, "data", 2],
136
+ [10, nil, 12, "data", 3],
137
+ [13, nil, 15, "data", nil] ],
138
+ @table.to_a )
139
+
140
+ # verify resulting table
141
+ assert_equal(<<-END_RESULT.gsub(/^\s+/, ""), @table.to_csv)
142
+ A,B,C,Type,Index
143
+ 1,100,3,data,1
144
+ 4,200,6,data,2
145
+ 10,,12,data,3
146
+ 13,,15,data,
147
+ END_RESULT
148
+
149
+ # with headers
150
+ @header_table["Type"] = "data"
151
+ assert_equal(%w[Type data data data], @header_table["Type"])
152
+
153
+ ###################
154
+ ### Column Mode ###
155
+ ###################
156
+ @table.by_col!
157
+
158
+ @table[1] = [2, 5, 11, 14]
159
+ assert_equal( [ %w[A B C Type Index],
160
+ [1, 2, 3, "data", 1],
161
+ [4, 5, 6, "data", 2],
162
+ [10, 11, 12, "data", 3],
163
+ [13, 14, 15, "data", nil] ],
164
+ @table.to_a )
165
+
166
+ @table["Extra"] = "new stuff"
167
+ assert_equal( [ %w[A B C Type Index Extra],
168
+ [1, 2, 3, "data", 1, "new stuff"],
169
+ [4, 5, 6, "data", 2, "new stuff"],
170
+ [10, 11, 12, "data", 3, "new stuff"],
171
+ [13, 14, 15, "data", nil, "new stuff"] ],
172
+ @table.to_a )
173
+
174
+ ################
175
+ ### Row Mode ###
176
+ ################
177
+ @table.by_row!
178
+
179
+ @table[1] = (1..6).to_a
180
+ assert_equal( [ %w[A B C Type Index Extra],
181
+ [1, 2, 3, "data", 1, "new stuff"],
182
+ [1, 2, 3, 4, 5, 6],
183
+ [10, 11, 12, "data", 3, "new stuff"],
184
+ [13, 14, 15, "data", nil, "new stuff"] ],
185
+ @table.to_a )
186
+
187
+ assert_raise(TypeError) { @table["Extra"] = nil }
188
+ end
189
+
190
+ def test_each
191
+ ######################
192
+ ### Mixed/Row Mode ###
193
+ ######################
194
+ i = 0
195
+ @table.each do |row|
196
+ assert_equal(@rows[i], row)
197
+ i += 1
198
+ end
199
+
200
+ # verify that we can chain the call
201
+ assert_equal(@table, @table.each { })
202
+
203
+ ###################
204
+ ### Column Mode ###
205
+ ###################
206
+ @table.by_col!
207
+
208
+ headers = @table.headers
209
+ @table.each do |header, column|
210
+ assert_equal(headers.shift, header)
211
+ assert_equal(@table[header], column)
212
+ end
213
+
214
+ ############################
215
+ ### One Shot Mode Change ###
216
+ ############################
217
+ @table.by_col_or_row!
218
+
219
+ @table.each { |row| assert_instance_of(FasterCSV::Row, row) }
220
+ @table.by_col.each { |tuple| assert_instance_of(Array, tuple) }
221
+ @table.each { |row| assert_instance_of(FasterCSV::Row, row) }
222
+ end
223
+
224
+ def test_enumerable
225
+ assert_equal( @rows.values_at(0, 2),
226
+ @table.select { |row| (row["B"] % 2).zero? } )
227
+
228
+ assert_equal(@rows[1], @table.find { |row| row["C"] > 5 })
229
+ end
230
+
231
+ def test_to_a
232
+ assert_equal([%w[A B C], [1, 2, 3], [4, 5, 6], [7, 8, 9]], @table.to_a)
233
+
234
+ # with headers
235
+ assert_equal( [%w[A B C], [1, 2, 3], [4, 5, 6], [7, 8, 9]],
236
+ @header_table.to_a )
237
+ end
238
+
239
+ def test_to_csv
240
+ csv = <<-END_CSV.gsub(/^\s+/, "")
241
+ A,B,C
242
+ 1,2,3
243
+ 4,5,6
244
+ 7,8,9
245
+ END_CSV
246
+
247
+ # normal conversion
248
+ assert_equal(csv, @table.to_csv)
249
+ assert_equal(csv, @table.to_s) # alias
250
+
251
+ # with options
252
+ assert_equal( csv.gsub(",", "|").gsub("\n", "\r\n"),
253
+ @table.to_csv(:col_sep => "|", :row_sep => "\r\n") )
254
+ assert_equal( csv.to_a[1..-1].join,
255
+ @table.to_csv(:write_headers => false) )
256
+
257
+ # with headers
258
+ assert_equal(csv, @header_table.to_csv)
259
+ end
260
+
261
+ def test_append
262
+ # verify that we can chain the call
263
+ assert_equal(@table, @table << [10, 11, 12])
264
+
265
+ # Array append
266
+ assert_equal(FasterCSV::Row.new(%w[A B C], [10, 11, 12]), @table[-1])
267
+
268
+ # Row append
269
+ assert_equal(@table, @table << FasterCSV::Row.new(%w[A B C], [13, 14, 15]))
270
+ assert_equal(FasterCSV::Row.new(%w[A B C], [13, 14, 15]), @table[-1])
271
+ end
272
+
273
+ def test_delete
274
+ ##################
275
+ ### Mixed Mode ###
276
+ ##################
277
+ # delete a row
278
+ assert_equal(@rows[1], @table.delete(1))
279
+
280
+ # delete a col
281
+ assert_equal(@rows.map { |row| row["A"] }, @table.delete("A"))
282
+
283
+ # verify resulting table
284
+ assert_equal(<<-END_RESULT.gsub(/^\s+/, ""), @table.to_csv)
285
+ B,C
286
+ 2,3
287
+ 8,9
288
+ END_RESULT
289
+
290
+ ###################
291
+ ### Column Mode ###
292
+ ###################
293
+ setup
294
+ @table.by_col!
295
+
296
+ assert_equal(@rows.map { |row| row[0] }, @table.delete(0))
297
+ assert_equal(@rows.map { |row| row["C"] }, @table.delete("C"))
298
+
299
+ # verify resulting table
300
+ assert_equal(<<-END_RESULT.gsub(/^\s+/, ""), @table.to_csv)
301
+ B
302
+ 2
303
+ 5
304
+ 8
305
+ END_RESULT
306
+
307
+ ################
308
+ ### Row Mode ###
309
+ ################
310
+ setup
311
+ @table.by_row!
312
+
313
+ assert_equal(@rows[1], @table.delete(1))
314
+ assert_raise(TypeError) { @table.delete("C") }
315
+
316
+ # verify resulting table
317
+ assert_equal(<<-END_RESULT.gsub(/^\s+/, ""), @table.to_csv)
318
+ A,B,C
319
+ 1,2,3
320
+ 7,8,9
321
+ END_RESULT
322
+ end
323
+
324
+ def test_delete_with_blank_rows
325
+ data = "col1,col2\nra1,ra2\n\nrb1,rb2"
326
+ table = FasterCSV.parse(data, :headers => true)
327
+ assert_equal(["ra2", nil, "rb2"], table.delete("col2"))
328
+ end
329
+
330
+ def test_delete_if
331
+ ######################
332
+ ### Mixed/Row Mode ###
333
+ ######################
334
+ # verify that we can chain the call
335
+ assert_equal(@table, @table.delete_if { |row| (row["B"] % 2).zero? })
336
+
337
+ # verify resulting table
338
+ assert_equal(<<-END_RESULT.gsub(/^\s+/, ""), @table.to_csv)
339
+ A,B,C
340
+ 4,5,6
341
+ END_RESULT
342
+
343
+ ###################
344
+ ### Column Mode ###
345
+ ###################
346
+ setup
347
+ @table.by_col!
348
+
349
+ assert_equal(@table, @table.delete_if { |h, v| h > "A" })
350
+ assert_equal(<<-END_RESULT.gsub(/^\s+/, ""), @table.to_csv)
351
+ A
352
+ 1
353
+ 4
354
+ 7
355
+ END_RESULT
356
+ end
357
+
358
+ def test_values_at
359
+ ##################
360
+ ### Mixed Mode ###
361
+ ##################
362
+ # rows
363
+ assert_equal(@rows.values_at(0, 2), @table.values_at(0, 2))
364
+ assert_equal(@rows.values_at(1..2), @table.values_at(1..2))
365
+
366
+ # cols
367
+ assert_equal([[1, 3], [4, 6], [7, 9]], @table.values_at("A", "C"))
368
+ assert_equal([[2, 3], [5, 6], [8, 9]], @table.values_at("B".."C"))
369
+
370
+ ###################
371
+ ### Column Mode ###
372
+ ###################
373
+ @table.by_col!
374
+
375
+ assert_equal([[1, 3], [4, 6], [7, 9]], @table.values_at(0, 2))
376
+ assert_equal([[1, 3], [4, 6], [7, 9]], @table.values_at("A", "C"))
377
+
378
+ ################
379
+ ### Row Mode ###
380
+ ################
381
+ @table.by_row!
382
+
383
+ assert_equal(@rows.values_at(0, 2), @table.values_at(0, 2))
384
+ assert_raise(TypeError) { @table.values_at("A", "C") }
385
+
386
+ ############################
387
+ ### One Shot Mode Change ###
388
+ ############################
389
+ assert_equal(@rows.values_at(0, 2), @table.values_at(0, 2))
390
+ assert_equal([[1, 3], [4, 6], [7, 9]], @table.by_col.values_at(0, 2))
391
+ assert_equal(@rows.values_at(0, 2), @table.values_at(0, 2))
392
+ end
393
+
394
+ def test_array_delegation
395
+ assert(!@table.empty?, "Table was empty.")
396
+
397
+ assert_equal(@rows.size, @table.size)
398
+ end
399
+
400
+ def test_inspect_shows_current_mode
401
+ str = @table.inspect
402
+ assert(str.include?("mode:#{@table.mode}"), "Mode not shown.")
403
+
404
+ @table.by_col!
405
+ str = @table.inspect
406
+ assert(str.include?("mode:#{@table.mode}"), "Mode not shown.")
407
+ end
408
+ end