amee-data-abstraction 1.3.1 → 2.0.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.
Files changed (39) hide show
  1. data/.rvmrc +1 -1
  2. data/CHANGELOG.txt +0 -3
  3. data/Gemfile +5 -7
  4. data/Gemfile.lock +20 -14
  5. data/README.txt +15 -28
  6. data/Rakefile +17 -16
  7. data/VERSION +1 -1
  8. data/amee-data-abstraction.gemspec +21 -24
  9. data/lib/amee-data-abstraction.rb +6 -0
  10. data/lib/amee-data-abstraction/calculation.rb +1 -1
  11. data/lib/amee-data-abstraction/calculation_set.rb +10 -152
  12. data/lib/amee-data-abstraction/drill.rb +6 -23
  13. data/lib/amee-data-abstraction/input.rb +0 -24
  14. data/lib/amee-data-abstraction/ongoing_calculation.rb +9 -13
  15. data/lib/amee-data-abstraction/term.rb +13 -31
  16. data/spec/amee-data-abstraction/calculation_set_spec.rb +11 -245
  17. data/spec/amee-data-abstraction/calculation_spec.rb +18 -23
  18. data/spec/amee-data-abstraction/drill_spec.rb +7 -34
  19. data/spec/amee-data-abstraction/input_spec.rb +73 -113
  20. data/spec/amee-data-abstraction/metadatum_spec.rb +1 -1
  21. data/spec/amee-data-abstraction/ongoing_calculation_spec.rb +29 -45
  22. data/spec/amee-data-abstraction/profile_spec.rb +2 -2
  23. data/spec/amee-data-abstraction/prototype_calculation_spec.rb +11 -18
  24. data/spec/amee-data-abstraction/term_spec.rb +8 -50
  25. data/spec/amee-data-abstraction/terms_list_spec.rb +12 -16
  26. data/spec/config/amee_units_spec.rb +2 -1
  27. data/spec/core-extensions/class_spec.rb +18 -18
  28. data/spec/core-extensions/hash_spec.rb +2 -1
  29. data/spec/core-extensions/ordered_hash_spec.rb +2 -1
  30. data/spec/core-extensions/proc_spec.rb +1 -1
  31. data/spec/fixtures/{config/electricity.rb → electricity.rb} +2 -2
  32. data/spec/fixtures/electricity_and_transport.rb +55 -0
  33. data/spec/fixtures/{config/calculations/transport.rb → transport.rb} +2 -2
  34. data/spec/spec_helper.rb +7 -43
  35. metadata +56 -61
  36. data/init.rb +0 -4
  37. data/rails/init.rb +0 -32
  38. data/spec/fixtures/config/calculations/electricity.rb +0 -35
  39. data/spec/fixtures/config/calculations/electricity_and_transport.rb +0 -53
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ require File.dirname(File.dirname(__FILE__)) + '/spec_helper.rb'
2
2
 
3
3
  describe Profile do
4
4
  it 'defaults to be a text-box' do
@@ -10,7 +10,7 @@ describe Profile do
10
10
  mocker.item_value_definitions.
11
11
  item_definition.data_category.
12
12
  item_value_definition('distance',['someusage'],['someotherusage'])
13
- t=CalculationSet.find("transport")[:transport].clone
13
+ t=Transport.clone
14
14
  t[:distance].compulsory?('someusage').should eql true
15
15
  t[:distance].compulsory?('someotherusage').should eql false
16
16
  t[:distance].optional?('someotherusage').should eql true
@@ -1,19 +1,17 @@
1
- require 'spec_helper'
1
+ require File.dirname(File.dirname(__FILE__)) + '/spec_helper.rb'
2
2
 
3
3
  class PrototypeCalculation
4
4
  def call_me
5
5
  #stub, because flexmock doesn't work for new instances during constructor
6
6
  @@called=true
7
7
  end
8
- cattr_accessor :called
8
+ def self.called
9
+ @@called
10
+ end
9
11
  end
10
12
  describe PrototypeCalculation do
11
- before :all do
12
- @calc = CalculationSet.find("transport")[:transport]
13
- end
14
-
15
13
  it 'can create an instance' do
16
- @calc.should be_a PrototypeCalculation
14
+ Transport.should be_a PrototypeCalculation
17
15
  end
18
16
  it 'can be initialized with a DSL block' do
19
17
  PrototypeCalculation.new {call_me}
@@ -23,11 +21,6 @@ describe PrototypeCalculation do
23
21
  pc=PrototypeCalculation.new {drill{label :alpha}}
24
22
  pc[:alpha].should be_a Drill
25
23
  end
26
- it 'can set custom drill choices in the DSL block' do
27
- pc=PrototypeCalculation.new {drill{label :alpha; choices "ball","cat","dog"}}
28
- pc[:alpha].should be_a Drill
29
- pc[:alpha].choices.should eql ["ball","cat","dog"]
30
- end
31
24
  it 'can''t make a DSL block term without a label' do
32
25
  lambda{
33
26
  pc=PrototypeCalculation.new {drill}
@@ -42,17 +35,17 @@ describe PrototypeCalculation do
42
35
  pc[:alpha].should be_a Output
43
36
  end
44
37
  it 'can construct an ongoing calculation' do
45
- @calc.begin_calculation.should be_a OngoingCalculation
38
+ Transport.begin_calculation.should be_a OngoingCalculation
46
39
  end
47
40
  it 'should make the terms of the ongoing calculation be their own instances' do
48
- oc=@calc.begin_calculation
41
+ oc=Transport.begin_calculation
49
42
  oc[:distance].value :somevalue
50
43
  oc[:distance].value.should eql :somevalue
51
- @calc[:distance].value.should be_nil
44
+ Transport[:distance].value.should be_nil
52
45
  end
53
46
  it 'should copy name, path, label when cloning ongoing' do
54
47
  [:path,:name,:label].each do |property|
55
- @calc.begin_calculation.send(property).should eql @calc.send(property)
48
+ Transport.begin_calculation.send(property).should eql Transport.send(property)
56
49
  end
57
50
  end
58
51
  it 'can autogenerate drill terms for itself, based on talking to amee' do
@@ -231,7 +224,7 @@ describe PrototypeCalculation do
231
224
  pc.terms.default_per_units.compact.map(&:name).should include 'hour'
232
225
  end
233
226
  it 'transfers memoised amee information to constructed ongoing calculations' do
234
- t=@calc.clone
227
+ t=Transport.clone
235
228
  flexmock(AMEE::Data::Category).should_receive(:get).
236
229
  with(AMEE::DataAbstraction.connection,'/data/transport/car/generic').
237
230
  once.and_return(true)
@@ -239,7 +232,7 @@ describe PrototypeCalculation do
239
232
  t.begin_calculation.send(:amee_data_category)
240
233
  end
241
234
  it 'can auto-create start and end date metadata' do
242
- t=@calc.clone
235
+ t=Transport.clone
243
236
  t.instance_eval{
244
237
  start_and_end_dates
245
238
  }
@@ -1,18 +1,16 @@
1
- require 'spec_helper'
1
+ require File.dirname(File.dirname(__FILE__)) + '/spec_helper.rb'
2
2
 
3
3
  class Term
4
4
  def call_me
5
5
  #stub, because flexmock doesn't work for new instances during constructor
6
6
  @@called=true
7
7
  end
8
- cattr_accessor :called
8
+ def self.called
9
+ @@called
10
+ end
9
11
  end
10
12
 
11
13
  describe Term do
12
- before :all do
13
- @calc = CalculationSet.find("transport")[:transport]
14
- end
15
-
16
14
  it 'can be initialized via DSL block' do
17
15
  Term.new {call_me}
18
16
  Term.called.should be_true
@@ -34,13 +32,8 @@ describe Term do
34
32
  Term.new {note 'hello'}.note.should eql 'hello'
35
33
  end
36
34
 
37
- it "has note with no '\"' character" do
38
- Term.new {note 'hello "some quote"'}.note.should eql "hello 'some quote'"
39
- end
40
-
41
-
42
35
  it 'has parent' do
43
- @calc[:distance].parent.should eql @calc
36
+ Transport[:distance].parent.should eql Transport
44
37
  end
45
38
  it "has name defaulting to label" do
46
39
  Term.new {label :hello}.name.should eql 'Hello'
@@ -94,18 +87,17 @@ describe Term do
94
87
  t.hidden?.should be_false
95
88
  end
96
89
  it 'knows which terms come before or after it' do
97
- @calc.terms.
90
+ Transport.terms.
98
91
  select{|x|x.before?(:distance)}.map(&:label).
99
92
  should eql [:fuel,:size]
100
- @calc.terms.
93
+ Transport.terms.
101
94
  select{|x|x.after?(:distance)}.map(&:label).
102
95
  should eql [:co2]
103
96
  end
104
97
 
105
98
  it "should respond to unit methods" do
106
99
  Term.new.methods.should include "unit","per_unit","default_unit","default_per_unit",
107
- "alternative_units","alternative_per_units", "unit_choices",
108
- "per_unit_choices"
100
+ "alternative_units","alternative_per_units"
109
101
  end
110
102
 
111
103
  it "has no default unit if none declared" do
@@ -141,48 +133,14 @@ describe Term do
141
133
  term = Term.new {path :hello; default_unit :kg; default_per_unit :kWh}
142
134
  units = term.alternative_units.map(&:name)
143
135
  units.should include "gigagram", "pound", "tonne"
144
- units.should_not include "kilogram", "kelvin"
145
- per_units = term.alternative_per_units.map(&:name)
146
- per_units.should include "joule", "british thermal unit", "megawatt hour"
147
- per_units.should_not include "kilowatt hour"
148
- end
149
-
150
- it "has unit choices which include default and alternative" do
151
- term = Term.new {path :hello; default_unit :kg; default_per_unit :kWh}
152
- units = term.alternative_units.map(&:name)
153
- units.should include "gigagram", "pound", "tonne"
154
- units.should_not include "kilogram", "kelvin"
155
-
156
- units = term.unit_choices.map(&:name)
157
- units.first.should eql "kilogram"
158
- units.should include "kilogram", "gigagram", "pound", "tonne"
159
- units.should_not include "kelvin"
160
-
161
136
  per_units = term.alternative_per_units.map(&:name)
162
137
  per_units.should include "joule", "british thermal unit", "megawatt hour"
163
- per_units.should_not include "kilowatt hour"
164
-
165
- per_units = term.per_unit_choices.map(&:name)
166
- per_units.first.should eql "kilowatt hour"
167
- per_units.should include "kilowatt hour", "joule", "british thermal unit", "megawatt hour"
168
138
  end
169
139
 
170
140
  it "has limited set of alternative units if specified" do
171
141
  term = Term.new {path :hello; default_unit :kg; alternative_units :t, :ton_us, :lb}
172
142
  units = term.alternative_units.map(&:name)
173
143
  units.should include "tonne", "pound", "short ton"
174
- units.should_not include "kilogram", "gigagram", "ounce", "gram"
175
- end
176
-
177
- it "has unit choices which include default and alternative with limited set of alternative units" do
178
- term = Term.new {path :hello; default_unit :kg; alternative_units :t, :ton_us, :lb}
179
- units = term.alternative_units.map(&:name)
180
- units.should include "tonne", "pound", "short ton"
181
- units.should_not include "kilogram", "gigagram", "ounce", "gram"
182
-
183
- units = term.unit_choices.map(&:name)
184
- units.first.should eql "kilogram"
185
- units.should include "kilogram", "tonne", "pound", "short ton"
186
144
  units.should_not include "gigagram", "ounce", "gram"
187
145
  end
188
146
 
@@ -1,31 +1,27 @@
1
- require 'spec_helper'
1
+ require File.dirname(File.dirname(__FILE__)) + '/spec_helper.rb'
2
2
 
3
3
  describe TermsList do
4
- before :all do
5
- @calc = CalculationSet.find("transport")[:transport]
6
- end
7
-
8
4
  it 'should be returned from calculations' do
9
- @calc.terms.should be_a TermsList
5
+ Transport.terms.should be_a TermsList
10
6
  end
11
7
  it 'should give properties' do
12
- @calc.terms.labels.should eql [:fuel,:size,:distance,:co2]
13
- @calc.terms.paths.should eql ['fuel','size','distance','default']
14
- @calc.terms.names.should eql ['Fuel Type','Vehicle Size','Distance Driven','Carbon Dioxide']
8
+ Transport.terms.labels.should eql [:fuel,:size,:distance,:co2]
9
+ Transport.terms.paths.should eql ['fuel','size','distance',:default]
10
+ Transport.terms.names.should eql ['Fuel Type','Vehicle Size','Distance Driven','Carbon Dioxide']
15
11
  end
16
12
  it 'should select by class' do
17
- @calc.terms.drills.labels.should eql [:fuel,:size]
18
- @calc.terms.profiles.labels.should eql [:distance]
19
- @calc.terms.outputs.labels.should eql [:co2]
13
+ Transport.terms.drills.labels.should eql [:fuel,:size]
14
+ Transport.terms.profiles.labels.should eql [:distance]
15
+ Transport.terms.outputs.labels.should eql [:co2]
20
16
  end
21
17
  it 'should select by property' do
22
- t=@calc.begin_calculation
18
+ t=Transport.begin_calculation
23
19
  t[:distance].value 5
24
20
  t.terms.set.labels.should eql [:distance]
25
21
  t.terms.unset.labels.should eql [:fuel,:size,:co2]
26
22
  end
27
23
  it 'should select by chain' do
28
- t=@calc.begin_calculation
24
+ t=Transport.begin_calculation
29
25
  t[:fuel].value 'diesel'
30
26
  t.terms.drills.set.labels.should eql [:fuel]
31
27
  t.terms.drills.unset.labels.should eql [:size]
@@ -33,7 +29,7 @@ describe TermsList do
33
29
  t.terms.unset.drills.labels.should eql [:size]
34
30
  end
35
31
  it 'should select by order' do
36
- t=@calc.clone
32
+ t=Transport.clone
37
33
  t.terms.before(:distance).labels.
38
34
  should eql [:fuel,:size]
39
35
  t.terms.after(:distance).labels.
@@ -44,7 +40,7 @@ describe TermsList do
44
40
  mocker.item_value_definitions.
45
41
  item_definition.data_category.
46
42
  item_value_definition('distance',['usage1'],['usage2'],['usage3'])
47
- t=@calc.clone
43
+ t=Transport.clone
48
44
  t.profiles.compulsory('usage1').labels.should eql [:distance]
49
45
  t.profiles.optional('usage2').labels.should eql [:distance]
50
46
  t.profiles.compulsory('usage2').labels.should be_empty
@@ -1,4 +1,5 @@
1
- require 'spec_helper'
1
+
2
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
3
 
3
4
  describe "AMEE units" do
4
5
 
@@ -1,25 +1,25 @@
1
- require 'spec_helper'
1
+ require File.dirname(File.dirname(__FILE__)) + '/spec_helper.rb'
2
2
 
3
- class Myclass
4
- attr_property :prop
5
- end
3
+ class Myclass
4
+ attr_property :prop
5
+ end
6
6
 
7
7
  describe Class do
8
8
  before :all do
9
9
  @it=Myclass.new
10
10
  end
11
- it 'can have a property defined' do
12
- @it.prop 5
13
- @it.prop.should eql 5
14
- end
15
- it 'can have a prop unset' do
16
- @it.prop 5
17
- @it.prop nil
18
- @it.prop.should be_nil
19
- end
20
- it 'does not unset by query' do
21
- @it.prop 5
22
- @it.prop
23
- @it.prop.should_not be_nil
24
- end
11
+ it 'can have a property defined' do
12
+ @it.prop 5
13
+ @it.prop.should eql 5
14
+ end
15
+ it 'can have a prop unset' do
16
+ @it.prop 5
17
+ @it.prop nil
18
+ @it.prop.should be_nil
19
+ end
20
+ it 'does not unset by query' do
21
+ @it.prop 5
22
+ @it.prop
23
+ @it.prop.should_not be_nil
24
+ end
25
25
  end
@@ -1,4 +1,5 @@
1
- require 'spec_helper'
1
+
2
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
3
 
3
4
  describe Hash do
4
5
  before(:each) do
@@ -1,4 +1,5 @@
1
- require 'spec_helper'
1
+ require File.dirname(File.dirname(__FILE__)) + '/spec_helper.rb'
2
+
2
3
 
3
4
  describe ActiveSupport::OrderedHash do
4
5
  it 'Can insert at start' do
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ require File.dirname(File.dirname(__FILE__)) + '/spec_helper.rb'
2
2
 
3
3
  describe Proc do
4
4
  before :all do
@@ -1,4 +1,4 @@
1
- calculation { # The application has support for an electricity calculation. :electricity is the internal label used to refer to it
1
+ Electricity=AMEE::DataAbstraction::PrototypeCalculation.new { # The application has support for an electricity calculation. :electricity is the internal label used to refer to it
2
2
  label :electricity
3
3
  name "Electricity Consumption"
4
4
  path '/business/energy/electricity/grid'
@@ -28,7 +28,7 @@ calculation { # The application has support for an electricity calculation. :ele
28
28
 
29
29
  output { #A marv output value
30
30
  label :co2
31
- path 'default' #It's not a marv, use the default output
31
+ path :default #It's not a marv, use the default output
32
32
  name "Carbon Dioxide"
33
33
  }
34
34
  }
@@ -0,0 +1,55 @@
1
+ ElectricityAndTransport=AMEE::DataAbstraction::CalculationSet.new {
2
+ all_calculations {
3
+ metadatum {
4
+ label :department
5
+ choices %w{stuff things more_stuff meta_things}
6
+ }
7
+ }
8
+
9
+ calculation{
10
+ name 'electricity'
11
+ label :electricity
12
+ path '/business/energy/electricity/grid'
13
+ profile {
14
+ label :usage
15
+ name 'Electricity Used'
16
+ path 'energyPerTime'
17
+ }
18
+ drill {
19
+ label :country
20
+ path 'country'
21
+ fixed 'Argentina'
22
+ }
23
+ output {
24
+ label :co2
25
+ path :default
26
+ }
27
+ }
28
+
29
+ calculation {
30
+ name 'transport'
31
+ label :transport
32
+ path '/transport/car/generic'
33
+
34
+ drill {
35
+ path 'fuel'
36
+ label :fuel
37
+ name 'Fuel Type'
38
+ }
39
+ drill {
40
+ path 'size'
41
+ label :size
42
+ name 'Vehicle Size'
43
+ }
44
+ profile {
45
+ path 'distance'
46
+ label :distance
47
+ name 'Distance Driven'
48
+ }
49
+ output {
50
+ label :co2
51
+ path :default
52
+ name 'Carbon Dioxide'
53
+ }
54
+ }
55
+ }
@@ -1,4 +1,4 @@
1
- calculation {
1
+ Transport=AMEE::DataAbstraction::PrototypeCalculation.new{
2
2
  name 'transport'
3
3
  label :transport
4
4
  path '/transport/car/generic'
@@ -20,7 +20,7 @@ calculation {
20
20
  }
21
21
  output {
22
22
  label :co2
23
- path 'default'
23
+ path :default
24
24
  name 'Carbon Dioxide'
25
25
  }
26
26
  }
data/spec/spec_helper.rb CHANGED
@@ -1,38 +1,17 @@
1
1
  require 'rubygems'
2
- require 'spec'
3
- require 'rspec_spinner'
4
- require 'flexmock'
5
- require 'amee'
6
-
7
- $:.unshift(File.dirname(__FILE__) + '/../lib')
2
+ require 'rspec'
8
3
  require 'amee-data-abstraction'
9
4
 
10
- # Fake up Rails.root to be fixtures directory
11
- class Rails
12
- def self.root
13
- File.dirname(__FILE__) + '/fixtures'
14
- end
15
- def self.logger
16
- nil
17
- end
18
- end
19
-
20
- Spec::Runner.configure do |config|
5
+ RSpec.configure do |config|
21
6
  config.mock_with :flexmock
22
- config.after(:each) do
23
- delete_lock_files
24
- end
25
- end
26
-
27
- def delete_lock_files
28
- config_dir = Dir.new("#{Rails.root}/config/calculations")
29
- config_dir.each do |file|
30
- File.delete("#{config_dir.path}/#{file}") if file =~ /lock/
31
- end
32
7
  end
33
8
 
34
9
  AMEE::DataAbstraction.connection=FlexMock.new('connection') #Global connection mock, shouldn't receive anything, as we mock the individual amee-ruby calls in the tests
35
10
 
11
+ Dir.glob(File.dirname(__FILE__) + '/fixtures/*') do |filename|
12
+ require filename
13
+ end
14
+
36
15
  include AMEE::DataAbstraction
37
16
 
38
17
  class AMEEMocker
@@ -98,21 +77,6 @@ class AMEEMocker
98
77
  return self
99
78
  end
100
79
 
101
- # This represents the skipping of drill choices which occur on an AMEE drill
102
- # down when only one choice exists for a given drill - it skips to the next,
103
- # offering the next set of choices or a uid. In these cases, the skipped drill
104
- # is set as an automatic selection
105
- def drill_with_skip(skipped_selections=[])
106
- test.flexmock(AMEE::Data::DrillDown).
107
- should_receive(:get).
108
- with(connection,
109
- "/data/#{path}/drill?#{selections.map{|k,v|"#{k}=#{v}"}.join('&')}").
110
- at_least.once.
111
- and_return(test.flexmock(:choices=>choices,:selections=>Hash[selections].merge(skipped_selections),
112
- :data_item_uid=>dataitemuid))
113
- return self
114
- end
115
-
116
80
  def profile_list
117
81
  test.flexmock(AMEE::Profile::ProfileList).should_receive(:new).
118
82
  with(connection).at_least.once.
@@ -283,7 +247,7 @@ class AMEEMocker
283
247
  def update
284
248
  test.flexmock(AMEE::Profile::Item).should_receive(:update).
285
249
  with(connection,pipath,
286
- {:get_item=>true}.merge(existing).merge(params)).
250
+ {:get_item=>false}.merge(existing).merge(params)).
287
251
  at_least.once
288
252
  return self
289
253
  end