carbon 1.1.3 → 2.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.
- 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
|
-
|