fastercsv 1.5.1 → 1.5.3

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/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.