StephanZ-fastercsv 1.4.0 → 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,23 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ # tc_encodings.rb
4
+ #
5
+ # Created by Michael Reinsch.
6
+ # Copyright (c) 2008 Ubiquitous Business Technology, Inc.
7
+
8
+ require "test/unit"
9
+
10
+ require "faster_csv"
11
+
12
+ class TestEncodings < Test::Unit::TestCase
13
+ def test_with_shift_jis_encoding
14
+ $KCODE = 'u' # make sure $KCODE != Shift_JIS
15
+ # this test data will not work with UTF-8 encoding
16
+ shift_jis_data = [ "82D082E782AA82C82094E0",
17
+ "82D082E7826082AA825C",
18
+ "82D082E7826082AA82C8" ].map { |f| [f].pack("H*") }
19
+ fields = FCSV.parse_line( shift_jis_data.map { |f| %Q{"#{f}"} }.join(","),
20
+ :encoding => "s" )
21
+ assert_equal(shift_jis_data, fields)
22
+ end
23
+ end
@@ -0,0 +1,212 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ # tc_features.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 "zlib"
10
+
11
+ require "faster_csv"
12
+
13
+ class TestFasterCSVFeatures < Test::Unit::TestCase
14
+ TEST_CASES = [ [%Q{a,b}, ["a", "b"]],
15
+ [%Q{a,"""b"""}, ["a", "\"b\""]],
16
+ [%Q{a,"""b"}, ["a", "\"b"]],
17
+ [%Q{a,"b"""}, ["a", "b\""]],
18
+ [%Q{a,"\nb"""}, ["a", "\nb\""]],
19
+ [%Q{a,"""\nb"}, ["a", "\"\nb"]],
20
+ [%Q{a,"""\nb\n"""}, ["a", "\"\nb\n\""]],
21
+ [%Q{a,"""\nb\n""",\nc}, ["a", "\"\nb\n\"", nil]],
22
+ [%Q{a,,,}, ["a", nil, nil, nil]],
23
+ [%Q{,}, [nil, nil]],
24
+ [%Q{"",""}, ["", ""]],
25
+ [%Q{""""}, ["\""]],
26
+ [%Q{"""",""}, ["\"",""]],
27
+ [%Q{,""}, [nil,""]],
28
+ [%Q{,"\r"}, [nil,"\r"]],
29
+ [%Q{"\r\n,"}, ["\r\n,"]],
30
+ [%Q{"\r\n,",}, ["\r\n,", nil]] ]
31
+
32
+ def setup
33
+ @sample_data = <<-END_DATA.gsub(/^ +/, "")
34
+ line,1,abc
35
+ line,2,"def\nghi"
36
+
37
+ line,4,jkl
38
+ END_DATA
39
+ @csv = FasterCSV.new(@sample_data)
40
+ end
41
+
42
+ def test_col_sep
43
+ [";", "\t"].each do |sep|
44
+ TEST_CASES.each do |test_case|
45
+ assert_equal( test_case.last.map { |t| t.tr(",", sep) unless t.nil? },
46
+ FasterCSV.parse_line( test_case.first.tr(",", sep),
47
+ :col_sep => sep ) )
48
+ end
49
+ end
50
+ assert_equal( [",,,", nil],
51
+ FasterCSV.parse_line(",,,;", :col_sep => ";") )
52
+ end
53
+
54
+ def test_row_sep
55
+ assert_raise(FasterCSV::MalformedCSVError) do
56
+ FasterCSV.parse_line("1,2,3\n,4,5\r\n", :row_sep => "\r\n")
57
+ end
58
+ assert_equal( ["1", "2", "3\n", "4", "5"],
59
+ FasterCSV.parse_line( %Q{1,2,"3\n",4,5\r\n},
60
+ :row_sep => "\r\n") )
61
+ end
62
+
63
+ def test_quote_char
64
+ TEST_CASES.each do |test_case|
65
+ assert_equal( test_case.last.map { |t| t.tr('"', "'") unless t.nil? },
66
+ FasterCSV.parse_line( test_case.first.tr('"', "'"),
67
+ :quote_char => "'" ) )
68
+ end
69
+ end
70
+
71
+ def test_row_sep_auto_discovery
72
+ ["\r\n", "\n", "\r"].each do |line_end|
73
+ data = "1,2,3#{line_end}4,5#{line_end}"
74
+ discovered = FasterCSV.new(data).instance_eval { @row_sep }
75
+ assert_equal(line_end, discovered)
76
+ end
77
+
78
+ assert_equal("\n", FasterCSV.new("\n\r\n\r").instance_eval { @row_sep })
79
+
80
+ assert_equal($/, FasterCSV.new("").instance_eval { @row_sep })
81
+
82
+ assert_equal($/, FasterCSV.new(STDERR).instance_eval { @row_sep })
83
+ end
84
+
85
+ def test_lineno
86
+ assert_equal(5, @sample_data.to_a.size)
87
+
88
+ 4.times do |line_count|
89
+ assert_equal(line_count, @csv.lineno)
90
+ assert_not_nil(@csv.shift)
91
+ assert_equal(line_count + 1, @csv.lineno)
92
+ end
93
+ assert_nil(@csv.shift)
94
+ end
95
+
96
+ def test_readline
97
+ test_lineno
98
+
99
+ @csv.rewind
100
+
101
+ test_lineno
102
+ end
103
+
104
+ def test_unknown_options
105
+ assert_raise(ArgumentError) do
106
+ FasterCSV.new(String.new, :unknown => :error)
107
+ end
108
+ end
109
+
110
+ def test_skip_blanks
111
+ assert_equal(4, @csv.to_a.size)
112
+
113
+ @csv = FasterCSV.new(@sample_data, :skip_blanks => true)
114
+
115
+ count = 0
116
+ @csv.each do |row|
117
+ count += 1
118
+ assert_equal("line", row.first)
119
+ end
120
+ assert_equal(3, count)
121
+ end
122
+
123
+ # reported by Kev Jackson
124
+ def test_failing_to_escape_col_sep_bug_fix
125
+ assert_nothing_raised(Exception) do
126
+ FasterCSV.new(String.new, :col_sep => "|")
127
+ end
128
+ end
129
+
130
+ # reported by Chris Roos
131
+ def test_failing_to_reset_headers_in_rewind_bug_fix
132
+ csv = FasterCSV.new( "forename,surname", :headers => true,
133
+ :return_headers => true )
134
+ csv.each { |row| assert row.header_row? }
135
+ csv.rewind
136
+ csv.each { |row| assert row.header_row? }
137
+ end
138
+
139
+ # reported by Dave Burt
140
+ def test_leading_empty_fields_with_multibyte_col_sep_bug_fix
141
+ data = <<-END_DATA.gsub(/^\s+/, "")
142
+ <=><=>A<=>B<=>C
143
+ 1<=>2<=>3
144
+ END_DATA
145
+ parsed = FasterCSV.parse(data, :col_sep => "<=>")
146
+ assert_equal([[nil, nil, "A", "B", "C"], ["1", "2", "3"]], parsed)
147
+ end
148
+
149
+ def test_gzip_reader_bug_fix
150
+ zipped = nil
151
+ assert_nothing_raised(NoMethodError) do
152
+ zipped = FasterCSV.new(
153
+ Zlib::GzipReader.open(
154
+ File.join(File.dirname(__FILE__), "line_endings.gz")
155
+ )
156
+ )
157
+ end
158
+ assert_equal("\r\n", zipped.instance_eval { @row_sep })
159
+ end
160
+
161
+ def test_gzip_writer_bug_fix
162
+ file = File.join(File.dirname(__FILE__), "temp.gz")
163
+ zipped = nil
164
+ assert_nothing_raised(NoMethodError) do
165
+ zipped = FasterCSV.new(Zlib::GzipWriter.open(file))
166
+ end
167
+ zipped << %w[one two three]
168
+ zipped << [1, 2, 3]
169
+ zipped.close
170
+
171
+ assert( Zlib::GzipReader.open(file) { |f| f.read }.
172
+ include?($INPUT_RECORD_SEPARATOR),
173
+ "@row_sep did not default" )
174
+ File.unlink(file)
175
+ end
176
+
177
+ def test_inspect_is_smart_about_io_types
178
+ str = FasterCSV.new("string,data").inspect
179
+ assert(str.include?("io_type:StringIO"), "IO type not detected.")
180
+
181
+ str = FasterCSV.new($stderr).inspect
182
+ assert(str.include?("io_type:$stderr"), "IO type not detected.")
183
+
184
+ str = FasterCSV.open( File.join( File.dirname(__FILE__),
185
+ "test_data.csv" ) ) { |csv| csv.inspect }
186
+ assert(str.include?("io_type:File"), "IO type not detected.")
187
+ end
188
+
189
+ def test_inspect_shows_key_attributes
190
+ str = @csv.inspect
191
+ %w[lineno col_sep row_sep quote_char].each do |attr_name|
192
+ assert_match(/\b#{attr_name}:[^\s>]+/, str)
193
+ end
194
+ end
195
+
196
+ def test_inspect_shows_headers_when_available
197
+ FasterCSV.open( File.join( File.dirname(__FILE__),
198
+ "test_data.csv" ),
199
+ :headers => true ) do |csv|
200
+ assert(csv.inspect.include?("headers:true"), "Header hint not shown.")
201
+ csv.shift # load headers
202
+ assert_match(/headers:\[[^\]]+\]/, csv.inspect)
203
+ end
204
+ end
205
+
206
+ def test_version
207
+ assert_not_nil(FasterCSV::VERSION)
208
+ assert_instance_of(String, FasterCSV::VERSION)
209
+ assert(FasterCSV::VERSION.frozen?)
210
+ assert_match(/\A\d\.\d\.\d\Z/, FasterCSV::VERSION)
211
+ end
212
+ end
@@ -0,0 +1,277 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ # tc_headers.rb
4
+ #
5
+ # Created by James Edward Gray II on 2006-02-25.
6
+ # Copyright 2006 Gray Productions. All rights reserved.
7
+
8
+ require "test/unit"
9
+
10
+ require "faster_csv"
11
+
12
+ class TestFasterCSVHeaders < Test::Unit::TestCase
13
+ def setup
14
+ @data = <<-END_CSV.gsub(/^\s+/, "")
15
+ first,second,third
16
+ A,B,C
17
+ 1,2,3
18
+ END_CSV
19
+ end
20
+
21
+ def test_first_row
22
+ [:first_row, true].each do |setting| # two names for the same setting
23
+ # activate headers
24
+ csv = nil
25
+ assert_nothing_raised(Exception) do
26
+ csv = FasterCSV.parse(@data, :headers => setting)
27
+ end
28
+
29
+ # first data row - skipping headers
30
+ row = csv[0]
31
+ assert_not_nil(row)
32
+ assert_instance_of(FasterCSV::Row, row)
33
+ assert_equal([%w{first A}, %w{second B}, %w{third C}], row.to_a)
34
+
35
+ # second data row
36
+ row = csv[1]
37
+ assert_not_nil(row)
38
+ assert_instance_of(FasterCSV::Row, row)
39
+ assert_equal([%w{first 1}, %w{second 2}, %w{third 3}], row.to_a)
40
+
41
+ # empty
42
+ assert_nil(csv[2])
43
+ end
44
+ end
45
+
46
+ def test_array_of_headers
47
+ # activate headers
48
+ csv = nil
49
+ assert_nothing_raised(Exception) do
50
+ csv = FasterCSV.parse(@data, :headers => [:my, :new, :headers])
51
+ end
52
+
53
+ # first data row - skipping headers
54
+ row = csv[0]
55
+ assert_not_nil(row)
56
+ assert_instance_of(FasterCSV::Row, row)
57
+ assert_equal( [[:my, "first"], [:new, "second"], [:headers, "third"]],
58
+ row.to_a )
59
+
60
+ # second data row
61
+ row = csv[1]
62
+ assert_not_nil(row)
63
+ assert_instance_of(FasterCSV::Row, row)
64
+ assert_equal([[:my, "A"], [:new, "B"], [:headers, "C"]], row.to_a)
65
+
66
+ # third data row
67
+ row = csv[2]
68
+ assert_not_nil(row)
69
+ assert_instance_of(FasterCSV::Row, row)
70
+ assert_equal([[:my, "1"], [:new, "2"], [:headers, "3"]], row.to_a)
71
+
72
+ # empty
73
+ assert_nil(csv[3])
74
+
75
+ # with return and convert
76
+ assert_nothing_raised(Exception) do
77
+ csv = FasterCSV.parse(@data, :headers => [:my, :new, :headers],
78
+ :return_headers => true,
79
+ :header_converters => lambda { |h| h.to_s } )
80
+ end
81
+ row = csv[0]
82
+ assert_not_nil(row)
83
+ assert_instance_of(FasterCSV::Row, row)
84
+ assert_equal( [["my", :my], ["new", :new], ["headers", :headers]],
85
+ row.to_a )
86
+ assert(row.header_row?)
87
+ assert(!row.field_row?)
88
+ end
89
+
90
+ def test_csv_header_string
91
+ # activate headers
92
+ csv = nil
93
+ assert_nothing_raised(Exception) do
94
+ csv = FasterCSV.parse(@data, :headers => "my,new,headers")
95
+ end
96
+
97
+ # first data row - skipping headers
98
+ row = csv[0]
99
+ assert_not_nil(row)
100
+ assert_instance_of(FasterCSV::Row, row)
101
+ assert_equal([%w{my first}, %w{new second}, %w{headers third}], row.to_a)
102
+
103
+ # second data row
104
+ row = csv[1]
105
+ assert_not_nil(row)
106
+ assert_instance_of(FasterCSV::Row, row)
107
+ assert_equal([%w{my A}, %w{new B}, %w{headers C}], row.to_a)
108
+
109
+ # third data row
110
+ row = csv[2]
111
+ assert_not_nil(row)
112
+ assert_instance_of(FasterCSV::Row, row)
113
+ assert_equal([%w{my 1}, %w{new 2}, %w{headers 3}], row.to_a)
114
+
115
+ # empty
116
+ assert_nil(csv[3])
117
+
118
+ # with return and convert
119
+ assert_nothing_raised(Exception) do
120
+ csv = FasterCSV.parse(@data, :headers => "my,new,headers",
121
+ :return_headers => true,
122
+ :header_converters => :symbol )
123
+ end
124
+ row = csv[0]
125
+ assert_not_nil(row)
126
+ assert_instance_of(FasterCSV::Row, row)
127
+ assert_equal( [[:my, "my"], [:new, "new"], [:headers, "headers"]],
128
+ row.to_a )
129
+ assert(row.header_row?)
130
+ assert(!row.field_row?)
131
+ end
132
+
133
+ def test_csv_header_string_inherits_separators
134
+ # parse with custom col_sep
135
+ csv = nil
136
+ assert_nothing_raised(Exception) do
137
+ csv = FasterCSV.parse( @data.tr(",", "|"), :col_sep => "|",
138
+ :headers => "my|new|headers" )
139
+ end
140
+
141
+ # verify headers were recognized
142
+ row = csv[0]
143
+ assert_not_nil(row)
144
+ assert_instance_of(FasterCSV::Row, row)
145
+ assert_equal([%w{my first}, %w{new second}, %w{headers third}], row.to_a)
146
+ end
147
+
148
+ def test_return_headers
149
+ # activate headers and request they are returned
150
+ csv = nil
151
+ assert_nothing_raised(Exception) do
152
+ csv = FasterCSV.parse(@data, :headers => true, :return_headers => true)
153
+ end
154
+
155
+ # header row
156
+ row = csv[0]
157
+ assert_not_nil(row)
158
+ assert_instance_of(FasterCSV::Row, row)
159
+ assert_equal( [%w{first first}, %w{second second}, %w{third third}],
160
+ row.to_a )
161
+ assert(row.header_row?)
162
+ assert(!row.field_row?)
163
+
164
+ # first data row - skipping headers
165
+ row = csv[1]
166
+ assert_not_nil(row)
167
+ assert_instance_of(FasterCSV::Row, row)
168
+ assert_equal([%w{first A}, %w{second B}, %w{third C}], row.to_a)
169
+ assert(!row.header_row?)
170
+ assert(row.field_row?)
171
+
172
+ # second data row
173
+ row = csv[2]
174
+ assert_not_nil(row)
175
+ assert_instance_of(FasterCSV::Row, row)
176
+ assert_equal([%w{first 1}, %w{second 2}, %w{third 3}], row.to_a)
177
+ assert(!row.header_row?)
178
+ assert(row.field_row?)
179
+
180
+ # empty
181
+ assert_nil(csv[3])
182
+ end
183
+
184
+ def test_converters
185
+ # create test data where headers and fields look alike
186
+ data = <<-END_MATCHING_CSV.gsub(/^\s+/, "")
187
+ 1,2,3
188
+ 1,2,3
189
+ END_MATCHING_CSV
190
+
191
+ # normal converters do not affect headers
192
+ csv = FasterCSV.parse( data, :headers => true,
193
+ :return_headers => true,
194
+ :converters => :numeric )
195
+ assert_equal([%w{1 1}, %w{2 2}, %w{3 3}], csv[0].to_a)
196
+ assert_equal([["1", 1], ["2", 2], ["3", 3]], csv[1].to_a)
197
+ assert_nil(csv[2])
198
+
199
+ # header converters do affect headers (only)
200
+ assert_nothing_raised(Exception) do
201
+ csv = FasterCSV.parse( data, :headers => true,
202
+ :return_headers => true,
203
+ :converters => :numeric,
204
+ :header_converters => :symbol )
205
+ end
206
+ assert_equal([[:"1", "1"], [:"2", "2"], [:"3", "3"]], csv[0].to_a)
207
+ assert_equal([[:"1", 1], [:"2", 2], [:"3", 3]], csv[1].to_a)
208
+ assert_nil(csv[2])
209
+ end
210
+
211
+ def test_builtin_downcase_converter
212
+ csv = FasterCSV.parse( "One,TWO Three", :headers => true,
213
+ :return_headers => true,
214
+ :header_converters => :downcase )
215
+ assert_equal(%w{one two\ three}, csv.headers)
216
+ end
217
+
218
+ def test_builtin_symbol_converter
219
+ csv = FasterCSV.parse( "One,TWO Three", :headers => true,
220
+ :return_headers => true,
221
+ :header_converters => :symbol )
222
+ assert_equal([:one, :two_three], csv.headers)
223
+ end
224
+
225
+ def test_custom_converter
226
+ converter = lambda { |header| header.tr(" ", "_") }
227
+ csv = FasterCSV.parse( "One,TWO Three",
228
+ :headers => true,
229
+ :return_headers => true,
230
+ :header_converters => converter )
231
+ assert_equal(%w{One TWO_Three}, csv.headers)
232
+ end
233
+
234
+ def test_table_support
235
+ csv = nil
236
+ assert_nothing_raised(Exception) do
237
+ csv = FasterCSV.parse(@data, :headers => true)
238
+ end
239
+
240
+ assert_instance_of(FasterCSV::Table, csv)
241
+ end
242
+
243
+ def test_skip_blanks
244
+ @data = <<-END_CSV.gsub(/^ +/, "")
245
+
246
+
247
+ A,B,C
248
+
249
+ 1,2,3
250
+
251
+
252
+
253
+ END_CSV
254
+
255
+ expected = [%w[1 2 3]]
256
+ FasterCSV.parse(@data, :headers => true, :skip_blanks => true) do |row|
257
+ assert_equal(expected.shift, row.fields)
258
+ end
259
+
260
+ expected = [%w[A B C], %w[1 2 3]]
261
+ FasterCSV.parse( @data,
262
+ :headers => true,
263
+ :return_headers => true,
264
+ :skip_blanks => true ) do |row|
265
+ assert_equal(expected.shift, row.fields)
266
+ end
267
+ end
268
+
269
+ def test_blank_row_bug_fix
270
+ @data += "\n#{@data}" # add a blank row
271
+
272
+ # ensure that everything returned is a Row object
273
+ FasterCSV.parse(@data, :headers => true) do |row|
274
+ assert_instance_of(FasterCSV::Row, row)
275
+ end
276
+ end
277
+ end