carbon 0.2.2 → 0.2.3
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/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
|