tronprint 0.0.16 → 1.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/README.rdoc CHANGED
@@ -43,6 +43,20 @@ In order to display your application's footprint, you can use Tronprint's
43
43
  built-in view helper: TronprintHelper. Feel free to cache your footprint
44
44
  to minimize the number of API requests made to CM1.
45
45
 
46
+ In whichever controller(s) that will use TronprintHelper (or in `ApplicationController`), simply require the helper:
47
+
48
+ class FoosController
49
+ helper TronprintHelper
50
+ end
51
+
52
+ ==== Helper Methods
53
+
54
+ TronprintHelper comes with a few helper methods:
55
+
56
+ * footprint_badge - A badge that displays total footprint and current rate of emissions for your app.
57
+ * cm1_badge - Displays a CM1 badge
58
+ * footprint_methodology - A URL for a live methodology statement reporting how your total footprint was calculated. {Example}[http://carbon.brighterplanet.com/computations?duration=128372]
59
+
46
60
  ==== Heroku
47
61
 
48
62
  Tronprint is available as a Heroku add-on. Add tronprint to your app, and
@@ -72,14 +86,14 @@ config/initializers/tronprint.rb:
72
86
 
73
87
  Tronprint.aggregator_options = { :adapter => :active_record }
74
88
 
75
- Before you get started with Tronprint on ActiveRecord and you're using a
76
- relational database, (e.g., mysql) then you need to create the table
77
- Tronprint will use for storage. The easiest way to do this is add to
78
- your Rakefile:
89
+ Tronprint automatically creates a storage table, `moneta_store` the next time your app
90
+ is run.
91
+
92
+ If you need to create the table manually, add to your Rakefile:
79
93
 
80
94
  require 'tronprint/rake_tasks/active_record'
81
95
 
82
- Then, run `rake tronprint:moneta`.
96
+ And run `rake tronprint:moneta`
83
97
 
84
98
  === Other Ruby Apps
85
99
 
@@ -89,7 +103,7 @@ When your application has started, all you have to do is make a call to
89
103
  Tronprint.run. This starts up a thread that collects statistics at a
90
104
  certain interval and stores the results in a key/value store.
91
105
 
92
- To retrieve the footprint, make a call to Tronprint.emission_estimate. This
106
+ To retrieve the footprint, make a call to Tronprint.statistics.emission_estimate. This
93
107
  returns an instance of {Carbon::EmissionEstimate}[http://rubydoc.info/gems/carbon/Carbon/EmissionEstimate].
94
108
  It can be converted to a float for the amount in kilograms or other
95
109
  methods, such as EmissionEstimate#methodology can provide a link to the
@@ -120,7 +134,7 @@ the options you would normally set in config/tronprint.yml.
120
134
  == Examples
121
135
 
122
136
  You can see an example Rails app using tronprint at http://github.com/brighterplanet/yaktrak.
123
- Files of note: config/initializers/tronprint.rb, Gemfile, app/views/trackings/_form.html.rb.
137
+ Files of note: `config/initializers/tronprint.rb`, `Gemfile`, `app/views/trackings/_form.html.rb`.
124
138
  The live example is at http://yaktrak.org
125
139
 
126
140
  == Note on Patches/Pull Requests
@@ -9,6 +9,8 @@ module Tronprint
9
9
  # {moneta}[http://github.com/wycats/moneta] will work.
10
10
  class Aggregator < Delegator
11
11
 
12
+ attr_accessor :adapter
13
+
12
14
  # Initialize the Aggregator with the following options:
13
15
  # +adapter+:: The underscore-ized name of the moneta class to use.
14
16
  #
@@ -16,17 +18,17 @@ module Tronprint
16
18
  # You'll have to read {moneda's source code}[https://github.com/wycats/moneta/tree/master/lib/moneta/adapters]
17
19
  # for options needed by your desired adapter.
18
20
  def initialize(options = {})
19
- adapter_underscored = options.delete :adapter
20
- adapter_underscored ||= 'pstore'
21
- adapter_underscored = adapter_underscored.to_s.downcase
21
+ self.adapter = options.delete :adapter
22
+ self.adapter ||= 'pstore'
23
+ self.adapter = self.adapter.to_s.downcase
22
24
  begin
23
- require "moneta/#{adapter_underscored}"
24
- klass = Moneta.const_get adapter_constant(adapter_underscored)
25
+ require "moneta/#{self.adapter}"
26
+ klass = Moneta.const_get adapter_constant
25
27
  rescue LoadError # Bundler hack
26
- require "moneta/adapters/#{adapter_underscored}"
27
- klass = Moneta::Adapters.const_get adapter_constant(adapter_underscored)
28
+ require "moneta/adapters/#{self.adapter}"
29
+ klass = Moneta::Adapters.const_get adapter_constant
28
30
  end
29
- args = adapter_underscored == 'memory' ? [] : [options]
31
+ args = self.adapter == 'memory' ? [] : [options]
30
32
  instance = klass.new(*args)
31
33
  __setobj__ instance # required in Ruby 1.8.7
32
34
  super instance
@@ -40,19 +42,97 @@ module Tronprint
40
42
  end
41
43
 
42
44
  # The class name of the desired moneta adapter
43
- def adapter_constant(adapter_underscored)
44
- case adapter_underscored
45
+ def adapter_constant
46
+ case self.adapter
45
47
  when 'pstore' then 'PStore'
46
48
  when 'yaml' then 'YAML'
47
49
  when 'mongodb' then 'MongoDB'
48
50
  else
49
- adapter_underscored.split('_').map(&:capitalize).join('')
51
+ self.adapter.split('_').map(&:capitalize).join('')
50
52
  end
51
53
  end
52
54
 
53
55
  # Increment the total statistic by the given +value+,
54
56
  # specified by the given +key+.
55
57
  def update(key, value)
58
+ update_total(key, value)
59
+ update_yearly(key, value)
60
+ update_monthly(key, value)
61
+ update_daily(key, value)
62
+ update_hourly(key, value)
63
+ end
64
+
65
+ def path(*args)
66
+ args.join('/')
67
+ end
68
+
69
+ def range_total(key, from, to)
70
+ raise "Invalid range" if from > to
71
+ total = 0
72
+ current = from
73
+ while current <= to
74
+ hourly_key = hourly_path(key, year(current), month(current), day(current), hour(current))
75
+ total += self[hourly_key].to_f
76
+ current = current + 3600
77
+ end
78
+
79
+ total
80
+ end
81
+
82
+ private
83
+
84
+ def year(time)
85
+ time.year.to_s
86
+ end
87
+ def current_year
88
+ year(Time.now)
89
+ end
90
+ def month(time)
91
+ sprintf('%02d', time.month)
92
+ end
93
+ def current_month
94
+ month(Time.now)
95
+ end
96
+ def day(time)
97
+ sprintf('%02d', time.day)
98
+ end
99
+ def current_day
100
+ day(Time.now)
101
+ end
102
+ def hour(time)
103
+ sprintf('%02d', time.hour)
104
+ end
105
+ def current_hour
106
+ hour(Time.now)
107
+ end
108
+
109
+ def update_total(key, value)
110
+ update_entry key, value
111
+ end
112
+
113
+ def update_yearly(key, value)
114
+ update_entry path(key, 'by_date', current_year), value
115
+ end
116
+
117
+ def update_monthly(key, value)
118
+ update_entry path(key, 'by_date', current_year, current_month), value
119
+ end
120
+
121
+ def update_daily(key, value)
122
+ update_entry path(key, 'by_date', current_year, current_month, current_day), value
123
+ end
124
+
125
+ def hourly_path(key, year, month, day, hour)
126
+ path(key, 'by_date', year, month, day, hour)
127
+ end
128
+ def update_hourly(key, value)
129
+ update_entry hourly_path(key, current_year, current_month,
130
+ current_day, current_hour),
131
+ value
132
+ update_entry path(key, 'hourly', current_hour), value
133
+ end
134
+
135
+ def update_entry(key, value)
56
136
  old_value = self[key]
57
137
  new_value = old_value ? old_value + value : value
58
138
  self[key] = new_value
@@ -0,0 +1,13 @@
1
+ module Tronprint
2
+ class App
3
+ def initialize(app)
4
+ @app = app
5
+ end
6
+
7
+ def call(env)
8
+ Tronprint.traffic_monitor.increment
9
+
10
+ @app.call(env)
11
+ end
12
+ end
13
+ end
@@ -1,19 +1,42 @@
1
+ require 'tronprint/statistics_formatter'
2
+
1
3
  # Rails helper for displaying footprint data.
2
4
  module TronprintHelper
5
+ include Tronprint::StatisticsFormatter
3
6
 
4
7
  # The total amount of CO2e generated by the application.
5
8
  def total_footprint
6
- emission_estimate.to_f
9
+ total_estimate.to_f
10
+ end
11
+
12
+ # The total amount of electricity used by the application.
13
+ def total_electricity
14
+ total_estimate.electricity_use.to_f
7
15
  end
16
+
8
17
  # A URL for the methodology statement of the emissions calculation.
9
18
  def footprint_methodology
10
- emission_estimate.methodology
19
+ Tronprint.statistics.total_footprint_methodology
11
20
  end
12
21
 
13
- # The Carbon::EmissionEstimate object representing the
14
- # estimate processed by CM1.
15
- def emission_estimate
16
- @emission_estimate ||= Tronprint.emission_estimate
22
+ # An informational badge displaying total energy, footprint, CO2/minute
23
+ def footprint_badge
24
+ footprint = pounds_with_precision total_estimate
25
+
26
+ two_hr_emissions = Tronprint.statistics.
27
+ emission_estimate(Time.now - 7200, Time.now).to_f
28
+ rate = two_hr_emissions / 120 # kgs CO2 per minute over last 2 hours
29
+ rate = rate < 0.0001 ? "< 0.0001" : pounds_with_precision(rate)
30
+
31
+ text = <<-HTML
32
+ <p class="cm1-footprint">
33
+ <span class="cm1-total-footprint">Total footprint: #{total_electricity.to_i}W, #{footprint}lbs CO<sub>2</sub>e</span>
34
+ |
35
+ <span class="cm1-current-footprint">Current footprint: #{rate}lbs CO<sub>2</sub>e/min</span>
36
+ </p>
37
+ HTML
38
+
39
+ text.html_safe
17
40
  end
18
41
 
19
42
  # Let the world know that your app is powered by CM1
@@ -21,4 +44,8 @@ module TronprintHelper
21
44
  %q{<script type="text/javascript" src="http://carbon.brighterplanet.com/badge.js"></script>}.
22
45
  html_safe
23
46
  end
47
+
48
+ def total_estimate
49
+ @total_estimate ||= Tronprint.statistics.emission_estimate
50
+ end
24
51
  end
@@ -1,12 +1,20 @@
1
1
  require 'rails'
2
2
  require 'tronprint/rails/tronprint_helper'
3
+ require 'tronprint/app'
3
4
 
4
5
  module Tronprint
5
6
 
6
7
  # Rails plugin class.
7
8
  class Railtie < Rails::Railtie
9
+ initializer 'tronprint.configure' do |app|
10
+ app.config.middleware.use Tronprint::App
11
+ end
12
+
8
13
  config.after_initialize do
9
- Tronprint.run # if Rails.env.production?
14
+ if Tronprint.aggregator.adapter == 'active_record' && !Moneta::Adapters::ActiveRecord::Store.table_exists?
15
+ Tronprint.aggregator.migrate
16
+ end
17
+ Tronprint.run
10
18
  end
11
19
 
12
20
  generators do
@@ -1,5 +1,5 @@
1
1
  namespace :tronprint do
2
- desc 'Set up ActiveRecord datastore for Tronprint'
2
+ desc 'Manually set up ActiveRecord datastore for Tronprint'
3
3
  task :moneta => :environment do
4
4
  adapter_options = Tronprint.aggregator_options
5
5
  ar = Moneta::Adapters::ActiveRecord.new
@@ -7,5 +7,3 @@ namespace :tronprint do
7
7
  puts 'Ensured that Moneta::Adapters::ActiveRecord::Store exists'
8
8
  end
9
9
  end
10
-
11
- task 'db:migrate' => 'tronprint:moneta'
@@ -0,0 +1,49 @@
1
+ module Tronprint
2
+ # The Statistics class is your gateway to fetching statistics about
3
+ # the energy usage and footprint of your app.
4
+ class Statistics
5
+
6
+ attr_accessor :aggregator, :cpu_monitor
7
+
8
+ def initialize(aggregator, cpu_monitor)
9
+ self.aggregator = aggregator
10
+ self.cpu_monitor = cpu_monitor
11
+ end
12
+
13
+ # Fetch the total amount of CPU time (in hours) used by the application.
14
+ def total_duration
15
+ aggregator[cpu_monitor.key] / 3600
16
+ end
17
+
18
+ # Fetch total CPU time for a given range
19
+ def range_duration(from, to)
20
+ aggregator.range_total cpu_monitor.key, from, to
21
+ end
22
+
23
+ # Calculate emissions using aggregated data. A call is made to
24
+ # Brighter Planet's CM1 emission estimate service. Specifically,
25
+ # the call is made to the {computation emitter}[http://carbon.brighterplanet.com/models/computation]
26
+ def emission_estimate(from = nil, to = nil)
27
+ duration = from.nil? ? total_duration : range_duration(from, to)
28
+
29
+ app = Application.new :zip_code => Tronprint.zip_code, :duration => duration,
30
+ :brighter_planet_key => Tronprint.brighter_planet_key
31
+ app.emission_estimate
32
+ end
33
+
34
+ # The total amount of CO2e generated by the application.
35
+ def total_footprint
36
+ emission_estimate.to_f
37
+ end
38
+
39
+ # The total amount of electricity used by the application.
40
+ def total_electricity
41
+ emission_estimate.electricity_use.to_f
42
+ end
43
+
44
+ # A URL for the methodology statement of the total_footprint calculation.
45
+ def total_footprint_methodology
46
+ emission_estimate.methodology
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,11 @@
1
+ module Tronprint
2
+ module StatisticsFormatter
3
+ def pounds_with_precision(number, precision = nil)
4
+ if precision.nil?
5
+ precision = number < 100 ? 4 : 0
6
+ end
7
+
8
+ number_with_precision(number * 2.2046, :precision => precision)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,29 @@
1
+ module Tronprint
2
+
3
+ # Tronprint::CPUMonitor is a thread that monitors aggregate CPU usage.
4
+ class TrafficMonitor
5
+ attr_accessor :aggregator, :application_name
6
+
7
+ # Parameters:
8
+ # +aggregator+:: A Tronprint::Aggregator instance.
9
+ # +application_name+:: A unique application name.
10
+ def initialize(aggregator, application_name)
11
+ self.aggregator = aggregator
12
+ self.application_name = application_name
13
+ end
14
+
15
+ # The key used to store number of requests in the Aggregator.
16
+ def key
17
+ [application_name, 'requests'].join('/')
18
+ end
19
+
20
+ # Increment the total number of requests
21
+ def increment
22
+ aggregator.update key, 1
23
+ end
24
+
25
+ def requests
26
+ aggregator[key] || 0
27
+ end
28
+ end
29
+ end
@@ -1,3 +1,3 @@
1
1
  module Tronprint
2
- VERSION = "0.0.16"
2
+ VERSION = "1.0.0"
3
3
  end
data/lib/tronprint.rb CHANGED
@@ -2,6 +2,8 @@ require 'yaml'
2
2
  require 'tronprint/aggregator'
3
3
  require 'tronprint/application'
4
4
  require 'tronprint/cpu_monitor'
5
+ require 'tronprint/traffic_monitor'
6
+ require 'tronprint/statistics'
5
7
 
6
8
  if defined?(Rails)
7
9
  require 'tronprint/rails'
@@ -72,9 +74,14 @@ module Tronprint
72
74
  @cpu_monitor ||= CPUMonitor.new aggregator, application_name
73
75
  end
74
76
 
75
- # Fetch the total amount of CPU time (in hours) used by the application.
76
- def total_duration
77
- aggregator[cpu_monitor.key] / 3600
77
+ # The Tronprint::TrafficMonitor instance
78
+ def traffic_monitor
79
+ @traffic_monitor ||= TrafficMonitor.new aggregator, application_name
80
+ end
81
+
82
+ # The Tronprint::Statistics interface
83
+ def statistics
84
+ @statistics ||= Statistics.new aggregator, cpu_monitor
78
85
  end
79
86
 
80
87
  # The current configuration.
@@ -117,13 +124,4 @@ module Tronprint
117
124
  }
118
125
  @default_config
119
126
  end
120
-
121
- # Calculate emissions using aggregated data. A call is made to
122
- # Brighter Planet's CM1 emission estimate service. Specifically,
123
- # the call is made to the {computation emitter}[http://carbon.brighterplanet.com/models/computation]
124
- def emission_estimate
125
- app = Application.new :zip_code => zip_code, :duration => total_duration,
126
- :brighter_planet_key => brighter_planet_key
127
- app.emission_estimate
128
- end
129
127
  end
@@ -1,18 +1,102 @@
1
1
  require 'spec_helper'
2
2
  require 'sandbox'
3
+ require 'time'
4
+ require 'timecop'
3
5
 
4
6
  describe Tronprint::Aggregator do
5
7
  let(:aggregator) { Tronprint::Aggregator.new :adapter => :memory }
6
8
 
7
9
  describe '#update' do
8
- it 'should write statistics to an uninitailzed key' do
10
+ let(:now) { Time.parse('2011-06-02 13:45:12') }
11
+ before do
12
+ Timecop.freeze now
13
+ end
14
+ after do
15
+ Timecop.return
16
+ end
17
+
18
+ it 'writes statistics to an uninitailzed key' do
9
19
  aggregator.update('foo/bar', 22.1)
10
20
  aggregator['foo/bar'].should == 22.1
11
21
  end
12
- it 'should cumulatively update statistics' do
22
+ it 'cumulatively updates statistics' do
13
23
  aggregator.update('foo/bar', 22.1)
14
24
  aggregator.update('foo/bar', 44.2)
15
25
  aggregator['foo/bar'].should be_within(0.01).of(66.3)
26
+ aggregator['foo/bar/by_date/2011'].should be_within(0.01).of(66.3)
27
+ aggregator['foo/bar/by_date/2011/06'].should be_within(0.01).of(66.3)
28
+ aggregator['foo/bar/by_date/2011/06/02'].should be_within(0.01).of(66.3)
29
+ aggregator['foo/bar/by_date/2011/06/02/13'].should be_within(0.01).of(66.3)
30
+ aggregator['foo/bar/hourly/13'].should be_within(0.01).of(66.3)
31
+ end
32
+ it 'stores by_date statistics in separate entries for each day, month, and year' do
33
+ aggregator.update('foo/bar', 22.1)
34
+ aggregator.update('foo/bar', 23.1)
35
+ aggregator['foo/bar/by_date/2011'].should be_within(0.01).of(45.2)
36
+ aggregator['foo/bar/by_date/2011/06'].should be_within(0.01).of(45.2)
37
+ aggregator['foo/bar/by_date/2011/06/02'].should be_within(0.01).of(45.2)
38
+ aggregator['foo/bar/by_date/2011/06/02/13'].should be_within(0.01).of(45.2)
39
+ aggregator['foo/bar/hourly/13'].should be_within(0.01).of(45.2)
40
+
41
+ Timecop.freeze Time.parse('2011-06-03 11:45:12')
42
+ aggregator.update('foo/bar', 33.1)
43
+ aggregator['foo/bar/by_date/2011'].should be_within(0.01).of(78.3)
44
+ aggregator['foo/bar/by_date/2011/06'].should be_within(0.01).of(78.3)
45
+ aggregator['foo/bar/by_date/2011/06/03'].should be_within(0.01).of(33.1)
46
+ aggregator['foo/bar/by_date/2011/06/03/11'].should be_within(0.01).of(33.1)
47
+ aggregator['foo/bar/hourly/11'].should be_within(0.01).of(33.1)
48
+
49
+ Timecop.freeze Time.parse('2011-05-03 11:45:12')
50
+ aggregator.update('foo/bar', 44.1)
51
+ aggregator['foo/bar/by_date/2011'].should be_within(0.01).of(122.4)
52
+ aggregator['foo/bar/by_date/2011/05'].should be_within(0.01).of(44.1)
53
+ aggregator['foo/bar/by_date/2011/06'].should be_within(0.01).of(78.3)
54
+ aggregator['foo/bar/by_date/2011/05/03'].should be_within(0.01).of(44.1)
55
+ aggregator['foo/bar/by_date/2011/05/03/11'].should be_within(0.01).of(44.1)
56
+ aggregator['foo/bar/hourly/11'].should be_within(0.01).of(77.2)
57
+
58
+ Timecop.freeze Time.parse('2012-05-03 00:45:12')
59
+ aggregator.update('foo/bar', 55.1)
60
+ aggregator['foo/bar/by_date/2012'].should be_within(0.01).of(55.1)
61
+ aggregator['foo/bar/by_date/2012/05'].should be_within(0.01).of(55.1)
62
+ aggregator['foo/bar/by_date/2012/05/03'].should be_within(0.01).of(55.1)
63
+ aggregator['foo/bar/by_date/2012/05/03/00'].should be_within(0.01).of(55.1)
64
+ aggregator['foo/bar/hourly/00'].should be_within(0.01).of(55.1)
65
+
66
+ Timecop.freeze Time.parse('2012-05-03 00:57:02')
67
+ aggregator.update('foo/bar', 55.1)
68
+ aggregator['foo/bar/by_date/2012'].should be_within(0.01).of(110.2)
69
+ aggregator['foo/bar/by_date/2012/05'].should be_within(0.01).of(110.2)
70
+ aggregator['foo/bar/by_date/2012/05/03'].should be_within(0.01).of(110.2)
71
+ aggregator['foo/bar/by_date/2012/05/03/00'].should be_within(0.01).of(110.2)
72
+ aggregator['foo/bar/hourly/00'].should be_within(0.01).of(110.2)
73
+ end
74
+ end
75
+
76
+ describe '#range_total' do
77
+ before :each do
78
+ [
79
+ '2011-06-02 13:01:00','2011-06-02 14:01:00','2011-06-02 15:01:00',
80
+ '2011-06-02 16:01:00','2011-06-02 18:01:00','2011-06-02 19:01:00',
81
+ '2011-06-02 19:01:00','2011-06-02 20:01:00','2011-06-02 21:01:00',
82
+ ].each do |time|
83
+ Timecop.freeze Time.parse(time)
84
+ aggregator.update('foozle', 1)
85
+ end
86
+ Timecop.return
87
+ end
88
+
89
+ it 'returns a total for a given range' do
90
+ result = aggregator.range_total('foozle', Time.parse('2011-06-02 18:01:00'), Time.parse('2011-06-02 20:01:00'))
91
+ result.should == 4
92
+ end
93
+ it 'counts missing hours as 0' do
94
+ result = aggregator.range_total('foozle', Time.parse('2011-06-02 01:01:00'), Time.parse('2011-06-02 04:01:00'))
95
+ result.should == 0
96
+ end
97
+ it 'counts missing hours as 0 when a range has partial data' do
98
+ result = aggregator.range_total('foozle', Time.parse('2011-06-02 16:01:00'), Time.parse('2011-06-02 18:01:00'))
99
+ result.should == 2
16
100
  end
17
101
  end
18
102
  end
@@ -1,10 +1,9 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Tronprint::Application do
4
- let(:application) { Tronprint::Application.new }
5
-
6
- describe '#duration' do
7
-
4
+ it 'reports emission esimates for application-related activity' do
5
+ app = Tronprint::Application.new :duration => 72831, :zip_code => 48915
6
+ app.should respond_to(:emission_estimate)
8
7
  end
9
8
  end
10
9
 
@@ -8,11 +8,11 @@ describe Tronprint::CPUMonitor do
8
8
  before :each do
9
9
  cpu_monitor.stub!(:elapsed_cpu_time).and_return 23.87
10
10
  end
11
- it 'should write the elapsed time to the aggregate statistics' do
11
+ it 'writes the elapsed time to the aggregate statistics' do
12
12
  cpu_monitor.monitor
13
13
  aggregator['my_app/application/cpu_time'].should == 23.87
14
14
  end
15
- it 'should increment the toal recorded cpu time' do
15
+ it 'increments the toal recorded cpu time' do
16
16
  cpu_monitor.stub!(:elapsed_cpu_time).and_return 9.0
17
17
  cpu_monitor.monitor
18
18
  cpu_monitor.total_recorded_cpu_time.should == 9.0
@@ -23,12 +23,12 @@ describe Tronprint::CPUMonitor do
23
23
  end
24
24
 
25
25
  describe '#elapsed_cpu_time' do
26
- it 'should return the total CPU time on the first run' do
26
+ it 'returns the total CPU time on the first run' do
27
27
  cpu_monitor.stub!(:total_recorded_cpu_time).and_return 0
28
28
  cpu_monitor.stub!(:total_cpu_time).and_return 9.0
29
29
  cpu_monitor.elapsed_cpu_time.should == 9.0
30
30
  end
31
- it 'should return the amount of CPU time used since the last check' do
31
+ it 'returns the amount of CPU time used since the last check' do
32
32
  cpu_monitor.stub!(:total_recorded_cpu_time).and_return 23.0
33
33
  cpu_monitor.stub!(:total_cpu_time).and_return 36.0
34
34
  cpu_monitor.elapsed_cpu_time.should == 13.0
@@ -36,17 +36,17 @@ describe Tronprint::CPUMonitor do
36
36
  end
37
37
 
38
38
  describe '#total_cpu_time' do
39
- it 'should return the total user and system time of the process' do
39
+ it 'returns the total user and system time of the process' do
40
40
  Process.stub!(:times).and_return [10.1, 12.3]
41
41
  cpu_monitor.total_cpu_time.should == 22.4
42
42
  end
43
43
  end
44
44
 
45
45
  describe '#total_recorded_cpu_time' do
46
- it 'should return 0 by default' do
46
+ it 'returns 0 by default' do
47
47
  cpu_monitor.total_recorded_cpu_time.should == 0
48
48
  end
49
- it 'should return total recorded time' do
49
+ it 'returns total recorded time' do
50
50
  cpu_monitor.total_recorded_cpu_time = 3
51
51
  cpu_monitor.total_recorded_cpu_time.should == 3
52
52
  end
@@ -9,8 +9,8 @@ describe TronprintHelper do
9
9
  end
10
10
 
11
11
  describe '#total_footprint' do
12
- it 'should return the total footprint' do
13
- helper.stub!(:emission_estimate).and_return 89.4
12
+ it 'returns the total footprint' do
13
+ Tronprint.statistics.stub!(:emission_estimate).and_return mock(Object, :to_f => 89.4)
14
14
  helper.total_footprint.should == 89.4
15
15
  end
16
16
  end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+ require 'tronprint/statistics_formatter'
3
+ require 'action_view'
4
+
5
+ class StatisticsFormatterHarness
6
+ include ActionView::Helpers
7
+ include Tronprint::StatisticsFormatter
8
+ end
9
+
10
+ describe Tronprint::StatisticsFormatter do
11
+ let(:formatter) { StatisticsFormatterHarness.new }
12
+
13
+ describe '#pounds_with_precision' do
14
+ it 'converts kilograms to pounds' do
15
+ formatter.pounds_with_precision(1).should == '2.2046'
16
+ end
17
+ it 'uses a precision of 4 if the number is less than 100' do
18
+ formatter.pounds_with_precision(8).should == '17.6368'
19
+ end
20
+ it 'uses a precision of 4 if the number is 0' do
21
+ formatter.pounds_with_precision(0).should == '0.0000'
22
+ end
23
+ it 'uses a precision of 0 if the number is at least 100' do
24
+ formatter.pounds_with_precision(60).should == '132.2760'
25
+ end
26
+ end
27
+ end
28
+
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tronprint::Statistics do
4
+ let(:aggregator) { Tronprint::Aggregator.new :adapter => :memory }
5
+ let(:cpu_monitor) { mock Tronprint::CPUMonitor, :total_recorded_cpu_time => 27.2,
6
+ :key => 'myapp' }
7
+ let(:statistics) { Tronprint::Statistics.new aggregator, cpu_monitor }
8
+
9
+ before do
10
+ Tronprint.zip_code = 48915
11
+ Tronprint.brighter_planet_key = 'ABC123'
12
+ Tronprint.application_name = 'groove'
13
+ end
14
+
15
+ after do
16
+ aggregator.clear
17
+ end
18
+
19
+ describe '#emission_estimate' do
20
+ it 'sends uses total duration if no range is given' do
21
+ statistics.stub!(:total_duration).and_return 28.7
22
+ Tronprint::Application.should_receive(:new).
23
+ with(:zip_code => 48915, :duration => 28.7, :brighter_planet_key => 'ABC123').
24
+ and_return mock(Object, :emission_estimate => nil)
25
+ statistics.emission_estimate
26
+ end
27
+ it 'sends a duration range if given' do
28
+ statistics.stub!(:range_duration).and_return 18.7
29
+ Tronprint::Application.should_receive(:new).
30
+ with(:zip_code => 48915, :duration => 18.7, :brighter_planet_key => 'ABC123').
31
+ and_return mock(Object, :emission_estimate => nil)
32
+ statistics.emission_estimate(Time.now - 7200, Time.now)
33
+ end
34
+ end
35
+
36
+ describe '#total_duration' do
37
+ it 'looks up the total for the application and return number of hours' do
38
+ mock_cpu = mock Tronprint::CPUMonitor, :key => 'groove/application/cpu_time'
39
+ statistics.instance_variable_set :@cpu_monitor, mock_cpu
40
+ statistics.aggregator.update 'groove/application/cpu_time', 5.0
41
+ statistics.total_duration.should be_within(0.00001).of(0.00138)
42
+ end
43
+ end
44
+ end
45
+
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+ require 'timecop'
3
+
4
+ describe Tronprint::TrafficMonitor do
5
+ let(:aggregator) { Tronprint::Aggregator.new :adapter => :memory }
6
+ let(:traffic_monitor) { Tronprint::TrafficMonitor.new aggregator, 'my_app' }
7
+
8
+ describe '#increment' do
9
+ it 'increments the user count for each time slice' do
10
+ Timecop.freeze Time.parse('2011-06-02 13:23:01')
11
+ 2.times { traffic_monitor.increment }
12
+ aggregator['my_app/requests'].should == 2
13
+ aggregator['my_app/requests/by_date/2011'].should == 2
14
+ aggregator['my_app/requests/by_date/2011/06'].should == 2
15
+ aggregator['my_app/requests/by_date/2011/06/02'].should == 2
16
+ aggregator['my_app/requests/by_date/2011/06/02/13'].should == 2
17
+ aggregator['my_app/requests/hourly/13'].should == 2
18
+ Timecop.return
19
+ end
20
+ it 'increments the toal recorded requests' do
21
+ traffic_monitor.increment
22
+ traffic_monitor.requests.should == 1
23
+ traffic_monitor.increment
24
+ traffic_monitor.requests.should == 2
25
+ end
26
+ end
27
+
28
+ describe '#requests' do
29
+ it 'returns 0 on the first run' do
30
+ traffic_monitor.requests.should == 0
31
+ end
32
+ it 'returns the total number of requests' do
33
+ aggregator['my_app/requests'] = 13
34
+ traffic_monitor.requests.should == 13
35
+ end
36
+ end
37
+ end
38
+
@@ -8,39 +8,27 @@ describe Tronprint do
8
8
  end
9
9
 
10
10
  describe '.run' do
11
- it 'should start up each monitor' do
11
+ it 'starts up each monitor' do
12
12
  Tronprint.should_receive :cpu_monitor
13
13
  Tronprint.run
14
14
  end
15
15
  end
16
16
 
17
17
  describe '.cpu_monitor' do
18
- it 'should start the CPU monitor' do
18
+ it 'starts the CPU monitor' do
19
+ Tronprint.instance_variable_set :@cpu_monitor, nil
19
20
  Tronprint::CPUMonitor.should_receive(:new).and_return mock_cpu
20
21
  Tronprint.cpu_monitor
21
22
  end
22
- it 'should return the CPU monitor instance' do
23
+ it 'returns the CPU monitor instance' do
23
24
  Tronprint.instance_variable_set :@cpu_monitor, nil
24
25
  Tronprint::CPUMonitor.stub!(:new).and_return mock_cpu
25
26
  Tronprint.cpu_monitor.should == mock_cpu
26
27
  end
27
28
  end
28
29
 
29
- describe '.emission_estimate' do
30
- it 'should send the zip code and total duration to the application' do
31
- Tronprint.instance_variable_set(:@emission_estimate, nil)
32
- Tronprint.zip_code = 48915
33
- Tronprint.brighter_planet_key = 'ABC123'
34
- Tronprint.stub!(:total_duration).and_return 28.7
35
- Tronprint::Application.should_receive(:new).
36
- with(:zip_code => 48915, :duration => 28.7, :brighter_planet_key => 'ABC123').
37
- and_return mock(Object, :emission_estimate => nil)
38
- Tronprint.emission_estimate
39
- end
40
- end
41
-
42
30
  describe '.brighter_planet_key' do
43
- it 'should return the brighter_planet_key config option' do
31
+ it 'returns the brighter_planet_key config option' do
44
32
  Tronprint.instance_variable_set :@brighter_planet_key, nil
45
33
  Tronprint.stub!(:config).and_return({ :brighter_planet_key => 'aaa' })
46
34
  Tronprint.brighter_planet_key.should == 'aaa'
@@ -48,11 +36,11 @@ describe Tronprint do
48
36
  end
49
37
 
50
38
  describe '.config' do
51
- it 'should return a configuration loaded from disk' do
39
+ it 'returns a configuration loaded from disk' do
52
40
  Tronprint.stub!(:load_config).and_return :foo => :bar
53
41
  Tronprint.config.should include(:foo => :bar)
54
42
  end
55
- it 'should return a default configuration if no config file exists' do
43
+ it 'returns a default configuration if no config file exists' do
56
44
  Tronprint.stub!(:default_config).and_return :foo => :bar
57
45
  Tronprint.config.should include(:foo => :bar)
58
46
  end
@@ -62,14 +50,14 @@ describe Tronprint do
62
50
  before :each do
63
51
  Tronprint.instance_variable_set :@loaded_config, nil
64
52
  end
65
- it 'should load a config file from cwd/config/tronprint.yml if it exists' do
53
+ it 'loads a config file from cwd/config/tronprint.yml if it exists' do
66
54
  Dir.stub!(:pwd).and_return '/some/dir'
67
55
  File.stub!(:exist?).and_return true
68
56
  YAML.should_receive(:load_file).with('/some/dir/config/tronprint.yml').
69
57
  and_return :my => :config
70
58
  Tronprint.load_config.should == { :my => :config }
71
59
  end
72
- it 'should return nil if no config file exists' do
60
+ it 'returns nil if no config file exists' do
73
61
  Tronprint.instance_variable_set :@loaded_config, nil
74
62
  Dir.stub!(:pwd).and_return '/some/dir'
75
63
  File.stub!(:exist?).and_return false
@@ -85,27 +73,17 @@ describe Tronprint do
85
73
  ENV['TRONPRINT_API_KEY'] = nil
86
74
  ENV['MONGOHQ_URL'] = nil
87
75
  end
88
- it 'should return a default configuration' do
76
+ it 'returns a default configuration' do
89
77
  Tronprint.default_config.should be_an_instance_of(Hash)
90
78
  end
91
- it 'should set the brighter_planet_key if ENV["TRONPRINT_API_KEY"] is set' do
79
+ it 'sets the brighter_planet_key if ENV["TRONPRINT_API_KEY"] is set' do
92
80
  ENV['TRONPRINT_API_KEY'] = 'abc123'
93
81
  Tronprint.default_config[:brighter_planet_key].should == 'abc123'
94
82
  end
95
- it 'should use MongoHQ if ENV["MONGOHQ_URL"] is set' do
83
+ it 'uses MongoHQ if ENV["MONGOHQ_URL"] is set' do
96
84
  ENV['MONGOHQ_URL'] = 'mongodb://foo.com/bar'
97
85
  Tronprint.default_config[:aggregator_options][:adapter].should == :mongodb
98
86
  Tronprint.default_config[:aggregator_options][:uri].should == 'mongodb://foo.com/bar'
99
87
  end
100
88
  end
101
-
102
- describe '.total_duration' do
103
- it 'should look up the total for the application and return number of hours' do
104
- mock_cpu = mock Tronprint::CPUMonitor, :key => 'groove/application/cpu_time'
105
- Tronprint.instance_variable_set :@cpu_monitor, mock_cpu
106
- Tronprint.application_name = 'groove'
107
- Tronprint.aggregator.update 'groove/application/cpu_time', 5.0
108
- Tronprint.total_duration.should be_within(0.00001).of(0.00138)
109
- end
110
- end
111
89
  end
data/tronprint.gemspec CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |s|
7
7
  s.version = Tronprint::VERSION
8
8
 
9
9
  s.authors = ['Derek Kastner']
10
- s.date = "2011-02-03"
10
+ s.date = "2011-06-15"
11
11
  s.description = %q{A gem for monitoring the carbon footprint of your ruby app}
12
12
  s.email = %q{dkastner@gmail.com}
13
13
  s.homepage = %q{http://github.com/brighterplanet/tronprint}
@@ -30,13 +30,16 @@ Gem::Specification.new do |s|
30
30
  s.rubygems_version = %q{1.3.7}
31
31
  s.summary = %q{Ruby process carbon footprinter}
32
32
 
33
+ s.add_development_dependency 'actionpack', '~> 3'
34
+ s.add_development_dependency 'activesupport', '~> 3'
33
35
  s.add_development_dependency 'cucumber'
34
36
  s.add_development_dependency 'bueller', '~> 0.0.2'
35
37
  s.add_development_dependency 'rake'
36
38
  s.add_development_dependency 'rspec', '~> 2.0'
37
- s.add_development_dependency 'sandbox'
39
+ s.add_development_dependency 'sandbox'
40
+ s.add_development_dependency 'timecop'
38
41
  s.add_runtime_dependency 'carbon', '~> 1.0.3'
39
42
  s.add_runtime_dependency 'i18n'
40
- s.add_runtime_dependency 'dkastner-moneta', '~> 1.0.3'
43
+ s.add_runtime_dependency 'dkastner-moneta', '~> 1.0.5'
41
44
  end
42
45
 
metadata CHANGED
@@ -1,150 +1,156 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: tronprint
3
- version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 0
8
- - 16
9
- version: 0.0.16
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
10
6
  platform: ruby
11
- authors:
7
+ authors:
12
8
  - Derek Kastner
13
9
  autorequire:
14
10
  bindir: bin
15
11
  cert_chain: []
16
-
17
- date: 2011-02-03 00:00:00 -05:00
18
- default_executable:
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
12
+ date: 2011-06-15 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: actionpack
16
+ requirement: &2157410400 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '3'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *2157410400
25
+ - !ruby/object:Gem::Dependency
26
+ name: activesupport
27
+ requirement: &2157409500 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: '3'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *2157409500
36
+ - !ruby/object:Gem::Dependency
21
37
  name: cucumber
22
- requirement: &id001 !ruby/object:Gem::Requirement
38
+ requirement: &2157409100 !ruby/object:Gem::Requirement
23
39
  none: false
24
- requirements:
25
- - - ">="
26
- - !ruby/object:Gem::Version
27
- segments:
28
- - 0
29
- version: "0"
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
30
44
  type: :development
31
45
  prerelease: false
32
- version_requirements: *id001
33
- - !ruby/object:Gem::Dependency
46
+ version_requirements: *2157409100
47
+ - !ruby/object:Gem::Dependency
34
48
  name: bueller
35
- requirement: &id002 !ruby/object:Gem::Requirement
49
+ requirement: &2157408560 !ruby/object:Gem::Requirement
36
50
  none: false
37
- requirements:
51
+ requirements:
38
52
  - - ~>
39
- - !ruby/object:Gem::Version
40
- segments:
41
- - 0
42
- - 0
43
- - 2
53
+ - !ruby/object:Gem::Version
44
54
  version: 0.0.2
45
55
  type: :development
46
56
  prerelease: false
47
- version_requirements: *id002
48
- - !ruby/object:Gem::Dependency
57
+ version_requirements: *2157408560
58
+ - !ruby/object:Gem::Dependency
49
59
  name: rake
50
- requirement: &id003 !ruby/object:Gem::Requirement
60
+ requirement: &2157408040 !ruby/object:Gem::Requirement
51
61
  none: false
52
- requirements:
53
- - - ">="
54
- - !ruby/object:Gem::Version
55
- segments:
56
- - 0
57
- version: "0"
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
58
66
  type: :development
59
67
  prerelease: false
60
- version_requirements: *id003
61
- - !ruby/object:Gem::Dependency
68
+ version_requirements: *2157408040
69
+ - !ruby/object:Gem::Dependency
62
70
  name: rspec
63
- requirement: &id004 !ruby/object:Gem::Requirement
71
+ requirement: &2157407300 !ruby/object:Gem::Requirement
64
72
  none: false
65
- requirements:
73
+ requirements:
66
74
  - - ~>
67
- - !ruby/object:Gem::Version
68
- segments:
69
- - 2
70
- - 0
71
- version: "2.0"
75
+ - !ruby/object:Gem::Version
76
+ version: '2.0'
72
77
  type: :development
73
78
  prerelease: false
74
- version_requirements: *id004
75
- - !ruby/object:Gem::Dependency
79
+ version_requirements: *2157407300
80
+ - !ruby/object:Gem::Dependency
76
81
  name: sandbox
77
- requirement: &id005 !ruby/object:Gem::Requirement
82
+ requirement: &2157406680 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *2157406680
91
+ - !ruby/object:Gem::Dependency
92
+ name: timecop
93
+ requirement: &2157400260 !ruby/object:Gem::Requirement
78
94
  none: false
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- segments:
83
- - 0
84
- version: "0"
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
85
99
  type: :development
86
100
  prerelease: false
87
- version_requirements: *id005
88
- - !ruby/object:Gem::Dependency
101
+ version_requirements: *2157400260
102
+ - !ruby/object:Gem::Dependency
89
103
  name: carbon
90
- requirement: &id006 !ruby/object:Gem::Requirement
104
+ requirement: &2157399320 !ruby/object:Gem::Requirement
91
105
  none: false
92
- requirements:
106
+ requirements:
93
107
  - - ~>
94
- - !ruby/object:Gem::Version
95
- segments:
96
- - 1
97
- - 0
98
- - 3
108
+ - !ruby/object:Gem::Version
99
109
  version: 1.0.3
100
110
  type: :runtime
101
111
  prerelease: false
102
- version_requirements: *id006
103
- - !ruby/object:Gem::Dependency
112
+ version_requirements: *2157399320
113
+ - !ruby/object:Gem::Dependency
104
114
  name: i18n
105
- requirement: &id007 !ruby/object:Gem::Requirement
115
+ requirement: &2157397400 !ruby/object:Gem::Requirement
106
116
  none: false
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- segments:
111
- - 0
112
- version: "0"
117
+ requirements:
118
+ - - ! '>='
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
113
121
  type: :runtime
114
122
  prerelease: false
115
- version_requirements: *id007
116
- - !ruby/object:Gem::Dependency
123
+ version_requirements: *2157397400
124
+ - !ruby/object:Gem::Dependency
117
125
  name: dkastner-moneta
118
- requirement: &id008 !ruby/object:Gem::Requirement
126
+ requirement: &2157366380 !ruby/object:Gem::Requirement
119
127
  none: false
120
- requirements:
128
+ requirements:
121
129
  - - ~>
122
- - !ruby/object:Gem::Version
123
- segments:
124
- - 1
125
- - 0
126
- - 3
127
- version: 1.0.3
130
+ - !ruby/object:Gem::Version
131
+ version: 1.0.5
128
132
  type: :runtime
129
133
  prerelease: false
130
- version_requirements: *id008
134
+ version_requirements: *2157366380
131
135
  description: A gem for monitoring the carbon footprint of your ruby app
132
136
  email: dkastner@gmail.com
133
137
  executables: []
134
-
135
138
  extensions: []
136
-
137
- extra_rdoc_files:
139
+ extra_rdoc_files:
138
140
  - LICENSE
139
141
  - README.rdoc
140
- files:
142
+ files:
141
143
  - lib/tronprint/aggregator.rb
144
+ - lib/tronprint/app.rb
142
145
  - lib/tronprint/application.rb
143
146
  - lib/tronprint/cpu_monitor.rb
144
147
  - lib/tronprint/rails/generator.rb
145
148
  - lib/tronprint/rails/tronprint_helper.rb
146
149
  - lib/tronprint/rails.rb
147
150
  - lib/tronprint/rake_tasks/active_record.rb
151
+ - lib/tronprint/statistics.rb
152
+ - lib/tronprint/statistics_formatter.rb
153
+ - lib/tronprint/traffic_monitor.rb
148
154
  - lib/tronprint/version.rb
149
155
  - lib/tronprint.rb
150
156
  - .document
@@ -159,55 +165,55 @@ files:
159
165
  - spec/spec_helper.rb
160
166
  - spec/tronprint/aggregator_spec.rb
161
167
  - spec/tronprint/application_spec.rb
162
- - spec/tronprint/computer_spec.rb
163
168
  - spec/tronprint/cpu_monitor_spec.rb
164
169
  - spec/tronprint/rails/tronprint_helper_spec.rb
170
+ - spec/tronprint/statistics_formatter_spec.rb
171
+ - spec/tronprint/statistics_spec.rb
172
+ - spec/tronprint/traffic_monitor_spec.rb
165
173
  - spec/tronprint_spec.rb
166
174
  - features/step_definitions/tronprint_steps.rb
167
175
  - features/support/env.rb
168
176
  - features/tronprint.feature
169
- has_rdoc: true
170
177
  homepage: http://github.com/brighterplanet/tronprint
171
178
  licenses: []
172
-
173
179
  post_install_message:
174
180
  rdoc_options: []
175
-
176
- require_paths:
181
+ require_paths:
177
182
  - lib
178
- required_ruby_version: !ruby/object:Gem::Requirement
183
+ required_ruby_version: !ruby/object:Gem::Requirement
179
184
  none: false
180
- requirements:
181
- - - ">="
182
- - !ruby/object:Gem::Version
183
- hash: 839406187484222147
184
- segments:
185
+ requirements:
186
+ - - ! '>='
187
+ - !ruby/object:Gem::Version
188
+ version: '0'
189
+ segments:
185
190
  - 0
186
- version: "0"
187
- required_rubygems_version: !ruby/object:Gem::Requirement
191
+ hash: -3534616707855240394
192
+ required_rubygems_version: !ruby/object:Gem::Requirement
188
193
  none: false
189
- requirements:
190
- - - ">="
191
- - !ruby/object:Gem::Version
192
- hash: 839406187484222147
193
- segments:
194
+ requirements:
195
+ - - ! '>='
196
+ - !ruby/object:Gem::Version
197
+ version: '0'
198
+ segments:
194
199
  - 0
195
- version: "0"
200
+ hash: -3534616707855240394
196
201
  requirements: []
197
-
198
202
  rubyforge_project:
199
- rubygems_version: 1.3.7
203
+ rubygems_version: 1.8.5
200
204
  signing_key:
201
205
  specification_version: 3
202
206
  summary: Ruby process carbon footprinter
203
- test_files:
207
+ test_files:
204
208
  - spec/spec.opts
205
209
  - spec/spec_helper.rb
206
210
  - spec/tronprint/aggregator_spec.rb
207
211
  - spec/tronprint/application_spec.rb
208
- - spec/tronprint/computer_spec.rb
209
212
  - spec/tronprint/cpu_monitor_spec.rb
210
213
  - spec/tronprint/rails/tronprint_helper_spec.rb
214
+ - spec/tronprint/statistics_formatter_spec.rb
215
+ - spec/tronprint/statistics_spec.rb
216
+ - spec/tronprint/traffic_monitor_spec.rb
211
217
  - spec/tronprint_spec.rb
212
218
  - features/step_definitions/tronprint_steps.rb
213
219
  - features/support/env.rb
@@ -1,9 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Tronprint::Application do
4
- it 'should report emission esimates for application-related activity' do
5
- app = Tronprint::Application.new :duration => 72831, :zip_code => 48915
6
- app.should respond_to(:emission_estimate)
7
- end
8
- end
9
-