carbon 0.2.2 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +5 -5
- data/VERSION +1 -1
- data/carbon.gemspec +2 -2
- data/lib/carbon.rb +4 -5
- data/lib/carbon/base.rb +1 -1
- data/lib/carbon/emission_estimate.rb +4 -6
- data/spec/lib/carbon_spec.rb +55 -55
- metadata +4 -4
data/README.rdoc
CHANGED
@@ -44,11 +44,11 @@ In order to calculate carbon emissions, we need to map the car's relevant attrib
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
-
When you want to calculate emissions, simply call <tt>RentalCar#
|
47
|
+
When you want to calculate emissions, simply call <tt>RentalCar#emission_estimate</tt>.
|
48
48
|
|
49
49
|
> my_car = RentalCar.new([...])
|
50
50
|
=> #<RentalCar [...]>
|
51
|
-
> my_emission = my_car.
|
51
|
+
> my_emission = my_car.emission_estimate
|
52
52
|
=> #<Carbon::EmissionEstimate [...]>
|
53
53
|
> my_emission.to_f
|
54
54
|
=> 4919.2
|
@@ -75,9 +75,9 @@ Let's say <tt>RentalCar#make</tt> returns a <tt>Make</tt> object. You should def
|
|
75
75
|
|
76
76
|
== A note on asynchronous queries
|
77
77
|
|
78
|
-
To request an emission estimate asynchronously, simply pass an URL as the <tt>:callback</tt> option to <tt>#
|
78
|
+
To request an emission estimate asynchronously, simply pass an URL as the <tt>:callback</tt> option to <tt>#emission_estimate</tt>:
|
79
79
|
|
80
|
-
> RentalCar.new.
|
80
|
+
> RentalCar.new.emission_estimate :callback => http://example.com/my/callback/handler
|
81
81
|
|
82
82
|
A good way to test this is to set up a {PostBin}[http://postbin.org].
|
83
83
|
|
@@ -86,7 +86,7 @@ A good way to test this is to set up a {PostBin}[http://postbin.org].
|
|
86
86
|
Since this gem connects to a web service, you need to be ready for network problems and latency. For example:
|
87
87
|
|
88
88
|
begin
|
89
|
-
my_emission = my_car.
|
89
|
+
my_emission = my_car.emission_estimate
|
90
90
|
rescue ::SocketError, ::Timeout::Error, ::Errno::ETIMEDOUT, ::Errno::ENETUNREACH, ::Errno::ECONNRESET, ::Errno::ECONNREFUSED
|
91
91
|
# These are general network errors raised by Net::HTTP.
|
92
92
|
# Your internet connection might be down, or our servers might be down.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.3
|
data/carbon.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{carbon}
|
8
|
-
s.version = "0.2.
|
8
|
+
s.version = "0.2.3"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Derek Kastner", "Seamus Abshere", "Andy Rossmeissl"]
|
12
|
-
s.date = %q{2010-07-
|
12
|
+
s.date = %q{2010-07-22}
|
13
13
|
s.description = %q{Carbon is a Ruby API wrapper for the Brighter Planet emission estimate web service (http://carbon.brighterplanet.com). By querying the web service, it can estimate the carbon emissions of many real-life objects, such as cars and houses, based on particular attributes that they may have.}
|
14
14
|
s.email = %q{derek.kastner@brighterplanet.com}
|
15
15
|
s.extra_rdoc_files = [
|
data/lib/carbon.rb
CHANGED
@@ -35,7 +35,7 @@ require 'carbon/emission_estimate'
|
|
35
35
|
# * A rental car emits carbon like an "automobile", which is one of Brighter Planet's recognized emitter classes.
|
36
36
|
# * Your implementation can provide up to three data points about a rental car: its make, its model, and its model year (but not necessarily all of them, all the time.)
|
37
37
|
#
|
38
|
-
# Once you've mixed in <tt>Carbon</tt>, you get the method <tt>
|
38
|
+
# Once you've mixed in <tt>Carbon</tt>, you get the method <tt>emission_estimate</tt>, which you can call at any time to request an emission estimate.
|
39
39
|
module Carbon
|
40
40
|
def self.included(klass) # :nodoc:
|
41
41
|
klass.cattr_accessor :carbon_base
|
@@ -73,7 +73,7 @@ module Carbon
|
|
73
73
|
self.carbon_base ||= ::Carbon::Base.new self, emitter_common_name
|
74
74
|
::Blockenspiel.invoke block, carbon_base
|
75
75
|
end
|
76
|
-
#
|
76
|
+
# Third-person singular preferred.
|
77
77
|
alias :emits_as :emit_as
|
78
78
|
end
|
79
79
|
|
@@ -82,10 +82,10 @@ module Carbon
|
|
82
82
|
# Note: please see the README about <b>exceptions that you should watch out for</b>.
|
83
83
|
#
|
84
84
|
# You can use it like a number...
|
85
|
-
# > my_car.
|
85
|
+
# > my_car.emission_estimate + 5.1
|
86
86
|
# => 415.39
|
87
87
|
# Or you can get information about the response
|
88
|
-
# > my_car.
|
88
|
+
# > my_car.emission_estimate.methodology
|
89
89
|
# => 'http://carbon.brighterplanet.com/automobiles.html?[...]'
|
90
90
|
#
|
91
91
|
# === Options:
|
@@ -99,5 +99,4 @@ module Carbon
|
|
99
99
|
@emission_estimate.take_options options
|
100
100
|
@emission_estimate
|
101
101
|
end
|
102
|
-
alias :emission :emission_estimate
|
103
102
|
end
|
data/lib/carbon/base.rb
CHANGED
@@ -6,11 +6,9 @@ module Carbon
|
|
6
6
|
#
|
7
7
|
# If you ask for a callback, on the other hand, you can't use them as numbers.
|
8
8
|
#
|
9
|
-
# So, you can just say <tt>my_car.
|
9
|
+
# So, you can just say <tt>my_car.emission_estimate.to_s</tt> and you'll get something like <tt>"4308.29"</tt>.
|
10
10
|
#
|
11
|
-
# At the same time, they contain all the data you get back from the emission estimate web service. For example, you could say <tt>puts my_donut_factor.
|
12
|
-
#
|
13
|
-
# Note: <b>you need to take care of storing emission estimates to local variables!</b> The gem doesn't cache these for you. Every time you call <tt>emission</tt> it will send another query to the server!
|
11
|
+
# At the same time, they contain all the data you get back from the emission estimate web service. For example, you could say <tt>puts my_donut_factor.emission_estimate.oven_count</tt> (see the tests) and you'd get back the oven count used in the calculation, if any.
|
14
12
|
class EmissionEstimate
|
15
13
|
def initialize(emitter)
|
16
14
|
@emitter = emitter
|
@@ -37,7 +35,7 @@ module Carbon
|
|
37
35
|
# This is useful for characteristics that are unique to an emitter.
|
38
36
|
#
|
39
37
|
# For example:
|
40
|
-
# > my_car.
|
38
|
+
# > my_car.emission_estimate.model
|
41
39
|
# => 'Ford Taurus'
|
42
40
|
def method_missing(method_id, *args, &blk)
|
43
41
|
if !block_given? and args.empty? and response.data.has_key? method_id.to_s
|
@@ -95,7 +93,7 @@ module Carbon
|
|
95
93
|
response.data['errors']
|
96
94
|
end
|
97
95
|
# The URL of the methodology report indicating how this estimate was calculated.
|
98
|
-
# > my_car.
|
96
|
+
# > my_car.emission_estimate.methodology
|
99
97
|
# => 'http://carbon.brighterplanet.com/automobiles.html?[...]'
|
100
98
|
def methodology
|
101
99
|
response.data['methodology']
|
data/spec/lib/carbon_spec.rb
CHANGED
@@ -55,8 +55,8 @@ describe Carbon do
|
|
55
55
|
c.model = 'Acura'
|
56
56
|
c.model_year = 2003
|
57
57
|
c.fuel_economy = 32
|
58
|
-
c.
|
59
|
-
c.
|
58
|
+
c.emission_estimate.should == 134.599
|
59
|
+
c.emission_estimate.emission_units.should == 'kilograms'
|
60
60
|
end
|
61
61
|
|
62
62
|
describe 'caching' do
|
@@ -65,10 +65,10 @@ describe Carbon do
|
|
65
65
|
c.model = 'Acura'
|
66
66
|
c.model_year = 2003
|
67
67
|
c.fuel_economy = 32
|
68
|
-
c.
|
69
|
-
first_raw_request = c.
|
70
|
-
c.
|
71
|
-
c.
|
68
|
+
c.emission_estimate.should == 134.599
|
69
|
+
first_raw_request = c.emission_estimate.response.raw_request
|
70
|
+
c.emission_estimate.should == 134.599
|
71
|
+
c.emission_estimate.response.raw_request.object_id.should == first_raw_request.object_id
|
72
72
|
end
|
73
73
|
|
74
74
|
it "should recalculate if parameters change" do
|
@@ -76,11 +76,11 @@ describe Carbon do
|
|
76
76
|
c.model = 'Acura'
|
77
77
|
c.model_year = 2003
|
78
78
|
c.fuel_economy = 32
|
79
|
-
c.
|
80
|
-
first_raw_request = c.
|
79
|
+
c.emission_estimate.should == 134.599
|
80
|
+
first_raw_request = c.emission_estimate.response.raw_request
|
81
81
|
c.model = 'Honda'
|
82
|
-
c.
|
83
|
-
c.
|
82
|
+
c.emission_estimate.should == 134.599
|
83
|
+
c.emission_estimate.response.raw_request.object_id.should_not == first_raw_request.object_id
|
84
84
|
end
|
85
85
|
|
86
86
|
it "should recalculate if parameters change (though the options hash)" do
|
@@ -88,19 +88,19 @@ describe Carbon do
|
|
88
88
|
c.model = 'Acura'
|
89
89
|
c.model_year = 2003
|
90
90
|
c.fuel_economy = 32
|
91
|
-
c.
|
92
|
-
first_raw_request = c.
|
93
|
-
c.
|
94
|
-
c.
|
91
|
+
c.emission_estimate.should == 134.599
|
92
|
+
first_raw_request = c.emission_estimate.response.raw_request
|
93
|
+
c.emission_estimate(:timeframe => Timeframe.new(:year => 2009)).should == 134.599
|
94
|
+
c.emission_estimate.response.raw_request.object_id.should_not == first_raw_request.object_id
|
95
95
|
end
|
96
96
|
|
97
97
|
it "should recalculate if the callback changes" do
|
98
98
|
c = RentalCar.new
|
99
99
|
c.model = 'Acura'
|
100
|
-
c.
|
101
|
-
first_raw_request = c.
|
102
|
-
c.
|
103
|
-
c.
|
100
|
+
c.emission_estimate.should == 134.599
|
101
|
+
first_raw_request = c.emission_estimate.response.raw_request
|
102
|
+
c.emission_estimate.callback = CALLBACK_URL
|
103
|
+
c.emission_estimate.response.raw_request.object_id.should_not == first_raw_request.object_id
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
@@ -108,115 +108,115 @@ describe Carbon do
|
|
108
108
|
it 'should send simple params' do
|
109
109
|
d = DonutFactory.new
|
110
110
|
d.oven_count = 12_000
|
111
|
-
d.
|
111
|
+
d.emission_estimate.request.body.should =~ /oven_count=12000/
|
112
112
|
end
|
113
113
|
|
114
114
|
it 'send complex params' do
|
115
115
|
d = DonutFactory.new
|
116
116
|
d.mixer.upc = 123
|
117
|
-
d.
|
117
|
+
d.emission_estimate.request.body.should include({:mixer => { :upc => 123 }}.to_query)
|
118
118
|
end
|
119
119
|
|
120
120
|
it 'should not send attributes that are blank' do
|
121
121
|
d = DonutFactory.new
|
122
122
|
d.mixer.upc = 123
|
123
|
-
d.
|
124
|
-
d.
|
123
|
+
d.emission_estimate.request.body.should_not =~ /oven_count/
|
124
|
+
d.emission_estimate.request.body.should_not =~ /timeframe/
|
125
125
|
end
|
126
126
|
|
127
127
|
it 'should send attributes that are false' do
|
128
128
|
d = DonutFactory.new
|
129
129
|
d.mixer.upc = false
|
130
|
-
d.
|
130
|
+
d.emission_estimate.request.body.should include({:mixer => { :upc => 'false' }}.to_query)
|
131
131
|
end
|
132
132
|
|
133
133
|
it 'should send the key' do
|
134
134
|
d = DonutFactory.new
|
135
|
-
d.
|
135
|
+
d.emission_estimate.request.body.should =~ /key=valid/
|
136
136
|
end
|
137
137
|
|
138
138
|
it 'should override defaults' do
|
139
139
|
d = DonutFactory.new
|
140
140
|
key = 'ADifferentOne'
|
141
|
-
d.
|
142
|
-
d.
|
143
|
-
d.
|
141
|
+
d.emission_estimate.key.should == 'valid'
|
142
|
+
d.emission_estimate.key = key
|
143
|
+
d.emission_estimate.key.should == key
|
144
144
|
end
|
145
145
|
|
146
146
|
it 'should accept timeframes' do
|
147
147
|
c = RentalCar.new
|
148
148
|
t = Timeframe.new(:year => 2009)
|
149
|
-
c.
|
150
|
-
c.
|
149
|
+
c.emission_estimate.timeframe = t
|
150
|
+
c.emission_estimate.request.body.should include(t.to_query(:timeframe))
|
151
151
|
end
|
152
152
|
|
153
153
|
it 'should accept timeframes inline' do
|
154
154
|
c = RentalCar.new
|
155
155
|
t = Timeframe.new(:year => 2009)
|
156
|
-
c.
|
157
|
-
c.
|
156
|
+
c.emission_estimate(:timeframe => t)
|
157
|
+
c.emission_estimate.request.body.should include(t.to_query(:timeframe))
|
158
158
|
end
|
159
159
|
|
160
160
|
it 'should read active subtimeframes back from calculations' do
|
161
161
|
c = RentalCar.new
|
162
|
-
c.
|
162
|
+
c.emission_estimate.active_subtimeframe.should == Timeframe.new(:year => 2008)
|
163
163
|
end
|
164
164
|
|
165
165
|
it 'should not generate post bodies with lots of empty params' do
|
166
166
|
c = RentalCar.new
|
167
|
-
c.
|
168
|
-
c.
|
169
|
-
c.
|
167
|
+
c.emission_estimate :timeframe => Timeframe.new(:year => 2009)
|
168
|
+
c.emission_estimate.request.body.should_not include('&&')
|
169
|
+
c.emission_estimate.request.body.should_not =~ /=[^a-z0-9]/i
|
170
170
|
end
|
171
171
|
end
|
172
172
|
|
173
173
|
describe 'asynchronous (queued) requests' do
|
174
174
|
it 'should post a message to SQS' do
|
175
175
|
c = RentalCar.new
|
176
|
-
c.
|
177
|
-
c.
|
176
|
+
c.emission_estimate.callback = CALLBACK_URL
|
177
|
+
c.emission_estimate.request.url.should =~ /queue.amazonaws.com/
|
178
178
|
end
|
179
179
|
|
180
180
|
it 'should have nil data in its response' do
|
181
181
|
c = RentalCar.new
|
182
|
-
c.
|
183
|
-
c.
|
184
|
-
c.
|
185
|
-
c.
|
182
|
+
c.emission_estimate.callback = CALLBACK_URL
|
183
|
+
c.emission_estimate.emission_value.should be_nil
|
184
|
+
c.emission_estimate.emission_units.should be_nil
|
185
|
+
c.emission_estimate.methodology.should be_nil
|
186
186
|
end
|
187
187
|
|
188
188
|
it "should not compare itself to numbers" do
|
189
189
|
c = RentalCar.new
|
190
|
-
c.
|
191
|
-
c.
|
190
|
+
c.emission_estimate.callback = CALLBACK_URL
|
191
|
+
c.emission_estimate.should_not == 0.0
|
192
192
|
end
|
193
193
|
|
194
194
|
it 'should not allow itself to be treated as a number' do
|
195
195
|
c = RentalCar.new
|
196
|
-
c.
|
196
|
+
c.emission_estimate.callback = CALLBACK_URL
|
197
197
|
lambda {
|
198
|
-
c.
|
198
|
+
c.emission_estimate + 5
|
199
199
|
}.should raise_error(::Carbon::TriedToUseAsyncResponseAsNumber)
|
200
200
|
lambda {
|
201
|
-
c.
|
201
|
+
c.emission_estimate.to_f
|
202
202
|
}.should raise_error(::Carbon::TriedToUseAsyncResponseAsNumber)
|
203
203
|
end
|
204
204
|
end
|
205
205
|
|
206
206
|
describe 'internally' do
|
207
|
-
it "should ignore invalid options passed to #
|
207
|
+
it "should ignore invalid options passed to #emission_estimate" do
|
208
208
|
c = RentalCar.new
|
209
209
|
t = Timeframe.new(:year => 2009)
|
210
|
-
c.
|
211
|
-
c.
|
212
|
-
c.
|
213
|
-
c.
|
210
|
+
c.emission_estimate :timeframe => t, :method_missing => 'helo there', :response => 'foo'
|
211
|
+
c.emission_estimate.instance_variable_get(:@timeframe).object_id.should == t.object_id
|
212
|
+
c.emission_estimate.instance_variable_get(:@method_missing).should be_nil
|
213
|
+
c.emission_estimate.instance_variable_get(:@response).should be_nil
|
214
214
|
end
|
215
215
|
|
216
216
|
it "should raise an error on EmissionEstimate if method isn't found" do
|
217
217
|
c = RentalCar.new
|
218
218
|
lambda {
|
219
|
-
c.
|
219
|
+
c.emission_estimate.foobar
|
220
220
|
}.should raise_error(NoMethodError, /EmissionEstimate/)
|
221
221
|
end
|
222
222
|
|
@@ -226,7 +226,7 @@ describe Carbon do
|
|
226
226
|
d.mixer.to_param
|
227
227
|
}.should raise_error(RuntimeError, /instead please/)
|
228
228
|
lambda {
|
229
|
-
d.
|
229
|
+
d.emission_estimate.to_f
|
230
230
|
}.should_not raise_error
|
231
231
|
end
|
232
232
|
end
|
@@ -236,7 +236,7 @@ end
|
|
236
236
|
# it 'should actually do a request!' do
|
237
237
|
# FakeWeb.clean_registry
|
238
238
|
# c = RentalCar.new
|
239
|
-
# c.
|
240
|
-
# c.
|
239
|
+
# c.emission_estimate.to_i.should be_close(5500, 500)
|
240
|
+
# c.emission_estimate.emission_units.should == 'kilograms'
|
241
241
|
# end
|
242
242
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: carbon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 17
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 0.2.
|
9
|
+
- 3
|
10
|
+
version: 0.2.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Derek Kastner
|
@@ -17,7 +17,7 @@ autorequire:
|
|
17
17
|
bindir: bin
|
18
18
|
cert_chain: []
|
19
19
|
|
20
|
-
date: 2010-07-
|
20
|
+
date: 2010-07-22 00:00:00 -05:00
|
21
21
|
default_executable:
|
22
22
|
dependencies:
|
23
23
|
- !ruby/object:Gem::Dependency
|