coverband 2.0.3 → 3.0.0.alpha

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -1
  3. data/.rubocop.yml +73 -0
  4. data/.travis.yml +0 -3
  5. data/README.md +3 -3
  6. data/changes.md +65 -49
  7. data/coverband.gemspec +1 -1
  8. data/lib/coverband.rb +9 -6
  9. data/lib/coverband/adapters/base.rb +22 -2
  10. data/lib/coverband/adapters/file_store.rb +11 -11
  11. data/lib/coverband/adapters/redis_store.rb +22 -57
  12. data/lib/coverband/collectors/coverage.rb +57 -53
  13. data/lib/coverband/configuration.rb +6 -14
  14. data/lib/coverband/integrations/background.rb +7 -0
  15. data/lib/coverband/{middleware.rb → integrations/middleware.rb} +1 -3
  16. data/lib/coverband/reporters/base.rb +37 -82
  17. data/lib/coverband/reporters/console_report.rb +3 -0
  18. data/lib/coverband/reporters/simple_cov_report.rb +4 -3
  19. data/lib/coverband/reporters/web.rb +38 -35
  20. data/lib/coverband/utils/s3_report_writer.rb +59 -0
  21. data/lib/coverband/{tasks.rb → utils/tasks.rb} +0 -0
  22. data/lib/coverband/version.rb +1 -1
  23. data/test/benchmarks/benchmark.rake +3 -3
  24. data/test/test_helper.rb +18 -17
  25. data/test/unit/adapters_base_test.rb +29 -0
  26. data/test/unit/adapters_file_store_test.rb +2 -2
  27. data/test/unit/adapters_redis_store_test.rb +14 -51
  28. data/test/unit/collectors_coverage_test.rb +3 -107
  29. data/test/unit/configuration_test.rb +2 -9
  30. data/test/unit/full_stack_test.rb +47 -0
  31. data/test/unit/middleware_test.rb +21 -57
  32. data/test/unit/reports_base_test.rb +12 -71
  33. data/test/unit/reports_console_test.rb +9 -22
  34. data/test/unit/reports_simple_cov_test.rb +3 -37
  35. data/test/unit/reports_web_test.rb +4 -0
  36. data/test/unit/{s3_report_writer_test.rb → utils_s3_report_writer_test.rb} +1 -1
  37. metadata +29 -18
  38. data/lib/coverband/adapters/memory_cache_store.rb +0 -53
  39. data/lib/coverband/collectors/base.rb +0 -126
  40. data/lib/coverband/collectors/trace.rb +0 -122
  41. data/lib/coverband/s3_report_writer.rb +0 -49
  42. data/test/unit/adapters_memory_cache_store_test.rb +0 -66
  43. data/test/unit/collectors_base_test.rb +0 -104
  44. data/test/unit/collectors_trace_test.rb +0 -106
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Coverband
4
+ module Utils
5
+ ###
6
+ # TODO: this is currently a html report writer
7
+ # this should support writing coverage the current method should be fine
8
+ # to write every report to S3 and sum them later or use the 2 pass
9
+ # method we do for redis if in a background thread
10
+ ###
11
+ class S3ReportWriter
12
+ def initialize(bucket_name, options = {})
13
+ @bucket_name = bucket_name
14
+ @region = options[:region]
15
+ @access_key_id = options[:access_key_id]
16
+ @secret_access_key = options[:secret_access_key]
17
+ begin
18
+ require 'aws-sdk'
19
+ rescue StandardError
20
+ err_msg = 'coverband requires aws-sdk in order use S3ReportWriter.'
21
+ Coverband.configuration.logger.error err_msg
22
+ return
23
+ end
24
+ end
25
+
26
+ def persist!
27
+ object.put(body: coverage_content)
28
+ end
29
+
30
+ private
31
+
32
+ def coverage_content
33
+ version = Gem::Specification.find_by_name('simplecov-html').version.version
34
+ File.read("#{SimpleCov.coverage_dir}/index.html").gsub("./assets/#{version}/", '')
35
+ rescue StandardError
36
+ File.read("#{SimpleCov.coverage_dir}/index.html").to_s.gsub('./assets/0.10.1/', '')
37
+ end
38
+
39
+ def object
40
+ bucket.object('coverband/index.html')
41
+ end
42
+
43
+ def s3
44
+ client_options = {
45
+ region: @region,
46
+ access_key_id: @access_key_id,
47
+ secret_access_key: @secret_access_key
48
+ }
49
+ resource_options = { client: Aws::S3::Client.new(client_options) }
50
+ resource_options = {} if client_options.values.any?(&:nil?)
51
+ Aws::S3::Resource.new(resource_options)
52
+ end
53
+
54
+ def bucket
55
+ s3.bucket(@bucket_name)
56
+ end
57
+ end
58
+ end
59
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Coverband
4
- VERSION = '2.0.3'
4
+ VERSION = '3.0.0.alpha'
5
5
  end
@@ -155,18 +155,18 @@ namespace :benchmarks do
155
155
  Benchmark.ips do |x|
156
156
  x.config(time: 12, warmup: 5, suite: suite)
157
157
  x.report 'coverband' do
158
- Coverband::Collectors::Base.instance.sample do
158
+ Coverband::Collectors::Coverage.instance.sample do
159
159
  work
160
160
  end
161
161
  end
162
- Coverband::Collectors::Base.instance.stop
162
+ Coverband::Collectors::Coverage.instance.stop
163
163
  x.report 'no coverband' do
164
164
  work
165
165
  end
166
166
  x.hold! 'temp_results' if hold_work
167
167
  x.compare!
168
168
  end
169
- Coverband::Collectors::Base.instance.reset_instance
169
+ Coverband::Collectors::Coverage.instance.reset_instance
170
170
  end
171
171
 
172
172
  def fake_line_numbers
@@ -14,7 +14,7 @@ SimpleCov.start do
14
14
  add_filter '/config/'
15
15
  end
16
16
 
17
- TEST_COVERAGE_FILE = '/tmp/fake_file.json'
17
+ TEST_COVERAGE_FILE = '/tmp/fake_file.json'.freeze
18
18
 
19
19
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
20
20
  $LOAD_PATH.unshift(File.dirname(__FILE__))
@@ -37,33 +37,34 @@ def test(name, &block)
37
37
  end
38
38
  end
39
39
 
40
+ def example_line
41
+ [0, 1, 2]
42
+ end
43
+
44
+ def basic_coverage
45
+ { 'app_path/dog.rb' => example_line }
46
+ end
47
+
40
48
  def fake_redis
41
49
  @redis ||= begin
42
50
  redis = OpenStruct.new
43
- # mocha requires method to exist to mock it
44
- def redis.smembers(key); end
45
- def redis.hgetall(key); end
46
51
  redis
47
52
  end
48
53
  end
49
54
 
50
- def fake_coverband_members
51
- ['/Users/danmayer/projects/hearno/script/tester.rb',
52
- '/Users/danmayer/projects/hearno/app/controllers/application_controller.rb',
53
- '/Users/danmayer/projects/hearno/app/models/account.rb']
54
- end
55
-
56
55
  def fake_coverage_report
57
- { '/Users/danmayer/projects/hearno/script/tester.rb' => [1, nil, 1, 1, nil, nil, nil] }
56
+ file_name = '/Users/danmayer/projects/hearno/script/tester.rb'
57
+ { file_name => [1, nil, 1, 1, nil, nil, nil] }
58
58
  end
59
59
 
60
60
  require 'coverband'
61
61
 
62
62
  Coverband.configure do |config|
63
- config.root = Dir.pwd
64
- config.root_paths = ['/app/']
65
- config.ignore = ['vendor']
66
- config.percentage = 100.0
67
- config.reporter = 'std_out'
68
- config.store = Coverband::Adapters::RedisStore.new(Redis.new)
63
+ config.root = Dir.pwd
64
+ config.s3_bucket = nil
65
+ config.root_paths = ['/app_path/']
66
+ config.ignore = ['vendor']
67
+ config.reporting_frequency = 100.0
68
+ config.reporter = 'std_out'
69
+ config.store = Coverband::Adapters::RedisStore.new(Redis.new)
69
70
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path('../test_helper', File.dirname(__FILE__))
4
+
5
+ class AdaptersBaseTest < Test::Unit::TestCase
6
+ def setup
7
+ @test_file_path = '/tmp/coverband_filestore_test_path.json'
8
+ @store = Coverband::Adapters::FileStore.new(@test_file_path)
9
+ end
10
+
11
+ def test_covered_merge
12
+ old_report = { '/Users/danmayer/projects/coverband_demo/config/coverband.rb' => [5, 7, nil],
13
+ '/Users/danmayer/projects/coverband_demo/config/initializers/assets.rb' => [5, 5, nil],
14
+ '/Users/danmayer/projects/coverband_demo/config/initializers/cookies_serializer.rb' => [5, 5, nil] }
15
+ new_report = { '/Users/danmayer/projects/coverband_demo/config/coverband.rb' => [5, 7, nil],
16
+ '/Users/danmayer/projects/coverband_demo/config/initializers/filter_logging.rb' => [5, 5, nil],
17
+ '/Users/danmayer/projects/coverband_demo/config/initializers/wrap_parameters.rb' => [5, 5, nil],
18
+ '/Users/danmayer/projects/coverband_demo/app/controllers/application_controller.rb' => [5, 5, nil] }
19
+ expected_result = {
20
+ '/Users/danmayer/projects/coverband_demo/app/controllers/application_controller.rb' => [5, 5, nil],
21
+ '/Users/danmayer/projects/coverband_demo/config/coverband.rb' => [10, 14, nil],
22
+ '/Users/danmayer/projects/coverband_demo/config/initializers/assets.rb' => [5, 5, nil],
23
+ '/Users/danmayer/projects/coverband_demo/config/initializers/cookies_serializer.rb' => [5, 5, nil],
24
+ '/Users/danmayer/projects/coverband_demo/config/initializers/filter_logging.rb' => [5, 5, nil],
25
+ '/Users/danmayer/projects/coverband_demo/config/initializers/wrap_parameters.rb' => [5, 5, nil]
26
+ }
27
+ assert_equal expected_result, @store.send(:merge_reports, new_report, old_report)
28
+ end
29
+ end
@@ -28,8 +28,8 @@ class AdaptersFileStoreTest < Test::Unit::TestCase
28
28
  end
29
29
 
30
30
  def test_save_report
31
- @store.save_report('cat.rb' => { 1 => 1 })
32
- assert_equal @store.covered_lines_for_file('cat.rb')['1'], 1
31
+ @store.send(:save_report, 'cat.rb' => [0,1])
32
+ assert_equal @store.covered_lines_for_file('cat.rb')[1], 1
33
33
  end
34
34
 
35
35
  private
@@ -5,42 +5,37 @@ require File.expand_path('../test_helper', File.dirname(__FILE__))
5
5
  class RedisTest < Test::Unit::TestCase
6
6
  BASE_KEY = Coverband::Adapters::RedisStore::BASE_KEY
7
7
 
8
- def example_hash
9
- {'1' => '1', '2' => '2'}
10
- end
11
-
12
8
  def setup
13
9
  @redis = Redis.new
14
- @redis.flushdb
15
10
  @store = Coverband::Adapters::RedisStore.new(@redis)
11
+ @store.clear!
16
12
  end
17
13
 
18
14
  def test_coverage
19
- @redis.sadd(BASE_KEY, 'dog.rb')
20
- @store.send(:pipelined_save, combined_report)
21
- expected = {'dog.rb' => example_hash}
15
+ expected = basic_coverage
16
+ @store.save_report(expected)
22
17
  assert_equal expected, @store.coverage
23
18
  end
24
19
 
25
- def test_covered_lines_for_file
26
- @store.send(:pipelined_save, combined_report)
27
- assert_equal [["1", "1"], ["2", "2"]], @store.covered_lines_for_file('dog.rb').sort
20
+ def test_coverage_increments
21
+ expected = basic_coverage
22
+ @store.save_report(expected)
23
+ assert_equal expected, @store.coverage
24
+ @store.save_report(expected)
25
+ assert_equal [0, 2, 4], @store.coverage['app_path/dog.rb']
28
26
  end
29
27
 
30
- def test_covered_lines_for_file__hash
31
- @redis.mapped_hmset("#{BASE_KEY}.dog.rb", '1' => 1, '2' => 2)
32
- @store = Coverband::Adapters::RedisStore.new(@redis)
33
- expected = [%w[1 1], %w[2 2]]
34
- assert_equal expected, @store.covered_lines_for_file('dog.rb').sort
28
+ def test_covered_lines_for_file
29
+ expected = basic_coverage
30
+ @store.save_report(expected)
31
+ assert_equal example_line, @store.covered_lines_for_file('app_path/dog.rb')
35
32
  end
36
33
 
37
34
  def test_covered_lines_when_null
38
- empty_hash = {}
39
- assert_equal empty_hash, @store.covered_lines_for_file('dog.rb')
35
+ assert_equal nil, @store.covered_lines_for_file('app_path/dog.rb')
40
36
  end
41
37
 
42
38
  def test_clear
43
- @redis.expects(:smembers).with(BASE_KEY).once.returns([])
44
39
  @redis.expects(:del).with(BASE_KEY).once
45
40
  @store.clear!
46
41
  end
@@ -63,35 +58,3 @@ class RedisTest < Test::Unit::TestCase
63
58
  }
64
59
  end
65
60
  end
66
-
67
- class RedisStoreTestV3Hash < RedisTest
68
- def setup
69
- @redis = Redis.current.tap do |redis|
70
- redis.stubs(:sadd).with(anything, anything)
71
- end
72
-
73
- @store = Coverband::Adapters::RedisStore.new(@redis)
74
- end
75
-
76
- test 'it stores the files into coverband' do
77
- @redis.expects(:sadd).with(BASE_KEY, [
78
- '/Users/danmayer/projects/cover_band_server/app.rb',
79
- '/Users/danmayer/projects/cover_band_server/server.rb'
80
- ])
81
-
82
- @store.save_report(test_data)
83
- end
84
-
85
- test 'it stores the file lines of the file app.rb' do
86
- @redis.expects(:mapped_hmset).with(
87
- "#{BASE_KEY}./Users/danmayer/projects/cover_band_server/app.rb",
88
- '54' => 1, '55' => 2
89
- )
90
- @redis.expects(:mapped_hmset).with(
91
- "#{BASE_KEY}./Users/danmayer/projects/cover_band_server/server.rb",
92
- '5' => 1
93
- )
94
-
95
- @store.save_report(test_data)
96
- end
97
- end
@@ -9,18 +9,16 @@ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.3.0')
9
9
 
10
10
  def setup
11
11
  Coverband.configure do |config|
12
- config.collector = 'coverage'
13
- config.store = Coverband::Adapters::RedisStore.new(Redis.new)
12
+ config.store = Coverband::Adapters::RedisStore.new(Redis.new)
14
13
  end
15
- @coverband = Coverband::Collectors::Base.instance.reset_instance
14
+ @coverband = Coverband::Collectors::Coverage.instance.reset_instance
16
15
  end
17
16
 
18
17
  def teardown
19
18
  Thread.current[:coverband_instance] = nil
20
19
  Coverband.configure do |config|
21
- config.collector = 'trace'
22
20
  end
23
- @coverband = Coverband::Collectors::Base.instance.reset_instance
21
+ @coverband = Coverband::Collectors::Coverage.instance.reset_instance
24
22
  end
25
23
 
26
24
  test 'gets coverage instance' do
@@ -31,107 +29,5 @@ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.3.0')
31
29
  assert_equal Coverband::Adapters::RedisStore, coverband.instance_variable_get('@store').class
32
30
  end
33
31
 
34
- test 'configure memory caching' do
35
- Coverband.configuration.memory_caching = true
36
- coverband = Coverband::Collectors::Base.instance.reset_instance
37
- assert_equal Coverband::Adapters::MemoryCacheStore, coverband.instance_variable_get('@store').class
38
- Coverband.configuration.memory_caching = false
39
- end
40
-
41
- test 'start should enable coverage' do
42
- assert_equal false, coverband.instance_variable_get('@enabled')
43
- coverband.expects(:record_coverage).once
44
- coverband.start
45
- assert_equal true, coverband.instance_variable_get('@enabled')
46
- end
47
-
48
- test 'stop should disable coverage' do
49
- assert_equal false, coverband.instance_variable_get('@enabled')
50
- coverband.expects(:record_coverage).once
51
- coverband.start
52
- assert_equal true, coverband.instance_variable_get('@enabled')
53
- coverband.stop
54
- assert_equal false, coverband.instance_variable_get('@enabled')
55
- end
56
-
57
- test 'allow for sampling with a block and enable when 100 percent sample' do
58
- logger = Logger.new(STDOUT)
59
- coverband.instance_variable_set('@sample_percentage', 100.0)
60
- coverband.instance_variable_set('@verbose', true)
61
- coverband.instance_variable_set('@logger', logger)
62
- coverband.instance_variable_set('@store', nil)
63
- assert_equal false, coverband.instance_variable_get('@enabled')
64
- logger.stubs('info')
65
- logger.expects(:debug).at_least_once
66
- coverband.sample { 1 + 1 }
67
- assert_equal true, coverband.instance_variable_get('@enabled')
68
- end
69
-
70
- test 'allow reporting with start stop save' do
71
- logger = Logger.new(STDOUT)
72
- coverband.instance_variable_set('@sample_percentage', 100.0)
73
- coverband.instance_variable_set('@verbose', true)
74
- coverband.instance_variable_set('@logger', logger)
75
- coverband.instance_variable_set('@store', nil)
76
- assert_equal false, coverband.instance_variable_get('@enabled')
77
- logger.expects(:info).at_least_once
78
- logger.stubs('debug')
79
- coverband.start
80
- logger.info(1 + 1)
81
- coverband.stop
82
- coverband.save
83
- end
84
-
85
- test 'allow reporting to redis start stop save' do
86
- dog_file = File.expand_path('./dog.rb', File.dirname(__FILE__))
87
- coverband.instance_variable_set('@sample_percentage', 100.0)
88
- store = Coverband::Adapters::RedisStore.new(Redis.new)
89
- coverband.instance_variable_set('@store', store)
90
-
91
- prior = Coverage.peek_result[dog_file].dup
92
- prior[4] = prior[4] + 5
93
- expected = {}
94
- prior.each_with_index do |count, index|
95
- expected[(index + 1)] = count if count
96
- end
97
-
98
- store.expects(:save_report).once.with(has_entries(dog_file => expected))
99
- assert_equal false, coverband.instance_variable_get('@enabled')
100
- coverband.start
101
- 5.times { Dog.new.bark }
102
- coverband.stop
103
- coverband.save
104
- end
105
-
106
- test 'coverage should count line numbers only the new calls' do
107
- dog_file = File.expand_path('./dog.rb', File.dirname(__FILE__))
108
- coverband.instance_variable_set('@sample_percentage', 100.0)
109
- coverband.instance_variable_set('@store', nil)
110
- original_count = Coverage.peek_result[dog_file][4]
111
- coverband.start
112
- 100.times { Dog.new.bark }
113
- coverband.stop
114
- coverband.save
115
- assert_equal (original_count + 100), coverband.instance_variable_get('@file_line_usage')[dog_file][5]
116
- 50.times { Dog.new.bark }
117
- coverband.save
118
- assert_equal 50, coverband.instance_variable_get('@file_line_usage')[dog_file][5]
119
- end
120
-
121
- test 'coverage should count line numbers' do
122
- dog_file = File.expand_path('./dog.rb', File.dirname(__FILE__))
123
- coverband.instance_variable_set('@sample_percentage', 100.0)
124
- coverband.instance_variable_set('@store', nil)
125
- original_count = Coverage.peek_result[dog_file][4]
126
- coverband.start
127
- 100.times { Dog.new.bark }
128
- coverband.stop
129
- coverband.save
130
- assert_equal (original_count + 100), coverband.instance_variable_get('@file_line_usage')[dog_file][5]
131
- end
132
-
133
- test 'sample should return the result of the block' do
134
- assert_equal 2, coverband.sample { 1 + 1 }
135
- end
136
32
  end
137
33
  end
@@ -3,15 +3,8 @@
3
3
  require File.expand_path('../test_helper', File.dirname(__FILE__))
4
4
 
5
5
  class BaseTest < Test::Unit::TestCase
6
- test 'defaults to ignore gems' do
7
- assert_equal Coverband.configuration.include_gems, false
8
- coverband = Coverband::Collectors::Base.instance.reset_instance
9
- assert_equal ['vendor', 'internal:prelude', 'schema.rb', 'gems'], coverband.instance_variable_get('@ignore_patterns')
10
- end
11
-
12
- test "doesn't ignore gems if include_gems = true" do
13
- Coverband.configuration.include_gems = true
14
- coverband = Coverband::Collectors::Base.instance.reset_instance
6
+ test 'defaults ' do
7
+ coverband = Coverband::Collectors::Coverage.instance.reset_instance
15
8
  assert_equal ['vendor', 'internal:prelude', 'schema.rb'], coverband.instance_variable_get('@ignore_patterns')
16
9
  end
17
10
  end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path('../test_helper', File.dirname(__FILE__))
4
+ require 'rack'
5
+
6
+ class FullStackTest < Test::Unit::TestCase
7
+ BASE_KEY = Coverband::Adapters::RedisStore::BASE_KEY
8
+ TEST_RACK_APP = '../fake_app/basic_rack.rb'.freeze
9
+
10
+ def setup
11
+ Coverband::Collectors::Coverage.instance.reset_instance
12
+ Coverband.configure do |config|
13
+ config.reporting_frequency = 100.0
14
+ config.store = Coverband::Adapters::RedisStore.new(Redis.new)
15
+ config.s3_bucket = nil
16
+ end
17
+ Coverband.configuration.store.clear!
18
+ Coverband.start
19
+ @rack_file = File.expand_path(TEST_RACK_APP, File.dirname(__FILE__))
20
+ require @rack_file
21
+ end
22
+
23
+ test 'call app' do
24
+ request = Rack::MockRequest.env_for('/anything.json')
25
+ middleware = Coverband::Middleware.new(fake_app_with_lines)
26
+ results = middleware.call(request)
27
+ assert_equal 'Hello Rack!', results.last
28
+ expected = [nil, nil, 1, nil, 1, 1, 1, nil, nil]
29
+ assert_equal expected, Coverband.configuration.store.coverage[@rack_file]
30
+
31
+ # additional calls increase count by 1
32
+ middleware.call(request)
33
+ expected = [nil, nil, 1, nil, 1, 1, 2, nil, nil]
34
+ assert_equal expected, Coverband.configuration.store.coverage[@rack_file]
35
+
36
+ expected = nil
37
+ # TODO: read the html to test it matches expectations? or return data as a hash?
38
+ actual = Coverband::Reporters::SimpleCovReport.report(Coverband.configuration.store, open_report: false)
39
+ assert_equal expected, actual
40
+ end
41
+
42
+ private
43
+
44
+ def fake_app_with_lines
45
+ @fake_app_with_lines ||= ::HelloWorld.new
46
+ end
47
+ end