amee-data-abstraction 1.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 (53) hide show
  1. data/.rvmrc +1 -0
  2. data/CHANGELOG.txt +4 -0
  3. data/Gemfile +16 -0
  4. data/Gemfile.lock +41 -0
  5. data/LICENSE.txt +27 -0
  6. data/README.txt +188 -0
  7. data/Rakefile +102 -0
  8. data/VERSION +1 -0
  9. data/amee-data-abstraction.gemspec +115 -0
  10. data/examples/_calculator_form.erb +27 -0
  11. data/examples/calculation_controller.rb +16 -0
  12. data/init.rb +4 -0
  13. data/lib/amee-data-abstraction.rb +30 -0
  14. data/lib/amee-data-abstraction/calculation.rb +236 -0
  15. data/lib/amee-data-abstraction/calculation_set.rb +101 -0
  16. data/lib/amee-data-abstraction/drill.rb +63 -0
  17. data/lib/amee-data-abstraction/exceptions.rb +47 -0
  18. data/lib/amee-data-abstraction/input.rb +197 -0
  19. data/lib/amee-data-abstraction/metadatum.rb +58 -0
  20. data/lib/amee-data-abstraction/ongoing_calculation.rb +545 -0
  21. data/lib/amee-data-abstraction/output.rb +16 -0
  22. data/lib/amee-data-abstraction/profile.rb +108 -0
  23. data/lib/amee-data-abstraction/prototype_calculation.rb +350 -0
  24. data/lib/amee-data-abstraction/term.rb +506 -0
  25. data/lib/amee-data-abstraction/terms_list.rb +150 -0
  26. data/lib/amee-data-abstraction/usage.rb +90 -0
  27. data/lib/config/amee_units.rb +129 -0
  28. data/lib/core-extensions/class.rb +27 -0
  29. data/lib/core-extensions/hash.rb +43 -0
  30. data/lib/core-extensions/ordered_hash.rb +21 -0
  31. data/lib/core-extensions/proc.rb +15 -0
  32. data/rails/init.rb +32 -0
  33. data/spec/amee-data-abstraction/calculation_set_spec.rb +54 -0
  34. data/spec/amee-data-abstraction/calculation_spec.rb +75 -0
  35. data/spec/amee-data-abstraction/drill_spec.rb +38 -0
  36. data/spec/amee-data-abstraction/input_spec.rb +77 -0
  37. data/spec/amee-data-abstraction/metadatum_spec.rb +17 -0
  38. data/spec/amee-data-abstraction/ongoing_calculation_spec.rb +494 -0
  39. data/spec/amee-data-abstraction/profile_spec.rb +39 -0
  40. data/spec/amee-data-abstraction/prototype_calculation_spec.rb +256 -0
  41. data/spec/amee-data-abstraction/term_spec.rb +385 -0
  42. data/spec/amee-data-abstraction/terms_list_spec.rb +53 -0
  43. data/spec/config/amee_units_spec.rb +71 -0
  44. data/spec/core-extensions/class_spec.rb +25 -0
  45. data/spec/core-extensions/hash_spec.rb +44 -0
  46. data/spec/core-extensions/ordered_hash_spec.rb +12 -0
  47. data/spec/core-extensions/proc_spec.rb +12 -0
  48. data/spec/fixtures/electricity.rb +35 -0
  49. data/spec/fixtures/electricity_and_transport.rb +55 -0
  50. data/spec/fixtures/transport.rb +26 -0
  51. data/spec/spec.opts +2 -0
  52. data/spec/spec_helper.rb +244 -0
  53. metadata +262 -0
@@ -0,0 +1,53 @@
1
+ require File.dirname(File.dirname(__FILE__)) + '/spec_helper.rb'
2
+
3
+ describe TermsList do
4
+ it 'should be returned from calculations' do
5
+ Transport.terms.should be_a TermsList
6
+ end
7
+ it 'should give properties' do
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']
11
+ end
12
+ it 'should select by class' do
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]
16
+ end
17
+ it 'should select by property' do
18
+ t=Transport.begin_calculation
19
+ t[:distance].value 5
20
+ t.terms.set.labels.should eql [:distance]
21
+ t.terms.unset.labels.should eql [:fuel,:size,:co2]
22
+ end
23
+ it 'should select by chain' do
24
+ t=Transport.begin_calculation
25
+ t[:fuel].value 'diesel'
26
+ t.terms.drills.set.labels.should eql [:fuel]
27
+ t.terms.drills.unset.labels.should eql [:size]
28
+ t.terms.set.drills.labels.should eql [:fuel]
29
+ t.terms.unset.drills.labels.should eql [:size]
30
+ end
31
+ it 'should select by order' do
32
+ t=Transport.clone
33
+ t.terms.before(:distance).labels.
34
+ should eql [:fuel,:size]
35
+ t.terms.after(:distance).labels.
36
+ should eql [:co2]
37
+ end
38
+ it 'can select terms by usage' do
39
+ mocker=AMEEMocker.new self,:path=>'transport/car/generic'
40
+ mocker.item_value_definitions.
41
+ item_definition.data_category.
42
+ item_value_definition('distance',['usage1'],['usage2'],['usage3'])
43
+ t=Transport.clone
44
+ t.profiles.compulsory('usage1').labels.should eql [:distance]
45
+ t.profiles.optional('usage2').labels.should eql [:distance]
46
+ t.profiles.compulsory('usage2').labels.should be_empty
47
+ t.profiles.optional('usage1').labels.should be_empty
48
+ t.profiles.in_use('usage2').labels.should eql [:distance]
49
+ t.profiles.in_use('usage1').labels.should eql [:distance]
50
+ t.profiles.in_use('usage3').labels.should be_empty
51
+ end
52
+
53
+ end
@@ -0,0 +1,71 @@
1
+
2
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
3
+
4
+ describe "AMEE units" do
5
+
6
+ include Quantify
7
+
8
+ # The Unit.<unit_name_symbol_or_label> pattern retrieves the unit which is
9
+ # provided as the (pseudo) method name (using #method_missing). In cases where
10
+ # the named unit does not exist an error is raised. In some cases, however,
11
+ # where the unit can be constructed from a known and compatible unit and prefix
12
+ # combination, it is created but not loaded to the canonical system of units.
13
+ # Therefore, to test for presence or absence of partiuclar units, we check that
14
+ # the units we want are #loaded? and that the ones we don't want are either NOT
15
+ # #loaded? (if the happen to be derivable) or otherwise raise an error.
16
+
17
+ it "should include commonly used SI units" do
18
+ Unit.metre.should be_loaded
19
+ Unit.second.should be_loaded
20
+ Unit.kg.should be_loaded
21
+ end
22
+
23
+ it "should include commonly used non SI units" do
24
+ Unit.foot.should be_loaded
25
+ Unit.pound.should be_loaded
26
+ Unit.month.should be_loaded
27
+ end
28
+
29
+ it "should exclude uncommonly used SI units" do
30
+ Unit.micrometre.should_not be_loaded
31
+ lambda{Unit.galileo}.should raise_error
32
+ lambda{Unit.inverse_centimetre}.should raise_error
33
+ end
34
+
35
+ it "should exclude uncommonly used non SI units" do
36
+ lambda{Unit.astronomical_unit}.should raise_error
37
+ lambda{Unit.dyne_centimetre}.should raise_error
38
+ lambda{Unit.maxwell}.should raise_error
39
+ end
40
+
41
+ it "should include commonly used SI units and prefixes" do
42
+ Unit.terajoule.should be_loaded
43
+ Unit.gigagram.should be_loaded
44
+ Unit.megawatt.should be_loaded
45
+ end
46
+
47
+ it "should include commonly used Non SI units and prefixes" do
48
+ Unit.MBTU.should be_loaded
49
+ end
50
+
51
+ it "should exclude uncommonly used SI units and prefixes" do
52
+ Unit.microjoule.should_not be_loaded
53
+ Unit.nanogram.should_not be_loaded
54
+ Unit.picowatt.should_not be_loaded
55
+ end
56
+
57
+ it "should represent the BTU with the 59F version" do
58
+ Unit.BTU.label.should eql "BTU_FiftyNineF"
59
+ end
60
+
61
+ it "should label the unit for 'day' as 'day'" do
62
+ Unit.day.label.should eql 'day'
63
+ end
64
+
65
+ it "should recognise the unit for megawatt_hour as 'MWh'" do
66
+ Unit.megawatt_hour.label.should eql 'MWh'
67
+ Unit.megawatt_hour.symbol.should eql 'MWh'
68
+ end
69
+
70
+ end
71
+
@@ -0,0 +1,25 @@
1
+ require File.dirname(File.dirname(__FILE__)) + '/spec_helper.rb'
2
+
3
+ class Myclass
4
+ attr_property :prop
5
+ end
6
+
7
+ describe Class do
8
+ before :all do
9
+ @it=Myclass.new
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
25
+ end
@@ -0,0 +1,44 @@
1
+
2
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
3
+
4
+ describe Hash do
5
+ before(:each) do
6
+ @hash = { 'first_name' => 'Kenny',
7
+ 'last_name' => 'Rogers',
8
+ 'date_of_birth' => {'day' => 17,
9
+ 'month' => 'April',
10
+ 'year' => 1939 },
11
+ 'interests' => [ {'movie' => 'Birds',
12
+ 'book' => 'Catch 22'},
13
+ "guitar",
14
+ {'song' => 'Leaving On a Jetplane'} ],
15
+ :already_a_symbol => 'dummy' }
16
+ end
17
+
18
+ it "should symbolize keys, returning new hash" do
19
+ new_hash = @hash.recursive_symbolize_keys
20
+ new_hash.keys.size.should eql 5
21
+ new_hash.keys.each { |k| k.should be_a Symbol }
22
+ new_hash[:first_name].should eql 'Kenny'
23
+ new_hash[:date_of_birth].should be_a Hash
24
+ new_hash[:date_of_birth].keys.each { |k| k.should be_a Symbol }
25
+ new_hash[:date_of_birth][:month].should eql 'April'
26
+ new_hash[:interests].should be_a Array
27
+ new_hash[:interests][0].keys.each { |k| k.should be_a Symbol }
28
+ new_hash[:interests][0][:movie].should eql 'Birds'
29
+ end
30
+
31
+ it "should symbolize keys in place, returning self" do
32
+ @hash.recursive_symbolize_keys!
33
+ @hash.keys.size.should eql 5
34
+ @hash.keys.each { |k| k.should be_a Symbol }
35
+ @hash[:first_name].should eql 'Kenny'
36
+ @hash[:date_of_birth].should be_a Hash
37
+ @hash[:date_of_birth].keys.each { |k| k.should be_a Symbol }
38
+ @hash[:date_of_birth][:month].should eql 'April'
39
+ @hash[:interests].should be_a Array
40
+ @hash[:interests][0].keys.each { |k| k.should be_a Symbol }
41
+ @hash[:interests][0][:movie].should eql 'Birds'
42
+ end
43
+ end
44
+
@@ -0,0 +1,12 @@
1
+ require File.dirname(File.dirname(__FILE__)) + '/spec_helper.rb'
2
+
3
+
4
+ describe ActiveSupport::OrderedHash do
5
+ it 'Can insert at start' do
6
+ x=ActiveSupport::OrderedHash[[[1,2],[3,4]]]
7
+ x.keys.should eql [1,3]
8
+ x.insert_at_start(5,6)
9
+ x.keys.should eql [5,1,3]
10
+ x.to_a.should eql [[5,6],[1,2],[3,4]]
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ require File.dirname(File.dirname(__FILE__)) + '/spec_helper.rb'
2
+
3
+ describe Proc do
4
+ before :all do
5
+ @it=Proc.new{|x|x.is_a? Float}
6
+ end
7
+ it 'uses call as ===' do
8
+ (@it===3.4).should be_true
9
+ (@it===7).should be_false
10
+ (@it==='hello').should be_false
11
+ end
12
+ end
@@ -0,0 +1,35 @@
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
+ label :electricity
3
+ name "Electricity Consumption"
4
+ path '/business/energy/electricity/grid'
5
+
6
+ drill {
7
+ fixed 'argentina' #Not to be unset, value pre-given
8
+ label :country #Name will default to label.humanize if not given
9
+ path 'country' #Some of the fields on the form are drill-downs, but the application doesn't need to display these differently
10
+ #type :autocompleting_text_box #default for a drill with entries is probably a dropdown
11
+ }
12
+
13
+ profile {
14
+ label :energy_used
15
+ # Symbol provided here is used in generating html ids for elements etc
16
+ path 'energyPerTime' #The amee profile item value corresponding to the field
17
+ name "Energy Used" #The display name used on the form
18
+ unit "kWh" #Default unit choice
19
+ interface :text_box #Probably not needed, as likely to be the default for profile item value unsets
20
+ validation lambda{|x|x.is_a? Float} #Probably not needed, as default can be deduced from PIV TYPE in API. Here as illustrative.
21
+ alternative_units :MWh, :MBTU, :BTU # If these are explcitly specified then the alternatives are limited to only these units. Otherwise all dimensionally equivalent units are available as alternatives by default
22
+ }
23
+
24
+ # Alternatively, the drill might be fixed
25
+ #permanent :country {
26
+ # drill_path 'country'
27
+ # value 'Argentina'
28
+
29
+ output { #A marv output value
30
+ label :co2
31
+ path :default #It's not a marv, use the default output
32
+ name "Carbon Dioxide"
33
+ }
34
+ }
35
+
@@ -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
+ }
@@ -0,0 +1,26 @@
1
+ Transport=AMEE::DataAbstraction::PrototypeCalculation.new{
2
+ name 'transport'
3
+ label :transport
4
+ path '/transport/car/generic'
5
+
6
+ drill {
7
+ path 'fuel'
8
+ label :fuel
9
+ name 'Fuel Type'
10
+ }
11
+ drill {
12
+ path 'size'
13
+ label :size
14
+ name 'Vehicle Size'
15
+ }
16
+ profile {
17
+ path 'distance'
18
+ label :distance
19
+ name 'Distance Driven'
20
+ }
21
+ output {
22
+ label :co2
23
+ path :default
24
+ name 'Carbon Dioxide'
25
+ }
26
+ }
data/spec/spec.opts ADDED
@@ -0,0 +1,2 @@
1
+ --colour
2
+ --format RspecSpinner::Bar
@@ -0,0 +1,244 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+ require 'rspec_spinner'
4
+ require 'flexmock'
5
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
6
+ require 'amee'
7
+ require 'amee-data-abstraction'
8
+
9
+ Spec::Runner.configure do |config|
10
+ config.mock_with :flexmock
11
+ end
12
+
13
+ AMEE::DataAbstraction.connection=FlexMock.new('connection') #Global connection mock, shouldn't receive anything, as we mock the individual amee-ruby calls in the tests
14
+
15
+ Dir.glob(File.dirname(__FILE__) + '/fixtures/*') do |filename|
16
+ require filename
17
+ end
18
+
19
+ include AMEE::DataAbstraction
20
+
21
+ class AMEEMocker
22
+ def initialize(test,options)
23
+ @path=options[:path]
24
+ sel=options[:selections]||[]
25
+ @selections=ActiveSupport::OrderedHash[sel]
26
+ @choices=options[:choices]||[]
27
+ @result=options[:result]
28
+ @params=options[:params]||{}
29
+ @existing=options[:existing]||{}
30
+ @test=test
31
+ @mock_dc=test.flexmock(:path=>"/data/#{path}")
32
+ @mock_id=test.flexmock
33
+ @mock_ivds=[]
34
+ @mock_rvds=[]
35
+ end
36
+
37
+ attr_accessor :path,:selections,:choices,:result,:params,
38
+ :existing,:mock_dc,:mock_id,:mock_ivds,:mock_rvds
39
+
40
+ attr_reader :test
41
+
42
+ def catuid
43
+ path.gsub(/\//,'-').to_sym
44
+ end
45
+
46
+ def select(opts)
47
+ # Like an array of pairs, not a hash, for ordering reasons.
48
+ opts.each do |k,v|
49
+ @selections[k]=v
50
+ end
51
+ end
52
+
53
+ def connection
54
+ AMEE::DataAbstraction.connection
55
+ end
56
+
57
+ def dataitemuid
58
+ "#{catuid}:#{selections.map{|k,v|"#{k}-#{v}"}.join('-')}"
59
+ end
60
+
61
+ def uid
62
+ dataitemuid+"PI"
63
+ end
64
+
65
+ def pipath
66
+ "/profiles/someprofileuid/#{path}/#{uid}"
67
+ end
68
+
69
+ def dipath
70
+ "/data/#{path}/#{dataitemuid}"
71
+ end
72
+
73
+ def drill
74
+ test.flexmock(AMEE::Data::DrillDown).
75
+ should_receive(:get).
76
+ with(connection,
77
+ "/data/#{path}/drill?#{selections.map{|k,v|"#{k}=#{v}"}.join('&')}").
78
+ at_least.once.
79
+ and_return(test.flexmock(:choices=>choices,:selections=>Hash[selections],
80
+ :data_item_uid=>dataitemuid))
81
+ return self
82
+ end
83
+
84
+ def profile_list
85
+ test.flexmock(AMEE::Profile::ProfileList).should_receive(:new).
86
+ with(connection).at_least.once.
87
+ and_return(test.flexmock(:first=>test.flexmock(:uid=>:someprofileuid)))
88
+ return self
89
+ end
90
+
91
+ def timestamp
92
+ test.flexmock(UUIDTools::UUID).should_receive(:timestamp_create).at_least.once.
93
+ and_return(:sometimestamp)
94
+ return self
95
+ end
96
+
97
+ def profile_category
98
+ test.flexmock(AMEE::Profile::Category).should_receive(:get).
99
+ with(connection,"/profiles/someprofileuid/#{path}").at_least.once.
100
+ and_return(catuid)
101
+ return self
102
+ end
103
+
104
+ def itemdef_drills(some_drills)
105
+ mock_id.should_receive(:drill_downs).and_return(some_drills)
106
+ return self
107
+ end
108
+
109
+ def return_value_definition(path,unit=nil,per_unit=nil)
110
+ rvd=test.flexmock :name=>path
111
+ rvd.should_receive(:unit).and_return unit
112
+ rvd.should_receive(:perunit).and_return per_unit
113
+ mock_rvds.push rvd
114
+ return self
115
+ end
116
+
117
+ def return_value_definitions
118
+ test.flexmock(AMEE::Admin::ReturnValueDefinitionList).should_receive(:new).
119
+ with(connection,:itemdefuid).and_return mock_rvds
120
+ return self
121
+ end
122
+
123
+ def item_value_definition_metadata(meta)
124
+ AMEE::Admin::ItemValueDefinition.new(:meta=>meta).meta
125
+ end
126
+
127
+ def item_value_definition(path,compulsories=[],optionals=[],forbiddens=[],choices=[],unit=nil,per_unit=nil,profile=true,drill=false,default=nil,type=nil,wikidoc=nil)
128
+ ivd=test.flexmock :path=>path
129
+ ivd.should_receive(:name).and_return path.to_s.humanize
130
+ ivd.should_receive(:profile?).and_return profile
131
+ ivd.should_receive(:drill?).and_return drill
132
+ ivd.should_receive(:versions).and_return ['2.0']
133
+ ivd.should_receive(:unit).and_return unit
134
+ ivd.should_receive(:perunit).and_return per_unit
135
+ ivd.should_receive(:choices).and_return choices
136
+ ivd.should_receive(:default).and_return default
137
+ ivd.should_receive(:valuetype).and_return type
138
+ ivd.should_receive(:meta).and_return(item_value_definition_metadata(:wikidoc=>wikidoc))#.should_receive(:wikidoc).and_return wikidoc
139
+ compulsories.each do |compulsory|
140
+ ivd.should_receive(:compulsory?).with(compulsory).and_return(true)
141
+ ivd.should_receive(:optional?).with(compulsory).and_return(false)
142
+ end
143
+ optionals.each do |optional|
144
+ ivd.should_receive(:optional?).with(optional).and_return(true)
145
+ ivd.should_receive(:compulsory?).with(optional).and_return(false)
146
+ end
147
+ forbiddens.each do |forbidden|
148
+ ivd.should_receive(:optional?).with(forbidden).and_return(false)
149
+ ivd.should_receive(:compulsory?).with(forbidden).and_return(false)
150
+ end
151
+ mock_ivds.push ivd
152
+ return self
153
+ end
154
+
155
+ def item_value_definitions
156
+ mock_id.should_receive(:item_value_definition_list).at_least.once.and_return(mock_ivds)
157
+ return self
158
+ end
159
+
160
+ def usages(someusages)
161
+ mock_id.should_receive(:usages).and_return(someusages)
162
+ return self
163
+ end
164
+
165
+ def item_definition(name=:itemdef_name)
166
+ mock_id.should_receive(:name).and_return(name)
167
+ mock_id.should_receive(:uid).and_return(:itemdefuid)
168
+ mock_dc.should_receive(:item_definition).at_least.once.and_return(mock_id)
169
+ return self
170
+ end
171
+
172
+ def data_category
173
+ test.flexmock(AMEE::Data::Category).should_receive(:get).
174
+ with(connection,"/data/#{path}").at_least.once.
175
+ and_return(mock_dc)
176
+ return self
177
+ end
178
+
179
+ def create
180
+ test.flexmock(AMEE::Profile::Item).should_receive(:create).
181
+ with(catuid,dataitemuid,
182
+ {:get_item=>false,:name=>:sometimestamp}.merge(params)).
183
+ at_least.once.
184
+ and_return(pipath)
185
+ return self
186
+ end
187
+
188
+ def get(with_pi=false,failing=false,once=false)
189
+ mock_pi=test.flexmock(
190
+ :amounts=>test.flexmock(:find=>{:value=>result}),
191
+ :data_item_uid=>dataitemuid
192
+ )
193
+ mock_di=test.flexmock
194
+ if with_pi
195
+ from_amee=existing.clone
196
+ params.each {|key,val| from_amee.delete key}
197
+ from_amee.each do |k,v|
198
+ if failing
199
+ mock_pi.should_receive(:values).and_return([{:path => k,:value => v }])
200
+ else
201
+ mock_pi.should_receive(:values).and_return([{:path => k,:value => v }]).once
202
+ end
203
+ end
204
+ selections.each do |k,v|
205
+ if failing
206
+ mock_di.should_receive(:value).with(k).and_return(v)
207
+ else
208
+ mock_di.should_receive(:value).with(k).and_return(v).once
209
+ end
210
+ end
211
+ test.flexmock(AMEE::Data::Item).should_receive(:get).
212
+ with(connection,dipath,{}).
213
+ at_least.once.
214
+ and_return(mock_di)
215
+ end
216
+ if once
217
+ test.flexmock(AMEE::Profile::Item).should_receive(:get).
218
+ with(connection,pipath,{}).
219
+ at_least.once.
220
+ and_return(mock_pi)
221
+ else
222
+ test.flexmock(AMEE::Profile::Item).should_receive(:get).
223
+ with(connection,pipath,{}).
224
+ at_least.once.
225
+ and_return(mock_pi)
226
+ end
227
+ return self
228
+ end
229
+
230
+ def delete
231
+ test.flexmock(AMEE::Profile::Item).should_receive(:delete).
232
+ at_least.once.
233
+ with(connection,pipath)
234
+ return self
235
+ end
236
+
237
+ def update
238
+ test.flexmock(AMEE::Profile::Item).should_receive(:update).
239
+ with(connection,pipath,
240
+ {:get_item=>false}.merge(existing).merge(params)).
241
+ at_least.once
242
+ return self
243
+ end
244
+ end