amee-data-abstraction 1.3.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|