smarter_csv 1.2.0 → 1.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 251eb1eff306211d163c6be6880ba45e3eb29985
4
- data.tar.gz: 9e16d1d4aaab86df7a65d73e6a23ace8f481ba4e
2
+ SHA256:
3
+ metadata.gz: c912f58ae42fab60cb40e5a708e1551efda1a4abf4f5ad88e79f5803b5c84137
4
+ data.tar.gz: 438245fc8061b621a15ad2c5f7cc16d0ea9dbaa7049f60c806d88673eaeffbe0
5
5
  SHA512:
6
- metadata.gz: e2ad758ddb7d644777df1b9f38b73c7c4c0753d76507834bf68e86394ae017b1f5caa16867efd82f4c0443d4a7c1b4c1d7f704d9c3796e71083bde689ee7aeba
7
- data.tar.gz: 8f7126500628a17fda587a05678aca9140d0ebb7ca168fc3144b1d9c00d2be6ec901a43900bd3d558aceb0a8dcfc139aba7347e6dbad01b2ff83c19dc3816763
6
+ metadata.gz: 7ab27854092a7b93aee3f596eeb5e3757cdfe0cf15fa95ff1e131268e02ce934fbbe2e7f25d786014f04222e8e5147821122f84fed9a9178bae555a13bafb505
7
+ data.tar.gz: 10129052b5e02a7b48a5e37aeb073abaceb43c526e05de51f84442d9a8f059caf3db530b43c59b44716eb688d8b76a1429b4f0a1e317375f8fc480004933999c
data/.travis.yml CHANGED
@@ -6,10 +6,12 @@ before_install:
6
6
 
7
7
  matrix:
8
8
  include:
9
- - rvm: 2.2.8
10
- - rvm: 2.3.5
11
- - rvm: 2.4.2
12
- - rvm: jruby-9.1.13.0
9
+ - rvm: 2.2.10
10
+ - rvm: 2.3.8
11
+ - rvm: 2.4.6
12
+ - rvm: 2.5.5
13
+ - rvm: 2.6.3
14
+ - rvm: jruby-9.2.7.0
13
15
  env:
14
16
  - JRUBY_OPTS="--server -Xcompile.invokedynamic=false -J-XX:+TieredCompilation -J-XX:TieredStopAtLevel=1 -J-noverify -J-Xms512m -J-Xmx1024m"
15
17
  - rvm: ruby-head
@@ -17,3 +19,5 @@ matrix:
17
19
  branches:
18
20
  only:
19
21
  - master
22
+ - 1.2-stable
23
+ - 2.0-develop
data/Gemfile CHANGED
@@ -3,7 +3,6 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in smarter_csv.gemspec
4
4
  gemspec
5
5
 
6
-
7
6
  gem "rake", "< 11"
8
7
  gem 'pry'
9
8
 
data/README.md CHANGED
@@ -2,6 +2,19 @@
2
2
 
3
3
  [![Build Status](https://secure.travis-ci.org/tilo/smarter_csv.svg?branch=master)](http://travis-ci.org/tilo/smarter_csv) [![Gem Version](https://badge.fury.io/rb/smarter_csv.svg)](http://badge.fury.io/rb/smarter_csv)
4
4
 
5
+ ---------------
6
+ #### Service Announcement
7
+
8
+ Work towards SmarterCSV 2.0 is on it's way, with much improved features, and more streamlined options.
9
+
10
+ Please check the 2.0-develop branch, and open issues marked v2.0 and leave your comments.
11
+
12
+ New versions on the 1.2 branch will soon print a deprecation warning if you set :verbose to true
13
+ See below for list of deprecated options.
14
+
15
+ ---------------
16
+ #### SmarterCSV
17
+
5
18
  `smarter_csv` is a Ruby Gem for smarter importing of CSV Files as Array(s) of Hashes, suitable for direct processing with Mongoid or ActiveRecord,
6
19
  and parallel processing with Resque or Sidekiq.
7
20
 
@@ -182,18 +195,48 @@ The options and the block are optional.
182
195
 
183
196
  `SmarterCSV.process` supports the following options:
184
197
 
198
+ #### Options:
199
+
185
200
  | Option | Default | Explanation |
186
201
  ---------------------------------------------------------------------------------------------------------------------------------
202
+ | :chunk_size | nil | if set, determines the desired chunk-size (defaults to nil, no chunk processing) |
203
+ | | | |
204
+ | :file_encoding | utf-8 | Set the file encoding eg.: 'windows-1252' or 'iso-8859-1' |
205
+ | :invalid_byte_sequence | '' | what to replace invalid byte sequences with |
206
+ | :force_utf8 | false | force UTF-8 encoding of all lines (including headers) in the CSV file |
207
+ | :skip_lines | nil | how many lines to skip before the first line or header line is processed |
208
+ | :comment_regexp | /^#/ | regular expression which matches comment lines (see NOTE about the CSV header) |
209
+ ---------------------------------------------------------------------------------------------------------------------------------
187
210
  | :col_sep | ',' | column separator |
211
+ | :force_simple_split | false | force simple splitting on :col_sep character for non-standard CSV-files. |
212
+ | | | e.g. when :quote_char is not properly escaped |
188
213
  | :row_sep | $/ ,"\n" | row separator or record separator , defaults to system's $/ , which defaults to "\n" |
189
214
  | | | This can also be set to :auto, but will process the whole cvs file first (slow!) |
190
215
  | :auto_row_sep_chars | 500 | How many characters to analyze when using `:row_sep => :auto`. nil or 0 means whole file. |
191
216
  | :quote_char | '"' | quotation character |
192
- | :comment_regexp | /^#/ | regular expression which matches comment lines (see NOTE about the CSV header) |
193
- | :chunk_size | nil | if set, determines the desired chunk-size (defaults to nil, no chunk processing) |
217
+ ---------------------------------------------------------------------------------------------------------------------------------
218
+ | :headers_in_file | true | Whether or not the file contains headers as the first line. |
219
+ | | | Important if the file does not contain headers, |
220
+ | | | otherwise you would lose the first line of data. |
221
+ | :user_provided_headers | nil | *careful with that axe!* |
222
+ | | | user provided Array of header strings or symbols, to define |
223
+ | | | what headers should be used, overriding any in-file headers. |
224
+ | | | You can not combine the :user_provided_headers and :key_mapping options |
225
+ | :remove_empty_hashes | true | remove / ignore any hashes which don't have any key/value pairs |
226
+ | :verbose | false | print out line number while processing (to track down problems in input files) |
227
+ ---------------------------------------------------------------------------------------------------------------------------------
228
+
229
+ #### Deprecated 1.x Options: to be replaced in 2.0
230
+
231
+ There have been a lot of 1-offs and feature creep around these options, and going forward we'll have a simpler, but more flexible way to address these features.
232
+
233
+ Instead of these options, there will be a new and more flexible way to process the header fields, as well as the fields in each line of the CSV.
234
+ And header and data validations will also be supported in 2.x
235
+
236
+ | Option | Default | Explanation |
194
237
  ---------------------------------------------------------------------------------------------------------------------------------
195
238
  | :key_mapping | nil | a hash which maps headers from the CSV file to keys in the result hash |
196
- | :required_headers | nil | An array. Eacn of the given headers must be present in the CSV file, |
239
+ | :required_headers | nil | An array. Eacn of the given headers must be present after header manipulation, |
197
240
  | | | or an exception is raised No validation if nil is given. |
198
241
  | :remove_unmapped_keys | false | when using :key_mapping option, should non-mapped keys / columns be removed? |
199
242
  | :downcase_header | true | downcase all column headers |
@@ -201,17 +244,7 @@ The options and the block are optional.
201
244
  | :strip_whitespace | true | remove whitespace before/after values and headers |
202
245
  | :keep_original_headers | false | keep the original headers from the CSV-file as-is. |
203
246
  | | | Disables other flags manipulating the header fields. |
204
- | :user_provided_headers | nil | *careful with that axe!* |
205
- | | | user provided Array of header strings or symbols, to define |
206
- | | | what headers should be used, overriding any in-file headers. |
207
- | | | You can not combine the :user_provided_headers and :key_mapping options |
208
247
  | :strip_chars_from_headers | nil | RegExp to remove extraneous characters from the header line (e.g. if headers are quoted) |
209
- | :headers_in_file | true | Whether or not the file contains headers as the first line. |
210
- | | | Important if the file does not contain headers, |
211
- | | | otherwise you would lose the first line of data. |
212
- | :skip_lines | nil | how many lines to skip before the first line or header line is processed |
213
- | :force_utf8 | false | force UTF-8 encoding of all lines (including headers) in the CSV file |
214
- | :invalid_byte_sequence | '' | how to replace invalid byte sequences with |
215
248
  ---------------------------------------------------------------------------------------------------------------------------------
216
249
  | :value_converters | nil | supply a hash of :header => KlassName; the class needs to implement self.convert(val)|
217
250
  | :remove_empty_values | true | remove values which have nil or empty strings as values |
@@ -220,11 +253,7 @@ The options and the block are optional.
220
253
  | | | /^\$0\.0+$/ to match $0.00 , or /^#VALUE!$/ to match errors in Excel spreadsheets |
221
254
  | :convert_values_to_numeric | true | converts strings containing Integers or Floats to the appropriate class |
222
255
  | | | also accepts either {:except => [:key1,:key2]} or {:only => :key3} |
223
- | :remove_empty_hashes | true | remove / ignore any hashes which don't have any key/value pairs |
224
- | :file_encoding | utf-8 | Set the file encoding eg.: 'windows-1252' or 'iso-8859-1' |
225
- | :force_simple_split | false | force simple splitting on :col_sep character for non-standard CSV-files. |
226
- | | | e.g. when :quote_char is not properly escaped |
227
- | :verbose | false | print out line number while processing (to track down problems in input files) |
256
+ ---------------------------------------------------------------------------------------------------------------------------------
228
257
 
229
258
 
230
259
  #### NOTES about File Encodings:
@@ -295,6 +324,21 @@ Planned in the next releases:
295
324
 
296
325
  ## Changes
297
326
 
327
+ #### 1.2.6 (2018-11-13)
328
+ * fixing error caused by calling f.close when we do not hand in a file
329
+
330
+ #### 1.2.5 (2018-09-16)
331
+ * fixing issue #136 with comments in CSV files
332
+ * fixing error class hierarchy
333
+
334
+ #### 1.2.4 (2018-08-06)
335
+ * using Rails blank? if it's available
336
+
337
+ #### 1.2.3 (2018-01-27)
338
+ * fixed regression / test
339
+ * fuxed quote_char interpolation for headers, but not data (thanks to Colin Petruno)
340
+ * bugfix (thanks to Joshua Smith for reporting)
341
+
298
342
  #### 1.2.0 (2018-01-20)
299
343
  * add default validation that a header can only appear once
300
344
  * add option `required_headers`
@@ -349,9 +393,6 @@ Planned in the next releases:
349
393
  #### 1.0.14 (2013-11-01)
350
394
  * added GPL-2 and MIT license to GEM spec file; if you need another license contact me
351
395
 
352
- #### 1.0.13 (2013-11-01) ### YANKED!
353
- * added GPL-2 license to GEM spec file; if you need another license contact me
354
-
355
396
  #### 1.0.12 (2013-10-15)
356
397
  * added RSpec tests
357
398
 
@@ -465,6 +506,8 @@ And a special thanks to those who contributed pull requests:
465
506
  * [Ivan Ushakov](https://github.com/IvanUshakov)
466
507
  * [Matthieu Paret](https://github.com/mtparet)
467
508
  * [Rohit Amarnath](https://github.com/ramarnat)
509
+ * [Joshua Smith](https://github.com/enviable)
510
+ * [Colin Petruno](https://github.com/colinpetruno)
468
511
 
469
512
 
470
513
  ## Contributing
@@ -1,16 +1,16 @@
1
1
  module SmarterCSV
2
-
3
- class HeaderSizeMismatch < Exception; end
4
- class IncorrectOption < Exception; end
5
- class DuplicateHeaders < Exception; end
6
- class MissingHeaders < Exception; end
2
+ class SmarterCSVException < StandardError; end
3
+ class HeaderSizeMismatch < SmarterCSVException; end
4
+ class IncorrectOption < SmarterCSVException; end
5
+ class DuplicateHeaders < SmarterCSVException; end
6
+ class MissingHeaders < SmarterCSVException; end
7
7
 
8
8
 
9
9
  def SmarterCSV.process(input, options={}, &block) # first parameter: filename or input object with readline method
10
10
  default_options = {:col_sep => ',' , :row_sep => $/ , :quote_char => '"', :force_simple_split => false , :verbose => false ,
11
11
  :remove_empty_values => true, :remove_zero_values => false , :remove_values_matching => nil , :remove_empty_hashes => true , :strip_whitespace => true,
12
12
  :convert_values_to_numeric => true, :strip_chars_from_headers => nil , :user_provided_headers => nil , :headers_in_file => true,
13
- :comment_regexp => /^#/, :chunk_size => nil , :key_mapping_hash => nil , :downcase_header => true, :strings_as_keys => false, :file_encoding => 'utf-8',
13
+ :comment_regexp => /\A#/, :chunk_size => nil , :key_mapping_hash => nil , :downcase_header => true, :strings_as_keys => false, :file_encoding => 'utf-8',
14
14
  :remove_unmapped_keys => false, :keep_original_headers => false, :value_converters => nil, :skip_lines => nil, :force_utf8 => false, :invalid_byte_sequence => '',
15
15
  :auto_row_sep_chars => 500, :required_headers => nil
16
16
  }
@@ -22,6 +22,7 @@ module SmarterCSV
22
22
  old_row_sep = $/
23
23
  file_line_count = 0
24
24
  csv_line_count = 0
25
+ has_rails = !! defined?(Rails)
25
26
  begin
26
27
  f = input.respond_to?(:readline) ? input : File.open(input, "r:#{options[:file_encoding]}")
27
28
 
@@ -59,7 +60,7 @@ module SmarterCSV
59
60
  else
60
61
  file_headerA = header.split(options[:col_sep])
61
62
  end
62
- file_headerA.map!{|x| x.gsub(%r/options[:quote_char]/,'') }
63
+ file_headerA.map!{|x| x.gsub(%r/#{options[:quote_char]}/,'') }
63
64
  file_headerA.map!{|x| x.strip} if options[:strip_whitespace]
64
65
  unless options[:keep_original_headers]
65
66
  file_headerA.map!{|x| x.gsub(/\s+|-+/,'_')}
@@ -68,14 +69,14 @@ module SmarterCSV
68
69
 
69
70
  file_header_size = file_headerA.size
70
71
  else
71
- raise SmarterCSV::IncorrectOption , "ERROR [smarter_csv]: If :headers_in_file is set to false, you have to provide :user_provided_headers" if options[:user_provided_headers].nil?
72
+ raise SmarterCSV::IncorrectOption , "ERROR: If :headers_in_file is set to false, you have to provide :user_provided_headers" if options[:user_provided_headers].nil?
72
73
  end
73
74
  if options[:user_provided_headers] && options[:user_provided_headers].class == Array && ! options[:user_provided_headers].empty?
74
75
  # use user-provided headers
75
76
  headerA = options[:user_provided_headers]
76
77
  if defined?(file_header_size) && ! file_header_size.nil?
77
78
  if headerA.size != file_header_size
78
- raise SmarterCSV::HeaderSizeMismatch , "ERROR [smarter_csv]: :user_provided_headers defines #{headerA.size} headers != CSV-file #{input} has #{file_header_size} headers"
79
+ raise SmarterCSV::HeaderSizeMismatch , "ERROR: :user_provided_headers defines #{headerA.size} headers != CSV-file #{input} has #{file_header_size} headers"
79
80
  else
80
81
  # we could print out the mapping of file_headerA to headerA here
81
82
  end
@@ -100,14 +101,14 @@ module SmarterCSV
100
101
  headerA.compact.each do |k|
101
102
  duplicate_headers << k if headerA.select{|x| x == k}.size > 1
102
103
  end
103
- raise SmarterCSV::DuplicateHeaders , "ERORR [smarter_csv]: duplicate headers: #{duplicate_headers.join(',')}" unless duplicate_headers.empty?
104
+ raise SmarterCSV::DuplicateHeaders , "ERROR: duplicate headers: #{duplicate_headers.join(',')}" unless duplicate_headers.empty?
104
105
 
105
106
  if options[:required_headers] && options[:required_headers].is_a?(Array)
106
107
  missing_headers = []
107
108
  options[:required_headers].each do |k|
108
109
  missing_headers << k unless headerA.include?(k)
109
110
  end
110
- raise SmarterCSV::MissingHeaders , "ERORR [smarter_csv]: missing headers: #{missing_headers.join(',')}" unless missing_headers.empty?
111
+ raise SmarterCSV::MissingHeaders , "ERROR: missing headers: #{missing_headers.join(',')}" unless missing_headers.empty?
111
112
  end
112
113
 
113
114
  # in case we use chunking.. we'll need to set it up..
@@ -155,7 +156,7 @@ module SmarterCSV
155
156
  else
156
157
  dataA = line.split(options[:col_sep])
157
158
  end
158
- dataA.map!{|x| x.gsub(%r/options[:quote_char]/,'') }
159
+ #### dataA.map!{|x| x.gsub(%r/#{options[:quote_char]}/,'') } # this is actually not a good idea as a default
159
160
  dataA.map!{|x| x.strip} if options[:strip_whitespace]
160
161
  hash = Hash.zip(headerA,dataA) # from Facets of Ruby library
161
162
  # make sure we delete any key/value pairs from the hash, which the user wanted to delete:
@@ -167,7 +168,13 @@ module SmarterCSV
167
168
 
168
169
  # remove empty values using the same regexp as used by the rails blank? method
169
170
  # which caters for double \n and \r\n characters such as "1\r\n\r\n2" whereas the original check (v =~ /^\s*$/) does not
170
- hash.delete_if{|k,v| v.nil? || v !~ /[^[:space:]]/} if options[:remove_empty_values]
171
+ if options[:remove_empty_values]
172
+ if has_rails
173
+ hash.delete_if{|k,v| v.blank?}
174
+ else
175
+ hash.delete_if{|k,v| v.nil? || v !~ /[^[:space:]]/}
176
+ end
177
+ end
171
178
 
172
179
  hash.delete_if{|k,v| ! v.nil? && v =~ /^(\d+|\d+\.\d+)$/ && v.to_f == 0} if options[:remove_zero_values] # values are typically Strings!
173
180
  hash.delete_if{|k,v| v =~ options[:remove_values_matching]} if options[:remove_values_matching]
@@ -241,7 +248,7 @@ module SmarterCSV
241
248
  end
242
249
  ensure
243
250
  $/ = old_row_sep # make sure this stupid global variable is always reset to it's previous value after we're done!
244
- f.close
251
+ f.close if f.respond_to?(:close)
245
252
  end
246
253
  if block_given?
247
254
  return chunk_count # when we do processing through a block we only care how many chunks we processed
@@ -1,3 +1,3 @@
1
1
  module SmarterCSV
2
- VERSION = "1.2.0"
2
+ VERSION = "1.2.7"
3
3
  end
@@ -0,0 +1,11 @@
1
+ not a comment#First Name,Last Name,Dogs,Cats,Birds,Fish
2
+ # comment two
3
+ Dan,McAllister,2,0,,
4
+ Lucy#L,Laweless,,5,0,
5
+ # anothter comment
6
+ ,,,,,
7
+ Miles,O'Brian,0,0,0,21
8
+ Nancy,Homes,2,0,1,
9
+ Hernán,Curaçon,3,0,0,
10
+ #comment,comment,1,2,3,4
11
+ ,,,,,
@@ -0,0 +1,3 @@
1
+ h1,h2
2
+ a,"b
3
+ #c"
@@ -0,0 +1,8 @@
1
+ Compte;Date de comptabilisation;Date op�ration;Libell�;R�f�rence;Date valeur;Montant
2
+ 22215449203;02/06/2018;01/06/2018;ECHEANCE PRET DONT CAP 410,33 ASS. 8,00E INT. 21,87 COM. 0,00E;8711552;01/06/2018;-440,20;
3
+ 22215449203;04/06/2018;04/06/2018;EVI Gaultier Laperche remboursement compte courant;1038326;04/06/2018;-144,07;
4
+ 22215449203;04/06/2018;04/06/2018;EVI Guillemain Nicolas remboursement CC pret d'honneur;1038328;04/06/2018;-144,07;
5
+ 22215449203;01/06/2018;01/06/2018;310518 SC****5448 INTERMARCHE 95ERMONT;701JQ1K;01/06/2018;-16,00;
6
+ 22215449203;01/06/2018;01/06/2018;EVI Stripe Payments UK L STRIPE E7U0R1;706AO1Q;01/06/2018;45,89;
7
+ 22215449203;01/06/2018;01/06/2018;EVI Compte N26 Heroku;1100653;01/06/2018;-700,00;
8
+ 22215449203;31/05/2018;31/05/2018;EVI Stripe Payments UK L STRIPE L2J1N7;6YISBWF;31/05/2018;465,89;
@@ -0,0 +1,9 @@
1
+ "ID","FIRST_NAME","LAST_NAME"
2
+ "1","""John","Cooke"""
3
+ "2","Jam
4
+ e
5
+ son""","McCollum"
6
+ "3","""Jean","Conn"
7
+ "4","Jenny","Traer"
8
+ "5","Bo""bbie","Faga"
9
+ "6","Mica","Copeland"
@@ -0,0 +1,4 @@
1
+ "REVIEW DATE","AUTHOR","""ISBN""","DISCOUNTED ""PRICE"""
2
+ "1985/01/21","Douglas Adams",0345391802,5.95
3
+ "1998/07/15","Timothy ""The Parser"" Campbell",0968411304,18.99
4
+ "1999/12/03","Richard Friedman",0060630353,5.95
@@ -0,0 +1,3 @@
1
+ Account_ID,options_trader,Stock_Symbol,Shares Issued,Purchase Date
2
+ 0002310234,Mike Smith,TSLA,2300,2011-08-19
3
+ 0024923423,John Doe,AAPL,1300,2013-03-21
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ fixture_path = 'spec/fixtures'
4
+
5
+ describe 'be_able_to' do
6
+ it 'ignore comments in CSV files' do
7
+ options = {}
8
+ data = SmarterCSV.process("#{fixture_path}/ignore_comments.csv", options)
9
+
10
+ data.size.should eq 5
11
+
12
+ # all the keys should be symbols
13
+ data.each{|item| item.keys.each{|x| x.is_a?(Symbol).should be_truthy}}
14
+ data.each do |h|
15
+ h.keys.each do |key|
16
+ [:"not_a_comment#first_name", :last_name, :dogs, :cats, :birds, :fish].should include( key )
17
+ end
18
+ end
19
+ end
20
+
21
+ it 'ignore comments in CSV files with CRLF' do
22
+ options = {row_sep: "\r\n"}
23
+ data = SmarterCSV.process("#{fixture_path}/ignore_comments2.csv", options)
24
+
25
+ # all the keys should be symbols
26
+ data.size.should eq 1
27
+ data.first[:h1].should eq 'a'
28
+ data.first[:h2].should eq "b\r\n#c"
29
+ end
30
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ fixture_path = 'spec/fixtures'
4
+
5
+ describe 'loading file with UTF-8 characters in the header' do
6
+
7
+ # file which caused issues because of UTF-8 characters in the header
8
+ it 'loads the file with force_utf8 flag set' do
9
+ options = {col_sep: ";", force_utf8: true}
10
+ data = SmarterCSV.process("#{fixture_path}/problematic.csv", options)
11
+
12
+ data.length.should eq 7
13
+ end
14
+
15
+ it 'loads the file with strings as keys' do
16
+ options = {
17
+ file_encoding: 'iso-8859-1:UTF-8', # important!
18
+ col_sep: ";", strings_as_keys: true,
19
+ }
20
+ data = SmarterCSV.process("#{fixture_path}/problematic.csv", options)
21
+
22
+ data.length.should eq 7
23
+ data.first.keys.sort.should eq [
24
+ "compte",
25
+ "date_de_comptabilisation",
26
+ "date_opération",
27
+ "date_valeur",
28
+ "libellé",
29
+ "montant",
30
+ "référence"
31
+ ]
32
+ end
33
+
34
+ end
@@ -2,9 +2,9 @@ require 'spec_helper'
2
2
 
3
3
  fixture_path = 'spec/fixtures'
4
4
 
5
- describe 'be_able_to' do
5
+ describe 'loading file with quoted fields' do
6
6
 
7
- it 'loads_file_with_quoted_fields' do
7
+ it 'leaving the quotes in the data' do
8
8
  options = {}
9
9
  data = SmarterCSV.process("#{fixture_path}/quoted.csv", options)
10
10
  data.flatten.size.should == 4
@@ -20,4 +20,29 @@ describe 'be_able_to' do
20
20
  end
21
21
  end
22
22
 
23
+
24
+ it 'removes quotes around quoted fields, but not inside data' do
25
+ options = {}
26
+ data = SmarterCSV.process("#{fixture_path}/quote_char.csv", options)
27
+
28
+ data.length.should eq 6
29
+ data[1][:first_name].should eq "Jam\ne\nson\""
30
+ data[2][:first_name].should eq "\"Jean"
31
+ end
32
+
33
+
34
+ # NOTE: quotes inside headers need to be escaped by doubling them
35
+ # e.g. 'correct ""EXAMPLE""'
36
+ # this escaping is illegal: 'incorrect \"EXAMPLE\"' <-- this caused CSV parsing error
37
+ # in case of CSV parsing errirs, use :user_provided_headers, or key_mapping
38
+ #
39
+ it 'removes quotes around headers and extra quotes inside headers' do
40
+ options = {}
41
+ data = SmarterCSV.process("#{fixture_path}/quoted2.csv", options)
42
+
43
+ data.length.should eq 3
44
+ data.first.keys[2].should eq :isbn
45
+ data.first.keys[3].should eq :discounted_price
46
+ end
47
+
23
48
  end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ fixture_path = 'spec/fixtures'
4
+
5
+ # somebody reported that a column called 'options_trader' would be truncated to 'trader'
6
+
7
+ describe 'loads simple file format' do
8
+
9
+ it 'with symbols as keys when using defaults' do
10
+ options = {}
11
+ data = SmarterCSV.process("#{fixture_path}/trading.csv", options)
12
+
13
+ data.flatten.size.should eq 2
14
+ data.each do |item|
15
+ # all keys should be symbols when using v1.x backwards compatible mode
16
+ item.keys.each{|x| x.class.should eq Symbol}
17
+ item[:account_id].class.should eq Fixnum
18
+ item[:options_trader].class.should eq String
19
+ item[:stock_symbol].class.should eq String
20
+ item[:shares_issued].class.should eq Fixnum
21
+ item[:purchase_date].class.should eq String
22
+ end
23
+ end
24
+
25
+ end
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smarter_csv
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.2.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - 'Tilo Sloboda
8
8
 
9
- '
10
- autorequire:
9
+ '
10
+ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2018-01-20 00:00:00.000000000 Z
13
+ date: 2021-02-04 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rspec
@@ -32,7 +32,7 @@ description: Ruby Gem for smarter importing of CSV Files as Array(s) of Hashes,
32
32
  email:
33
33
  - 'tilo.sloboda@gmail.com
34
34
 
35
- '
35
+ '
36
36
  executables: []
37
37
  extensions: []
38
38
  extra_rdoc_files: []
@@ -58,6 +58,8 @@ files:
58
58
  - spec/fixtures/chunk_cornercase.csv
59
59
  - spec/fixtures/duplicate_headers.csv
60
60
  - spec/fixtures/empty.csv
61
+ - spec/fixtures/ignore_comments.csv
62
+ - spec/fixtures/ignore_comments2.csv
61
63
  - spec/fixtures/line_endings_n.csv
62
64
  - spec/fixtures/line_endings_r.csv
63
65
  - spec/fixtures/line_endings_rn.csv
@@ -68,9 +70,13 @@ files:
68
70
  - spec/fixtures/no_header.csv
69
71
  - spec/fixtures/numeric.csv
70
72
  - spec/fixtures/pets.csv
73
+ - spec/fixtures/problematic.csv
74
+ - spec/fixtures/quote_char.csv
71
75
  - spec/fixtures/quoted.csv
76
+ - spec/fixtures/quoted2.csv
72
77
  - spec/fixtures/separator.csv
73
78
  - spec/fixtures/skip_lines.csv
79
+ - spec/fixtures/trading.csv
74
80
  - spec/fixtures/user_import.csv
75
81
  - spec/fixtures/valid_unicode.csv
76
82
  - spec/fixtures/with_dashes.csv
@@ -84,6 +90,7 @@ files:
84
90
  - spec/smarter_csv/convert_values_to_numeric_spec.rb
85
91
  - spec/smarter_csv/extenstions_spec.rb
86
92
  - spec/smarter_csv/header_transformation_spec.rb
93
+ - spec/smarter_csv/ignore_comments_spec.rb
87
94
  - spec/smarter_csv/invalid_headers_spec.rb
88
95
  - spec/smarter_csv/keep_headers_spec.rb
89
96
  - spec/smarter_csv/key_mapping_spec.rb
@@ -92,6 +99,7 @@ files:
92
99
  - spec/smarter_csv/malformed_spec.rb
93
100
  - spec/smarter_csv/no_header_spec.rb
94
101
  - spec/smarter_csv/not_downcase_header_spec.rb
102
+ - spec/smarter_csv/problematic.rb
95
103
  - spec/smarter_csv/quoted_spec.rb
96
104
  - spec/smarter_csv/remove_empty_values_spec.rb
97
105
  - spec/smarter_csv/remove_keys_from_hashes_spec.rb
@@ -101,6 +109,7 @@ files:
101
109
  - spec/smarter_csv/skip_lines_spec.rb
102
110
  - spec/smarter_csv/strings_as_keys_spec.rb
103
111
  - spec/smarter_csv/strip_chars_from_headers_spec.rb
112
+ - spec/smarter_csv/trading_spec.rb
104
113
  - spec/smarter_csv/valid_unicode_spec.rb
105
114
  - spec/smarter_csv/value_converters_spec.rb
106
115
  - spec/spec.opts
@@ -111,7 +120,7 @@ licenses:
111
120
  - MIT
112
121
  - GPL-2
113
122
  metadata: {}
114
- post_install_message:
123
+ post_install_message:
115
124
  rdoc_options: []
116
125
  require_paths:
117
126
  - lib
@@ -127,9 +136,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
127
136
  version: '0'
128
137
  requirements:
129
138
  - csv
130
- rubyforge_project:
131
- rubygems_version: 2.6.13
132
- signing_key:
139
+ rubygems_version: 3.0.6
140
+ signing_key:
133
141
  specification_version: 4
134
142
  summary: Ruby Gem for smarter importing of CSV Files (and CSV-like files), with lots
135
143
  of optional features, e.g. chunked processing for huge CSV files
@@ -143,6 +151,8 @@ test_files:
143
151
  - spec/fixtures/chunk_cornercase.csv
144
152
  - spec/fixtures/duplicate_headers.csv
145
153
  - spec/fixtures/empty.csv
154
+ - spec/fixtures/ignore_comments.csv
155
+ - spec/fixtures/ignore_comments2.csv
146
156
  - spec/fixtures/line_endings_n.csv
147
157
  - spec/fixtures/line_endings_r.csv
148
158
  - spec/fixtures/line_endings_rn.csv
@@ -153,9 +163,13 @@ test_files:
153
163
  - spec/fixtures/no_header.csv
154
164
  - spec/fixtures/numeric.csv
155
165
  - spec/fixtures/pets.csv
166
+ - spec/fixtures/problematic.csv
167
+ - spec/fixtures/quote_char.csv
156
168
  - spec/fixtures/quoted.csv
169
+ - spec/fixtures/quoted2.csv
157
170
  - spec/fixtures/separator.csv
158
171
  - spec/fixtures/skip_lines.csv
172
+ - spec/fixtures/trading.csv
159
173
  - spec/fixtures/user_import.csv
160
174
  - spec/fixtures/valid_unicode.csv
161
175
  - spec/fixtures/with_dashes.csv
@@ -169,6 +183,7 @@ test_files:
169
183
  - spec/smarter_csv/convert_values_to_numeric_spec.rb
170
184
  - spec/smarter_csv/extenstions_spec.rb
171
185
  - spec/smarter_csv/header_transformation_spec.rb
186
+ - spec/smarter_csv/ignore_comments_spec.rb
172
187
  - spec/smarter_csv/invalid_headers_spec.rb
173
188
  - spec/smarter_csv/keep_headers_spec.rb
174
189
  - spec/smarter_csv/key_mapping_spec.rb
@@ -177,6 +192,7 @@ test_files:
177
192
  - spec/smarter_csv/malformed_spec.rb
178
193
  - spec/smarter_csv/no_header_spec.rb
179
194
  - spec/smarter_csv/not_downcase_header_spec.rb
195
+ - spec/smarter_csv/problematic.rb
180
196
  - spec/smarter_csv/quoted_spec.rb
181
197
  - spec/smarter_csv/remove_empty_values_spec.rb
182
198
  - spec/smarter_csv/remove_keys_from_hashes_spec.rb
@@ -186,6 +202,7 @@ test_files:
186
202
  - spec/smarter_csv/skip_lines_spec.rb
187
203
  - spec/smarter_csv/strings_as_keys_spec.rb
188
204
  - spec/smarter_csv/strip_chars_from_headers_spec.rb
205
+ - spec/smarter_csv/trading_spec.rb
189
206
  - spec/smarter_csv/valid_unicode_spec.rb
190
207
  - spec/smarter_csv/value_converters_spec.rb
191
208
  - spec/spec.opts