rw_fastercsv 1.5.6 → 1.5.7
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +33 -33
- data/lib/faster_csv.rb +7 -2
- data/test/quotes_firstrow.csv +4 -0
- data/test/tc_csv_parsing.rb +9 -9
- data/test/tc_features.rb +5 -5
- data/test/tc_rp_cases.rb +24 -0
- data/test/tc_speed.rb +3 -3
- metadata +4 -3
data/Rakefile
CHANGED
@@ -12,7 +12,7 @@ task :default => [:test]
|
|
12
12
|
|
13
13
|
Rake::TestTask.new do |test|
|
14
14
|
test.libs << "test"
|
15
|
-
|
15
|
+
test.test_files = %w[test/ts_all.rb]
|
16
16
|
test.verbose = true
|
17
17
|
end
|
18
18
|
|
@@ -49,38 +49,38 @@ task :benchmark do
|
|
49
49
|
%Q{'#{TESTS}.times { FasterCSV.foreach("#{path}") { |row| } }'}
|
50
50
|
end
|
51
51
|
|
52
|
-
spec = Gem::Specification.new do |spec|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
FasterCSV is intended as a complete replacement to the CSV standard library. It
|
80
|
-
is significantly faster and smaller while still being pure Ruby code. It also
|
81
|
-
strives for a better interface.
|
82
|
-
END_DESC
|
83
|
-
end
|
52
|
+
# spec = Gem::Specification.new do |spec|
|
53
|
+
# spec.name = "fastercsv"
|
54
|
+
# spec.version = '1.5.6'
|
55
|
+
#
|
56
|
+
# spec.platform = Gem::Platform::RUBY
|
57
|
+
# spec.summary = "FasterCSV is CSV, but faster, smaller, and cleaner."
|
58
|
+
#
|
59
|
+
# spec.test_files = %w[test/ts_all.rb]
|
60
|
+
# spec.files = Dir.glob("{lib,test,examples}/**/*.rb").
|
61
|
+
# reject { |item| item.include?(".svn") } +
|
62
|
+
# Dir.glob("{test,examples}/**/*.csv").
|
63
|
+
# reject { |item| item.include?(".svn") } +
|
64
|
+
# %w[Rakefile setup.rb test/line_endings.gz]
|
65
|
+
#
|
66
|
+
# spec.has_rdoc = true
|
67
|
+
# spec.extra_rdoc_files = %w[ AUTHORS COPYING README INSTALL TODO CHANGELOG
|
68
|
+
# LICENSE ]
|
69
|
+
# spec.rdoc_options << "--title" << "FasterCSV Documentation" <<
|
70
|
+
# "--main" << "README"
|
71
|
+
#
|
72
|
+
# spec.require_path = "lib"
|
73
|
+
#
|
74
|
+
# spec.author = "James Edward Gray II"
|
75
|
+
# spec.email = "james@grayproductions.net"
|
76
|
+
# spec.rubyforge_project = "fastercsv"
|
77
|
+
# spec.homepage = "http://fastercsv.rubyforge.org"
|
78
|
+
# spec.description = <<END_DESC
|
79
|
+
# FasterCSV is intended as a complete replacement to the CSV standard library. It
|
80
|
+
# is significantly faster and smaller while still being pure Ruby code. It also
|
81
|
+
# strives for a better interface.
|
82
|
+
# END_DESC
|
83
|
+
# end
|
84
84
|
|
85
85
|
Rake::GemPackageTask.new(spec) do |pkg|
|
86
86
|
pkg.need_zip = true
|
data/lib/faster_csv.rb
CHANGED
@@ -833,7 +833,8 @@ class FasterCSV
|
|
833
833
|
:header_converters => nil,
|
834
834
|
:skip_blanks => false,
|
835
835
|
:force_quotes => false,
|
836
|
-
:raise_exception => false
|
836
|
+
:raise_exception => false,
|
837
|
+
:single_line => true}.freeze
|
837
838
|
|
838
839
|
#
|
839
840
|
# This method will build a drop-in replacement for many of the standard CSV
|
@@ -1591,9 +1592,12 @@ class FasterCSV
|
|
1591
1592
|
# add another read to the line
|
1592
1593
|
if read_line = @io.gets(@row_sep)
|
1593
1594
|
line += read_line
|
1595
|
+
|
1596
|
+
line = '' if @single_line && line.scan(Regexp.new(@quote_char)).size%2 != 0
|
1594
1597
|
else
|
1595
1598
|
return nil
|
1596
1599
|
end
|
1600
|
+
|
1597
1601
|
# copy the line so we can chop it up in parsing
|
1598
1602
|
parse = line.dup
|
1599
1603
|
parse.sub!(@parsers[:line_end], "")
|
@@ -1804,7 +1808,8 @@ class FasterCSV
|
|
1804
1808
|
@encoding = options.delete(:encoding) # nil will use $KCODE
|
1805
1809
|
@field_size_limit = options.delete(:field_size_limit)
|
1806
1810
|
@raise_exception = options.delete(:raise_exception)
|
1807
|
-
|
1811
|
+
@single_line = options.delete(:single_line)
|
1812
|
+
|
1808
1813
|
# prebuild Regexps for faster parsing
|
1809
1814
|
esc_col_sep = Regexp.escape(@col_sep)
|
1810
1815
|
esc_row_sep = Regexp.escape(@row_sep)
|
@@ -0,0 +1,4 @@
|
|
1
|
+
NameF,NameL,E-mail Address,Address,Phone,Comment,IM,Gcolumn8,Column9,Column10,Column11
|
2
|
+
"slash,,myemail@at.com,,,,,,,,
|
3
|
+
Aaron1, Highlander1,Aaron1_Highlander1@example.com,Moscow 1,495-333-22-11,this is short comment 1,testbuddy,FirstText1,SecondText1,ThirdText1,ForthText1
|
4
|
+
Aaron2, Highlander2,Aaron2_Highlander2@example.com,Moscow 2,495-333-22-12,this is short comment 2,testbuddy,FirstText2,SecondText2,ThirdText2,ForthText2
|
data/test/tc_csv_parsing.rb
CHANGED
@@ -52,7 +52,7 @@ class TestCSVParsing < Test::Unit::TestCase
|
|
52
52
|
["foo,\"\r\n\n\",baz", ["foo", "\r\n\n", "baz"]],
|
53
53
|
["foo,\"foo,bar\",baz", ["foo", "foo,bar", "baz"]],
|
54
54
|
[";,;", [";", ";"]] ].each do |csv_test|
|
55
|
-
assert_equal(csv_test.last, FasterCSV.parse_line(csv_test.first))
|
55
|
+
assert_equal(csv_test.last, FasterCSV.parse_line(csv_test.first, :single_line => false))
|
56
56
|
end
|
57
57
|
|
58
58
|
[ ["foo,\"\"\"\"\"\",baz", ["foo", "\"\"", "baz"]],
|
@@ -71,7 +71,7 @@ class TestCSVParsing < Test::Unit::TestCase
|
|
71
71
|
["foo,bar", ["foo", "bar"]],
|
72
72
|
["foo,\"\r\n\n\",baz", ["foo", "\r\n\n", "baz"]],
|
73
73
|
["foo,\"foo,bar\",baz", ["foo", "foo,bar", "baz"]] ].each do |csv_test|
|
74
|
-
assert_equal(csv_test.last, FasterCSV.parse_line(csv_test.first))
|
74
|
+
assert_equal(csv_test.last, FasterCSV.parse_line(csv_test.first, :single_line => false))
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
@@ -94,7 +94,7 @@ class TestCSVParsing < Test::Unit::TestCase
|
|
94
94
|
[%Q{,"\r"}, [nil,"\r"]],
|
95
95
|
[%Q{"\r\n,"}, ["\r\n,"]],
|
96
96
|
[%Q{"\r\n,",}, ["\r\n,", nil]] ].each do |edge_case|
|
97
|
-
assert_equal(edge_case.last, FasterCSV.parse_line(edge_case.first))
|
97
|
+
assert_equal(edge_case.last, FasterCSV.parse_line(edge_case.first, :single_line => false))
|
98
98
|
end
|
99
99
|
end
|
100
100
|
|
@@ -121,7 +121,7 @@ class TestCSVParsing < Test::Unit::TestCase
|
|
121
121
|
[%Q{"a\r\n\r\na","two CRLFs"}, ["a\r\n\r\na", 'two CRLFs']],
|
122
122
|
[%Q{with blank,"start\n\nfinish"\n}, ['with blank', "start\n\nfinish"]],
|
123
123
|
].each do |edge_case|
|
124
|
-
assert_equal(edge_case.last, FasterCSV.parse_line(edge_case.first))
|
124
|
+
assert_equal(edge_case.last, FasterCSV.parse_line(edge_case.first, :single_line => false))
|
125
125
|
end
|
126
126
|
end
|
127
127
|
|
@@ -138,7 +138,7 @@ class TestCSVParsing < Test::Unit::TestCase
|
|
138
138
|
|
139
139
|
def test_malformed_csv
|
140
140
|
assert_raise(FasterCSV::MalformedCSVError) do
|
141
|
-
FasterCSV.parse_line("1,2\r,3", :row_sep => "\n")
|
141
|
+
FasterCSV.parse_line("1,2\r,3", :row_sep => "\n", :raise_exception => true, :single_line => false)
|
142
142
|
end
|
143
143
|
|
144
144
|
bad_data = <<-END_DATA.gsub(/^ +/, "")
|
@@ -152,7 +152,7 @@ class TestCSVParsing < Test::Unit::TestCase
|
|
152
152
|
assert_equal(6, lines.size)
|
153
153
|
assert_match(/\Aline,4/, lines.find { |l| l =~ /some\rjunk/ })
|
154
154
|
|
155
|
-
csv = FasterCSV.new(bad_data)
|
155
|
+
csv = FasterCSV.new(bad_data, :raise_exception => true, :single_line => false)
|
156
156
|
begin
|
157
157
|
loop do
|
158
158
|
assert_not_nil(csv.shift)
|
@@ -164,10 +164,10 @@ class TestCSVParsing < Test::Unit::TestCase
|
|
164
164
|
end
|
165
165
|
|
166
166
|
assert_nothing_raised(FasterCSV::MalformedCSVError) do
|
167
|
-
FasterCSV.parse_line('1,2,"3...'
|
167
|
+
FasterCSV.parse_line('1,2,"3...')
|
168
168
|
end
|
169
169
|
assert_raise(FasterCSV::MalformedCSVError) do
|
170
|
-
FasterCSV.parse_line('1,2,"3...')
|
170
|
+
FasterCSV.parse_line('1,2,"3...',{:raise_exception => true, :single_line => false} )
|
171
171
|
end
|
172
172
|
|
173
173
|
bad_data = <<-END_DATA.gsub(/^ +/, "")
|
@@ -181,7 +181,7 @@ class TestCSVParsing < Test::Unit::TestCase
|
|
181
181
|
assert_equal(6, lines.size)
|
182
182
|
assert_match(/\Aline,4/, lines.find { |l| l =~ /8'10"/ })
|
183
183
|
|
184
|
-
csv = FasterCSV.new(bad_data)
|
184
|
+
csv = FasterCSV.new(bad_data, :raise_exception => true, :single_line => false)
|
185
185
|
begin
|
186
186
|
loop do
|
187
187
|
assert_not_nil(csv.shift)
|
data/test/tc_features.rb
CHANGED
@@ -36,7 +36,7 @@ class TestFasterCSVFeatures < Test::Unit::TestCase
|
|
36
36
|
|
37
37
|
line,4,jkl
|
38
38
|
END_DATA
|
39
|
-
@csv = FasterCSV.new(@sample_data)
|
39
|
+
@csv = FasterCSV.new(@sample_data, :single_line => false)
|
40
40
|
end
|
41
41
|
|
42
42
|
def test_col_sep
|
@@ -44,7 +44,7 @@ class TestFasterCSVFeatures < Test::Unit::TestCase
|
|
44
44
|
TEST_CASES.each do |test_case|
|
45
45
|
assert_equal( test_case.last.map { |t| t.tr(",", sep) unless t.nil? },
|
46
46
|
FasterCSV.parse_line( test_case.first.tr(",", sep),
|
47
|
-
:col_sep => sep ) )
|
47
|
+
:col_sep => sep, :single_line => false ) )
|
48
48
|
end
|
49
49
|
end
|
50
50
|
assert_equal( [",,,", nil],
|
@@ -53,7 +53,7 @@ class TestFasterCSVFeatures < Test::Unit::TestCase
|
|
53
53
|
|
54
54
|
def test_row_sep
|
55
55
|
assert_raise(FasterCSV::MalformedCSVError) do
|
56
|
-
FasterCSV.parse_line("1,2,3\n,4,5\r\n", :row_sep => "\r\n")
|
56
|
+
FasterCSV.parse_line("1,2,3\n,4,5\r\n", :row_sep => "\r\n", :raise_exception => true, :single_line => false)
|
57
57
|
end
|
58
58
|
assert_equal( ["1", "2", "3\n", "4", "5"],
|
59
59
|
FasterCSV.parse_line( %Q{1,2,"3\n",4,5\r\n},
|
@@ -64,7 +64,7 @@ class TestFasterCSVFeatures < Test::Unit::TestCase
|
|
64
64
|
TEST_CASES.each do |test_case|
|
65
65
|
assert_equal( test_case.last.map { |t| t.tr('"', "'") unless t.nil? },
|
66
66
|
FasterCSV.parse_line( test_case.first.tr('"', "'"),
|
67
|
-
:quote_char => "'" ) )
|
67
|
+
:quote_char => "'", :single_line => false ) )
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
@@ -110,7 +110,7 @@ class TestFasterCSVFeatures < Test::Unit::TestCase
|
|
110
110
|
def test_skip_blanks
|
111
111
|
assert_equal(4, @csv.to_a.size)
|
112
112
|
|
113
|
-
@csv = FasterCSV.new(@sample_data, :skip_blanks => true)
|
113
|
+
@csv = FasterCSV.new(@sample_data, :skip_blanks => true, :single_line => false)
|
114
114
|
|
115
115
|
count = 0
|
116
116
|
@csv.each do |row|
|
data/test/tc_rp_cases.rb
CHANGED
@@ -41,5 +41,29 @@ class TestFasterCSVRPCases < Test::Unit::TestCase
|
|
41
41
|
assert_equal(5,lines.size)
|
42
42
|
end
|
43
43
|
|
44
|
+
#RPBS-3899
|
45
|
+
def test_success_import_file_with_unclosed_quotes
|
46
|
+
lines = []
|
47
|
+
csv = FasterCSV.open(File.join(File.dirname(__FILE__), "quotes_firstrow.csv"), :raise_exception => false)
|
48
|
+
assert_nothing_raised do
|
49
|
+
while line = csv.gets
|
50
|
+
lines<<line
|
51
|
+
end
|
52
|
+
end
|
53
|
+
# puts lines.inspect
|
54
|
+
assert_equal(4,lines.size)
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_failed_import_file_with_unclosed_quotes
|
58
|
+
lines = []
|
59
|
+
csv = FasterCSV.open(File.join(File.dirname(__FILE__), "quotes_firstrow.csv"), :raise_exception => false, :single_line => false)
|
60
|
+
assert_nothing_raised do
|
61
|
+
while line = csv.gets
|
62
|
+
lines<<line
|
63
|
+
end
|
64
|
+
end
|
65
|
+
assert_equal(1,lines.size)
|
66
|
+
end
|
67
|
+
|
44
68
|
|
45
69
|
end
|
data/test/tc_speed.rb
CHANGED
@@ -40,16 +40,16 @@ class TestFasterCSVSpeed < Test::Unit::TestCase
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def test_the_parse_fails_fast_when_it_can_for_unquoted_fields
|
43
|
-
assert_parse_errors_out('valid,fields,bad start"' + BIG_DATA)
|
43
|
+
assert_parse_errors_out('valid,fields,bad start"' + BIG_DATA, :raise_exception => true, :single_line => false)
|
44
44
|
end
|
45
45
|
|
46
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)
|
47
|
+
assert_parse_errors_out('valid,fields,"bad start"unescaped' + BIG_DATA, :raise_exception => true, :single_line => false)
|
48
48
|
end
|
49
49
|
|
50
50
|
def test_field_size_limit_controls_lookahead
|
51
51
|
assert_parse_errors_out( 'valid,fields,"' + BIG_DATA + '"',
|
52
|
-
:field_size_limit => 2048 )
|
52
|
+
:field_size_limit => 2048, :raise_exception => true, :single_line => false)
|
53
53
|
end
|
54
54
|
|
55
55
|
private
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 1
|
7
7
|
- 5
|
8
|
-
-
|
9
|
-
version: 1.5.
|
8
|
+
- 7
|
9
|
+
version: 1.5.7
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- James Edward Gray II
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-11-
|
18
|
+
date: 2010-11-22 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|
@@ -41,6 +41,7 @@ files:
|
|
41
41
|
- lib/fastercsv.rb
|
42
42
|
- test/export.csv
|
43
43
|
- test/line_endings.gz
|
44
|
+
- test/quotes_firstrow.csv
|
44
45
|
- test/tc_csv_parsing.rb
|
45
46
|
- test/tc_csv_writing.rb
|
46
47
|
- test/tc_data_converters.rb
|