sheet2hash 0.1.0 → 0.2.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,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: