fastercsv 1.5.1 → 1.5.3

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  Below is a complete listing of changes for each revision of FasterCSV.
4
4
 
5
+ == 1.5.3
6
+
7
+ * A bug fix from Timothy Elliott to return the new parser to its strict quote
8
+ tolerance.
9
+
10
+ == 1.5.2
11
+
12
+ * A bug fix to allow IO Exceptions to reach the calling code from Moses Hohman.
13
+ * Added support for <tt>:write_headers => false</tt> to Table.to_csv().
14
+
5
15
  == 1.5.1
6
16
 
7
17
  * A bug fix for deleting blank Table rows from Andy Hartford.
@@ -82,7 +82,7 @@ require "stringio"
82
82
  #
83
83
  class FasterCSV
84
84
  # The version of the installed library.
85
- VERSION = "1.5.1".freeze
85
+ VERSION = "1.5.3".freeze
86
86
 
87
87
  #
88
88
  # A FasterCSV::Row is part Array and part Hash. It retains an order for the
@@ -704,8 +704,12 @@ class FasterCSV
704
704
  # Returns the table as a complete CSV String. Headers will be listed first,
705
705
  # then all of the field rows.
706
706
  #
707
+ # This method assumes you want the Table.headers(), unless you explicitly
708
+ # pass <tt>:write_headers => false</tt>.
709
+ #
707
710
  def to_csv(options = Hash.new)
708
- @table.inject([headers.to_csv(options)]) do |rows, row|
711
+ wh = options.fetch(:write_headers, true)
712
+ @table.inject(wh ? [headers.to_csv(options)] : [ ]) do |rows, row|
709
713
  if row.header_row?
710
714
  rows
711
715
  else
@@ -1576,10 +1580,10 @@ class FasterCSV
1576
1580
  #
1577
1581
  loop do
1578
1582
  # add another read to the line
1579
- begin
1580
- line += @io.gets(@row_sep)
1581
- rescue
1582
- return nil
1583
+ if read_line = @io.gets(@row_sep)
1584
+ line += read_line
1585
+ else
1586
+ return nil
1583
1587
  end
1584
1588
  # copy the line so we can chop it up in parsing
1585
1589
  parse = line.dup
@@ -1610,12 +1614,14 @@ class FasterCSV
1610
1614
  parse.split(@col_sep, -1).each do |match|
1611
1615
  if current_field.empty? && match.count(@quote_and_newlines).zero?
1612
1616
  csv << (match.empty? ? nil : match)
1613
- elsif(current_field.empty? ? match[0] : current_field[0]) == @quote_char[0]
1617
+ elsif (current_field.empty? ? match[0] : current_field[0]) ==
1618
+ @quote_char[0]
1614
1619
  current_field << match
1615
1620
  field_quotes += match.count(@quote_char)
1616
1621
  if field_quotes % 2 == 0
1617
1622
  in_quotes = current_field[@parsers[:quoted_field], 1]
1618
- raise MalformedCSVError unless in_quotes
1623
+ raise MalformedCSVError if !in_quotes ||
1624
+ in_quotes[@parsers[:stray_quote]]
1619
1625
  current_field = in_quotes
1620
1626
  current_field.gsub!(@quote_char * 2, @quote_char) # unescape contents
1621
1627
  csv << current_field
@@ -1793,14 +1799,17 @@ class FasterCSV
1793
1799
  esc_row_sep = Regexp.escape(@row_sep)
1794
1800
  esc_quote = Regexp.escape(@quote_char)
1795
1801
  @parsers = {
1796
- :any_field => Regexp.new( "[^#{esc_col_sep}]+",
1797
- Regexp::MULTILINE,
1798
- @encoding ),
1799
- :quoted_field => Regexp.new( "^#{esc_quote}(.*)#{esc_quote}$",
1800
- Regexp::MULTILINE,
1801
- @encoding ),
1802
+ :any_field => Regexp.new( "[^#{esc_col_sep}]+",
1803
+ Regexp::MULTILINE,
1804
+ @encoding ),
1805
+ :quoted_field => Regexp.new( "^#{esc_quote}(.*)#{esc_quote}$",
1806
+ Regexp::MULTILINE,
1807
+ @encoding ),
1808
+ :stray_quote => Regexp.new( "[^#{esc_quote}]#{esc_quote}[^#{esc_quote}]",
1809
+ Regexp::MULTILINE,
1810
+ @encoding ),
1802
1811
  # safer than chomp!()
1803
- :line_end => Regexp.new("#{esc_row_sep}\\z", nil, @encoding)
1812
+ :line_end => Regexp.new("#{esc_row_sep}\\z", nil, @encoding)
1804
1813
  }
1805
1814
  end
1806
1815
 
@@ -114,6 +114,10 @@ class TestCSVParsing < Test::Unit::TestCase
114
114
  [["foo,\"foo,bar,baz,foo\",\"foo\"", ["foo", "foo,bar,baz,foo", "foo"]]].each do |edge_case|
115
115
  assert_equal(edge_case.last, FasterCSV.parse_line(edge_case.first))
116
116
  end
117
+
118
+ assert_raise(FasterCSV::MalformedCSVError) do
119
+ FasterCSV.parse_line("1,\"23\"4\"5\", 6")
120
+ end
117
121
  end
118
122
 
119
123
  def test_malformed_csv
@@ -181,7 +181,7 @@ class TestFasterCSVInterface < Test::Unit::TestCase
181
181
  csv << lines.first.keys
182
182
  lines.each { |line| csv << line }
183
183
  end
184
- FasterCSV.open( @path, "w", :headers => true,
184
+ FasterCSV.open( @path, "r", :headers => true,
185
185
  :converters => :all,
186
186
  :header_converters => :symbol ) do |csv|
187
187
  csv.each { |line| assert_equal(lines.shift, line.to_hash) }
@@ -251,6 +251,8 @@ class TestFasterCSVTable < Test::Unit::TestCase
251
251
  # with options
252
252
  assert_equal( csv.gsub(",", "|").gsub("\n", "\r\n"),
253
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) )
254
256
 
255
257
  # with headers
256
258
  assert_equal(csv, @header_table.to_csv)
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastercsv
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.1
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 5
8
+ - 3
9
+ version: 1.5.3
5
10
  platform: ruby
6
11
  authors:
7
12
  - James Edward Gray II
@@ -9,7 +14,7 @@ autorequire:
9
14
  bindir: bin
10
15
  cert_chain: []
11
16
 
12
- date: 2010-01-30 00:00:00 -06:00
17
+ date: 2010-03-16 00:00:00 -05:00
13
18
  default_executable:
14
19
  dependencies: []
15
20
 
@@ -80,18 +85,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
80
85
  requirements:
81
86
  - - ">="
82
87
  - !ruby/object:Gem::Version
88
+ segments:
89
+ - 0
83
90
  version: "0"
84
- version:
85
91
  required_rubygems_version: !ruby/object:Gem::Requirement
86
92
  requirements:
87
93
  - - ">="
88
94
  - !ruby/object:Gem::Version
95
+ segments:
96
+ - 0
89
97
  version: "0"
90
- version:
91
98
  requirements: []
92
99
 
93
100
  rubyforge_project: fastercsv
94
- rubygems_version: 1.3.5
101
+ rubygems_version: 1.3.6
95
102
  signing_key:
96
103
  specification_version: 3
97
104
  summary: FasterCSV is CSV, but faster, smaller, and cleaner.