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.
- data/.rvmrc +1 -1
- data/CHANGELOG.txt +0 -3
- data/Gemfile +5 -7
- data/Gemfile.lock +20 -14
- data/README.txt +15 -28
- data/Rakefile +17 -16
- data/VERSION +1 -1
- data/amee-data-abstraction.gemspec +21 -24
- data/lib/amee-data-abstraction.rb +6 -0
- data/lib/amee-data-abstraction/calculation.rb +1 -1
- data/lib/amee-data-abstraction/calculation_set.rb +10 -152
- data/lib/amee-data-abstraction/drill.rb +6 -23
- data/lib/amee-data-abstraction/input.rb +0 -24
- data/lib/amee-data-abstraction/ongoing_calculation.rb +9 -13
- data/lib/amee-data-abstraction/term.rb +13 -31
- data/spec/amee-data-abstraction/calculation_set_spec.rb +11 -245
- data/spec/amee-data-abstraction/calculation_spec.rb +18 -23
- data/spec/amee-data-abstraction/drill_spec.rb +7 -34
- data/spec/amee-data-abstraction/input_spec.rb +73 -113
- data/spec/amee-data-abstraction/metadatum_spec.rb +1 -1
- data/spec/amee-data-abstraction/ongoing_calculation_spec.rb +29 -45
- data/spec/amee-data-abstraction/profile_spec.rb +2 -2
- data/spec/amee-data-abstraction/prototype_calculation_spec.rb +11 -18
- data/spec/amee-data-abstraction/term_spec.rb +8 -50
- data/spec/amee-data-abstraction/terms_list_spec.rb +12 -16
- data/spec/config/amee_units_spec.rb +2 -1
- data/spec/core-extensions/class_spec.rb +18 -18
- data/spec/core-extensions/hash_spec.rb +2 -1
- data/spec/core-extensions/ordered_hash_spec.rb +2 -1
- data/spec/core-extensions/proc_spec.rb +1 -1
- data/spec/fixtures/{config/electricity.rb → electricity.rb} +2 -2
- data/spec/fixtures/electricity_and_transport.rb +55 -0
- data/spec/fixtures/{config/calculations/transport.rb → transport.rb} +2 -2
- data/spec/spec_helper.rb +7 -43
- metadata +56 -61
- data/init.rb +0 -4
- data/rails/init.rb +0 -32
- data/spec/fixtures/config/calculations/electricity.rb +0 -35
- 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=
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
41
|
+
oc=Transport.begin_calculation
|
49
42
|
oc[:distance].value :somevalue
|
50
43
|
oc[:distance].value.should eql :somevalue
|
51
|
-
|
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
|
-
|
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
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
90
|
+
Transport.terms.
|
98
91
|
select{|x|x.before?(:distance)}.map(&:label).
|
99
92
|
should eql [:fuel,:size]
|
100
|
-
|
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"
|
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
|
-
|
5
|
+
Transport.terms.should be_a TermsList
|
10
6
|
end
|
11
7
|
it 'should give properties' do
|
12
|
-
|
13
|
-
|
14
|
-
|
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
|
-
|
18
|
-
|
19
|
-
|
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
|
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
|
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
|
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
|
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,25 +1,25 @@
|
|
1
|
-
require 'spec_helper'
|
1
|
+
require File.dirname(File.dirname(__FILE__)) + '/spec_helper.rb'
|
2
2
|
|
3
|
-
class Myclass
|
4
|
-
|
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
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
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,4 @@
|
|
1
|
-
|
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
|
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
|
-
|
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
|
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 '
|
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
|
-
|
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=>
|
250
|
+
{:get_item=>false}.merge(existing).merge(params)).
|
287
251
|
at_least.once
|
288
252
|
return self
|
289
253
|
end
|