coverband 1.5.4 → 2.0.0.alpha
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.
- 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
|