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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.travis.yml +3 -0
  4. data/Gemfile +2 -1
  5. data/Rakefile +5 -3
  6. data/coverband.gemspec +27 -23
  7. data/lib/coverband.rb +10 -14
  8. data/lib/coverband/adapters/file_store.rb +6 -7
  9. data/lib/coverband/adapters/memory_cache_store.rb +8 -5
  10. data/lib/coverband/adapters/redis_store.rb +10 -50
  11. data/lib/coverband/baseline.rb +5 -5
  12. data/lib/coverband/collectors/base.rb +140 -0
  13. data/lib/coverband/collectors/coverage.rb +148 -0
  14. data/lib/coverband/collectors/trace.rb +100 -0
  15. data/lib/coverband/configuration.rb +8 -10
  16. data/lib/coverband/middleware.rb +5 -5
  17. data/lib/coverband/reporters/base.rb +26 -31
  18. data/lib/coverband/reporters/console_report.rb +2 -3
  19. data/lib/coverband/reporters/simple_cov_report.rb +5 -6
  20. data/lib/coverband/s3_report_writer.rb +7 -8
  21. data/lib/coverband/s3_web.rb +3 -5
  22. data/lib/coverband/tasks.rb +23 -26
  23. data/lib/coverband/version.rb +3 -1
  24. data/test/benchmarks/benchmark.rake +38 -32
  25. data/test/benchmarks/dog.rb +3 -3
  26. data/test/fake_app/basic_rack.rb +4 -2
  27. data/test/test_helper.rb +17 -11
  28. data/test/unit/adapters_file_store_test.rb +12 -11
  29. data/test/unit/adapters_memory_cache_store_test.rb +3 -4
  30. data/test/unit/adapters_redis_store_test.rb +42 -118
  31. data/test/unit/baseline_test.rb +17 -20
  32. data/test/unit/collectors_base_test.rb +96 -0
  33. data/test/unit/collectors_coverage_test.rb +137 -0
  34. data/test/unit/collectors_trace_test.rb +96 -0
  35. data/test/unit/configuration_test.rb +8 -8
  36. data/test/unit/dog.rb +3 -1
  37. data/test/unit/middleware_test.rb +70 -61
  38. data/test/unit/reports_base_test.rb +62 -62
  39. data/test/unit/reports_console_test.rb +18 -21
  40. data/test/unit/reports_simple_cov_test.rb +23 -26
  41. data/test/unit/s3_report_writer_test.rb +6 -8
  42. data/test/unit/s3_web_test.rb +2 -1
  43. metadata +45 -25
  44. data/lib/coverband/base.rb +0 -210
  45. 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 "coverband requires simplecov in order to generate a report, when configured for the scov report style."
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
- class S3ReportWriter
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
- begin
21
- File.read("#{SimpleCov.coverage_dir}/index.html").gsub("./assets/#{Gem::Specification.find_by_name('simplecov-html').version.version}/", '')
22
- rescue
23
- File.read("#{SimpleCov.coverage_dir}/index.html").to_s.gsub("./assets/0.10.1/", '')
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
@@ -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
@@ -1,5 +1,6 @@
1
- namespace :coverband do
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 "record coverband coverage baseline"
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 "invoking rake environment"
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 "invoking rake env"
27
- Rake::Task["env"].invoke
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', Dir.pwd),
31
- File.expand_path('./config/application.rb', Dir.pwd),
32
- File.expand_path('./config/environment.rb', Dir.pwd)]
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.exists?(baseline_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.exists?("#{Rails.root}/lib")
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 "report runtime coverband code coverage"
57
- task :coverage => :environment do
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 "report runtime coverband code coverage after disabling simplecov filters"
72
- task :coverage_no_filters => :environment do
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 "coverage without filters only makes sense for SimpleCov reports"
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 "reset coverband coverage data"
87
- task :clear => :environment do
83
+ desc 'reset coverband coverage data'
84
+ task clear: :environment do
88
85
  Coverband.configuration.store.clear!
89
86
  end
90
87
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Coverband
2
- VERSION = "1.5.4"
4
+ VERSION = '2.0.0.alpha'
3
5
  end
@@ -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
- classifier_dir = File.join(File.dirname(__FILE__), 'classifier-reborn')
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 array'
38
- task :setup_array do
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.store = Coverband::Adapters::RedisStore.new(Redis.new, array: true)
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 = '/tmp/benchmark_store.json'
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 "here are some good words. I hope you love them"
77
- b.train_uninteresting "here are some bad words, I hate you"
78
- b.classify "I hate bad words and you" # returns 'Uninteresting'
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 = [ ["This text deals with dogs. Dogs.", :dog],
84
- ["This text involves dogs too. Dogs! ", :dog],
85
- ["This text revolves around cats. Cats.", :cat],
86
- ["This text also involves cats. Cats!", :cat],
87
- ["This text involves birds. Birds.",:bird ]]
88
- strings.each {|x| lsi.add_item x.first, x.last}
89
- lsi.search("dog", 3)
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 "This text is also about dogs!"
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
- bm = Benchmark.bm(15) do |x|
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 "no coverband" do
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 :run => :setup do
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 redis array'
132
- task :run_array => :setup_array do
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 file store'
138
- task :run_file => :setup_file do
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 "runs benchmarks"
145
- task benchmarks: [ "benchmarks:run" ]
150
+ desc 'runs benchmarks'
151
+ task benchmarks: ['benchmarks:run_file', 'benchmarks:run', 'benchmarks:run_coverage']
@@ -1,7 +1,7 @@
1
- class Dog
1
+ # frozen_string_literal: true
2
2
 
3
+ class Dog
3
4
  def bark
4
- "bark"
5
+ 'bark'
5
6
  end
6
-
7
7
  end
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rack'
2
4
 
3
5
  class HelloWorld
4
- def call(env)
5
- [200, {"Content-Type" => "text/html"}, "Hello Rack!"]
6
+ def call(_env)
7
+ [200, { 'Content-Type' => 'text/html' }, 'Hello Rack!']
6
8
  end
7
9
  end
@@ -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 = instance_method(test_name) rescue false
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
- def redis.smembers(key)
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
- ["/Users/danmayer/projects/hearno/script/tester.rb",
42
- "/Users/danmayer/projects/hearno/app/controllers/application_controller.rb",
43
- "/Users/danmayer/projects/hearno/app/models/account.rb"
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
- {"/Users/danmayer/projects/hearno/script/tester.rb"=>[1, nil, 1, 1, nil, nil, nil]}
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 = "/tmp/coverband_filestore_test_path.json"
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')["1"], 1
13
- assert_equal @store.covered_lines_for_file('dog.rb')["2"], 2
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(), ['dog.rb']
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, File.exist?(@test_file_path)
27
+ assert_equal false, File.exist?(@test_file_path)
27
28
  end
28
29
 
29
30
  def test_save_report
30
- @store.save_report({"cat.rb" => {1 => 1}})
31
- assert_equal @store.covered_lines_for_file('cat.rb')["1"], 1
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
- "dog.rb" => { 1 => 1, 2 => 2 },
39
+ 'dog.rb' => { 1 => 1, 2 => 2 }
39
40
  }
40
41
  end
41
- end
42
+ end