coverband 0.0.15 → 0.0.16
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.md +92 -76
- data/lib/coverband.rb +4 -1
- data/lib/coverband/base.rb +25 -12
- data/lib/coverband/redis_store.rb +1 -1
- data/lib/coverband/version.rb +1 -1
- data/test/unit/base_test.rb +7 -3
- metadata +4 -4
data/README.md
CHANGED
@@ -15,15 +15,21 @@ After running in production for 30 minutes, we were able very easily delete 2000
|
|
15
15
|
|
16
16
|
Add this line to your application's Gemfile:
|
17
17
|
|
18
|
-
|
18
|
+
```bash
|
19
|
+
gem 'coverband'
|
20
|
+
```
|
19
21
|
|
20
22
|
And then execute:
|
21
23
|
|
22
|
-
|
24
|
+
```bash
|
25
|
+
$ bundle
|
26
|
+
```
|
23
27
|
|
24
28
|
Or install it yourself as:
|
25
29
|
|
26
|
-
|
30
|
+
```bash
|
31
|
+
$ gem install coverband
|
32
|
+
```
|
27
33
|
|
28
34
|
## Example Output
|
29
35
|
|
@@ -52,51 +58,55 @@ After installing the gem, you likely want to get the rake tasks configured as we
|
|
52
58
|
|
53
59
|
Either add the below to your `Rakefile` or to a file included in your Rakefile
|
54
60
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
61
|
+
```ruby
|
62
|
+
require 'coverband'
|
63
|
+
Coverband.configure do |config|
|
64
|
+
config.redis = Redis.new
|
65
|
+
# merge in lines to consider covered manually to override any misses
|
66
|
+
# existing_coverage = {'./cover_band_server/app.rb' => Array.new(31,1)}
|
67
|
+
# JSON.parse(File.read('./tmp/coverband_baseline.json')).merge(existing_coverage)
|
68
|
+
config.coverage_baseline = JSON.parse(File.read('./tmp/coverband_baseline.json'))
|
69
|
+
config.root_paths = ['/app/']
|
70
|
+
config.ignore = ['vendor']
|
71
|
+
end
|
72
|
+
|
73
|
+
desc "report unused lines"
|
74
|
+
task :coverband => :environment do
|
75
|
+
Coverband::Reporter
|
76
|
+
end
|
70
77
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
78
|
+
desc "get coverage baseline"
|
79
|
+
task :coverband_baseline do
|
80
|
+
Coverband::Reporter.baseline {
|
81
|
+
#rails
|
82
|
+
require File.expand_path("../config/environment", __FILE__)
|
83
|
+
#sinatra
|
84
|
+
#require File.expand_path("./app", __FILE__)
|
85
|
+
}
|
86
|
+
end
|
87
|
+
```
|
80
88
|
|
81
89
|
#### Configure rack middleware
|
82
90
|
|
83
91
|
For the best coverage you want this loaded as early as possible. I have been putting it directly in my `config.ru` but you could use an initializer, though you may end up missing some boot up coverage.
|
84
92
|
|
85
|
-
|
93
|
+
```ruby
|
94
|
+
require File.dirname(__FILE__) + '/config/environment'
|
86
95
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
96
|
+
require 'coverband'
|
97
|
+
|
98
|
+
Coverband.configure do |config|
|
99
|
+
config.root = Dir.pwd
|
100
|
+
config.redis = Redis.new
|
101
|
+
config.coverage_baseline = JSON.parse(File.read('./tmp/coverband_baseline.json'))
|
102
|
+
config.root_paths = ['/app/']
|
103
|
+
config.ignore = ['vendor']
|
104
|
+
config.percentage = 100.0
|
105
|
+
end
|
106
|
+
|
107
|
+
use Coverband::Middleware
|
108
|
+
run ActionController::Dispatcher.new
|
109
|
+
```
|
100
110
|
|
101
111
|
#### Configure Manually (for example for background jobs)
|
102
112
|
|
@@ -104,42 +114,47 @@ It is easy to use coverband outside of a Rack environment. Make sure you configu
|
|
104
114
|
|
105
115
|
For example if you had a base resque class, you could use the `before_perform` and `after_perform` hooks to add Coverband
|
106
116
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
+
```ruby
|
118
|
+
def before_perform(*args)
|
119
|
+
if (rand * 100.0) > Coverband.configuration.percentage
|
120
|
+
@@coverband ||= Coverband::Base.new
|
121
|
+
@recording_samples = true
|
122
|
+
@@coverband.start
|
123
|
+
else
|
124
|
+
@recording_samples = false
|
125
|
+
end
|
126
|
+
end
|
117
127
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
128
|
+
def after_perform(*args)
|
129
|
+
if @recording_samples
|
130
|
+
@@coverband.stop
|
131
|
+
@@coverband.save
|
132
|
+
end
|
133
|
+
end
|
134
|
+
```
|
124
135
|
|
125
136
|
In general you can run coverband anywhere by using the lines below
|
126
137
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
138
|
+
```ruby
|
139
|
+
require 'coverband'
|
140
|
+
|
141
|
+
Coverband.configure do |config|
|
142
|
+
config.redis = Redis.new
|
143
|
+
config.percentage = 50.0
|
144
|
+
end
|
145
|
+
|
146
|
+
coverband = Coverband::Base.new
|
133
147
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
148
|
+
#manual
|
149
|
+
coverband.start
|
150
|
+
coverband.stop
|
151
|
+
coverband.save
|
138
152
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
153
|
+
#sampling
|
154
|
+
coverband.sample {
|
155
|
+
#code to sample coverband
|
156
|
+
}
|
157
|
+
```
|
143
158
|
|
144
159
|
## Clearing Line Coverage Data
|
145
160
|
|
@@ -150,11 +165,12 @@ you can live with minor inconsistancy for some files.
|
|
150
165
|
|
151
166
|
As often as you like or as part of a deploy hook you can clear the recorded coverband data with the following command.
|
152
167
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
168
|
+
```ruby
|
169
|
+
# defaults to the currently configured Coverband.configuration.redis
|
170
|
+
Coverband::Reporter.clear_coverage
|
171
|
+
# or pass in the current target redis
|
172
|
+
Coverband::Reporter.clear_coverage(Redis.new(:host => 'target.com', :port => 6789))
|
173
|
+
```
|
158
174
|
|
159
175
|
## TODO
|
160
176
|
|
data/lib/coverband.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'redis'
|
2
|
+
require 'logger'
|
2
3
|
|
3
4
|
require 'coverband/version'
|
4
5
|
require 'coverband/redis_store'
|
@@ -18,7 +19,7 @@ module Coverband
|
|
18
19
|
end
|
19
20
|
|
20
21
|
class Configuration
|
21
|
-
attr_accessor :redis, :coverage_baseline, :root_paths, :root, :ignore, :percentage, :verbose, :reporter, :stats
|
22
|
+
attr_accessor :redis, :coverage_baseline, :root_paths, :root, :ignore, :percentage, :verbose, :reporter, :stats, :logger, :startup_delay
|
22
23
|
|
23
24
|
def initialize
|
24
25
|
@root = Dir.pwd
|
@@ -30,6 +31,8 @@ module Coverband
|
|
30
31
|
@percentage = 0.0
|
31
32
|
@verbose = false
|
32
33
|
@reporter = 'scov'
|
34
|
+
@logger = nil
|
35
|
+
@startup_delay = 0
|
33
36
|
end
|
34
37
|
end
|
35
38
|
|
data/lib/coverband/base.rb
CHANGED
@@ -6,11 +6,14 @@ module Coverband
|
|
6
6
|
@enabled = false
|
7
7
|
@tracer_set = false
|
8
8
|
@files = {}
|
9
|
+
@file_usage = {}
|
10
|
+
@startup_delay = Coverband.configuration.startup_delay
|
9
11
|
@ignore_patterns = Coverband.configuration.ignore
|
10
12
|
@sample_percentage = Coverband.configuration.percentage
|
11
13
|
@reporter = Coverband::RedisStore.new(Coverband.configuration.redis) if Coverband.configuration.redis
|
12
14
|
@stats = Coverband.configuration.stats
|
13
15
|
@verbose = Coverband.configuration.verbose
|
16
|
+
@logger = Coverband.configuration.logger || Logger.new(STDOUT)
|
14
17
|
end
|
15
18
|
|
16
19
|
def start
|
@@ -39,7 +42,8 @@ module Coverband
|
|
39
42
|
protected
|
40
43
|
|
41
44
|
def configure_sampling
|
42
|
-
if (rand * 100.0) > @sample_percentage
|
45
|
+
if @startup_delay!=0 || (rand * 100.0) > @sample_percentage
|
46
|
+
@startup_delay -= 1 if @startup_delay > 0
|
43
47
|
@enabled = false
|
44
48
|
else
|
45
49
|
@enabled = true
|
@@ -55,8 +59,8 @@ module Coverband
|
|
55
59
|
@stats.increment "coverband.request.recorded.#{@enabled}" if @stats
|
56
60
|
rescue RuntimeError => err
|
57
61
|
if @verbose
|
58
|
-
|
59
|
-
|
62
|
+
@logger.info "error stating recording coverage"
|
63
|
+
@logger.info "error: #{err.inspect} #{err.message}"
|
60
64
|
end
|
61
65
|
end
|
62
66
|
|
@@ -77,10 +81,16 @@ module Coverband
|
|
77
81
|
end
|
78
82
|
|
79
83
|
def add_file(file, line)
|
80
|
-
if file.match(@project_directory) && !@ignore_patterns.any?{|pattern| file.match(/#{pattern}/) }
|
84
|
+
if !file.match(/(\/gems\/|internal\:prelude)/) && file.match(@project_directory) && !@ignore_patterns.any?{|pattern| file.match(/#{pattern}/) }
|
85
|
+
if @verbose
|
86
|
+
if @file_usage.include?(file)
|
87
|
+
@file_usage[file] += 1
|
88
|
+
else
|
89
|
+
@file_usage[file] = 1
|
90
|
+
end
|
91
|
+
end
|
81
92
|
if @files.include?(file)
|
82
|
-
@files[file] << line
|
83
|
-
@files[file].uniq!
|
93
|
+
@files[file] << line unless @files.include?(line)
|
84
94
|
else
|
85
95
|
@files[file] = [line]
|
86
96
|
end
|
@@ -89,29 +99,32 @@ module Coverband
|
|
89
99
|
|
90
100
|
def report_coverage
|
91
101
|
unless @enabled
|
92
|
-
|
102
|
+
@logger.info "coverage disabled" if @verbose
|
93
103
|
return
|
94
104
|
end
|
95
105
|
|
96
106
|
unset_tracer
|
97
107
|
|
108
|
+
@logger.info "coverband file usage: #{@file_usage.sort_by {|_key, value| value}.inspect}" if @verbose
|
109
|
+
|
98
110
|
if @reporter
|
99
111
|
if @reporter.class.name.match(/redis/i)
|
100
112
|
before_time = Time.now
|
101
|
-
@stats.increment "coverband.files.
|
113
|
+
@stats.increment "coverband.files.recorded_files", @files.length if @stats
|
102
114
|
@reporter.store_report(@files)
|
103
115
|
time_spent = Time.now - before_time
|
104
116
|
@stats.timing "coverband.files.recorded_time", time_spent if @stats
|
105
117
|
@files = {}
|
118
|
+
@@file_usage = {}
|
106
119
|
end
|
107
120
|
elsif @verbose
|
108
|
-
|
109
|
-
|
121
|
+
@logger.info "coverage report: "
|
122
|
+
@logger.info @files.inspect
|
110
123
|
end
|
111
124
|
rescue RuntimeError => err
|
112
125
|
if @verbose
|
113
|
-
|
114
|
-
|
126
|
+
@logger.info "coverage missing"
|
127
|
+
@logger.info "error: #{err.inspect} #{err.message}"
|
115
128
|
end
|
116
129
|
end
|
117
130
|
end
|
data/lib/coverband/version.rb
CHANGED
data/test/unit/base_test.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require File.expand_path('../test_helper', File.dirname(__FILE__))
|
2
2
|
|
3
3
|
class BaseTest < Test::Unit::TestCase
|
4
|
-
|
4
|
+
|
5
5
|
should "start should enable coverage" do
|
6
6
|
coverband = Coverband::Base.new
|
7
7
|
assert_equal false, coverband.instance_variable_get("@enabled")
|
@@ -22,23 +22,27 @@ class BaseTest < Test::Unit::TestCase
|
|
22
22
|
end
|
23
23
|
|
24
24
|
should "allow for sampling with a block and enable when 100 percent sample" do
|
25
|
+
logger = Logger.new(STDOUT)
|
25
26
|
coverband = Coverband::Base.new
|
26
27
|
coverband.instance_variable_set("@sample_percentage", 100.0)
|
27
28
|
coverband.instance_variable_set("@verbose", true)
|
29
|
+
coverband.instance_variable_set("@logger", logger)
|
28
30
|
coverband.instance_variable_set("@reporter", nil)
|
29
31
|
assert_equal false, coverband.instance_variable_get("@enabled")
|
30
|
-
|
32
|
+
logger.expects(:info).at_least_once
|
31
33
|
coverband.sample { 1 + 1 }
|
32
34
|
assert_equal true, coverband.instance_variable_get("@enabled")
|
33
35
|
end
|
34
36
|
|
35
37
|
should "allow reporting with start stop save" do
|
38
|
+
logger = Logger.new(STDOUT)
|
36
39
|
coverband = Coverband::Base.new
|
37
40
|
coverband.instance_variable_set("@sample_percentage", 100.0)
|
38
41
|
coverband.instance_variable_set("@verbose", true)
|
42
|
+
coverband.instance_variable_set("@logger", logger)
|
39
43
|
coverband.instance_variable_set("@reporter", nil)
|
40
44
|
assert_equal false, coverband.instance_variable_get("@enabled")
|
41
|
-
|
45
|
+
logger.expects(:info).at_least_once
|
42
46
|
coverband.start
|
43
47
|
1 + 1
|
44
48
|
coverband.stop
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: coverband
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.16
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-02-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -182,7 +182,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
182
182
|
version: '0'
|
183
183
|
segments:
|
184
184
|
- 0
|
185
|
-
hash: -
|
185
|
+
hash: -615228549007876358
|
186
186
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
187
187
|
none: false
|
188
188
|
requirements:
|
@@ -191,7 +191,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
191
191
|
version: '0'
|
192
192
|
segments:
|
193
193
|
- 0
|
194
|
-
hash: -
|
194
|
+
hash: -615228549007876358
|
195
195
|
requirements: []
|
196
196
|
rubyforge_project:
|
197
197
|
rubygems_version: 1.8.23
|