carbon 1.1.3 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/.gitignore +4 -22
  2. data/CHANGELOG +11 -0
  3. data/Gemfile +10 -1
  4. data/README.markdown +185 -0
  5. data/Rakefile +13 -26
  6. data/bin/carbon +3 -3
  7. data/carbon.gemspec +17 -23
  8. data/developer_notes/MULTI.markdown +25 -0
  9. data/developer_notes/REDUCE_HTTP_CONNECTIONS.markdown +46 -0
  10. data/features/shell.feature +1 -1
  11. data/features/support/env.rb +3 -4
  12. data/lib/carbon.rb +242 -96
  13. data/lib/carbon/registry.rb +50 -0
  14. data/lib/carbon/shell.rb +14 -8
  15. data/lib/carbon/shell/emitter.rb +33 -29
  16. data/lib/carbon/version.rb +1 -1
  17. data/test/carbon_test.rb +167 -0
  18. metadata +128 -182
  19. data/MIT-LICENSE.txt +0 -19
  20. data/README.rdoc +0 -266
  21. data/doc/INTEGRATION_GUIDE.rdoc +0 -1002
  22. data/doc/examining-response-with-jsonview.png +0 -0
  23. data/doc/shell_example +0 -43
  24. data/doc/timeout-error.png +0 -0
  25. data/doc/with-committee-reports.png +0 -0
  26. data/doc/without-committee-reports.png +0 -0
  27. data/lib/carbon/base.rb +0 -62
  28. data/lib/carbon/emission_estimate.rb +0 -165
  29. data/lib/carbon/emission_estimate/request.rb +0 -100
  30. data/lib/carbon/emission_estimate/response.rb +0 -61
  31. data/lib/carbon/emission_estimate/storage.rb +0 -33
  32. data/spec/fixtures/vcr_cassettes/flight.yml +0 -47
  33. data/spec/fixtures/vcr_cassettes/residence.yml +0 -44
  34. data/spec/lib/carbon/emission_estimate/request_spec.rb +0 -41
  35. data/spec/lib/carbon/emission_estimate/response_spec.rb +0 -33
  36. data/spec/lib/carbon/emission_estimate_spec.rb +0 -32
  37. data/spec/lib/carbon_spec.rb +0 -384
  38. data/spec/spec_helper.rb +0 -60
  39. 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
-
@@ -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
-