iron-import 0.5.0

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.
@@ -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: []