sheet2hash 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 39d612017da95d04fcee0ab66f8aa7d5b840449f
4
+ data.tar.gz: 3cbba116e7babb690febc7a3edc10b7aaba4584b
5
+ SHA512:
6
+ metadata.gz: 03e6ad958495e3a1ccbd25c6849e9b7b6d47add075346041c31c67534daa263502912a1c30368aa9f9b1e7b7cee639a4f8059e04354fda7342b4a0245d97deee
7
+ data.tar.gz: 91d3b21a2f50a4f05334b65a67f899ddfaa99b96a9eab568fd9c74f7e45124b8bd5d85d32ccfe94edb83725d7e00c000c4bac4361a9db39a2fcd62f99114e621
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Sheet2hash
2
2
 
3
- Convert Excel or Spreadsheet to Ruby hash
3
+ Convert Excel or Spreadsheet to Ruby Hash
4
4
 
5
5
  ## Installation
6
6
 
data/Rakefile CHANGED
@@ -1 +1,14 @@
1
1
  require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+ require 'yard'
4
+
5
+ YARD::Rake::YardocTask.new
6
+
7
+ Rake::TestTask.new(:test) do |t|
8
+ t.libs << 'lib'
9
+ t.libs << 'test'
10
+ t.pattern = 'test/**/*_test.rb'
11
+ t.verbose = false
12
+ end
13
+
14
+ task :default => :test
@@ -2,18 +2,36 @@ require 'roo'
2
2
  require 'sheet2hash/errors'
3
3
  require 'sheet2hash/options'
4
4
 
5
+ # Sheet2hash
6
+ # @author Wei-Ming Wu
5
7
  module Sheet2hash
8
+ # Sheet2hash::Workbook converts Excel or Spreadsheet into Ruby Hash.
9
+ # @author Wei-Ming Wu
6
10
  class Workbook
7
- include Options
11
+ include Options, Errors
8
12
 
9
- def initialize(path, opts = {})
13
+ # Creates a Workbook.
14
+ #
15
+ # @return [Workbook] a Workbook object
16
+ def initialize path, opts = {}
10
17
  @workbook = Roo::Spreadsheet.open path
11
18
  @opts = process_options opts
12
19
  @sheet_opts = {}
13
20
  set_sheet_attributes
14
21
  end
15
22
 
16
- def turn_to(sheet, sheet_opts = {})
23
+ # Turns to specified sheet of this Workbook.
24
+ #
25
+ # @param sheet [String, Integer] the name or index(1-based) of a sheet
26
+ # @param sheet_opts [Hash] the options of turn_to
27
+ # @option sheet_opts [Array, Integer] :header using an Array to store the header of this sheet or choosing an index(1-based) of rows as the header
28
+ # @option sheet_opts [Integer] :start the index(1-based) of rows to start
29
+ # @option sheet_opts [Integer] :end the index(1-based) of rows to end
30
+ # @option sheet_opts [Integer] :keep_row the indices(1-based) of rows to keep
31
+ # @option sheet_opts [Integer] :skip_row the indices(1-based) of rows to skip
32
+ # @option sheet_opts [Integer] :keep_col the indices(1-based) of columns to keep
33
+ # @option sheet_opts [Integer] :skip_col the indices(1-based) of columns to skip
34
+ def turn_to sheet, sheet_opts = {}
17
35
  if sheet.kind_of?(Integer) && sheet <= sheets.size
18
36
  @workbook.default_sheet = sheets[sheet - 1]
19
37
  @sheet_opts = process_options sheet_opts
@@ -27,14 +45,23 @@ module Sheet2hash
27
45
  end
28
46
  end
29
47
 
48
+ # Returns all sheets of this Workbook.
49
+ #
50
+ # @return [Array] all sheets of this Workbook
30
51
  def sheets
31
52
  @workbook.sheets
32
53
  end
33
54
 
55
+ # Returns the name of current sheet.
56
+ #
57
+ # @return [String] the name of current sheet
34
58
  def sheet
35
59
  @workbook.default_sheet
36
60
  end
37
61
 
62
+ # Converts all sheets to a Hash, sheet names are the keys, values are Array of Hash.
63
+ #
64
+ # @return [Hash] sheet names are the keys, values are Array of Hash
38
65
  def to_h
39
66
  hash = {}
40
67
  sheets.each do |sheet|
@@ -44,6 +71,9 @@ module Sheet2hash
44
71
  hash
45
72
  end
46
73
 
74
+ # Converts current sheet to an Array of Hash.
75
+ #
76
+ # @param [Array] Array of Hash
47
77
  def to_a
48
78
  ary = []
49
79
  @rows.each do |row|
@@ -55,13 +85,14 @@ module Sheet2hash
55
85
  end
56
86
 
57
87
  private
88
+
58
89
  def set_sheet_attributes
59
90
  @header = header
60
91
  @rows = rows
61
92
  @columns = columns
62
93
  end
63
94
 
64
- def trim_int_cell(cell)
95
+ def trim_int_cell cell
65
96
  cell.kind_of?(Numeric) && cell % 1 == 0 ? cell.to_i : cell
66
97
  end
67
98
 
@@ -76,7 +107,7 @@ module Sheet2hash
76
107
  end
77
108
  end
78
109
 
79
- def collect_columns(columns, opts)
110
+ def collect_columns columns, opts
80
111
  columns.keep_if { |col| opts[:keep_col].include? col } if opts[:keep_col]
81
112
  columns = columns - opts[:skip_col] if opts[:skip_col]
82
113
  columns
@@ -88,8 +119,8 @@ module Sheet2hash
88
119
  end
89
120
 
90
121
  def last_row
91
- last_row = @sheet_opts[:end] || @opts[:end]
92
- last_row || @workbook.last_row
122
+ last_row = @sheet_opts[:end] || @opts[:end] || @workbook.last_row
123
+ last_row > @workbook.last_row ? @workbook.last_row : last_row
93
124
  end
94
125
 
95
126
  def rows
@@ -100,14 +131,20 @@ module Sheet2hash
100
131
  elsif @opts[:keep_row] || @opts[:skip_row]
101
132
  rows = collect_rows rows, @opts
102
133
  rows - [@opts[:header]]
134
+ elsif @sheet_opts[:header].kind_of?(Integer) || @sheet_opts[:header].kind_of?(Integer)
135
+ rows - [@sheet_opts[:header] || @sheet_opts[:header]]
103
136
  else
104
137
  rows - [@workbook.first_row]
105
138
  end
106
139
  end
107
140
 
108
- def collect_rows(rows, opts)
141
+ def collect_rows rows, opts
109
142
  rows.keep_if { |row| opts[:keep_row].include? row } if opts[:keep_row]
110
143
  rows = rows - opts[:skip_row] if opts[:skip_row]
144
+ rows = rows - [@workbook.first_row] unless opts[:keep_row] && opts[:keep_row].include?(1)
145
+ unless opts[:header].kind_of?(Integer) && opts[:keep_row].include?(opts[:header])
146
+ rows = rows - [opts[:header]]
147
+ end
111
148
  rows
112
149
  end
113
150
 
@@ -121,11 +158,11 @@ module Sheet2hash
121
158
  match_header_with_columns header
122
159
  end
123
160
 
124
- def match_header_with_columns(header)
161
+ def match_header_with_columns header
125
162
  header.each_with_index.select { |h, i| columns.include?(i + 1) }.map { |i| i.first }
126
163
  end
127
164
 
128
- def process_header(header)
165
+ def process_header header
129
166
  if header.kind_of? Array
130
167
  unique_header header
131
168
  elsif header.kind_of? Integer
@@ -135,13 +172,13 @@ module Sheet2hash
135
172
  end
136
173
  end
137
174
 
138
- def header_from_row(row)
175
+ def header_from_row row
139
176
  header = []
140
177
  (@workbook.first_column..@workbook.last_column).each { |col| header << @workbook.cell(row, col) }
141
178
  unique_header header
142
179
  end
143
180
 
144
- def unique_header(header)
181
+ def unique_header header
145
182
  header.reverse!
146
183
  dup_header = header.dup
147
184
  header = header.map do |field|
@@ -1,4 +1,10 @@
1
1
  module Sheet2hash
2
- class SheetNotFoundError < Exception ; end
3
- class InvalidHeaderError < Exception ; end
4
- end
2
+ # Sheet2hash::Errors defines all errors of Sheet2hash.
3
+ # @author Wei-Ming Wu
4
+ module Errors
5
+ # SheetNotFoundError is an Exception.
6
+ class SheetNotFoundError < Exception ; end
7
+ # InvalidHeaderError is an Exception.
8
+ class InvalidHeaderError < Exception ; end
9
+ end
10
+ end
@@ -1,16 +1,20 @@
1
1
  module Sheet2hash
2
+ # Sheet2hash::Options processes the options of Sheet2hash.
3
+ # @author Wei-Ming Wu
2
4
  module Options
3
- def process_options(opts)
5
+ # Regulates options of Sheet2hash.
6
+ def process_options opts
4
7
  regulate_options opts
5
8
  opts
6
9
  end
7
10
 
8
11
  private
9
- def regulate_options(opts)
12
+
13
+ def regulate_options opts
10
14
  opts[:keep_row] = Array(opts[:keep_row]) if opts[:keep_row]
11
15
  opts[:skip_row] = Array(opts[:skip_row]) if opts[:skip_row]
12
16
  opts[:keep_col] = Array(opts[:keep_col]) if opts[:keep_col]
13
17
  opts[:skip_col] = Array(opts[:skip_col]) if opts[:skip_col]
14
18
  end
15
19
  end
16
- end
20
+ end
@@ -1,7 +1,11 @@
1
1
  module Sheet2hash
2
+ # Major version of Sheet2hash
2
3
  MAJOR = 0
3
- MINOR = 1
4
+ # Minor version of Sheet2hash
5
+ MINOR = 2
6
+ # Patch version of Sheet2hash
4
7
  PATCH = 0
5
8
 
9
+ # String of version of Sheet2hash
6
10
  VERSION = [MAJOR, MINOR, PATCH].compact.join('.')
7
11
  end
@@ -21,7 +21,9 @@ Gem::Specification.new do |spec|
21
21
  spec.require_paths = ["lib"]
22
22
 
23
23
  spec.add_dependency "roo"
24
-
24
+
25
+ spec.add_development_dependency "simplecov"
26
+ spec.add_development_dependency "yard"
25
27
  spec.add_development_dependency "bundler", "~> 1.3"
26
28
  spec.add_development_dependency "rake"
27
29
  end
Binary file
Binary file
Binary file
@@ -0,0 +1,21 @@
1
+ require "rubygems"
2
+ require "bundler"
3
+ require "json"
4
+ require "simplecov"
5
+
6
+ SimpleCov.start
7
+
8
+ begin
9
+ Bundler.setup(:default, :development)
10
+ rescue Bundler::BundlerError => e
11
+ $stderr.puts e.message
12
+ $stderr.puts "Run `bundle install` to install missing gems"
13
+ exit e.status_code
14
+ end
15
+
16
+ require "test/unit"
17
+
18
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
19
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
20
+
21
+ require "sheet2hash"
@@ -0,0 +1,88 @@
1
+ require 'test_helper'
2
+
3
+ class WorkbookTest < Test::Unit::TestCase
4
+ include Sheet2hash::Errors
5
+
6
+ def setup
7
+ @header = Sheet2hash::Workbook.new File.expand_path('../header.xls', __FILE__)
8
+ @no_header = Sheet2hash::Workbook.new File.expand_path('../no-header.xls', __FILE__)
9
+ @dup_header = Sheet2hash::Workbook.new File.expand_path('../dup-header.xls', __FILE__)
10
+ end
11
+
12
+ def test_turn_to
13
+ @header.turn_to 'Sheet1'
14
+ assert_equal 'Sheet1', @header.sheet
15
+ @header.turn_to 1
16
+ assert_equal 'Sheet1', @header.sheet
17
+ end
18
+
19
+ def test_turn_to_error
20
+ assert_raise SheetNotFoundError do
21
+ @header.turn_to 'No Sheet'
22
+ end
23
+ end
24
+
25
+ def test_sheets
26
+ assert_equal ['Sheet1'], @header.sheets
27
+ end
28
+
29
+ def test_sheet
30
+ assert_equal 'Sheet1', @header.sheet
31
+ end
32
+
33
+ def test_to_h
34
+ assert_equal({ 'Sheet1' => [{ 'col1' => 1, 'col2' => 2, 'col3' => 3 }, { 'col1' => 'one', 'col2' => 'two', 'col3' => 'three' }] }, @header.to_h)
35
+ end
36
+
37
+ def test_to_a
38
+ assert_equal [{ 'col1' => 1, 'col2' => 2, 'col3' => 3 }, { 'col1' => 'one', 'col2' => 'two', 'col3' => 'three' }], @header.to_a
39
+ end
40
+
41
+ def test_option_header1
42
+ @header.turn_to 1, header: [:col1, :col2]
43
+ assert_equal [{ col1: 1, col2: 2 }, { col1: 'one', col2: 'two' }], @header.to_a
44
+ end
45
+
46
+ def test_option_header2
47
+ @no_header.turn_to 1, header: 2
48
+ assert_equal [{ 'one' => 1, 'two' => 2, 'three' => 3 }], @no_header.to_a
49
+ end
50
+
51
+ def test_option_start
52
+ @header.turn_to 1, start: 3
53
+ assert_equal [{ 'col1' => 'one', 'col2' => 'two', 'col3' => 'three' }], @header.to_a
54
+ @header.turn_to 1, start: 4
55
+ assert_equal [], @header.to_a
56
+ end
57
+
58
+ def test_option_end
59
+ @header.turn_to 1, end: 2
60
+ assert_equal [{ 'col1' => 1, 'col2' => 2, 'col3' => 3 }], @header.to_a
61
+ @header.turn_to 1, end: 4
62
+ assert_equal [{ 'col1' => 1, 'col2' => 2, 'col3' => 3 }, { 'col1' => 'one', 'col2' => 'two', 'col3' => 'three' }], @header.to_a
63
+ end
64
+
65
+ def test_option_keep_row
66
+ @header.turn_to 1, keep_row: 1
67
+ assert_equal [{ 'col1' => 'col1', 'col2' => 'col2', 'col3' => 'col3' }], @header.to_a
68
+ end
69
+
70
+ def test_option_skip_row
71
+ @header.turn_to 1, skip_row: 3
72
+ assert_equal [{ 'col1' => 1, 'col2' => 2, 'col3' => 3 }], @header.to_a
73
+ end
74
+
75
+ def test_option_keep_col
76
+ @header.turn_to 1, keep_col: 1
77
+ assert_equal [{ 'col1' => 1 }, { 'col1' => 'one' }], @header.to_a
78
+ end
79
+
80
+ def test_option_skip_col
81
+ @header.turn_to 1, skip_col: [2, 3]
82
+ assert_equal [{ 'col1' => 1 }, { 'col1' => 'one' }], @header.to_a
83
+ end
84
+
85
+ def test_uniq_unique_header
86
+ assert_equal [{ 'col' => 1, 'col_dup' => 2, 'col_dup2' => 3 }, { 'col' => 'one', 'col_dup' => 'two', 'col_dup2' => 'three' }], @dup_header.to_a
87
+ end
88
+ end
metadata CHANGED
@@ -1,20 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sheet2hash
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
5
- prerelease:
4
+ version: 0.2.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Wei-Ming Wu
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-03-30 00:00:00.000000000 Z
11
+ date: 2013-09-16 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: roo
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - '>='
20
18
  - !ruby/object:Gem::Version
@@ -22,7 +20,34 @@ dependencies:
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: simplecov
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: yard
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
26
51
  requirements:
27
52
  - - '>='
28
53
  - !ruby/object:Gem::Version
@@ -30,7 +55,6 @@ dependencies:
30
55
  - !ruby/object:Gem::Dependency
31
56
  name: bundler
32
57
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
58
  requirements:
35
59
  - - ~>
36
60
  - !ruby/object:Gem::Version
@@ -38,7 +62,6 @@ dependencies:
38
62
  type: :development
39
63
  prerelease: false
40
64
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
65
  requirements:
43
66
  - - ~>
44
67
  - !ruby/object:Gem::Version
@@ -46,7 +69,6 @@ dependencies:
46
69
  - !ruby/object:Gem::Dependency
47
70
  name: rake
48
71
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
72
  requirements:
51
73
  - - '>='
52
74
  - !ruby/object:Gem::Version
@@ -54,7 +76,6 @@ dependencies:
54
76
  type: :development
55
77
  prerelease: false
56
78
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
79
  requirements:
59
80
  - - '>='
60
81
  - !ruby/object:Gem::Version
@@ -76,35 +97,39 @@ files:
76
97
  - lib/sheet2hash/options.rb
77
98
  - lib/sheet2hash/version.rb
78
99
  - sheet2hash.gemspec
100
+ - test/dup-header.xls
101
+ - test/header.xls
102
+ - test/no-header.xls
103
+ - test/test_helper.rb
104
+ - test/workbook_test.rb
79
105
  homepage: http://github.com/wnameless/sheet2hash
80
106
  licenses:
81
107
  - Apache License, Version 2.0
108
+ metadata: {}
82
109
  post_install_message:
83
110
  rdoc_options: []
84
111
  require_paths:
85
112
  - lib
86
113
  required_ruby_version: !ruby/object:Gem::Requirement
87
- none: false
88
114
  requirements:
89
115
  - - '>='
90
116
  - !ruby/object:Gem::Version
91
117
  version: '0'
92
- segments:
93
- - 0
94
- hash: 1249836198874523190
95
118
  required_rubygems_version: !ruby/object:Gem::Requirement
96
- none: false
97
119
  requirements:
98
120
  - - '>='
99
121
  - !ruby/object:Gem::Version
100
122
  version: '0'
101
- segments:
102
- - 0
103
- hash: 1249836198874523190
104
123
  requirements: []
105
124
  rubyforge_project:
106
- rubygems_version: 1.8.25
125
+ rubygems_version: 2.0.6
107
126
  signing_key:
108
- specification_version: 3
109
- summary: sheet2hash-0.1.0
110
- test_files: []
127
+ specification_version: 4
128
+ summary: sheet2hash-0.2.0
129
+ test_files:
130
+ - test/dup-header.xls
131
+ - test/header.xls
132
+ - test/no-header.xls
133
+ - test/test_helper.rb
134
+ - test/workbook_test.rb
135
+ has_rdoc: