carbon 1.1.3 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -22
- data/CHANGELOG +11 -0
- data/Gemfile +10 -1
- data/README.markdown +185 -0
- data/Rakefile +13 -26
- data/bin/carbon +3 -3
- data/carbon.gemspec +17 -23
- data/developer_notes/MULTI.markdown +25 -0
- data/developer_notes/REDUCE_HTTP_CONNECTIONS.markdown +46 -0
- data/features/shell.feature +1 -1
- data/features/support/env.rb +3 -4
- data/lib/carbon.rb +242 -96
- data/lib/carbon/registry.rb +50 -0
- data/lib/carbon/shell.rb +14 -8
- data/lib/carbon/shell/emitter.rb +33 -29
- data/lib/carbon/version.rb +1 -1
- data/test/carbon_test.rb +167 -0
- metadata +128 -182
- data/MIT-LICENSE.txt +0 -19
- data/README.rdoc +0 -266
- data/doc/INTEGRATION_GUIDE.rdoc +0 -1002
- data/doc/examining-response-with-jsonview.png +0 -0
- data/doc/shell_example +0 -43
- data/doc/timeout-error.png +0 -0
- data/doc/with-committee-reports.png +0 -0
- data/doc/without-committee-reports.png +0 -0
- data/lib/carbon/base.rb +0 -62
- data/lib/carbon/emission_estimate.rb +0 -165
- data/lib/carbon/emission_estimate/request.rb +0 -100
- data/lib/carbon/emission_estimate/response.rb +0 -61
- data/lib/carbon/emission_estimate/storage.rb +0 -33
- data/spec/fixtures/vcr_cassettes/flight.yml +0 -47
- data/spec/fixtures/vcr_cassettes/residence.yml +0 -44
- data/spec/lib/carbon/emission_estimate/request_spec.rb +0 -41
- data/spec/lib/carbon/emission_estimate/response_spec.rb +0 -33
- data/spec/lib/carbon/emission_estimate_spec.rb +0 -32
- data/spec/lib/carbon_spec.rb +0 -384
- data/spec/spec_helper.rb +0 -60
- data/spec/specwatchr +0 -60
@@ -1,47 +0,0 @@
|
|
1
|
-
---
|
2
|
-
- !ruby/struct:VCR::HTTPInteraction
|
3
|
-
request: !ruby/struct:VCR::Request
|
4
|
-
method: :post
|
5
|
-
uri: http://carbon.brighterplanet.com:80/flights.json
|
6
|
-
body: !!null
|
7
|
-
headers:
|
8
|
-
content-type:
|
9
|
-
- application/x-www-form-urlencoded
|
10
|
-
response: !ruby/struct:VCR::Response
|
11
|
-
status: !ruby/struct:VCR::ResponseStatus
|
12
|
-
code: 200
|
13
|
-
message: OK
|
14
|
-
headers:
|
15
|
-
server:
|
16
|
-
- nginx/0.7.67
|
17
|
-
date:
|
18
|
-
- Thu, 17 Nov 2011 15:53:19 GMT
|
19
|
-
content-type:
|
20
|
-
- application/json
|
21
|
-
transfer-encoding:
|
22
|
-
- chunked
|
23
|
-
connection:
|
24
|
-
- keep-alive
|
25
|
-
status:
|
26
|
-
- 200 OK
|
27
|
-
body: ! '{"emission":1092.2723218858448,"emitter":"Flight","timeframe":"2011-01-01/2012-01-01","emission_units":"kilograms","methodology":"http://impact.brighterplanet.com/flights","execution_id":"UNSUPPORTED","scope":"The
|
28
|
-
flight greenhouse gas emission is the anthropogenic greenhouse gas emissions
|
29
|
-
attributed to a single passenger on this flight. It includes CO2 emissions from
|
30
|
-
combustion of non-biogenic fuel and extra forcing effects of high-altitude fuel
|
31
|
-
combustion.","complies":[],"errors":[],"equivalents":{"cars_off_the_road_for_a_year":0.19879356258322375,"cars_off_the_road_for_a_month":2.3833382063549133,"cars_off_the_road_for_a_week":10.327434803430663,"cars_off_the_road_for_a_day":72.48974491427597,"cars_to_priuses_for_a_year":0.3975871251664475,"cars_to_priuses_for_a_month":4.766676412709827,"cars_to_priuses_for_a_week":20.654869606861325,"cars_to_priuses_for_a_day":144.97948982855195,"one_way_domestic_flight":3.5498850461289955,"round_trip_domestic_flight":1.7749425230644977,"one_way_cross_country_flight":1.2473749915936347,"round_trip_cross_country_flight":0.6236874957968174,"vegan_meals_instead_of_non_vegan_ones":878.9373378813549,"days_of_veganism":292.97911262711824,"weeks_of_veganism":41.8536908300218,"months_of_veganism":9.766006829981338,"years_of_veganism":0.802820156586096,"barrels_of_petroleum":2.540625420706475,"canisters_of_bbq_propane":45.5117108360175,"railroad_cars_full_of_coal":0.005461361609429225,"homes_energy_in_a_year":0.10595041522292695,"homes_energy_in_a_month":1.2659436210656942,"homes_energy_in_a_week":5.484299328188827,"homes_energy_in_a_day":38.49932252951037,"homes_electricity_in_a_year":0.1605640313172192,"homes_electricity_in_a_month":1.9213070141972008,"homes_electricity_in_a_week":8.32529963741391,"homes_electricity_in_a_day":58.43547694857081,"homes_with_lowered_thermostat_2_degrees_for_a_winter":5.7333374175788,"homes_with_raised_thermostat_3_degrees_for_a_summer":2.577762679650594,"replaced_refrigerators":1.0999182281390458,"loads_of_cold_laundry":500.8745804686168,"lightbulbs_for_a_year":2.0163347062012695,"lightbulbs_for_a_month":24.537897711165503,"lightbulbs_for_a_week":105.16179460652536,"lightbulbs_for_a_day":736.1358390626432,"lightbulbs_for_an_evening":4416.816126648181,"lightbulbs_to_CFLs_for_a_day":12529.975725977742,"lightbulbs_to_CFLs_for_a_week":1789.9962202047284,"lightbulbs_to_CFLs_for_a_month":417.666367259675,"lightbulbs_to_CFLs_for_a_year":34.32902680455022,"days_with_lightbulbs_to_CFLs":278.4442448397833,"weeks_with_lightbulbs_to_CFLs":39.777281146116806,"months_with_lightbulbs_to_CFLs":9.281037919064023,"years_with_lightbulbs_to_CFLs":0.7624060806763198,"recycled_kgs_of_trash":753.2910681501824,"recycled_bags_of_trash":417.3954837238473},"reports":[{"committee":{"name":"emission"},"conclusion":{"value":1092.2723218858448,"units":"kilograms"},"quorum":{"name":"from
|
32
|
-
fuel use and greenhouse gas emission factor"}},{"committee":{"name":"ghg_emission_factor"},"conclusion":5.15214,"quorum":{"name":"from
|
33
|
-
fuel and aviation multiplier"}},{"committee":{"name":"aviation_multiplier"},"conclusion":2.0,"quorum":{"name":"default"}},{"committee":{"name":"energy"},"conclusion":{"value":7976.996543941375,"units":"megajoules"},"quorum":{"name":"from
|
34
|
-
fuel use and fuel"}},{"committee":{"name":"fuel_use"},"conclusion":212.00361828014084,"quorum":{"name":"from
|
35
|
-
fuel per segment, segments per trip, trips, freight_share, passengers, seat
|
36
|
-
class multiplier, fuel, date, and timeframe"}},{"committee":{"name":"fuel_per_segment"},"conclusion":8444.423485578423,"quorum":{"name":"from
|
37
|
-
adjusted distance per segment and fuel use coefficients"}},{"committee":{"name":"seat_class_multiplier"},"conclusion":1.0,"quorum":{"name":"default"}},{"committee":{"name":"distance_class"},"conclusion":{"flight_distance_class":{"distance":1108.0,"distance_units":"kilometres","max_distance":3700.0,"max_distance_units":"kilometres","min_distance":0.0,"min_distance_units":"kilometres","name":"short
|
38
|
-
haul"}},"quorum":{"name":"from adjusted distance per segment"}},{"committee":{"name":"adjusted_distance_per_segment"},"conclusion":952.9200693676661,"quorum":{"name":"from
|
39
|
-
adjusted distance and segments per trip"}},{"committee":{"name":"adjusted_distance"},"conclusion":1600.905716537679,"quorum":{"name":"from
|
40
|
-
distance, route inefficiency factor, and dogleg factor"}},{"committee":{"name":"distance"},"conclusion":1250.472807191592,"quorum":{"name":"default"}},{"committee":{"name":"route_inefficiency_factor"},"conclusion":1.100000023841858,"quorum":{"name":"default"}},{"committee":{"name":"dogleg_factor"},"conclusion":1.1638548181950328,"quorum":{"name":"from
|
41
|
-
segments per trip"}},{"committee":{"name":"fuel_use_coefficients"},"conclusion":{"m3":1.0627617772702186e-07,"m2":-0.0001553124677028947,"m1":7.176288726885266,"b":1655.0651026365715},"quorum":{"name":"default"}},{"committee":{"name":"fuel"},"conclusion":{"fuel":{"biogenic_fraction":0.0,"carbon_content":18.672,"carbon_content_units":"grams_per_megajoule","co2_biogenic_emission_factor":0.0,"co2_biogenic_emission_factor_units":"kilograms_per_litre","co2_emission_factor":2.57607,"co2_emission_factor_units":"kilograms_per_litre","density":0.8156,"density_units":"kilograms_per_litre","energy_content":37.6267,"energy_content_units":"megajoules_per_litre","name":"Jet
|
42
|
-
Fuel","oxidation_factor":1.0}},"quorum":{"name":"default"}},{"committee":{"name":"passengers"},"conclusion":130,"quorum":{"name":"from
|
43
|
-
seats and load factor"}},{"committee":{"name":"seats"},"conclusion":168.87079036564523,"quorum":{"name":"default"}},{"committee":{"name":"load_factor"},"conclusion":0.7706950558978438,"quorum":{"name":"default"}},{"committee":{"name":"freight_share"},"conclusion":0.06795767512927696,"quorum":{"name":"default"}},{"committee":{"name":"trips"},"conclusion":1.7,"quorum":{"name":"default"}},{"committee":{"name":"segments_per_trip"},"conclusion":1.68,"quorum":{"name":"default"}},{"committee":{"name":"date"},"conclusion":"2011-01-01","quorum":{"name":"from
|
44
|
-
timeframe"}}],"date":"2011-01-01","segments_per_trip":1.68,"trips":1.7,"freight_share":0.06795767512927696,"load_factor":0.7706950558978438,"seats":168.87079036564523,"passengers":130,"fuel":{"fuel":{"biogenic_fraction":0.0,"carbon_content":18.672,"carbon_content_units":"grams_per_megajoule","co2_biogenic_emission_factor":0.0,"co2_biogenic_emission_factor_units":"kilograms_per_litre","co2_emission_factor":2.57607,"co2_emission_factor_units":"kilograms_per_litre","density":0.8156,"density_units":"kilograms_per_litre","energy_content":37.6267,"energy_content_units":"megajoules_per_litre","name":"Jet
|
45
|
-
Fuel","oxidation_factor":1.0}},"fuel_use_coefficients":{"m3":1.0627617772702186e-07,"m2":-0.0001553124677028947,"m1":7.176288726885266,"b":1655.0651026365715},"dogleg_factor":1.1638548181950328,"route_inefficiency_factor":1.100000023841858,"distance":1250.472807191592,"adjusted_distance":1600.905716537679,"adjusted_distance_per_segment":952.9200693676661,"distance_class":{"flight_distance_class":{"distance":1108.0,"distance_units":"kilometres","max_distance":3700.0,"max_distance_units":"kilometres","min_distance":0.0,"min_distance_units":"kilometres","name":"short
|
46
|
-
haul"}},"seat_class_multiplier":1.0,"fuel_per_segment":8444.423485578423,"fuel_use":212.00361828014084,"energy":{"value":7976.996543941375,"units":"megajoules"},"aviation_multiplier":2.0,"ghg_emission_factor":5.15214,"carbon":{"value":1092.2723218858448,"units":"kilograms"}}'
|
47
|
-
http_version: '1.1'
|
@@ -1,44 +0,0 @@
|
|
1
|
-
---
|
2
|
-
- !ruby/struct:VCR::HTTPInteraction
|
3
|
-
request: !ruby/struct:VCR::Request
|
4
|
-
method: :post
|
5
|
-
uri: http://carbon.brighterplanet.com:80/residences.json
|
6
|
-
body: !!null
|
7
|
-
headers:
|
8
|
-
content-type:
|
9
|
-
- application/x-www-form-urlencoded
|
10
|
-
response: !ruby/struct:VCR::Response
|
11
|
-
status: !ruby/struct:VCR::ResponseStatus
|
12
|
-
code: 200
|
13
|
-
message: OK
|
14
|
-
headers:
|
15
|
-
server:
|
16
|
-
- nginx/0.7.67
|
17
|
-
date:
|
18
|
-
- Thu, 17 Nov 2011 16:06:52 GMT
|
19
|
-
content-type:
|
20
|
-
- application/json
|
21
|
-
transfer-encoding:
|
22
|
-
- chunked
|
23
|
-
connection:
|
24
|
-
- keep-alive
|
25
|
-
status:
|
26
|
-
- 200 OK
|
27
|
-
body: ! '{"emission":3913.377091407546,"emitter":"Residence","timeframe":"2011-01-01/2012-01-01","emission_units":"kilograms","methodology":"http://impact.brighterplanet.com/residences","execution_id":"UNSUPPORTED","scope":null,"complies":[],"errors":[],"equivalents":{"cars_off_the_road_for_a_year":0.7122346306361733,"cars_off_the_road_for_a_month":8.538988813451265,"cars_off_the_road_for_a_week":37.000980399258346,"cars_off_the_road_for_a_day":259.71518404835314,"cars_to_priuses_for_a_year":1.4244692612723466,"cars_to_priuses_for_a_month":17.07797762690253,"cars_to_priuses_for_a_week":74.00196079851669,"cars_to_priuses_for_a_day":519.4303680967063,"one_way_domestic_flight":12.718475547074522,"round_trip_domestic_flight":6.359237773537261,"one_way_cross_country_flight":4.469076638387417,"round_trip_cross_country_flight":2.2345383191937085,"vegan_meals_instead_of_non_vegan_ones":3149.043671553464,"days_of_veganism":1049.6812238511545,"weeks_of_veganism":149.95278338855434,"months_of_veganism":34.98950457427486,"years_of_veganism":2.876332162184546,"barrels_of_petroleum":9.10251511461395,"canisters_of_bbq_propane":163.05868326767822,"railroad_cars_full_of_coal":0.01956688545703773,"homes_energy_in_a_year":0.3795975778665319,"homes_energy_in_a_month":4.535604048941346,"homes_energy_in_a_week":19.64906637595729,"homes_energy_in_a_day":137.93480234084177,"homes_electricity_in_a_year":0.5752664324369092,"homes_electricity_in_a_month":6.883630303785873,"homes_electricity_in_a_week":29.827760190708315,"homes_electricity_in_a_day":209.3617610132123,"homes_with_lowered_thermostat_2_degrees_for_a_winter":20.54131635279821,"homes_with_raised_thermostat_3_degrees_for_a_summer":9.23556993572181,"replaced_refrigerators":3.9407707310473987,"loads_of_cold_laundry":1794.526025790027,"lightbulbs_for_a_year":7.22409411073833,"lightbulbs_for_a_month":87.9140163584705,"lightbulbs_for_a_week":376.7721196065357,"lightbulbs_for_a_day":2637.416577377024,"lightbulbs_for_an_evening":15824.503377639234,"lightbulbs_to_CFLs_for_a_day":44892.21138303146,"lightbulbs_to_CFLs_for_a_week":6413.17193661104,"lightbulbs_to_CFLs_for_a_month":1496.4088723436914,"lightbulbs_to_CFLs_for_a_year":122.99352860584776,"days_with_lightbulbs_to_CFLs":997.6059148957943,"weeks_with_lightbulbs_to_CFLs":142.5134535377886,"months_with_lightbulbs_to_CFLs":33.251965145689915,"years_with_lightbulbs_to_CFLs":2.7315372098024673,"recycled_kgs_of_trash":2698.880077974671,"recycled_bags_of_trash":1495.4383548250225},"reports":[{"committee":{"name":"emission"},"conclusion":{"value":3913.377091407546,"units":"kilograms"},"quorum":{"name":"from
|
28
|
-
fuel and electricity use and occupation and residents"}},{"committee":{"name":"fuel_oil_consumed"},"conclusion":199.07480656200002,"quorum":{"name":"from
|
29
|
-
research"}},{"committee":{"name":"natural_gas_consumed"},"conclusion":42683876171.345726,"quorum":{"name":"from
|
30
|
-
research"}},{"committee":{"name":"propane_consumed"},"conclusion":183.25178523799994,"quorum":{"name":"from
|
31
|
-
research"}},{"committee":{"name":"biomass_consumed"},"conclusion":3798201078.0000005,"quorum":{"name":"from
|
32
|
-
research"}},{"committee":{"name":"kerosene_consumed"},"conclusion":4.050390626,"quorum":{"name":"from
|
33
|
-
research"}},{"committee":{"name":"coal_consumed"},"conclusion":2.871239704507795,"quorum":{"name":"from
|
34
|
-
research"}},{"committee":{"name":"dirty_electricity_generated"},"conclusion":11462.092843034108,"quorum":{"name":"from
|
35
|
-
electricity generated and green electricity"}},{"committee":{"name":"green_electricity"},"conclusion":0.0,"quorum":{"name":"default"}},{"committee":{"name":"electricity_generated"},"conclusion":11462.092843034108,"quorum":{"name":"from
|
36
|
-
electricity used and loss rate"}},{"committee":{"name":"electricity_used"},"conclusion":10752.83,"quorum":{"name":"from
|
37
|
-
research"}},{"committee":{"name":"missing_annual_energy"},"conclusion":0,"quorum":{"name":"from
|
38
|
-
fuel reports"}},{"committee":{"name":"electricity_loss_rate"},"conclusion":0.061879,"quorum":{"name":"default"}},{"committee":{"name":"electricity_emission_factor"},"conclusion":0.6060757767293904,"quorum":{"name":"default"}},{"committee":{"name":"occupation"},"conclusion":0.937,"quorum":{"name":"default"}},{"committee":{"name":"residents"},"conclusion":2.57,"quorum":{"name":"default"}},{"committee":{"name":"air_conditioner_use"},"conclusion":{"air_conditioner_use":{"fugitive_emission":0.4994479354338,"fugitive_emission_units":"kilograms_per_square_metre"}},"quorum":{"name":"default"}},{"committee":{"name":"predicted_fuel_shares"},"conclusion":{"fuel_oil":0.41679323558325115,"natural_gas":0.1613371881024962,"propane":0.25265921858930535,"kerosene":0.008254483221570639,"biomass":0.014356500316711278,"coal":0.0002819952830220514,"electricity":0.14631737890364346},"quorum":{"name":"from
|
39
|
-
research"}},{"committee":{"name":"predicted_annual_energy_consumption"},"conclusion":264563159141.1461,"quorum":{"name":"from
|
40
|
-
research"}},{"committee":{"name":"predicted_annual_fuel_oil_consumption"},"conclusion":199.07480656200002,"quorum":{"name":"default"}},{"committee":{"name":"predicted_annual_natural_gas_consumption"},"conclusion":42683876171.345726,"quorum":{"name":"default"}},{"committee":{"name":"predicted_annual_propane_consumption"},"conclusion":183.25178523799997,"quorum":{"name":"default"}},{"committee":{"name":"predicted_annual_kerosene_consumption"},"conclusion":4.050390626,"quorum":{"name":"default"}},{"committee":{"name":"predicted_annual_biomass_consumption"},"conclusion":3798201078.0,"quorum":{"name":"default"}},{"committee":{"name":"predicted_annual_coal_consumption"},"conclusion":2.871239704507795,"quorum":{"name":"default"}},{"committee":{"name":"predicted_annual_electricity_use"},"conclusion":10752.83,"quorum":{"name":"default"}},{"committee":{"name":"active_subtimeframe"},"conclusion":{"startDate":"2011-01-01","endDate":"2012-01-01"},"quorum":{"name":"from
|
41
|
-
acquisition and retirement"}},{"committee":{"name":"acquisition"},"conclusion":"2011-01-01","quorum":{"name":"from
|
42
|
-
retirement"}},{"committee":{"name":"retirement"},"conclusion":"2012-01-01","quorum":{"name":"from
|
43
|
-
acquisition"}},{"committee":{"name":"floorspace_estimate"},"conclusion":214.47688717440002,"quorum":{"name":"default"}}],"floorspace_estimate":214.47688717440002,"retirement":"2012-01-01","acquisition":"2011-01-01","active_subtimeframe":{"startDate":"2011-01-01","endDate":"2012-01-01"},"predicted_annual_electricity_use":10752.83,"predicted_annual_coal_consumption":2.871239704507795,"predicted_annual_biomass_consumption":3798201078.0,"predicted_annual_kerosene_consumption":4.050390626,"predicted_annual_propane_consumption":183.25178523799997,"predicted_annual_natural_gas_consumption":42683876171.345726,"predicted_annual_fuel_oil_consumption":199.07480656200002,"predicted_annual_energy_consumption":264563159141.1461,"predicted_fuel_shares":{"fuel_oil":0.41679323558325115,"natural_gas":0.1613371881024962,"propane":0.25265921858930535,"kerosene":0.008254483221570639,"biomass":0.014356500316711278,"coal":0.0002819952830220514,"electricity":0.14631737890364346},"air_conditioner_use":{"air_conditioner_use":{"fugitive_emission":0.4994479354338,"fugitive_emission_units":"kilograms_per_square_metre"}},"residents":2.57,"occupation":0.937,"electricity_emission_factor":0.6060757767293904,"electricity_loss_rate":0.061879,"missing_annual_energy":0,"electricity_used":10752.83,"electricity_generated":11462.092843034108,"green_electricity":0.0,"dirty_electricity_generated":11462.092843034108,"coal_consumed":2.871239704507795,"kerosene_consumed":4.050390626,"biomass_consumed":3798201078.0000005,"propane_consumed":183.25178523799994,"natural_gas_consumed":42683876171.345726,"fuel_oil_consumed":199.07480656200002,"carbon":{"value":3913.377091407546,"units":"kilograms"}}'
|
44
|
-
http_version: '1.1'
|
@@ -1,41 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Carbon::EmissionEstimate::Request do
|
4
|
-
let(:emitter) do
|
5
|
-
mock Object,
|
6
|
-
:class => mock(Object,
|
7
|
-
:carbon_base => mock(Object,
|
8
|
-
:emitter_common_name => 'dirigible',
|
9
|
-
:translation_table => []))
|
10
|
-
end
|
11
|
-
let(:emission_estimate) { Carbon::EmissionEstimate.new emitter }
|
12
|
-
let(:request) { Carbon::EmissionEstimate::Request.new emission_estimate }
|
13
|
-
|
14
|
-
describe '#params' do
|
15
|
-
it 'returns a hash of params' do
|
16
|
-
request.params.should be_a_kind_of(Hash)
|
17
|
-
end
|
18
|
-
it 'validates the params' do
|
19
|
-
request.should_receive :validate
|
20
|
-
request.params
|
21
|
-
end
|
22
|
-
it 'includes compliance' do
|
23
|
-
emission_estimate.comply = :iso
|
24
|
-
request.params.should include(:comply => :iso)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
describe '#validate' do
|
29
|
-
it 'warns the user if no key is given' do
|
30
|
-
Carbon.should_receive :warn
|
31
|
-
request.validate({})
|
32
|
-
end
|
33
|
-
it 'does nothing if all parameters are OK' do
|
34
|
-
Carbon.should_not_receive :warn
|
35
|
-
request.validate(
|
36
|
-
:key => 'ABC123'
|
37
|
-
)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
@@ -1,33 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Carbon::EmissionEstimate::Response do
|
4
|
-
let(:parent) { mock(Object, :mode => :realtime) }
|
5
|
-
let(:response) { Carbon::EmissionEstimate::Response.new parent }
|
6
|
-
let(:rest_response) { mock(Object, :success? => true, :status_code => 200,
|
7
|
-
:body => 'OK') }
|
8
|
-
|
9
|
-
describe '#load_realtime_data' do
|
10
|
-
before do
|
11
|
-
::Carbon::EmissionEstimate.stub! :parse
|
12
|
-
response.stub! :sleep
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'should retry a request that is rate limited' do
|
16
|
-
response.should_receive(:perform).once.ordered.
|
17
|
-
and_raise ::Carbon::RateLimited
|
18
|
-
response.should_receive(:perform).once.ordered.
|
19
|
-
and_return rest_response
|
20
|
-
|
21
|
-
response.send :load_realtime_data
|
22
|
-
end
|
23
|
-
|
24
|
-
it 'should not rescue from generic network errors' do
|
25
|
-
response.should_receive(:perform).once.ordered.
|
26
|
-
and_raise EOFError
|
27
|
-
|
28
|
-
lambda {
|
29
|
-
response.send :load_realtime_data
|
30
|
-
}.should raise_error EOFError
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
@@ -1,32 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'uri'
|
3
|
-
|
4
|
-
describe Carbon::EmissionEstimate do
|
5
|
-
describe '.parse' do
|
6
|
-
it 'parses a standard CM1 response' do
|
7
|
-
response = nil
|
8
|
-
VCR.use_cassette('flight', :record => :once) do
|
9
|
-
response = Net::HTTP.post_form(URI('http://carbon.brighterplanet.com/flights.json'), {})
|
10
|
-
end
|
11
|
-
estimate = Carbon::EmissionEstimate.parse response.body
|
12
|
-
estimate['emission'].should > 0
|
13
|
-
end
|
14
|
-
it 'parses a CM1 response with an active_subtimeframe' do
|
15
|
-
response = nil
|
16
|
-
VCR.use_cassette('residence', :record => :once) do
|
17
|
-
response = Net::HTTP.post_form(URI('http://carbon.brighterplanet.com/residences.json'), {})
|
18
|
-
end
|
19
|
-
estimate = Carbon::EmissionEstimate.parse response.body
|
20
|
-
estimate['active_subtimeframe'].should be_a(Timeframe)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
describe '#take_options' do
|
25
|
-
it 'accepts the :comply option' do
|
26
|
-
estimate = Carbon::EmissionEstimate.new(RentalCar.new)
|
27
|
-
estimate.take_options :comply => :iso
|
28
|
-
estimate.comply.should == :iso
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
data/spec/lib/carbon_spec.rb
DELETED
@@ -1,384 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
CALLBACK_URL = 'http://www.postbin.org/1dj0146'
|
4
|
-
KEY = 'valid'
|
5
|
-
EXISTING_UNIQUE_ID = 'oisjoaioijodijaosijdoias'
|
6
|
-
MISSING_UNIQUE_ID = 'd09joijdoijaloijdoais'
|
7
|
-
OTHER_UNIQUE_ID = '1092fjoid;oijsao;ga'
|
8
|
-
|
9
|
-
FakeWeb.register_uri :post,
|
10
|
-
%r{http://carbon.brighterplanet.com/automobile_trips},
|
11
|
-
:status => ["200", "OK"],
|
12
|
-
:body => {
|
13
|
-
'emission' => '134.599',
|
14
|
-
'emission_units' => 'kilograms',
|
15
|
-
'methodology' => 'http://carbon.brighterplanet.com/something',
|
16
|
-
'active_subtimeframe' => Timeframe.new(:year => 2008)
|
17
|
-
}.to_json
|
18
|
-
#
|
19
|
-
FakeWeb.register_uri :post,
|
20
|
-
%r{http://certified.carbon.brighterplanet.com/automobile_trips},
|
21
|
-
:status => ["200", "OK"],
|
22
|
-
:body => {
|
23
|
-
'emission' => '54321',
|
24
|
-
'emission_units' => 'kilograms',
|
25
|
-
'methodology' => 'http://certified.carbon.brighterplanet.com/something',
|
26
|
-
'active_subtimeframe' => Timeframe.new(:year => 2008)
|
27
|
-
}.to_json
|
28
|
-
#
|
29
|
-
FakeWeb.register_uri :post,
|
30
|
-
/carbon.brighterplanet.com.factories/,
|
31
|
-
:status => ["200", "OK"],
|
32
|
-
:body => {
|
33
|
-
'emission' => 1000.0,
|
34
|
-
'emission_units' => 'kilograms',
|
35
|
-
'methodology' => 'http://carbon.brighterplanet.com/something',
|
36
|
-
'active_subtimeframe' => Timeframe.new(:year => 2008)
|
37
|
-
}.to_json
|
38
|
-
#
|
39
|
-
FakeWeb.register_uri :post,
|
40
|
-
/queue.amazonaws.com/,
|
41
|
-
:status => ["200", "OK"],
|
42
|
-
:body => 'You would see an amazon aws response'
|
43
|
-
# yep, it's stored!
|
44
|
-
FakeWeb.register_uri :get,
|
45
|
-
"http://storage.carbon.brighterplanet.com/#{Digest::SHA1.hexdigest(KEY+EXISTING_UNIQUE_ID)}",
|
46
|
-
:status => ["200", "OK"],
|
47
|
-
:body => {
|
48
|
-
'emission' => 1234,
|
49
|
-
'emission_units' => 'kilograms',
|
50
|
-
'methodology' => 'http://carbon.brighterplanet.com/something',
|
51
|
-
'updated_at' => Time.now.as_json
|
52
|
-
}.to_json
|
53
|
-
#
|
54
|
-
FakeWeb.register_uri :get,
|
55
|
-
"http://storage.carbon.brighterplanet.com/#{Digest::SHA1.hexdigest(KEY+OTHER_UNIQUE_ID)}",
|
56
|
-
:status => ["200", "OK"],
|
57
|
-
:body => {
|
58
|
-
'emission' => 99982,
|
59
|
-
'emission_units' => 'kilograms',
|
60
|
-
'methodology' => 'http://carbon.brighterplanet.com/something',
|
61
|
-
'updated_at' => Time.now.as_json
|
62
|
-
}.to_json
|
63
|
-
#
|
64
|
-
FakeWeb.register_uri :get,
|
65
|
-
"http://storage.carbon.brighterplanet.com/#{Digest::SHA1.hexdigest(KEY+MISSING_UNIQUE_ID)}",
|
66
|
-
[
|
67
|
-
{
|
68
|
-
:status => ["404", "Not Found"],
|
69
|
-
:body => "It's not here, you better ask carbon for it!"
|
70
|
-
},
|
71
|
-
{
|
72
|
-
:status => ["200", "OK"],
|
73
|
-
:body => {
|
74
|
-
'emission' => 9876,
|
75
|
-
'emission_units' => 'kilograms',
|
76
|
-
'methodology' => 'http://carbon.brighterplanet.com/something',
|
77
|
-
'updated_at' => Time.now.as_json
|
78
|
-
}.to_json
|
79
|
-
}
|
80
|
-
]
|
81
|
-
#
|
82
|
-
# FakeWeb.register_uri :post,
|
83
|
-
# /carbon.brighterplanet.com.*#{MISSING_UNIQUE_ID}/,
|
84
|
-
# :status => ["302", "Moved Permanently"],
|
85
|
-
# :body => {
|
86
|
-
# 'emission' => 9876,
|
87
|
-
# 'emission_units' => 'kilograms',
|
88
|
-
# 'methodology' => 'http://carbon.brighterplanet.com/something'
|
89
|
-
# }.to_json,
|
90
|
-
# :headers => { 'Location' => "http://storage.carbon.brighterplanet.com/#{Digest::SHA1.hexdigest(KEY+MISSING_UNIQUE_ID)}" }
|
91
|
-
|
92
|
-
|
93
|
-
# set up timeouts
|
94
|
-
module Carbon
|
95
|
-
class EmissionEstimate
|
96
|
-
attr_accessor :sleep_before_performing
|
97
|
-
VALID_OPTIONS.push :sleep_before_performing
|
98
|
-
class Response
|
99
|
-
def perform_request_with_delay
|
100
|
-
sleep parent.sleep_before_performing if parent.sleep_before_performing
|
101
|
-
perform_request_without_delay
|
102
|
-
end
|
103
|
-
alias_method_chain :perform_request, :delay
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
describe Carbon do
|
109
|
-
before(:each) do
|
110
|
-
Carbon.key = KEY
|
111
|
-
end
|
112
|
-
|
113
|
-
it 'should be simple to use' do
|
114
|
-
c = RentalCar.new
|
115
|
-
c.model = 'Acura'
|
116
|
-
c.model_year = 2003
|
117
|
-
c.fuel_economy = 32
|
118
|
-
c.emission_estimate.should == 134.599
|
119
|
-
c.emission_estimate.emission_units.should == 'kilograms'
|
120
|
-
end
|
121
|
-
|
122
|
-
describe 'caching' do
|
123
|
-
it "should keep around estimates if the parameters don't change" do
|
124
|
-
c = RentalCar.new
|
125
|
-
c.model = 'Acura'
|
126
|
-
c.model_year = 2003
|
127
|
-
c.fuel_economy = 32
|
128
|
-
c.emission_estimate.should == 134.599
|
129
|
-
first_raw_request = c.emission_estimate.response.raw_request
|
130
|
-
c.emission_estimate.should == 134.599
|
131
|
-
c.emission_estimate.response.raw_request.object_id.should == first_raw_request.object_id
|
132
|
-
end
|
133
|
-
|
134
|
-
it "should recalculate if parameters change" do
|
135
|
-
c = RentalCar.new
|
136
|
-
c.model = 'Acura'
|
137
|
-
c.model_year = 2003
|
138
|
-
c.fuel_economy = 32
|
139
|
-
c.emission_estimate.should == 134.599
|
140
|
-
first_raw_request = c.emission_estimate.response.raw_request
|
141
|
-
c.model = 'Honda'
|
142
|
-
c.emission_estimate.should == 134.599
|
143
|
-
c.emission_estimate.response.raw_request.object_id.should_not == first_raw_request.object_id
|
144
|
-
end
|
145
|
-
|
146
|
-
it "should recalculate if parameters change (though the options hash)" do
|
147
|
-
c = RentalCar.new
|
148
|
-
c.model = 'Acura'
|
149
|
-
c.model_year = 2003
|
150
|
-
c.fuel_economy = 32
|
151
|
-
c.emission_estimate.should == 134.599
|
152
|
-
first_raw_request = c.emission_estimate.response.raw_request
|
153
|
-
c.emission_estimate(:timeframe => Timeframe.new(:year => 2009)).should == 134.599
|
154
|
-
c.emission_estimate.response.raw_request.object_id.should_not == first_raw_request.object_id
|
155
|
-
end
|
156
|
-
|
157
|
-
it "should recalculate if the callback changes" do
|
158
|
-
c = RentalCar.new
|
159
|
-
c.model = 'Acura'
|
160
|
-
c.emission_estimate.should == 134.599
|
161
|
-
first_raw_request = c.emission_estimate.response.raw_request
|
162
|
-
c.emission_estimate.callback = CALLBACK_URL
|
163
|
-
c.emission_estimate.response.raw_request.object_id.should_not == first_raw_request.object_id
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
describe 'requests that can be stored (cached) by guid' do
|
168
|
-
it 'should find existing unique ids on S3' do
|
169
|
-
d = DonutFactory.new
|
170
|
-
d.emission_estimate(:guid => EXISTING_UNIQUE_ID).should == 1234
|
171
|
-
d.emission_estimate(:guid => EXISTING_UNIQUE_ID).updated_at.should be_instance_of(Time)
|
172
|
-
end
|
173
|
-
it "should pass through to realtime if unique id isn't found on S3" do
|
174
|
-
d = DonutFactory.new
|
175
|
-
d.emission_estimate(:guid => MISSING_UNIQUE_ID).should == 1000
|
176
|
-
d.emission_estimate(:guid => MISSING_UNIQUE_ID).response.data.keys.should_not include('updated_at')
|
177
|
-
d1 = DonutFactory.new
|
178
|
-
d1.emission_estimate(:guid => MISSING_UNIQUE_ID).should == 9876
|
179
|
-
d1.emission_estimate(:guid => MISSING_UNIQUE_ID).updated_at.should be_instance_of(Time)
|
180
|
-
end
|
181
|
-
it "should depend on the user to update the guid if they want a new estimate" do
|
182
|
-
d = DonutFactory.new
|
183
|
-
d.oven_count = 12_000
|
184
|
-
str1 = d.emission_estimate(:guid => EXISTING_UNIQUE_ID).methodology
|
185
|
-
str1.should equal(d.emission_estimate(:guid => EXISTING_UNIQUE_ID).methodology)
|
186
|
-
d.oven_count = 13_000
|
187
|
-
str1.should equal(d.emission_estimate(:guid => EXISTING_UNIQUE_ID).methodology)
|
188
|
-
str1.should_not equal(d.emission_estimate(:guid => OTHER_UNIQUE_ID).methodology)
|
189
|
-
end
|
190
|
-
it 'should be deferrable for use in 2-pass reporting systems' do
|
191
|
-
d = DonutFactory.new
|
192
|
-
d.emission_estimate(:guid => EXISTING_UNIQUE_ID, :defer => true).number.should be_nil
|
193
|
-
d.emission_estimate(:guid => EXISTING_UNIQUE_ID, :defer => true).request.url.should =~ /amazonaws/
|
194
|
-
end
|
195
|
-
it 'should complain if you provide defer but not guid' do
|
196
|
-
d = DonutFactory.new
|
197
|
-
lambda {
|
198
|
-
d.emission_estimate(:defer => true).request.params
|
199
|
-
}.should raise_error(ArgumentError, /defer.*guid/i)
|
200
|
-
end
|
201
|
-
it 'should complain if you provide guid and callback' do
|
202
|
-
d = DonutFactory.new
|
203
|
-
lambda {
|
204
|
-
d.emission_estimate(:defer => true, :callback => 'foobar').request.params
|
205
|
-
}.should raise_error(ArgumentError, /callback.*defer/i)
|
206
|
-
end
|
207
|
-
it 'should send guid along with other parameters when queueing up deferred request' do
|
208
|
-
d = DonutFactory.new
|
209
|
-
d.emission_estimate(:guid => EXISTING_UNIQUE_ID, :defer => true).request.params[:MessageBody].should =~ /#{EXISTING_UNIQUE_ID.to_query(:guid)}/
|
210
|
-
end
|
211
|
-
end
|
212
|
-
|
213
|
-
describe 'synchronous (realtime) requests' do
|
214
|
-
it 'should send simple params' do
|
215
|
-
d = DonutFactory.new
|
216
|
-
d.oven_count = 12_000
|
217
|
-
d.emission_estimate.request.body.should =~ /oven_count=12000/
|
218
|
-
end
|
219
|
-
|
220
|
-
it 'send complex params' do
|
221
|
-
d = DonutFactory.new
|
222
|
-
d.mixer.upc = 123
|
223
|
-
d.emission_estimate.request.body.should include({:mixer => { :upc => 123 }}.to_query)
|
224
|
-
end
|
225
|
-
|
226
|
-
it 'should not send attributes that are blank' do
|
227
|
-
d = DonutFactory.new
|
228
|
-
d.mixer.upc = 123
|
229
|
-
d.emission_estimate.request.body.should_not =~ /oven_count/
|
230
|
-
d.emission_estimate.request.body.should_not =~ /timeframe/
|
231
|
-
end
|
232
|
-
|
233
|
-
it 'should send attributes that are false' do
|
234
|
-
d = DonutFactory.new
|
235
|
-
d.mixer.upc = false
|
236
|
-
d.emission_estimate.request.body.should include({:mixer => { :upc => 'false' }}.to_query)
|
237
|
-
end
|
238
|
-
|
239
|
-
it 'should send the key' do
|
240
|
-
d = DonutFactory.new
|
241
|
-
d.emission_estimate.request.body.should =~ /key=valid/
|
242
|
-
end
|
243
|
-
|
244
|
-
it 'should override defaults' do
|
245
|
-
d = DonutFactory.new
|
246
|
-
key = 'ADifferentOne'
|
247
|
-
d.emission_estimate.key.should == KEY
|
248
|
-
d.emission_estimate.key = key
|
249
|
-
d.emission_estimate.key.should == key
|
250
|
-
end
|
251
|
-
|
252
|
-
it 'should accept timeouts' do
|
253
|
-
d = DonutFactory.new
|
254
|
-
lambda {
|
255
|
-
d.emission_estimate(:sleep_before_performing => 2, :timeout => 1).to_f
|
256
|
-
}.should raise_error(::Timeout::Error)
|
257
|
-
end
|
258
|
-
|
259
|
-
it 'should accept timeframes' do
|
260
|
-
c = RentalCar.new
|
261
|
-
t = Timeframe.new(:year => 2009)
|
262
|
-
c.emission_estimate.timeframe = t
|
263
|
-
c.emission_estimate.request.body.should include(t.to_query(:timeframe))
|
264
|
-
end
|
265
|
-
|
266
|
-
it 'should accept timeframes inline' do
|
267
|
-
c = RentalCar.new
|
268
|
-
t = Timeframe.new(:year => 2009)
|
269
|
-
c.emission_estimate(:timeframe => t)
|
270
|
-
c.emission_estimate.request.body.should include(t.to_query(:timeframe))
|
271
|
-
end
|
272
|
-
|
273
|
-
it 'should read active subtimeframes back from calculations' do
|
274
|
-
c = RentalCar.new
|
275
|
-
c.emission_estimate.active_subtimeframe.should == Timeframe.new(:year => 2008)
|
276
|
-
end
|
277
|
-
|
278
|
-
it 'should not generate post bodies with lots of empty params' do
|
279
|
-
c = RentalCar.new
|
280
|
-
c.emission_estimate :timeframe => Timeframe.new(:year => 2009)
|
281
|
-
c.emission_estimate.request.body.should_not include('&&')
|
282
|
-
c.emission_estimate.request.body.should_not =~ /=[^a-z0-9]/i
|
283
|
-
end
|
284
|
-
|
285
|
-
it 'should do certified calculations' do
|
286
|
-
c = RentalCar.new
|
287
|
-
c.emission_estimate.certified = true
|
288
|
-
c.emission_estimate.should == 54321
|
289
|
-
end
|
290
|
-
|
291
|
-
it 'should do certified calculations (inline)' do
|
292
|
-
c = RentalCar.new
|
293
|
-
c.emission_estimate(:certified => true).should == 54321
|
294
|
-
end
|
295
|
-
|
296
|
-
it 'complies to given standards' do
|
297
|
-
c = RentalCar.new
|
298
|
-
c.emission_estimate(:comply => :iso).request.body.should =~ /comply=iso/
|
299
|
-
end
|
300
|
-
end
|
301
|
-
|
302
|
-
describe 'asynchronous (queued) requests' do
|
303
|
-
it 'should post a message to SQS' do
|
304
|
-
c = RentalCar.new
|
305
|
-
c.emission_estimate.callback = CALLBACK_URL
|
306
|
-
c.emission_estimate.request.url.should =~ /queue.amazonaws.com/
|
307
|
-
end
|
308
|
-
|
309
|
-
it 'should default to non-certified' do
|
310
|
-
c = RentalCar.new
|
311
|
-
c.emission_estimate.callback = CALLBACK_URL
|
312
|
-
c.emission_estimate.request.url.should_not =~ /certified/
|
313
|
-
end
|
314
|
-
|
315
|
-
it 'should accept certified' do
|
316
|
-
c = RentalCar.new
|
317
|
-
c.emission_estimate.callback = CALLBACK_URL
|
318
|
-
c.emission_estimate.certified = true
|
319
|
-
c.emission_estimate.request.url.should =~ /certified/
|
320
|
-
end
|
321
|
-
|
322
|
-
it 'should have nil data in its response' do
|
323
|
-
c = RentalCar.new
|
324
|
-
c.emission_estimate.callback = CALLBACK_URL
|
325
|
-
c.emission_estimate.number.should be_nil
|
326
|
-
c.emission_estimate.emission_units.should be_nil
|
327
|
-
c.emission_estimate.methodology.should be_nil
|
328
|
-
end
|
329
|
-
|
330
|
-
it "should not compare itself to numbers" do
|
331
|
-
c = RentalCar.new
|
332
|
-
c.emission_estimate.callback = CALLBACK_URL
|
333
|
-
c.emission_estimate.should_not == 0.0
|
334
|
-
end
|
335
|
-
|
336
|
-
it 'should not allow itself to be treated as a number' do
|
337
|
-
c = RentalCar.new
|
338
|
-
c.emission_estimate.callback = CALLBACK_URL
|
339
|
-
lambda {
|
340
|
-
c.emission_estimate + 5
|
341
|
-
}.should raise_error(::Carbon::TriedToUseAsyncResponseAsNumber)
|
342
|
-
lambda {
|
343
|
-
c.emission_estimate.to_f
|
344
|
-
}.should raise_error(::Carbon::TriedToUseAsyncResponseAsNumber)
|
345
|
-
end
|
346
|
-
end
|
347
|
-
|
348
|
-
describe 'internally' do
|
349
|
-
it "should ignore invalid options passed to #emission_estimate" do
|
350
|
-
c = RentalCar.new
|
351
|
-
t = Timeframe.new(:year => 2009)
|
352
|
-
c.emission_estimate :timeframe => t, :method_missing => 'helo there', :response => 'foo'
|
353
|
-
c.emission_estimate.instance_variable_get(:@timeframe).object_id.should == t.object_id
|
354
|
-
c.emission_estimate.instance_variable_get(:@method_missing).should be_nil
|
355
|
-
c.emission_estimate.instance_variable_get(:@response).should be_nil
|
356
|
-
end
|
357
|
-
|
358
|
-
it "should raise an error on EmissionEstimate if method isn't found" do
|
359
|
-
c = RentalCar.new
|
360
|
-
lambda {
|
361
|
-
c.emission_estimate.foobar
|
362
|
-
}.should raise_error(NoMethodError, /EmissionEstimate/)
|
363
|
-
end
|
364
|
-
|
365
|
-
it "should use #to_characteristic instead of #to_param if it's available" do
|
366
|
-
d = DonutFactory.new
|
367
|
-
lambda {
|
368
|
-
d.mixer.to_param
|
369
|
-
}.should raise_error(RuntimeError, /instead please/)
|
370
|
-
lambda {
|
371
|
-
d.emission_estimate.to_f
|
372
|
-
}.should_not raise_error
|
373
|
-
end
|
374
|
-
end
|
375
|
-
end
|
376
|
-
|
377
|
-
# an average car emits 6 tons of carbon in a year
|
378
|
-
# it 'should actually do a request!' do
|
379
|
-
# FakeWeb.clean_registry
|
380
|
-
# c = RentalCar.new
|
381
|
-
# c.emission_estimate.to_i.should be_close(5500, 500)
|
382
|
-
# c.emission_estimate.emission_units.should == 'kilograms'
|
383
|
-
# end
|
384
|
-
|