smarter_csv 1.0.11 → 1.0.12

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
2
  SHA1:
3
- metadata.gz: b8da8da62110a7342bf1607f6d971125192d79d4
4
- data.tar.gz: f1e42ed0dba9a1cadb609044929bdea223874887
3
+ metadata.gz: 0d4a07a52c8c5b769270afadb3a0057c9cc5f632
4
+ data.tar.gz: 27ba30864fc20db120821a4f34bb28f2247e5c4a
5
5
  SHA512:
6
- metadata.gz: 2a15724a84cb1a1985b557236dcbbc732b1afe2fac044db9002f4c4df8e178fdd875aeaf5d0f69b76478aac77b7e96cc874ae069f90e0701b0d113823f3daf24
7
- data.tar.gz: aced7129287273dbfea183445bf448303c0aa51af159d7880cab6e51fa79b672f8a8231cf2cfbb5a864075dae42d52e036bd5fab850298f15ca54ab27764b8f8
6
+ metadata.gz: acf2ab6699268f419fcde32239da0b97f200dff744cd9c920c1f2c8cfedf9d6be0aba76b4ab77e359c429e911e83f41c6f23d7629b40a19dae0b34c134023eaa
7
+ data.tar.gz: 53620d67dd6a6bb8cddf17807ed6a688fb98ccc136b367b44ce77a1ea9f22b420c87c196b8430b472947c42ea091a015b05866234620b2b9f140b8a3e2ca47b7
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ bundler_args: --without development
3
+ rvm:
4
+ - "1.9.2"
5
+ - "1.9.3"
6
+ - "2.0.0"
7
+ branches:
8
+ only:
9
+ - master
data/Gemfile CHANGED
@@ -2,3 +2,10 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in smarter_csv.gemspec
4
4
  gemspec
5
+
6
+
7
+ gem "rake"
8
+
9
+ group :test do
10
+ gem "rspec", "~> 2.14"
11
+ end
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # SmarterCSV
1
+ # SmarterCSV [![Build Status](https://secure.travis-ci.org/tilo/smarter_csv.png?branch=master)](http://travis-ci.org/tilo/smarter_csv)
2
2
 
3
3
  `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,
4
4
  and parallel processing with Resque or Sidekiq.
@@ -176,6 +176,21 @@ The options and the block are optional.
176
176
  * if the chunk_size is > 0 , then the array may contain up to chunk_size Hashes.
177
177
  * this can be very useful when passing chunked data to a post-processing step, e.g. through Resque
178
178
 
179
+ #### Known Issue:
180
+ * if your CSV data contains the :row_sep character, e.g. CR, smarter_csv will not be able to handle the data, but will report `CSV::MalformedCSVError: Unclosed quoted field`.
181
+
182
+
183
+ Example of Invalid CSV:
184
+
185
+ id,name,comment
186
+ 1,James,a simple comment
187
+ 2,Paul,"a comment which contains
188
+ the :row_sep character CR"
189
+ 3,Frank,"some other comment"
190
+
191
+ The second row contains a comment with an embedded \n carriage return character.
192
+ `smarter_csv` handles this special case as invalid CSV.
193
+
179
194
 
180
195
  ## See also:
181
196
 
@@ -200,6 +215,9 @@ Or install it yourself as:
200
215
 
201
216
  ## Changes
202
217
 
218
+ #### 1.0.12 (2013-10-15)
219
+ * added RSpec tests
220
+
203
221
  #### 1.0.11 (2013-09-28)
204
222
  * bugfix : fixed issue #18 - fixing issue with last chunk not being properly returned (thanks to Jordan Running)
205
223
  * added RSpec tests
@@ -34,6 +34,9 @@ module SmarterCSV
34
34
  file_headerA.map!{|x| x.strip} if options[:strip_whitespace]
35
35
  file_headerA.map!{|x| x.gsub(/\s+/,'_')}
36
36
  file_headerA.map!{|x| x.downcase } if options[:downcase_header]
37
+
38
+ # puts "HeaderA: #{file_headerA.join(' , ')}" if options[:verbose]
39
+
37
40
  file_header_size = file_headerA.size
38
41
  end
39
42
  if options[:user_provided_headers] && options[:user_provided_headers].class == Array && ! options[:user_provided_headers].empty?
@@ -1,3 +1,3 @@
1
1
  module SmarterCSV
2
- VERSION = "1.0.11"
2
+ VERSION = "1.0.12"
3
3
  end
@@ -1,7 +1,8 @@
1
- first name,last name,dogs,cats,birds,fish
2
- Dan,McAllister,2,,,
3
- Lucy,Laweless,,5,,
1
+ First Name,Last Name,Dogs,Cats,Birds,Fish
2
+ Dan,McAllister,2,0,,
3
+ Lucy,Laweless,,5,0,
4
+ ,,,,,
5
+ Miles,O'Brian,0,0,0,21
6
+ Nancy,Homes,2,0,1,
7
+ Hernán,Curaçon,3,0,0,
4
8
  ,,,,,
5
- Miles,O'Brian,,,,21
6
- Nancy,Homes,2,,1,
7
- ,,,,,
@@ -0,0 +1 @@
1
+ #timestampitem_idparent_idname#some comments here#these can be multiple comments in the header section#even more comments here1381388409101Thing 11381388409111Thing 21381388409121Thing 313813884091Parent 113813884092Parent 21381388409202Thing 41381388409212Thing 51381388409222Thing 6
@@ -0,0 +1,7 @@
1
+ Dan,McAllister,2,0,,
2
+ Lucy,Laweless,,5,0,
3
+ ,,,,,
4
+ Miles,O'Brian,0,0,0,21
5
+ Nancy,Homes,2,0,1,
6
+ Hernán,Curaçon,3,0,0,
7
+ ,,,,,
@@ -0,0 +1,5 @@
1
+ Year,Make,Model,Description,Price
2
+ 1997,Ford,E350,"ac, abs, moon",3000.00
3
+ 1999,Chevy,"Venture ""Extended Edition""","",4900.00
4
+ 1999,Chevy,"Venture ""Extended Edition, Very Large""",,5000.00
5
+ 1996,Jeep,Grand Cherokee,"MUST SELL! air, moon roof, loaded",4799.00
@@ -0,0 +1,4 @@
1
+ Year;Make;Model;Length
2
+ 1997;Ford;E350;2,34
3
+ 2000;Mercury;Cougar;2,38
4
+ 2013;Tesla;Model S;4,97
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ fixture_path = 'spec/fixtures'
4
+
5
+ # this reads a binary database dump file, which is in structure like a CSV file
6
+ # but contains control characters delimiting the rows and columns, and also
7
+ # contains a comment section which is commented our by a leading # character
8
+
9
+ # same as binary_file_spec , but reading the file with strings as keys
10
+
11
+ describe 'be_able_to' do
12
+ it 'loads_binary_file_with_strings_as_keys' do
13
+ options = {:col_sep => "\cA", :row_sep => "\cB", :comment_regexp => /^#/, :strings_as_keys => true}
14
+ data = SmarterCSV.process("#{fixture_path}/binary.csv", options)
15
+ data.flatten.size.should == 8
16
+ data.each do |item|
17
+ # all keys should be strings
18
+ item.keys.each{|x| x.class.should be == String}
19
+ item['timestamp'].should == 1381388409
20
+ item['item_id'].class.should be == Fixnum
21
+ item['name'].size.should be > 0
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ fixture_path = 'spec/fixtures'
4
+
5
+ # this reads a binary database dump file, which is in structure like a CSV file
6
+ # but contains control characters delimiting the rows and columns, and also
7
+ # contains a comment section which is commented our by a leading # character
8
+
9
+ describe 'be_able_to' do
10
+ it 'loads_binary_file_with_comments' do
11
+ options = {:col_sep => "\cA", :row_sep => "\cB", :comment_regexp => /^#/}
12
+ data = SmarterCSV.process("#{fixture_path}/binary.csv", options)
13
+ data.flatten.size.should == 8
14
+ data.each do |item|
15
+ # all keys should be symbols
16
+ item.keys.each{|x| x.class.should be == Symbol}
17
+ item[:timestamp].should == 1381388409
18
+ item[:item_id].class.should be == Fixnum
19
+ item[:name].size.should be > 0
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ fixture_path = 'spec/fixtures'
4
+
5
+ describe 'be_able_to' do
6
+ it 'loads_chunk_cornercase_csv_files' do
7
+ (0..5).each do |chunk_size| # test for all chunk-sizes
8
+ options = {:chunk_size => chunk_size, :remove_empty_hashes => true}
9
+ data = SmarterCSV.process("#{fixture_path}/chunk_cornercase.csv", options)
10
+ data.flatten.size.should == 5 # end-result must always be 5 rows
11
+ end
12
+ end
13
+
14
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ fixture_path = 'spec/fixtures'
4
+
5
+ describe 'be_able_to' do
6
+ it 'loads_file_with_different_column_separator' do
7
+ options = {:col_sep => ';'}
8
+ data = SmarterCSV.process("#{fixture_path}/separator.csv", options)
9
+ data.flatten.size.should == 3
10
+ end
11
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ fixture_path = 'spec/fixtures'
4
+
5
+ describe 'be_able_to' do
6
+ it 'remove_values_matching' do
7
+ options = {:remove_zero_values => true, :key_mapping => {:first_name => :vorname, :last_name => :nachname} }
8
+ data = SmarterCSV.process("#{fixture_path}/basic.csv", options)
9
+ data.size.should == 5
10
+ # all the keys should be symbols
11
+ data.each{|item| item.keys.each{|x| x.class.should be == Symbol}}
12
+
13
+ data.each do |hash|
14
+ hash.keys.each do |key|
15
+ [:vorname, :nachname, :dogs, :cats, :birds, :fish].should include( key )
16
+ end
17
+ hash.values.should_not include( 0 )
18
+ end
19
+
20
+ data.each do |h|
21
+ h.size.should <= 6
22
+ end
23
+ end
24
+
25
+ end
@@ -5,8 +5,14 @@ fixture_path = 'spec/fixtures'
5
5
  describe 'be_able_to' do
6
6
  it 'loads_basic_csv_file' do
7
7
  data = SmarterCSV.process("#{fixture_path}/basic.csv")
8
- data.size.should == 4
8
+ data.size.should == 5
9
+
10
+ # all the keys should be symbols
11
+ data.each{|item| item.keys.each{|x| x.class.should be == Symbol}}
9
12
  data.each do |h|
13
+ h.keys.each do |key|
14
+ [:first_name, :last_name, :dogs, :cats, :birds, :fish].should include( key )
15
+ end
10
16
  h.size.should <= 6
11
17
  end
12
18
  end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ fixture_path = 'spec/fixtures'
4
+
5
+ describe 'be_able_to' do
6
+ it 'loads_csv_file_without_header' do
7
+ options = {:headers_in_file => false, :user_provided_headers => [:a,:b,:c,:d,:e,:f]}
8
+ data = SmarterCSV.process("#{fixture_path}/no_header.csv", options)
9
+ data.size.should == 5
10
+ # all the keys should be symbols
11
+ data.each{|item| item.keys.each{|x| x.class.should be == Symbol}}
12
+
13
+ data.each do |item|
14
+ item.keys.each do |key|
15
+ [:a,:b,:c,:d,:e,:f].should include( key )
16
+ end
17
+ end
18
+
19
+ data.each do |h|
20
+ h.size.should <= 6
21
+ end
22
+ end
23
+
24
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ fixture_path = 'spec/fixtures'
4
+
5
+ describe 'be_able_to' do
6
+ it 'not_downcase_headers' do
7
+ options = {:downcase_header => false}
8
+ data = SmarterCSV.process("#{fixture_path}/basic.csv", options)
9
+ data.size.should == 5
10
+ # all the keys should be symbols
11
+ data.each{|item| item.keys.each{|x| x.class.should be == Symbol}}
12
+
13
+ data.each do |item|
14
+ item.keys.each do |key|
15
+ [:First_Name, :Last_Name, :Dogs, :Cats, :Birds, :Fish].should include( key )
16
+ end
17
+ end
18
+
19
+ data.each do |h|
20
+ h.size.should <= 6
21
+ end
22
+ end
23
+
24
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ fixture_path = 'spec/fixtures'
4
+
5
+ describe 'be_able_to' do
6
+ it 'loads_file_with_quoted_fields' do
7
+ options = {}
8
+ data = SmarterCSV.process("#{fixture_path}/quoted.csv", options)
9
+ data.flatten.size.should == 4
10
+ data[1][:description].should be_nil
11
+ data[2][:description].should be_nil
12
+ end
13
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ fixture_path = 'spec/fixtures'
4
+
5
+ describe 'be_able_to' do
6
+ it 'remove_values_matching' do
7
+ options = {:remove_zero_values => true, :key_mapping => {:first_name => :vorname, :last_name => :nachname, :fish => nil} }
8
+ data = SmarterCSV.process("#{fixture_path}/basic.csv", options)
9
+ data.size.should == 5
10
+ # all the keys should be symbols
11
+ data.each{|item| item.keys.each{|x| x.class.should be == Symbol}}
12
+
13
+ data.each do |hash|
14
+ hash.keys.each do |key|
15
+ [:vorname, :nachname, :dogs, :cats, :birds].should include( key )
16
+ end
17
+ hash.values.should_not include( 0 )
18
+ end
19
+
20
+ data.each do |h|
21
+ h.size.should <= 6
22
+ end
23
+ end
24
+
25
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ fixture_path = 'spec/fixtures'
4
+
5
+ describe 'be_able_to' do
6
+ it 'remove_values_matching' do
7
+ options = {:remove_zero_values => true, :remove_empty_values => true, :remove_values_matching => /^\d+$/}
8
+ data = SmarterCSV.process("#{fixture_path}/basic.csv", options)
9
+ data.size.should == 5
10
+ # all the keys should be symbols
11
+ data.each{|item| item.keys.each{|x| x.class.should be == Symbol}}
12
+
13
+ data.each do |hash|
14
+ hash.keys.each do |key|
15
+ [:first_name, :last_name].should include( key )
16
+ end
17
+ hash.values.each{|x| x.class.should be == String}
18
+ hash.values.should_not include( 0 )
19
+ end
20
+
21
+ data.each do |h|
22
+ h.size.should <= 6
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ fixture_path = 'spec/fixtures'
4
+
5
+ describe 'be_able_to' do
6
+ it 'remove_zero_values' do
7
+ options = {:remove_zero_values => true, :remove_empty_values => true}
8
+ data = SmarterCSV.process("#{fixture_path}/basic.csv", options)
9
+ data.size.should == 5
10
+ # all the keys should be symbols
11
+ data.each{|item| item.keys.each{|x| x.class.should be == Symbol}}
12
+
13
+ data.each do |hash|
14
+ hash.keys.each do |key|
15
+ [:first_name, :last_name, :dogs, :cats, :birds, :fish].should include( key )
16
+ end
17
+ hash.values.should_not include( 0 )
18
+ end
19
+
20
+ data.each do |h|
21
+ h.size.should <= 6
22
+ end
23
+ end
24
+
25
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ fixture_path = 'spec/fixtures'
4
+
5
+ describe 'be_able_to' do
6
+ it 'use_strings_as_keys' do
7
+ options = {:strings_as_keys => true}
8
+ data = SmarterCSV.process("#{fixture_path}/basic.csv", options)
9
+ data.size.should == 5
10
+ # all the keys should be symbols
11
+ data.each{|item| item.keys.each{|x| x.class.should be == String}}
12
+
13
+ data.each do |item|
14
+ item.keys.each do |key|
15
+ ["first_name", "last_name", "dogs", "cats", "birds", "fish"].should include( key )
16
+ end
17
+ end
18
+
19
+ data.each do |h|
20
+ h.size.should <= 6
21
+ end
22
+ end
23
+
24
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ fixture_path = 'spec/fixtures'
4
+
5
+ describe 'be_able_to' do
6
+ it 'strip_whitespace_from_headers' do
7
+ options = {:strip_chars_from_headers => ' '}
8
+ data = SmarterCSV.process("#{fixture_path}/basic.csv", options)
9
+ data.size.should == 5
10
+ # all the keys should be symbols
11
+ data.each{|item| item.keys.each{|x| x.class.should be == Symbol}}
12
+
13
+ data.each do |item|
14
+ item.keys.each do |key|
15
+ [:firstname, :lastname, :dogs, :cats, :birds, :fish].should include( key )
16
+ end
17
+ end
18
+
19
+ data.each do |h|
20
+ h.size.should <= 6
21
+ end
22
+ end
23
+
24
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smarter_csv
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.11
4
+ version: 1.0.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - |
@@ -11,7 +11,7 @@ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
13
 
14
- date: 2013-09-28 00:00:00 Z
14
+ date: 2013-10-16 00:00:00 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rspec
@@ -37,7 +37,9 @@ extra_rdoc_files: []
37
37
 
38
38
  files:
39
39
  - .gitignore
40
+ - .rspec
40
41
  - .rvmrc
42
+ - .travis.yml
41
43
  - Gemfile
42
44
  - LICENSE
43
45
  - README.md
@@ -48,10 +50,26 @@ files:
48
50
  - lib/smarter_csv/version.rb
49
51
  - smarter_csv.gemspec
50
52
  - spec/fixtures/basic.csv
53
+ - spec/fixtures/binary.csv
51
54
  - spec/fixtures/chunk_cornercase.csv
55
+ - spec/fixtures/no_header.csv
52
56
  - spec/fixtures/pets.csv
53
- - spec/smarter_csv/chunked_reading.rb
57
+ - spec/fixtures/quoted.csv
58
+ - spec/fixtures/separator.csv
59
+ - spec/smarter_csv/binary_file2_spec.rb
60
+ - spec/smarter_csv/binary_file_spec.rb
61
+ - spec/smarter_csv/chunked_reading_spec.rb
62
+ - spec/smarter_csv/column_separator_spec.rb
63
+ - spec/smarter_csv/key_mapping_spec.rb
54
64
  - spec/smarter_csv/load_basic_spec.rb
65
+ - spec/smarter_csv/no_header_spec.rb
66
+ - spec/smarter_csv/not_downcase_header_spec.rb
67
+ - spec/smarter_csv/quoted_spec.rb
68
+ - spec/smarter_csv/remove_keys_from_hashes_spec.rb
69
+ - spec/smarter_csv/remove_values_matching_spec.rb
70
+ - spec/smarter_csv/remove_zero_values_spec.rb
71
+ - spec/smarter_csv/strings_as_keys_spec.rb
72
+ - spec/smarter_csv/strip_chars_from_headers_spec.rb
55
73
  - spec/spec.opts
56
74
  - spec/spec/spec_helper.rb
57
75
  - spec/spec_helper.rb
@@ -80,10 +98,26 @@ specification_version: 4
80
98
  summary: Ruby Gem for smarter importing of CSV Files (and CSV-like files), with lots of optional features, e.g. chunked processing for huge CSV files
81
99
  test_files:
82
100
  - spec/fixtures/basic.csv
101
+ - spec/fixtures/binary.csv
83
102
  - spec/fixtures/chunk_cornercase.csv
103
+ - spec/fixtures/no_header.csv
84
104
  - spec/fixtures/pets.csv
85
- - spec/smarter_csv/chunked_reading.rb
105
+ - spec/fixtures/quoted.csv
106
+ - spec/fixtures/separator.csv
107
+ - spec/smarter_csv/binary_file2_spec.rb
108
+ - spec/smarter_csv/binary_file_spec.rb
109
+ - spec/smarter_csv/chunked_reading_spec.rb
110
+ - spec/smarter_csv/column_separator_spec.rb
111
+ - spec/smarter_csv/key_mapping_spec.rb
86
112
  - spec/smarter_csv/load_basic_spec.rb
113
+ - spec/smarter_csv/no_header_spec.rb
114
+ - spec/smarter_csv/not_downcase_header_spec.rb
115
+ - spec/smarter_csv/quoted_spec.rb
116
+ - spec/smarter_csv/remove_keys_from_hashes_spec.rb
117
+ - spec/smarter_csv/remove_values_matching_spec.rb
118
+ - spec/smarter_csv/remove_zero_values_spec.rb
119
+ - spec/smarter_csv/strings_as_keys_spec.rb
120
+ - spec/smarter_csv/strip_chars_from_headers_spec.rb
87
121
  - spec/spec.opts
88
122
  - spec/spec/spec_helper.rb
89
123
  - spec/spec_helper.rb
@@ -1,13 +0,0 @@
1
- require 'spec_helper'
2
-
3
- fixture_path = 'spec/fixtures'
4
-
5
- describe 'be_able_to' do
6
- it 'loads_chunk_cornercase_csv_files' do
7
- (0..5).each do |chunk_size| # test for all chunk-sizes
8
- options = {:chunk_size => chunk_size, :remove_empty_hashes => true}
9
- data = SmarterCSV.process("#{fixture_path}/chunk_cornercase.csv", options)
10
- data.flatten.size.should == 5 # end-result must always be 5 rows
11
- end
12
-
13
- end