rw_fastercsv 1.5.6 → 1.5.7
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.
- 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
|