md_data 1.1.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -5,4 +5,5 @@ gemspec
5
5
 
6
6
  group :development do
7
7
  gem 'rspec'
8
+ gem "simplecov", :require => false, :group => :test
8
9
  end
data/LICENSE CHANGED
@@ -19,4 +19,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
19
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
20
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
21
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -5,15 +5,15 @@ An easy notation for describing multidimensional data.
5
5
  For example:
6
6
 
7
7
  ```
8
- 1994
8
+ 1994
9
9
  BuenosAires
10
10
  Coal
11
11
  19t
12
12
  Potassium
13
13
  5t
14
- 1995
14
+ 1995
15
15
  BuenosAires
16
- Coal
16
+ Coal
17
17
  8t
18
18
  Potassium
19
19
  6t
@@ -41,7 +41,7 @@ class MaterialConsumption
41
41
  end
42
42
  end
43
43
 
44
- MaterialConsumption.select(:year => 1994, :city => :buenos_aires, :material => :coal) #=> '8t'
44
+ MaterialConsumption.select(:year => :year_1994, :city => :buenos_aires, :material => :coal) #=> '8t'
45
45
  ```
46
46
  ##Usage
47
47
  By defining dimensions you get helper methods that can be used in 'context' and 'add' conditionals.
@@ -50,10 +50,9 @@ By defining dimensions you get helper methods that can be used in 'context' and
50
50
  context 'year_1994 && buenos_aires' do
51
51
  add '8t', 'coal'
52
52
  end
53
-
54
53
  ```
55
54
 
56
- eqauls
55
+ Equals
57
56
 
58
57
  ```
59
58
  context 'year == :year_1994 && city == :buenos_aires' do
@@ -65,7 +64,7 @@ Important thing here is that this is still just Ruby in quotes. You can add any
65
64
  while you still have basic scenario covered and simplified.
66
65
 
67
66
  ##Usage
68
- For any type of ruled based queryingr, when you want to pull out specific data based on attributes and rules.
67
+ For any type of ruled based querying, when you want to pull out specific data based on attributes and rules.
69
68
 
70
69
  ## Installation
71
70
 
@@ -84,7 +83,7 @@ Or install it yourself as:
84
83
  ## Limitations
85
84
 
86
85
  * No nested context allowed(yet)
87
- * Tests for misformed data definition
86
+ * Tests for mis formed data definition
88
87
  * Support for same dimension instance value and resolving of ambiguity
89
88
 
90
89
  ## Contributing
@@ -1,3 +1,6 @@
1
+ require 'simplecov'
2
+ SimpleCov.start
3
+
1
4
  require "md_data/version"
2
5
  require "md_data/md_data"
3
6
 
@@ -1,20 +1,45 @@
1
1
  module MdData
2
+ #raise this if you cant find appropriate rule
3
+ class NoRuleFound < StandardError ; end
4
+
2
5
  def self.included(base)
3
6
  base.extend MdDataClassMethods
4
7
  end
5
8
 
6
- module MdDataClassMethods
9
+ def attributes
10
+ @attributes
11
+ end
12
+
13
+ def attributes=(value)
14
+ @attributes = value
15
+ end
16
+
17
+ def define_helpers_methods(dimensions, attributes)
18
+ dimensions.merge(attributes).each_key { |key| define_helper(key) }
19
+ end
7
20
 
21
+ def define_helper(key)
22
+ Kernel.send(:define_method, key) do
23
+ (instance_variable_get "@attributes")[key]
24
+ end
25
+ end
26
+
27
+ module MdDataClassMethods
8
28
  def table_data(&block)
9
29
  @table_data_block = block
10
30
  end
11
31
 
12
- def select(attributes)
32
+ def select(attributes, parent = nil)
13
33
  @rules = []
14
34
  @current_context = nil
15
35
  load_rules
16
- container = self.new
17
- define_helpers_methods(attributes)
36
+ if (parent.nil?)
37
+ container = self.new
38
+ else
39
+ container = self.new(parent)
40
+ end
41
+ container.attributes = attributes
42
+ container.define_helpers_methods(dimensions, attributes)
18
43
  define_dimension_values_methods
19
44
  define_select_from_rules
20
45
  container.select_from_rules(@rules)
@@ -27,7 +52,6 @@ module MdData
27
52
  def dimensions
28
53
  @dimensions ||= {}
29
54
  end
30
-
31
55
 
32
56
  private
33
57
  def load_rules
@@ -35,7 +59,11 @@ module MdData
35
59
  end
36
60
 
37
61
  def add(value, condition)
38
- context_condition = @current_context.nil? ? '' : " && #{@current_context} "
62
+ if @current_context.nil?
63
+ context_condition = ''
64
+ else
65
+ context_condition = " && #{@current_context} "
66
+ end
39
67
  @rules << ( [value , (condition + context_condition)] )
40
68
  end
41
69
 
@@ -44,39 +72,33 @@ module MdData
44
72
  block.call
45
73
  end
46
74
 
47
- def define_helpers_methods(attributes)
48
- attributes.each do |key,value|
49
- self.send(:define_method, key) do
50
- value
51
- end
52
- end
53
- end
54
75
 
55
76
  def define_dimension_values_methods
56
77
  unless @dimensions.nil?
57
78
  @dimensions.each do |name, values|
58
- values.each do |value|
59
- self.send(:define_method, value) do
60
- eval "#{name} == :#{value}"
61
- end
62
- end
79
+ values.each { |value| equal?(name, value) }
63
80
  end
64
81
  end
65
82
  end
66
83
 
84
+ def equal?(name, value)
85
+ self.send(:define_method, value) do
86
+ instance_eval "#{name} == :#{value}"
87
+ end
88
+ end
89
+
67
90
  def define_select_from_rules
68
91
  self.send(:define_method, :select_from_rules) do |rules|
69
92
  result = nil
70
93
  rules.each do |rule|
71
- rule_is_satisfied = eval(rule[1])
94
+ rule_is_satisfied = instance_eval(rule[1])
72
95
  if rule_is_satisfied
73
96
  result = rule[0]
74
97
  break
75
98
  end
76
99
  end
77
- result
100
+ result.nil? ? raise(NoRuleFound.new('No rule found')) : result
78
101
  end
79
102
  end
80
-
81
- end
82
- end
103
+ end #MdDataClassMethods
104
+ end #MdData
@@ -1,3 +1,3 @@
1
1
  module MdData
2
- VERSION = "1.1.0"
2
+ VERSION = "1.1.1"
3
3
  end
@@ -1,7 +1,7 @@
1
1
  require 'md_data'
2
2
 
3
3
  describe MdData do
4
-
4
+ # use this as an example of extended class
5
5
  class TestClass; include MdData end
6
6
 
7
7
  it 'adds table_data class method when included' do
@@ -13,10 +13,12 @@ describe MdData do
13
13
  end
14
14
 
15
15
  it 'should store block for latter usage and allow change' do
16
+ # use this as an example of extended class
16
17
  class TestClass
17
18
  table_data { "LATER" }
18
19
  end
19
20
  TestClass.send(:load_rules).should == "LATER"
21
+ # use this as an example of extended class
20
22
  class TestClass
21
23
  table_data { "ALIGATOR" }
22
24
  end
@@ -24,6 +26,7 @@ describe MdData do
24
26
  end
25
27
 
26
28
  it 'rules can be created with add' do
29
+ # use this as an example of extended class
27
30
  class TestClass
28
31
  table_data { add "8t", "year == 1994" }
29
32
  end
@@ -31,9 +34,10 @@ describe MdData do
31
34
  end
32
35
 
33
36
  it 'multiple rules can be created with add' do
37
+ # use this as an example of extended class
34
38
  class TestClass
35
39
  table_data do
36
- add "8t", "year == 1994"
40
+ add "8t", "year == 1994"
37
41
  add "9t", "year == 1995"
38
42
  end
39
43
  end
@@ -42,6 +46,7 @@ describe MdData do
42
46
  end
43
47
 
44
48
  it 'should create pull out item based on rules and attributes' do
49
+ # use this as an example of extended class
45
50
  class TestClass
46
51
  table_data { add "8t" , "year == 1994" }
47
52
  end
@@ -49,6 +54,7 @@ describe MdData do
49
54
  end
50
55
 
51
56
  it 'item can be anythinig' do
57
+ # use this as an example of extended class
52
58
  class TestClass
53
59
  table_data { add TestClass.new , "year == 1994" }
54
60
  end
@@ -56,11 +62,12 @@ describe MdData do
56
62
  end
57
63
 
58
64
 
59
- it 'rules can be created with add in context' do
65
+ it 'rules can be created with add in precondition' do
66
+ # use this as an example of extended class
60
67
  class TestClass
61
68
  table_data do
62
69
  context "time_of_day == :morning" do
63
- add "8t", "year == 1994"
70
+ add "8t", "year == 1994"
64
71
  end
65
72
  end
66
73
  end
@@ -68,11 +75,12 @@ describe MdData do
68
75
  end
69
76
 
70
77
  it 'rules can be created to comapre with string' do
78
+ # use this as an example of extended class
71
79
  class TestClass
72
80
  table_data do
73
81
  context "time_of_day == 'morning'" do
74
- add "8t", "year == 1995"
75
- add "6t", "year == 1994"
82
+ add "8t", "year == 1995"
83
+ add "6t", "year == 1994"
76
84
  end
77
85
  end
78
86
  end
@@ -80,14 +88,15 @@ describe MdData do
80
88
  end
81
89
 
82
90
  it 'can have multiple contexts' do
91
+ # use this as an example of extended class
83
92
  class TestClass
84
93
  table_data do
85
94
  context "time_of_day == :morning" do
86
- add "18t", "year == 1995"
87
- add "16t", "year == 1994"
95
+ add "18t", "year == 1995"
96
+ add "16t", "year == 1994"
88
97
  end
89
98
  context "time_of_day == :evening" do
90
- add "8t", "year == 1995"
99
+ add "8t", "year == 1995"
91
100
  end
92
101
  end
93
102
  end
@@ -96,6 +105,7 @@ describe MdData do
96
105
  end
97
106
 
98
107
  it 'is aware of dimensions' do
108
+ # use this as an example of extended class
99
109
  class TestClass
100
110
  dimension :year, [:year_1994, :year_1995]
101
111
  dimension :time_of_day, [:morning, :evening]
@@ -107,6 +117,7 @@ describe MdData do
107
117
 
108
118
 
109
119
  it 'is creates helper methods for dimensions values' do
120
+ # use this as an example of extended class
110
121
  class TestClass
111
122
 
112
123
  dimension :year, [:year_1994, :year_1995]
@@ -114,16 +125,90 @@ describe MdData do
114
125
 
115
126
  table_data do
116
127
  context "morning" do
117
- add "18t", "year_1995"
118
- add "16t", "year_1994"
128
+ add "18t", "year_1995"
129
+ add "16t", "year_1994"
119
130
  end
120
131
  context "evening" do
121
- add "8t", "year_1995"
132
+ add "8t", "year_1995"
133
+ end
134
+ end
135
+ end
136
+ TestClass.select(:year => :year_1995, :time_of_day => :morning).should ==
137
+ "18t"
138
+ end
139
+
140
+
141
+ it 'is shuld create helper methods for dimensions when atttibute not sent' do
142
+ # use this as an example of extended class
143
+ class TestClassIsolated
144
+ include MdData
145
+ dimension :year, [:year_1994, :year_1995]
146
+ dimension :my_time_of_day, [:morning, :evening]
147
+
148
+ table_data do
149
+ context "my_time_of_day == :evening" do
150
+ add "8t", "year_1995"
151
+ add "7t", "year_1994"
152
+ end
153
+ context "morning" do
154
+ add "8t", "year_1995"
155
+ add "6t", "year_1994"
156
+ end
157
+ context "true" do
158
+ add "16t", "year_1995"
122
159
  end
123
160
  end
161
+
124
162
  end
125
- TestClass.select(:year => :year_1995, :time_of_day => :morning).should == "18t"
163
+
164
+ TestClassIsolated.select({:year => :year_1995}).should == "16t"
165
+ TestClassIsolated.select({:year => :year_1995}).should == "16t"
166
+ TestClassIsolated.select({:year => :year_1995,
167
+ :my_time_of_day => :morning}).should == "8t"
168
+ TestClassIsolated.select({:year => :year_1994,
169
+ :my_time_of_day => :evening}).should == "7t"
126
170
  end
127
171
 
128
172
 
173
+ it 'is shuld create helper methods for dimensions
174
+ even if atttibute not sent and using delegator' do
175
+ # use this as an example of extended class
176
+ class TestClassIsolated
177
+ include MdData
178
+ dimension :year, [:year_1994, :year_1995]
179
+ dimension :my_2_time_of_day, [:morning, :evening]
180
+
181
+ table_data do
182
+ context "my_2_time_of_day == :evening" do
183
+ add "8t", "year_1995"
184
+ add "7t", "year_1994"
185
+ end
186
+ context "morning" do
187
+ add "8t", "year_1995"
188
+ add "6t", "year_1994"
189
+ end
190
+ context "true" do
191
+ add "16t", "year_1995"
192
+ end
193
+ end
194
+
195
+ end
196
+
197
+ # use this as an example of extended class
198
+ class Testing
199
+ attr_reader :table
200
+ def initialize
201
+ @table = TestClassIsolated
202
+ end
203
+ end
204
+
205
+ t = Testing.new
206
+ t.table.select({:year => :year_1995}).should == "16t"
207
+ t.table.select({:year => :year_1995}).should == "16t"
208
+ t.table.select({:year => :year_1995,
209
+ :my_2_time_of_day => :morning}).should == "8t"
210
+ t.table.select({:year => :year_1994,
211
+ :my_2_time_of_day => :evening}).should == "7t"
212
+ end
213
+
129
214
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: md_data
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-03-27 00:00:00.000000000Z
12
+ date: 2012-04-27 00:00:00.000000000Z
13
13
  dependencies: []
14
14
  description: Describe multidimensional data with simple notation
15
15
  email:
@@ -49,9 +49,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
49
49
  version: '0'
50
50
  requirements: []
51
51
  rubyforge_project:
52
- rubygems_version: 1.8.17
52
+ rubygems_version: 1.8.10
53
53
  signing_key:
54
54
  specification_version: 3
55
55
  summary: Easy way to descriebe and find values from multidimensional table.
56
56
  test_files:
57
57
  - spec/md_data/md_data_spec.rb
58
+ has_rdoc: