iron-import 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,93 @@
1
+ describe Importer::DataReader do
2
+
3
+ before do
4
+ @importer = Importer.new
5
+ @reader = Importer::DataReader.new(@importer, :test)
6
+ end
7
+
8
+ it 'should parse integers' do
9
+ {
10
+ '1234' => 1234,
11
+ '-2' => -2,
12
+ '5.00' => 5,
13
+ 'foo' => nil,
14
+ '' => nil,
15
+ 55 => 55,
16
+ 3.0 => 3
17
+ }.each_pair do |val, res|
18
+ @reader.parse_value(val, :integer).should == res
19
+ end
20
+ end
21
+
22
+ it 'should parse floats' do
23
+ {
24
+ '1.256' => 1.256,
25
+ '-20.3' => -20.3,
26
+ '5.00' => 5.0,
27
+ 'foo' => nil,
28
+ '' => nil,
29
+ 55 => 55.0,
30
+ '3' => 3.0
31
+ }.each_pair do |val, res|
32
+ @reader.parse_value(val, :float).should == res
33
+ end
34
+ end
35
+
36
+ it 'should parse strings' do
37
+ {
38
+ 'blah' => 'blah',
39
+ " spaces \t" => 'spaces',
40
+ '' => nil,
41
+ 255 => '255',
42
+ -1.5 => '-1.5'
43
+ }.each_pair do |val, res|
44
+ @reader.parse_value(val, :string).should == res
45
+ end
46
+ end
47
+
48
+ it 'should parse cents' do
49
+ {
50
+ '$123.00' => 12300,
51
+ '5' => 500,
52
+ '0.5' => 50,
53
+ '-95' => -9500,
54
+ 52 => 5200,
55
+ 1.0 => 100,
56
+ 1.25 => 125
57
+ }.each_pair do |val, res|
58
+ @reader.parse_value(val, :cents).should == res
59
+ end
60
+ end
61
+
62
+ it 'should parse dates' do
63
+ {
64
+ '1/5/73' => Date.new(1973,1,5),
65
+ '05/30/01' => Date.new(2001,5,30),
66
+ '2005-12-10' => Date.new(2005,12,10),
67
+ '4/10/14 22:28' => Date.new(2014,4,10),
68
+ '5/10/2014, 10:28:07 PM' => Date.new(2014,5,10),
69
+ Date.new(2000,4,1) => Date.new(2000,4,1)
70
+ }.each_pair do |val, res|
71
+ @reader.parse_value(val, :date).should == res
72
+ end
73
+ end
74
+
75
+ it 'should build an instance based on format' do
76
+ Importer::DataReader.for_format(@importer, :csv).should be_a(Importer::CsvReader)
77
+ Importer::DataReader.for_format(@importer, :xls).should be_a(Importer::XlsReader)
78
+ Importer::DataReader.for_format(@importer, :xlsx).should be_a(Importer::XlsxReader)
79
+ Importer::DataReader.for_format(@importer, :foo).should be_nil
80
+ end
81
+
82
+ it 'should build an instance based on a path' do
83
+ Importer::DataReader.for_path(@importer, '/tmp/foo.csv').should be_a(Importer::CsvReader)
84
+ Importer::DataReader.for_path(@importer, 'BAR.XLS').should be_a(Importer::XlsReader)
85
+ Importer::DataReader.for_path(@importer, '/tmp/nog_bog.xlsx').should be_a(Importer::XlsxReader)
86
+ Importer::DataReader.for_path(@importer, '/tmp/blinkin.bmp').should be_nil
87
+ end
88
+
89
+ it 'should build an instance based on stream' do
90
+ Importer::DataReader.for_stream(@importer, mock(original_filename: "nanodrop.xlsx", content_type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")).should be_a(Importer::XlsxReader)
91
+ end
92
+
93
+ end
@@ -0,0 +1,28 @@
1
+ describe Importer do
2
+
3
+ it 'should respond to build' do
4
+ Importer.should respond_to(:build)
5
+ end
6
+
7
+ it 'should import a test csv file' do
8
+ importer = Importer.build do
9
+ column :number
10
+ column :string
11
+ column :date
12
+ column :cost
13
+ end
14
+ importer.import(SpecHelper.sample_path('simple.csv')).should be_true
15
+ count = 0
16
+ found = false
17
+ importer.process do |row|
18
+ count += 1
19
+ if row.line == 4
20
+ found = true
21
+ row[:date].should == '2004-02-01'
22
+ end
23
+ end
24
+ found.should be_true
25
+ count.should == 3
26
+ end
27
+
28
+ end
@@ -0,0 +1,37 @@
1
+ describe Importer::Row do
2
+
3
+ before do
4
+ @importer = Importer.new
5
+ @sheet = @importer.default_sheet
6
+ @row = Importer::Row.new(@sheet, 5)
7
+ end
8
+
9
+ it 'should store and retrieve values' do
10
+ @row.set_values(:a => 1, :b => 2)
11
+ @row.values.should == {:a => 1, :b => 2}
12
+ end
13
+
14
+ it 'should allow [] access' do
15
+ @row.set_values(:a => 1, :b => 2)
16
+ @row[:b].should == 2
17
+ end
18
+
19
+ it 'should test for value presence in all columns' do
20
+ @row.set_values(:a => 1, :b => 2)
21
+ @row.should be_all
22
+ @row.set_values(:a => 1, :b => nil)
23
+ @row.should_not be_all
24
+ end
25
+
26
+ it 'should test for specific value\'s presence' do
27
+ @row.set_values(:a => 1, :b => 2, :c => nil)
28
+ @row.all?(:a, :b).should be_true
29
+ @row.all?(:c).should be_false
30
+ end
31
+
32
+ it 'should be empty? with zero values' do
33
+ @row.set_values(:a => nil, :b => nil)
34
+ @row.should be_empty
35
+ end
36
+
37
+ end
@@ -0,0 +1,65 @@
1
+ describe Importer::Sheet do
2
+
3
+ before do
4
+ @importer = Importer.new
5
+ @sheet = @importer.default_sheet
6
+ end
7
+
8
+ it 'should respond to build' do
9
+ @sheet.should respond_to(:build)
10
+ @sheet.build do
11
+ column :foo
12
+ end
13
+ @sheet.columns.count.should == 1
14
+ end
15
+
16
+ it 'should define columns' do
17
+ @sheet.column(:foo)
18
+ @sheet.columns.count.should == 1
19
+ end
20
+
21
+ it 'should find headers automatically' do
22
+ # Define a few sample columns
23
+ @sheet.column(:alpha)
24
+ @sheet.column(:gamma)
25
+ # Some dummy data
26
+ rows = [
27
+ ['', '', '', ''],
28
+ ['Alpha', 'Beta', 'Gamma', 'Epsilon']
29
+ ]
30
+
31
+ # Parse it!
32
+ @sheet.parse_header(rows).should be_true
33
+
34
+ @sheet.column(:alpha).data.index.should == 0
35
+ @sheet.column(:gamma).data.index.should == 2
36
+ @sheet.data.start_row.should == 3
37
+ end
38
+
39
+ it 'should record an error if a column can\'t be found' do
40
+ # Define a few sample columns
41
+ @sheet.column(:alpha)
42
+ @sheet.column(:gamma)
43
+ # Some dummy data
44
+ rows = [
45
+ ['', '', '', ''],
46
+ ['Bob', 'Beta', 'Gamma', 'Epsilon']
47
+ ]
48
+
49
+ # Parse it!
50
+ @sheet.parse_header(rows).should be_false
51
+ @importer.errors.count.should == 1
52
+ @importer.error_summary.should =~ /unable to locate required column header/i
53
+ end
54
+
55
+ it 'should match by sheet name or number' do
56
+ @sheet.id = 5
57
+ @sheet.match_sheet?('foo', 3).should be_false
58
+ @sheet.match_sheet?('foo', 4).should be_true
59
+
60
+ @sheet.id = 'Sheet 5'
61
+ @sheet.match_sheet?('Sheet', 4).should be_false
62
+ @sheet.match_sheet?('Sheet 5', 3).should be_true
63
+ end
64
+
65
+ end
@@ -0,0 +1,35 @@
1
+ describe Importer::XlsxReader do
2
+
3
+ it 'should load our nanodrop data' do
4
+ importer = Importer.build do
5
+ column :sample_id do
6
+ required!
7
+ validate do |val|
8
+ raise 'Invalid ID' unless val.match(/[0-9]{3,}\.[0-9]\z/)
9
+ end
10
+ end
11
+ column :a260 do
12
+ type :float
13
+ end
14
+ column :a280 do
15
+ type :float
16
+ end
17
+ column :factor do
18
+ type :integer
19
+ end
20
+
21
+ # Skip empty rows
22
+ filter do |row|
23
+ row.all?
24
+ end
25
+ end
26
+ res = importer.import(SpecHelper.sample_path('nanodrop.xlsx'))
27
+ importer.error_summary.should be_nil
28
+ res.should be_true
29
+ importer.default_sheet.dump.should == [
30
+ {:sample_id => 'Windsor_buccal_500.1', :a260 => 2.574, :a280 => 1.277, :factor => 50},
31
+ {:sample_id => 'Weston_fecal_206.2', :a260 => 0.746, :a280 => 0.351, :factor => 50}
32
+ ]
33
+ end
34
+
35
+ end
Binary file
@@ -0,0 +1,4 @@
1
+ Number,"String",Date,Cost
2
+ 123,Abc,5/13/77,8.99
3
+ ,,,
4
+ 5.0,"String with end spaces ",2004-02-01,10
Binary file
@@ -0,0 +1,21 @@
1
+ # Set up development requirements
2
+ require 'roo'
3
+
4
+ # Require our library
5
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'iron', 'import'))
6
+
7
+ # Config RSpec options
8
+ RSpec.configure do |config|
9
+ config.color = true
10
+ config.add_formatter 'documentation'
11
+ config.backtrace_exclusion_patterns = [/rspec/]
12
+ end
13
+
14
+ module SpecHelper
15
+
16
+ # Helper to find sample file paths
17
+ def self.sample_path(file)
18
+ File.expand_path(File.join(File.dirname(__FILE__), 'samples', file))
19
+ end
20
+
21
+ end
metadata ADDED
@@ -0,0 +1,128 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: iron-import
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0
5
+ platform: ruby
6
+ authors:
7
+ - Rob Morris
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-03-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: iron-extensions
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 1.2.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 1.2.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: iron-dsl
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.6'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.6'
55
+ - !ruby/object:Gem::Dependency
56
+ name: roo
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.13'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.13'
69
+ description: Simple yet powerful library for importing tabular data including support
70
+ for auto-detecting column order, parsing/validating cell data, aggregating errors,
71
+ etc.
72
+ email:
73
+ - rob@irongaze.com
74
+ executables: []
75
+ extensions: []
76
+ extra_rdoc_files: []
77
+ files:
78
+ - ".rspec"
79
+ - History.txt
80
+ - LICENSE
81
+ - README.rdoc
82
+ - Version.txt
83
+ - lib/iron/import.rb
84
+ - lib/iron/import/column.rb
85
+ - lib/iron/import/csv_reader.rb
86
+ - lib/iron/import/data_reader.rb
87
+ - lib/iron/import/error.rb
88
+ - lib/iron/import/importer.rb
89
+ - lib/iron/import/row.rb
90
+ - lib/iron/import/sheet.rb
91
+ - lib/iron/import/xls_reader.rb
92
+ - lib/iron/import/xlsx_reader.rb
93
+ - spec/importer/column_spec.rb
94
+ - spec/importer/csv_reader_spec.rb
95
+ - spec/importer/data_reader_spec.rb
96
+ - spec/importer/importer_spec.rb
97
+ - spec/importer/row_spec.rb
98
+ - spec/importer/sheet_spec.rb
99
+ - spec/importer/xlsx_reader_spec.rb
100
+ - spec/samples/nanodrop.xlsx
101
+ - spec/samples/simple.csv
102
+ - spec/samples/test-products.xls
103
+ - spec/spec_helper.rb
104
+ homepage: http://irongaze.com
105
+ licenses:
106
+ - MIT
107
+ metadata: {}
108
+ post_install_message:
109
+ rdoc_options: []
110
+ require_paths:
111
+ - lib
112
+ required_ruby_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: 1.9.2
117
+ required_rubygems_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ requirements: []
123
+ rubyforge_project:
124
+ rubygems_version: 2.4.3
125
+ signing_key:
126
+ specification_version: 4
127
+ summary: CSV, XLS, and XLSX import automation support
128
+ test_files: []