goodsheet 0.2.2 → 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9a61094f40016b3c32594b97b5d3e134c4b59016
4
- data.tar.gz: 5fc1f3d8bbbdeaf1efafbceeb2610296004bce86
3
+ metadata.gz: 857c86e4b9ce1ab63a12d69a98a89194374731c8
4
+ data.tar.gz: 6bc6c520ab684b0933288c25db1d389c1aa221de
5
5
  SHA512:
6
- metadata.gz: 0ff578441474684622d97d9e7481abb007783c6ee0fb302689377c081eff0662dda889766140dbe0d51e7b99d0e9ba0e0846deb7463c0df85994fe6a8c5a3d07
7
- data.tar.gz: 50dcf983da1e79799d313366c47369d0b8569aad10ff6a9312ceae7c4eeae8d5b0229ef0b49dc30dda941434e315214450349a8c2723feb699272e5eb98c21dc
6
+ metadata.gz: 7e93e30871d1548a6f71fd969f1cde562ab99564045f29a79108ebfc191e73f53a23b830769d9c29a286028ba6c6d27c88cb3485f7846f86ddb3b61c709ce867
7
+ data.tar.gz: 8cbded3dfb2890d91799a872d7d3b0489aec4bfaa55abe549a89321c331f30c83ed7c11a8db6b5422958d2318c08db1dcee92aacb0a476538f0443d519cece94
data/README.md CHANGED
@@ -39,6 +39,7 @@ res.values # => {:a => [1.0, 1.0, 1.4], :b => [0.0, 3.7, 10.9]}
39
39
  By default:
40
40
  * the first sheet is selected
41
41
  * one line (the first) is skipped (i'm expeting that is the header line)
42
+ * the content is returned as an hash of columns
42
43
 
43
44
  Pass your validation rules into the block passed to the read method, together with the column_names method that define the position (or index) and the name of the columns you want to read.
44
45
 
@@ -81,7 +82,7 @@ end
81
82
 
82
83
  Get the content of header row:
83
84
  ```ruby
84
- ss.header_row # => ["year", "month", "day"]
85
+ ss.get_header # => ["year", "month", "day"]
85
86
  ```
86
87
 
87
88
  Get the number of rows:
@@ -94,16 +95,17 @@ ss.rows_wo_skipped # => except the skipped ones, aliased by `rows` method
94
95
 
95
96
  Use the `validate` and `read` methods to perform validation and reading. Note that the reading function include a validation call.
96
97
  Pass the previously seen `options` hash and a block to `validate`/`read` method.
97
- Inside the block you define columns names and indexes you want to validate/read using the `column_names` method. You can use one of these 3 forms:
98
+ Inside the block you define columns names and indexes you want to validate/read using the `column_names` method. You can use one of these 4 forms:
98
99
  - `column_names :a => 0, :b => 1, :c => 3`
99
100
  - `column_names 0 => :a, 1 => :b, 3 => :c`
100
101
  - `column_names [:a, :b, nil, :c]`
102
+ - `column_names :a, :b, nil, :c`
101
103
 
102
104
  Aside from define the columns settings, into block you define the validation rules.
103
105
  Refer to the [official guide](http://guides.rubyonrails.org/active_record_validations.html) and [ROR Api](http://api.rubyonrails.org/classes/ActiveModel/Validations/ClassMethods.html)
104
106
 
105
107
 
106
- Another example:
108
+ Here another example:
107
109
  ```ruby
108
110
  ss = Goodsheet::Spreadsheet.new("my_data.xlsx")
109
111
  ss.sheet(1, :max_errors => 50, :force_nil => 0.0)
@@ -121,12 +123,49 @@ res = ss.read do
121
123
  end
122
124
  end
123
125
  end
126
+
127
+ res.valid?
128
+ ```
129
+
130
+ If validation fails you get `false` on `res.valid?` call, and you retrieve an array with errors by calling `errors` method on result object:
131
+ If validation fails you can retrieve the errors array by calling `errors` method on result object:
132
+
133
+ ```ruby
134
+ res.valid? # => false
135
+ res.invalid? # => true
136
+ res.errors # => a ValidationErrors object
137
+ res.errors.size # => 1
138
+ res.errors[0].to_s # => "Row 5 is invalid for the following reason(s): Year is not a number, Month is not a number"
139
+ ```
140
+
141
+ If the validation ends successfully without errors, the result values are available using one of these three forms:
142
+ - hash of columns (default)
143
+ - array of rows, where the rows are array
144
+ - array of rows, where the rows are hashes
145
+
146
+
147
+ ```
148
+ +------+-------+
149
+ | year | month |
150
+ +------+-------+
151
+ | 2012 | 1 |
152
+ +------+-------+
153
+ | 2012 | 2 |
154
+ +------+-------+
155
+ | 2012 | 3 |
156
+ +------+-------+
124
157
  ```
125
158
 
159
+ ```ruby
160
+ res.values # => { :year => [2012, 2012, 2012], :month => [1, 2, 3]}
161
+ res.values(:columns) # same as the previous
162
+ res.values(:rows_array) # => [[2012, 1], [2012, 2], [2012, 3]]
163
+ res.values(:rows_hash) # => [{:year => 2012, :month => 1}, {:year => 2012, :month => 2}, {:year => 2012, :month => 3}]
164
+ ```
126
165
 
127
166
 
128
167
 
129
- Warning:
168
+ Note:
130
169
  * integer numbers are converted to float numbers. Also don't pretend to obtain an integer in validation. This undesired behaviour depend on Roo gem
131
170
  * if you import data from a CSV spreadsheet keep in mind that numbers are readed as strings
132
171
 
@@ -1,11 +1,11 @@
1
1
  module Goodsheet
2
2
 
3
3
  class ReadResult
4
- attr_reader :values
4
+ attr_reader :vv, :errors
5
5
 
6
6
  def initialize(errors=ValidationErrors.new)
7
7
  @errors = errors
8
- @values = {}
8
+ @vv = {}
9
9
  end
10
10
 
11
11
  def valid?
@@ -18,11 +18,30 @@ module Goodsheet
18
18
 
19
19
  def add(attribute, row, force_nil=nil)
20
20
  attribute = attribute.to_sym
21
- (@values[attribute] ||= []) << (row.send(attribute) || force_nil)
21
+ (@vv[attribute] ||= []) << (row.send(attribute) || force_nil)
22
22
  end
23
23
 
24
- def errors
25
- @errors.array
24
+ def values(format=:columns)
25
+ values_size = @vv.values.first.size
26
+
27
+ case format
28
+ when :columns
29
+ @vv
30
+
31
+ when :rows_array
32
+ Array.new(values_size) do |i1|
33
+ Array.new(@vv.size) do |i2|
34
+ @vv[@vv.keys[i2]][i1]
35
+ end
36
+ end
37
+
38
+ when :rows_hash
39
+ Array.new(values_size) do |i1|
40
+ hh = {}
41
+ @vv.keys.each{|k| hh[k] = @vv[k][i1] }
42
+ hh
43
+ end
44
+ end
26
45
  end
27
46
  end
28
47
  end
data/lib/goodsheet/row.rb CHANGED
@@ -30,37 +30,47 @@ module Goodsheet
30
30
  end
31
31
 
32
32
  # Define the position (or index) and the name of columns.
33
- # There are available three mode to define them:
34
- # using an hash index to name (like { 0 => :year, 2 => :day })
35
- # or name to index (like { :year => 0, :day => 2 }) or using an array
33
+ # You have four ways to define them:
34
+ # using an hash index-to-name (like { 0 => :year, 2 => :day })
35
+ # or its reversed version name-to-index (like { :year => 0, :day => 2 }), using an array
36
36
  # with the names at desired positions (like [:year, nil, :day]), put a nil
37
- # at the position
37
+ # at the position, or simply put the list of names.
38
38
  # The positions are 0-based.
39
- def self.column_names(param)
39
+ def self.column_names(*attr)
40
+ # def self.column_names(param)
40
41
  @keys = {}
41
- if param.is_a? Hash
42
- if param.first[0].is_a? Integer
43
- param.each do |idx, name|
42
+ raise ArgumentError, 'You have to pass at least one attribute' if attr.empty?
43
+ if attr[0].is_a? Array
44
+ attr[0].each_with_index do |name, idx|
45
+ if name
46
+ self.keys[idx] = name
47
+ attr_accessor name
48
+ end
49
+ end
50
+
51
+ elsif attr[0].is_a? Hash
52
+ if attr[0].first[0].is_a? Integer
53
+ attr[0].each do |idx, name|
44
54
  self.keys[idx] = name
45
55
  attr_accessor name
46
56
  end
47
57
  else
48
- param.each do |name, idx|
58
+ attr[0].each do |name, idx|
49
59
  self.keys[idx] = name
50
60
  attr_accessor name
51
61
  end
52
62
  end
53
- elsif param.is_a? Array
54
- param.each_with_index do |name, idx|
63
+
64
+ else
65
+ attr.each_with_index do |name, idx|
55
66
  if name
67
+ name = name.to_s.gsub(" ", "_").to_sym unless name.is_a? Symbol
56
68
  self.keys[idx] = name
57
69
  attr_accessor name
58
70
  end
59
71
  end
60
-
61
- else
62
- raise "parameter non valid"
63
72
  end
73
+
64
74
  end
65
75
 
66
76
 
@@ -4,7 +4,7 @@ module Goodsheet
4
4
 
5
5
  class Spreadsheet < Roo::Spreadsheet
6
6
  attr_reader :skip, :header_row, :max_errors, :row_limit
7
- attr_reader :s_opts
7
+ attr_reader :s_opts, :ss
8
8
 
9
9
  # Initialize a Goodsheet object. The first sheet will be selected.
10
10
  #
@@ -7,7 +7,7 @@ module Goodsheet
7
7
  end
8
8
 
9
9
  def to_s
10
- "line #{@line} is invalid for the following reason(s): #{@val_err.full_messages.join(', ')}"
10
+ "Row #{@line} is invalid for the following reason(s): #{@val_err.full_messages.join(', ')}"
11
11
  end
12
12
  end
13
13
  end
@@ -22,5 +22,19 @@ module Goodsheet
22
22
  def to_s
23
23
  @array.to_s
24
24
  end
25
+
26
+ def [](i)
27
+ @array[i]
28
+ end
29
+
30
+ def to_a
31
+ @array
32
+ end
33
+
34
+ def each(&block)
35
+ @array.each do |i|
36
+ yield(i)
37
+ end
38
+ end
25
39
  end
26
40
  end
@@ -1,3 +1,3 @@
1
1
  module Goodsheet
2
- VERSION = "0.2.2"
2
+ VERSION = "0.3.0"
3
3
  end
Binary file
data/test/test_row.rb CHANGED
@@ -4,17 +4,22 @@ require 'goodsheet'
4
4
  class TestRow < Test::Unit::TestCase
5
5
 
6
6
  def test_column_names
7
- assert_raise RuntimeError do
7
+ assert_raise ArgumentError do
8
+ Goodsheet::Row.column_names
9
+ end
10
+ assert_raise NameError do
8
11
  Goodsheet::Row.column_names(6)
9
12
  end
10
13
 
14
+ Goodsheet::Row.column_names(:a, nil, :b, :c)
15
+ assert_equal(Goodsheet::Row.keys, {0 => :a, 2 => :b, 3 => :c})
16
+
11
17
  Goodsheet::Row.column_names([:a, nil, :b, :c])
12
18
  assert_equal(Goodsheet::Row.keys, {0 => :a, 2 => :b, 3 => :c})
13
19
 
14
20
  Goodsheet::Row.column_names(:a => 0, :b => 2, :c => 3)
15
21
  assert_equal(Goodsheet::Row.keys, {0 => :a, 2 => :b, 3 => :c})
16
22
 
17
-
18
23
  Goodsheet::Row.column_names(0 => :a, 2 => :b, 3 => :c)
19
24
  assert_equal(Goodsheet::Row.keys, {0 => :a, 2 => :b, 3 => :c})
20
25
  end
@@ -168,4 +168,26 @@ class TestSpreadsheet_01 < Test::Unit::TestCase
168
168
 
169
169
  end
170
170
 
171
+ def test_result_formats
172
+ result = @ss.read do
173
+ column_names :a, :b, :c, :d
174
+ end
175
+ y = {
176
+ :a=>[2012.0, 2012.0, 2012.0, 2013.0],
177
+ :b=>["F", "F", "G", "F"],
178
+ :c=>[3.1, 2.5, 0.0, 0.78],
179
+ :d=>[4.1, 3.5, 1.0, 1.78]
180
+ }
181
+ values_size = y.values.first.size
182
+
183
+ assert_equal(y, result.values)
184
+ assert_equal(y, result.values(:columns))
185
+
186
+ y = [[2012.0, "F", 3.1, 4.1], [2012.0, "F", 2.5, 3.5], [2012.0, "G", 0.0, 1.0], [2013.0, "F", 0.78, 1.78]]
187
+ assert_equal(y, result.values(:rows_array))
188
+
189
+ y = [{:a=>2012.0, :b=>"F", :c=>3.1, :d=>4.1}, {:a=>2012.0, :b=>"F", :c=>2.5, :d=>3.5}, {:a=>2012.0, :b=>"G", :c=>0.0, :d=>1.0}, {:a=>2013.0, :b=>"F", :c=>0.78, :d=>1.78}]
190
+ assert_equal(y, result.values(:rows_hash))
191
+ end
192
+
171
193
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: goodsheet
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Iwan Buetti