smarter_csv 1.0.11 → 1.0.12

Sign up to get free protection for your applications and to get access to all the features.
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