coverband 1.5.4 → 2.0.0.alpha
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/.travis.yml +3 -0
- data/Gemfile +2 -1
- data/Rakefile +5 -3
- data/coverband.gemspec +27 -23
- data/lib/coverband.rb +10 -14
- data/lib/coverband/adapters/file_store.rb +6 -7
- data/lib/coverband/adapters/memory_cache_store.rb +8 -5
- data/lib/coverband/adapters/redis_store.rb +10 -50
- data/lib/coverband/baseline.rb +5 -5
- data/lib/coverband/collectors/base.rb +140 -0
- data/lib/coverband/collectors/coverage.rb +148 -0
- data/lib/coverband/collectors/trace.rb +100 -0
- data/lib/coverband/configuration.rb +8 -10
- data/lib/coverband/middleware.rb +5 -5
- data/lib/coverband/reporters/base.rb +26 -31
- data/lib/coverband/reporters/console_report.rb +2 -3
- data/lib/coverband/reporters/simple_cov_report.rb +5 -6
- data/lib/coverband/s3_report_writer.rb +7 -8
- data/lib/coverband/s3_web.rb +3 -5
- data/lib/coverband/tasks.rb +23 -26
- data/lib/coverband/version.rb +3 -1
- data/test/benchmarks/benchmark.rake +38 -32
- data/test/benchmarks/dog.rb +3 -3
- data/test/fake_app/basic_rack.rb +4 -2
- data/test/test_helper.rb +17 -11
- data/test/unit/adapters_file_store_test.rb +12 -11
- data/test/unit/adapters_memory_cache_store_test.rb +3 -4
- data/test/unit/adapters_redis_store_test.rb +42 -118
- data/test/unit/baseline_test.rb +17 -20
- data/test/unit/collectors_base_test.rb +96 -0
- data/test/unit/collectors_coverage_test.rb +137 -0
- data/test/unit/collectors_trace_test.rb +96 -0
- data/test/unit/configuration_test.rb +8 -8
- data/test/unit/dog.rb +3 -1
- data/test/unit/middleware_test.rb +70 -61
- data/test/unit/reports_base_test.rb +62 -62
- data/test/unit/reports_console_test.rb +18 -21
- data/test/unit/reports_simple_cov_test.rb +23 -26
- data/test/unit/s3_report_writer_test.rb +6 -8
- data/test/unit/s3_web_test.rb +2 -1
- metadata +45 -25
- data/lib/coverband/base.rb +0 -210
- data/test/unit/base_test.rb +0 -100
@@ -1,12 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Coverband
|
2
4
|
module Reporters
|
3
5
|
class SimpleCovReport < Base
|
4
|
-
|
5
6
|
def self.report(store, options = {})
|
6
7
|
begin
|
7
8
|
require 'simplecov'
|
8
|
-
rescue
|
9
|
-
Coverband.configuration.logger.error
|
9
|
+
rescue StandardError
|
10
|
+
Coverband.configuration.logger.error 'coverband requires simplecov in order to generate a report, when configured for the scov report style.'
|
10
11
|
return
|
11
12
|
end
|
12
13
|
|
@@ -25,7 +26,7 @@ module Coverband
|
|
25
26
|
report_files = SimpleCov.add_not_loaded_files(scov_style_report)
|
26
27
|
filtered_report_files = {}
|
27
28
|
report_files.each_pair do |file, data|
|
28
|
-
next if Coverband.configuration.ignore.any?{ |i| file.match(i) }
|
29
|
+
next if Coverband.configuration.ignore.any? { |i| file.match(i) }
|
29
30
|
filtered_report_files[file] = data
|
30
31
|
end
|
31
32
|
|
@@ -39,8 +40,6 @@ module Coverband
|
|
39
40
|
|
40
41
|
S3ReportWriter.new(Coverband.configuration.s3_bucket).persist! if Coverband.configuration.s3_bucket
|
41
42
|
end
|
42
|
-
|
43
43
|
end
|
44
44
|
end
|
45
45
|
end
|
46
|
-
|
@@ -1,10 +1,11 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
+
class S3ReportWriter
|
3
4
|
def initialize(bucket_name)
|
4
5
|
@bucket_name = bucket_name
|
5
6
|
begin
|
6
7
|
require 'aws-sdk'
|
7
|
-
rescue
|
8
|
+
rescue StandardError
|
8
9
|
Coverband.configuration.logger.error "coverband requires 'aws-sdk' in order use S3ReportWriter."
|
9
10
|
return
|
10
11
|
end
|
@@ -17,11 +18,10 @@ class S3ReportWriter
|
|
17
18
|
private
|
18
19
|
|
19
20
|
def coverage_content
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
end
|
21
|
+
version = Gem::Specification.find_by_name('simplecov-html').version.version
|
22
|
+
File.read("#{SimpleCov.coverage_dir}/index.html").gsub("./assets/#{version}/", '')
|
23
|
+
rescue StandardError
|
24
|
+
File.read("#{SimpleCov.coverage_dir}/index.html").to_s.gsub('./assets/0.10.1/', '')
|
25
25
|
end
|
26
26
|
|
27
27
|
def object
|
@@ -35,5 +35,4 @@ class S3ReportWriter
|
|
35
35
|
def bucket
|
36
36
|
s3.bucket(@bucket_name)
|
37
37
|
end
|
38
|
-
|
39
38
|
end
|
data/lib/coverband/s3_web.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'sinatra/base'
|
2
4
|
|
3
5
|
module Coverband
|
4
|
-
|
5
6
|
class S3Web < Sinatra::Base
|
6
|
-
|
7
7
|
set :public_folder, proc { File.expand_path('public', Gem::Specification.find_by_name('simplecov-html').full_gem_path) }
|
8
8
|
|
9
9
|
get '/' do
|
10
|
-
s3.get_object(bucket: Coverband.configuration.s3_bucket, key:'coverband/index.html').body.read
|
10
|
+
s3.get_object(bucket: Coverband.configuration.s3_bucket, key: 'coverband/index.html').body.read
|
11
11
|
end
|
12
12
|
|
13
13
|
private
|
@@ -15,7 +15,5 @@ module Coverband
|
|
15
15
|
def s3
|
16
16
|
@s3 ||= Aws::S3::Client.new
|
17
17
|
end
|
18
|
-
|
19
18
|
end
|
20
|
-
|
21
19
|
end
|
data/lib/coverband/tasks.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
+
namespace :coverband do
|
3
4
|
def safely_import_files(files_to_cover)
|
4
5
|
if files_to_cover.any?
|
5
6
|
files = Coverband::Baseline.exclude_files(files_to_cover)
|
@@ -16,32 +17,30 @@ namespace :coverband do
|
|
16
17
|
end
|
17
18
|
end
|
18
19
|
|
19
|
-
desc
|
20
|
+
desc 'record coverband coverage baseline'
|
20
21
|
task :baseline do
|
21
22
|
Coverband::Baseline.record do
|
22
|
-
if Rake::Task.tasks.any?{ |key| key.to_s.match(/environment$/) }
|
23
|
-
Coverband.configuration.logger.info
|
23
|
+
if Rake::Task.tasks.any? { |key| key.to_s.match(/environment$/) }
|
24
|
+
Coverband.configuration.logger.info 'invoking rake environment'
|
24
25
|
Rake::Task['environment'].invoke
|
25
|
-
elsif Rake::Task.tasks.any?{ |key| key.to_s.match(/env$/) }
|
26
|
-
Coverband.configuration.logger.info
|
27
|
-
Rake::Task[
|
26
|
+
elsif Rake::Task.tasks.any? { |key| key.to_s.match(/env$/) }
|
27
|
+
Coverband.configuration.logger.info 'invoking rake env'
|
28
|
+
Rake::Task['env'].invoke
|
28
29
|
end
|
29
30
|
|
30
|
-
baseline_files = [File.expand_path('./config/boot.rb',
|
31
|
-
|
32
|
-
|
31
|
+
baseline_files = [File.expand_path('./config/boot.rb', Dir.pwd),
|
32
|
+
File.expand_path('./config/application.rb', Dir.pwd),
|
33
|
+
File.expand_path('./config/environment.rb', Dir.pwd)]
|
33
34
|
|
34
35
|
baseline_files.each do |baseline_file|
|
35
|
-
if File.
|
36
|
-
require baseline_file
|
37
|
-
end
|
36
|
+
require baseline_file if File.exist?(baseline_file)
|
38
37
|
end
|
39
38
|
|
40
39
|
safely_import_files(Coverband.configuration.additional_files.flatten)
|
41
40
|
|
42
41
|
if defined? Rails
|
43
42
|
safely_import_files(Dir.glob("#{Rails.root}/app/**/*.rb"))
|
44
|
-
if File.
|
43
|
+
if File.exist?("#{Rails.root}/lib")
|
45
44
|
safely_import_files(Dir.glob("#{Rails.root}/lib/**/*.rb"))
|
46
45
|
end
|
47
46
|
end
|
@@ -53,9 +52,9 @@ namespace :coverband do
|
|
53
52
|
# You might want to override them and clear the filters.
|
54
53
|
# Or run the task `coverage_no_filters` below.
|
55
54
|
###
|
56
|
-
desc
|
57
|
-
task :
|
58
|
-
if Coverband.configuration.reporter=='scov'
|
55
|
+
desc 'report runtime coverband code coverage'
|
56
|
+
task coverage: :environment do
|
57
|
+
if Coverband.configuration.reporter == 'scov'
|
59
58
|
Coverband::Reporters::SimpleCovReport.report(Coverband.configuration.store)
|
60
59
|
else
|
61
60
|
Coverband::Reporters::ConsoleReport.report(Coverband.configuration.store)
|
@@ -63,18 +62,16 @@ namespace :coverband do
|
|
63
62
|
end
|
64
63
|
|
65
64
|
def clear_simplecov_filters
|
66
|
-
if defined? SimpleCov
|
67
|
-
SimpleCov.filters.clear
|
68
|
-
end
|
65
|
+
SimpleCov.filters.clear if defined? SimpleCov
|
69
66
|
end
|
70
67
|
|
71
|
-
desc
|
72
|
-
task :
|
73
|
-
if Coverband.configuration.reporter=='scov'
|
68
|
+
desc 'report runtime coverband code coverage after disabling simplecov filters'
|
69
|
+
task coverage_no_filters: :environment do
|
70
|
+
if Coverband.configuration.reporter == 'scov'
|
74
71
|
clear_simplecov_filters
|
75
72
|
Coverband::Reporters::SimpleCovReport.report(Coverband.configuration.store)
|
76
73
|
else
|
77
|
-
puts
|
74
|
+
puts 'coverage without filters only makes sense for SimpleCov reports'
|
78
75
|
end
|
79
76
|
end
|
80
77
|
|
@@ -83,8 +80,8 @@ namespace :coverband do
|
|
83
80
|
# You may want to have a hook that saves current coverband data on deploy
|
84
81
|
# and then resets the coverband store data.
|
85
82
|
###
|
86
|
-
desc
|
87
|
-
task :
|
83
|
+
desc 'reset coverband coverage data'
|
84
|
+
task clear: :environment do
|
88
85
|
Coverband.configuration.store.clear!
|
89
86
|
end
|
90
87
|
end
|
data/lib/coverband/version.rb
CHANGED
@@ -1,17 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'coverband'
|
2
4
|
require 'redis'
|
3
5
|
require File.join(File.dirname(__FILE__), 'dog')
|
4
6
|
|
5
7
|
namespace :benchmarks do
|
6
|
-
|
7
8
|
def classifier_dir
|
8
|
-
|
9
|
+
File.join(File.dirname(__FILE__), 'classifier-reborn')
|
9
10
|
end
|
10
11
|
|
11
12
|
def clone_classifier
|
13
|
+
# rubocop:disable Style/IfUnlessModifier
|
12
14
|
unless Dir.exist? classifier_dir
|
13
15
|
system "git clone git@github.com:jekyll/classifier-reborn.git #{classifier_dir}"
|
14
16
|
end
|
17
|
+
# rubocop:enable Style/IfUnlessModifier
|
15
18
|
end
|
16
19
|
|
17
20
|
desc 'set up coverband default redis'
|
@@ -28,14 +31,13 @@ namespace :benchmarks do
|
|
28
31
|
config.percentage = 100.0
|
29
32
|
config.logger = $stdout
|
30
33
|
config.verbose = false
|
31
|
-
#config.memory_caching = true
|
32
|
-
#config.trace_point_events = [:call]
|
34
|
+
# config.memory_caching = true
|
35
|
+
# config.trace_point_events = [:call]
|
33
36
|
end
|
34
|
-
|
35
37
|
end
|
36
38
|
|
37
|
-
desc 'set up coverband redis
|
38
|
-
task :
|
39
|
+
desc 'set up coverband with coverage redis'
|
40
|
+
task :setup_coverage do
|
39
41
|
clone_classifier
|
40
42
|
$LOAD_PATH.unshift(File.join(classifier_dir, 'lib'))
|
41
43
|
require 'benchmark'
|
@@ -48,7 +50,7 @@ namespace :benchmarks do
|
|
48
50
|
config.percentage = 100.0
|
49
51
|
config.logger = $stdout
|
50
52
|
config.verbose = false
|
51
|
-
config.
|
53
|
+
config.collector = 'coverage'
|
52
54
|
end
|
53
55
|
end
|
54
56
|
|
@@ -67,28 +69,28 @@ namespace :benchmarks do
|
|
67
69
|
config.percentage = 100.0
|
68
70
|
config.logger = $stdout
|
69
71
|
config.verbose = false
|
70
|
-
config.coverage_file
|
72
|
+
config.coverage_file = '/tmp/benchmark_store.json'
|
71
73
|
end
|
72
74
|
end
|
73
75
|
|
74
76
|
def bayes_classification
|
75
77
|
b = ClassifierReborn::Bayes.new 'Interesting', 'Uninteresting'
|
76
|
-
b.train_interesting
|
77
|
-
b.train_uninteresting
|
78
|
-
b.classify
|
78
|
+
b.train_interesting 'here are some good words. I hope you love them'
|
79
|
+
b.train_uninteresting 'here are some bad words, I hate you'
|
80
|
+
b.classify 'I hate bad words and you' # returns 'Uninteresting'
|
79
81
|
end
|
80
82
|
|
81
83
|
def lsi_classification
|
82
84
|
lsi = ClassifierReborn::LSI.new
|
83
|
-
strings = [
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
strings.each {|x| lsi.add_item x.first, x.last}
|
89
|
-
lsi.search(
|
85
|
+
strings = [['This text deals with dogs. Dogs.', :dog],
|
86
|
+
['This text involves dogs too. Dogs! ', :dog],
|
87
|
+
['This text revolves around cats. Cats.', :cat],
|
88
|
+
['This text also involves cats. Cats!', :cat],
|
89
|
+
['This text involves birds. Birds.', :bird]]
|
90
|
+
strings.each { |x| lsi.add_item x.first, x.last }
|
91
|
+
lsi.search('dog', 3)
|
90
92
|
lsi.find_related(strings[2], 2)
|
91
|
-
lsi.classify
|
93
|
+
lsi.classify 'This text is also about dogs!'
|
92
94
|
end
|
93
95
|
|
94
96
|
def work
|
@@ -97,49 +99,53 @@ namespace :benchmarks do
|
|
97
99
|
lsi_classification
|
98
100
|
end
|
99
101
|
|
100
|
-
#simulate many calls to the same line
|
102
|
+
# simulate many calls to the same line
|
101
103
|
10_000.times { Dog.new.bark }
|
102
104
|
end
|
103
105
|
|
104
106
|
def run_work
|
105
107
|
puts "benchmark for: #{Coverband.configuration.inspect}"
|
106
108
|
puts "store: #{Coverband.configuration.store.inspect}"
|
107
|
-
|
108
|
-
|
109
|
+
Benchmark.bm(15) do |x|
|
109
110
|
x.report 'coverband' do
|
110
111
|
SAMPLINGS.times do
|
111
|
-
Coverband::Base.instance.sample do
|
112
|
+
Coverband::Collectors::Base.instance.sample do
|
112
113
|
work
|
113
114
|
end
|
114
115
|
end
|
115
116
|
end
|
116
117
|
|
117
|
-
x.report
|
118
|
+
x.report 'no coverband' do
|
118
119
|
SAMPLINGS.times do
|
119
120
|
work
|
120
121
|
end
|
121
122
|
end
|
122
123
|
end
|
124
|
+
Coverband::Collectors::Base.instance.stop
|
125
|
+
Coverband::Collectors::Base.instance.reset_instance
|
123
126
|
end
|
124
127
|
|
125
128
|
desc 'runs benchmarks on default redis setup'
|
126
|
-
task :
|
129
|
+
task run: :setup do
|
130
|
+
puts 'Coverband tracepoint configured with default redis store'
|
127
131
|
SAMPLINGS = 5
|
128
132
|
run_work
|
129
133
|
end
|
130
134
|
|
131
|
-
desc 'runs benchmarks
|
132
|
-
task :
|
135
|
+
desc 'runs benchmarks file store'
|
136
|
+
task run_file: :setup_file do
|
137
|
+
puts 'Coverband tracepoint configured with file store'
|
133
138
|
SAMPLINGS = 5
|
134
139
|
run_work
|
135
140
|
end
|
136
141
|
|
137
|
-
desc 'runs benchmarks
|
138
|
-
task :
|
142
|
+
desc 'runs benchmarks coverage'
|
143
|
+
task run_coverage: :setup_coverage do
|
144
|
+
puts 'Coverband Coverage configured with to use default redis store'
|
139
145
|
SAMPLINGS = 5
|
140
146
|
run_work
|
141
147
|
end
|
142
148
|
end
|
143
149
|
|
144
|
-
desc
|
145
|
-
task benchmarks: [
|
150
|
+
desc 'runs benchmarks'
|
151
|
+
task benchmarks: ['benchmarks:run_file', 'benchmarks:run', 'benchmarks:run_coverage']
|
data/test/benchmarks/dog.rb
CHANGED
data/test/fake_app/basic_rack.rb
CHANGED
data/test/test_helper.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rubygems'
|
2
4
|
require 'simplecov'
|
3
5
|
require 'test/unit'
|
@@ -16,8 +18,12 @@ $LOAD_PATH.unshift(File.dirname(__FILE__))
|
|
16
18
|
Mocha::Configuration.prevent(:stubbing_non_existent_method)
|
17
19
|
|
18
20
|
def test(name, &block)
|
19
|
-
test_name = "test_#{name.gsub(/\s+/,'_')}".to_sym
|
20
|
-
defined =
|
21
|
+
test_name = "test_#{name.gsub(/\s+/, '_')}".to_sym
|
22
|
+
defined = begin
|
23
|
+
instance_method(test_name)
|
24
|
+
rescue StandardError
|
25
|
+
false
|
26
|
+
end
|
21
27
|
raise "#{test_name} is already defined in #{self}" if defined
|
22
28
|
if block_given?
|
23
29
|
define_method(test_name, &block)
|
@@ -30,22 +36,22 @@ end
|
|
30
36
|
|
31
37
|
def fake_redis
|
32
38
|
@redis ||= begin
|
33
|
-
redis = OpenStruct.new
|
34
|
-
|
35
|
-
end
|
39
|
+
redis = OpenStruct.new
|
40
|
+
# mocha requires method to exist to mock it
|
41
|
+
def redis.smembers(key); end
|
42
|
+
def redis.hgetall(key); end
|
36
43
|
redis
|
37
44
|
end
|
38
45
|
end
|
39
46
|
|
40
47
|
def fake_coverband_members
|
41
|
-
[
|
42
|
-
|
43
|
-
|
44
|
-
]
|
48
|
+
['/Users/danmayer/projects/hearno/script/tester.rb',
|
49
|
+
'/Users/danmayer/projects/hearno/app/controllers/application_controller.rb',
|
50
|
+
'/Users/danmayer/projects/hearno/app/models/account.rb']
|
45
51
|
end
|
46
52
|
|
47
53
|
def fake_coverage_report
|
48
|
-
{
|
54
|
+
{ '/Users/danmayer/projects/hearno/script/tester.rb' => [1, nil, 1, 1, nil, nil, nil] }
|
49
55
|
end
|
50
56
|
|
51
57
|
require 'coverband'
|
@@ -58,7 +64,7 @@ end
|
|
58
64
|
Coverband.configure do |config|
|
59
65
|
config.root = Dir.pwd
|
60
66
|
config.redis = Redis.new
|
61
|
-
#config.coverage_baseline = JSON.parse(File.read('./tmp/coverband_baseline.json'))
|
67
|
+
# config.coverage_baseline = JSON.parse(File.read('./tmp/coverband_baseline.json'))
|
62
68
|
config.root_paths = ['/app/']
|
63
69
|
config.ignore = ['vendor']
|
64
70
|
config.percentage = 100.0
|
@@ -1,41 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require File.expand_path('../test_helper', File.dirname(__FILE__))
|
2
4
|
|
3
5
|
class AdaptersFileStoreTest < Test::Unit::TestCase
|
4
|
-
|
5
6
|
def setup
|
6
|
-
@test_file_path =
|
7
|
+
@test_file_path = '/tmp/coverband_filestore_test_path.json'
|
7
8
|
File.open(@test_file_path, 'w') { |f| f.write(test_data.to_json) }
|
8
9
|
@store = Coverband::Adapters::FileStore.new(@test_file_path)
|
9
10
|
end
|
10
11
|
|
11
12
|
def test_covered_lines_for_file
|
12
|
-
assert_equal @store.covered_lines_for_file('dog.rb')[
|
13
|
-
assert_equal @store.covered_lines_for_file('dog.rb')[
|
13
|
+
assert_equal @store.covered_lines_for_file('dog.rb')['1'], 1
|
14
|
+
assert_equal @store.covered_lines_for_file('dog.rb')['2'], 2
|
14
15
|
end
|
15
16
|
|
16
17
|
def test_covered_lines_when_null
|
17
|
-
assert_equal @store.covered_lines_for_file('none.rb'),
|
18
|
+
assert_equal @store.covered_lines_for_file('none.rb'), []
|
18
19
|
end
|
19
20
|
|
20
21
|
def test_covered_files
|
21
|
-
assert_equal @store.covered_files
|
22
|
+
assert_equal @store.covered_files, ['dog.rb']
|
22
23
|
end
|
23
24
|
|
24
25
|
def test_clear
|
25
26
|
@store.clear!
|
26
|
-
assert_equal false,
|
27
|
+
assert_equal false, File.exist?(@test_file_path)
|
27
28
|
end
|
28
29
|
|
29
30
|
def test_save_report
|
30
|
-
@store.save_report(
|
31
|
-
assert_equal @store.covered_lines_for_file('cat.rb')[
|
31
|
+
@store.save_report('cat.rb' => { 1 => 1 })
|
32
|
+
assert_equal @store.covered_lines_for_file('cat.rb')['1'], 1
|
32
33
|
end
|
33
34
|
|
34
35
|
private
|
35
36
|
|
36
37
|
def test_data
|
37
38
|
{
|
38
|
-
|
39
|
+
'dog.rb' => { 1 => 1, 2 => 2 }
|
39
40
|
}
|
40
41
|
end
|
41
|
-
end
|
42
|
+
end
|