coverband 4.2.1.rc3 → 4.2.1.rc4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +4 -0
  3. data/Gemfile +1 -0
  4. data/README.md +6 -4
  5. data/Rakefile +5 -2
  6. data/changes.md +32 -13
  7. data/lib/coverband.rb +3 -4
  8. data/lib/coverband/adapters/base.rb +59 -30
  9. data/lib/coverband/adapters/file_store.rb +8 -8
  10. data/lib/coverband/adapters/redis_store.rb +18 -10
  11. data/lib/coverband/collectors/coverage.rb +3 -4
  12. data/lib/coverband/collectors/delta.rb +18 -8
  13. data/lib/coverband/configuration.rb +25 -9
  14. data/lib/coverband/integrations/background.rb +3 -1
  15. data/lib/coverband/reporters/base.rb +6 -3
  16. data/lib/coverband/reporters/web.rb +11 -0
  17. data/lib/coverband/utils/file_path_helper.rb +12 -3
  18. data/lib/coverband/utils/source_file.rb +2 -1
  19. data/lib/coverband/utils/tasks.rb +1 -11
  20. data/lib/coverband/version.rb +1 -1
  21. data/test/benchmarks/benchmark.rake +135 -10
  22. data/test/coverband/adapters/base_test.rb +73 -42
  23. data/test/coverband/adapters/file_store_test.rb +48 -37
  24. data/test/coverband/adapters/redis_store_test.rb +35 -5
  25. data/test/coverband/collectors/coverage_test.rb +1 -1
  26. data/test/coverband/collectors/delta_test.rb +10 -1
  27. data/test/coverband/coverband_test.rb +14 -1
  28. data/test/coverband/utils/html_formatter_test.rb +0 -2
  29. data/test/dog.rb.erb +12 -0
  30. data/test/forked/rails_full_stack_test.rb +35 -25
  31. data/test/forked/rails_rake_full_stack_test.rb +12 -4
  32. data/test/rails4_dummy/config/coverband.rb +2 -0
  33. data/test/rails5_dummy/config/coverband.rb +2 -0
  34. data/test/rails_test_helper.rb +2 -1
  35. data/test/test_helper.rb +19 -6
  36. data/test/unique_files.rb +12 -5
  37. metadata +5 -4
@@ -3,49 +3,80 @@
3
3
  require File.expand_path('../../test_helper', File.dirname(__FILE__))
4
4
 
5
5
  class AdaptersBaseTest < Minitest::Test
6
- def setup
7
- super
8
- @test_file_path = '/tmp/coverband_filestore_test_path.json'
9
- @store = Coverband::Adapters::FileStore.new(@test_file_path)
10
- mock_file_hash
6
+
7
+ def test_abstract_methods
8
+ abstract_methods = %w(clear! clear_file! migrate! size save_coverage coverage)
9
+ abstract_methods.each do |method|
10
+ assert_raises RuntimeError do
11
+ Coverband::Adapters::Base.new.send(method.to_sym)
12
+ end
13
+ end
14
+ end
15
+
16
+ def test_size_in_mib
17
+ base = Coverband::Adapters::Base.new
18
+ def base.size
19
+ 3.0
20
+ end
21
+ assert_equal "0.00", base.size_in_mib
11
22
  end
12
23
 
13
- def test_covered_merge
14
- old_time = 1541958097
15
- current_time = Time.now.to_i
16
- old_data = {
17
- 'first_updated_at' => old_time,
18
- 'last_updated_at' => current_time,
19
- 'file_hash' => 'abcd',
20
- 'data' => [5, 7, nil]
21
- }
22
- old_report = { '/projects/coverband_demo/config/coverband.rb' => old_data,
23
- '/projects/coverband_demo/config/initializers/assets.rb' => old_data,
24
- '/projects/coverband_demo/config/initializers/cookies_serializer.rb' => old_data }
25
- new_report = { '/projects/coverband_demo/config/coverband.rb' => [5, 7, nil],
26
- '/projects/coverband_demo/config/initializers/filter_logging.rb' => [5, 7, nil],
27
- '/projects/coverband_demo/config/initializers/wrap_parameters.rb' => [5, 7, nil],
28
- '/projects/coverband_demo/app/controllers/application_controller.rb' => [5, 7, nil] }
29
- expected_merge = {
30
- 'first_updated_at' => old_time,
31
- 'last_updated_at' => current_time,
32
- 'file_hash' => 'abcd',
33
- 'data' => [10, 14, nil]
34
- }
35
- new_data = {
36
- 'first_updated_at' => current_time,
37
- 'last_updated_at' => current_time,
38
- 'file_hash' => 'abcd',
39
- 'data' => [5, 7, nil]
40
- }
41
- expected_result = {
42
- '/projects/coverband_demo/app/controllers/application_controller.rb' => new_data,
43
- '/projects/coverband_demo/config/coverband.rb' => expected_merge,
44
- '/projects/coverband_demo/config/initializers/assets.rb' => old_data,
45
- '/projects/coverband_demo/config/initializers/cookies_serializer.rb' => old_data,
46
- '/projects/coverband_demo/config/initializers/filter_logging.rb' => new_data,
47
- '/projects/coverband_demo/config/initializers/wrap_parameters.rb' => new_data
48
- }
49
- assert_equal expected_result, @store.send(:merge_reports, new_report, old_report)
24
+ def test_array_add
25
+ original = [5, 7, nil, nil]
26
+ latest = [3, 4, nil, 1]
27
+ assert_equal [8, 11, nil, nil], Coverband::Adapters::Base.new.send(:array_add, latest, original)
28
+ Coverband.configuration.stubs(:use_oneshot_lines_coverage).returns(true)
29
+ assert_equal [1, 1, nil, nil], Coverband::Adapters::Base.new.send(:array_add, latest, original)
30
+ Coverband.configuration.stubs(:use_oneshot_lines_coverage).returns(false)
31
+ Coverband.configuration.stubs(:simulate_oneshot_lines_coverage).returns(true)
32
+ assert_equal [1, 1, nil, nil], Coverband::Adapters::Base.new.send(:array_add, latest, original)
33
+ end
34
+
35
+ describe 'Coverband::Adapters::Base using file' do
36
+ def setup
37
+ super
38
+ @test_file_path = '/tmp/coverband_filestore_test_path.json'
39
+ @store = Coverband::Adapters::FileStore.new(@test_file_path)
40
+ mock_file_hash
41
+ end
42
+
43
+ def test_covered_merge
44
+ old_time = 1541958097
45
+ current_time = Time.now.to_i
46
+ old_data = {
47
+ 'first_updated_at' => old_time,
48
+ 'last_updated_at' => current_time,
49
+ 'file_hash' => 'abcd',
50
+ 'data' => [5, 7, nil]
51
+ }
52
+ old_report = { '/projects/coverband_demo/config/coverband.rb' => old_data,
53
+ '/projects/coverband_demo/config/initializers/assets.rb' => old_data,
54
+ '/projects/coverband_demo/config/initializers/cookies_serializer.rb' => old_data }
55
+ new_report = { '/projects/coverband_demo/config/coverband.rb' => [5, 7, nil],
56
+ '/projects/coverband_demo/config/initializers/filter_logging.rb' => [5, 7, nil],
57
+ '/projects/coverband_demo/config/initializers/wrap_parameters.rb' => [5, 7, nil],
58
+ '/projects/coverband_demo/app/controllers/application_controller.rb' => [5, 7, nil] }
59
+ expected_merge = {
60
+ 'first_updated_at' => old_time,
61
+ 'last_updated_at' => current_time,
62
+ 'file_hash' => 'abcd',
63
+ 'data' => [10, 14, nil]
64
+ }
65
+ new_data = {
66
+ 'first_updated_at' => current_time,
67
+ 'last_updated_at' => current_time,
68
+ 'file_hash' => 'abcd',
69
+ 'data' => [5, 7, nil]
70
+ }
71
+ expected_result = {
72
+ '/projects/coverband_demo/app/controllers/application_controller.rb' => new_data,
73
+ '/projects/coverband_demo/config/coverband.rb' => expected_merge,
74
+ '/projects/coverband_demo/config/initializers/assets.rb' => old_data,
75
+ '/projects/coverband_demo/config/initializers/cookies_serializer.rb' => old_data,
76
+ '/projects/coverband_demo/config/initializers/filter_logging.rb' => new_data,
77
+ '/projects/coverband_demo/config/initializers/wrap_parameters.rb' => new_data
78
+ }
79
+ assert_equal expected_result, @store.send(:merge_reports, new_report, old_report)
80
+ end
50
81
  end
51
82
  end
@@ -3,45 +3,56 @@
3
3
  require File.expand_path('../../test_helper', File.dirname(__FILE__))
4
4
 
5
5
  class AdaptersFileStoreTest < Minitest::Test
6
- def setup
7
- super
8
- @test_file_path = '/tmp/coverband_filestore_test_path.json'
9
- File.open(@test_file_path, 'w') { |f| f.write(test_data.to_json) }
10
- @store = Coverband::Adapters::FileStore.new(@test_file_path)
11
- end
12
-
13
- def test_coverage
14
- assert_equal @store.coverage['dog.rb']['data'][0], 1
15
- assert_equal @store.coverage['dog.rb']['data'][1], 2
16
- end
17
-
18
- def test_covered_lines_when_null
19
- assert_nil @store.coverage['none.rb']
20
- end
21
6
 
22
- def test_covered_files
23
- assert_equal @store.covered_files, ['dog.rb']
7
+ def test_covered_lines_when_no_file
8
+ @store = Coverband::Adapters::FileStore.new('')
9
+ expected = {}
10
+ assert_equal expected, @store.coverage
24
11
  end
25
12
 
26
- def test_clear
27
- @store.clear!
28
- assert_equal false, File.exist?(@test_file_path)
29
- end
30
-
31
- def test_save_report
32
- mock_file_hash
33
- @store.send(:save_report, 'cat.rb' => [0, 1])
34
- assert_equal @store.coverage['cat.rb']['data'][1], 1
35
- end
36
-
37
- private
38
-
39
- def test_data
40
- {
41
- 'dog.rb' => { 'data' => [1, 2, nil],
42
- 'file_hash' => 'abcd',
43
- 'first_updated_at' => 1541968729,
44
- 'last_updated_at' => 1541968729 }
45
- }
13
+ describe 'Coverband::Adapters::FileStore with file' do
14
+ def setup
15
+ super
16
+ @test_file_path = '/tmp/coverband_filestore_test_path.json'
17
+ File.open(@test_file_path, 'w') { |f| f.write(test_data.to_json) }
18
+ @store = Coverband::Adapters::FileStore.new(@test_file_path)
19
+ end
20
+
21
+ def test_size
22
+ assert @store.size > 1
23
+ end
24
+
25
+ def test_coverage
26
+ assert_equal @store.coverage['dog.rb']['data'][0], 1
27
+ assert_equal @store.coverage['dog.rb']['data'][1], 2
28
+ end
29
+
30
+ def test_covered_lines_when_null
31
+ assert_nil @store.coverage['none.rb']
32
+ end
33
+
34
+ def test_covered_files
35
+ assert_equal @store.covered_files, ['dog.rb']
36
+ end
37
+
38
+ def test_clear
39
+ @store.clear!
40
+ assert_equal false, File.exist?(@test_file_path)
41
+ end
42
+
43
+ def test_save_report
44
+ mock_file_hash
45
+ @store.send(:save_report, 'cat.rb' => [0, 1])
46
+ assert_equal @store.coverage['cat.rb']['data'][1], 1
47
+ end
48
+
49
+ def test_data
50
+ {
51
+ 'dog.rb' => { 'data' => [1, 2, nil],
52
+ 'file_hash' => 'abcd',
53
+ 'first_updated_at' => 1541968729,
54
+ 'last_updated_at' => 1541968729 }
55
+ }
56
+ end
46
57
  end
47
58
  end
@@ -46,19 +46,19 @@ class RedisTest < Minitest::Test
46
46
  assert_equal expected[key], data['data']
47
47
  end
48
48
 
49
- @store.type = nil
49
+ @store.type = Coverband::RUNTIME_TYPE
50
50
  assert_equal [], @store.coverage.keys
51
51
  end
52
52
 
53
53
  def test_merged_coverage_with_types
54
54
  mock_file_hash
55
- assert_nil @store.type
55
+ assert_equal Coverband::RUNTIME_TYPE, @store.type
56
56
  @store.type = :eager_loading
57
57
  @store.save_report('app_path/dog.rb' => [0, 1, 1])
58
- @store.type = nil
58
+ @store.type = Coverband::RUNTIME_TYPE
59
59
  @store.save_report('app_path/dog.rb' => [1, 0, 1])
60
60
  assert_equal [1, 1, 2], @store.get_coverage_report[:merged]['app_path/dog.rb']['data']
61
- assert_nil @store.type
61
+ assert_equal Coverband::RUNTIME_TYPE, @store.type
62
62
  end
63
63
 
64
64
  def test_coverage_for_file
@@ -68,12 +68,42 @@ class RedisTest < Minitest::Test
68
68
  assert_equal example_line, @store.coverage['app_path/dog.rb']['data']
69
69
  end
70
70
 
71
+ def test_coverage_with_simulate_oneshot_lines_coverage
72
+ Coverband.configuration.stubs(:simulate_oneshot_lines_coverage).returns(true)
73
+ mock_file_hash
74
+ expected = basic_coverage
75
+ @store.save_report(expected)
76
+ assert_equal example_line, @store.get_coverage_report[:runtime]['app_path/dog.rb']['data']
77
+ end
78
+
71
79
  def test_coverage_when_null
72
80
  assert_nil @store.coverage['app_path/dog.rb']
73
81
  end
74
82
 
75
83
  def test_clear
76
- @redis.expects(:del).twice
84
+ @redis.expects(:del).times(3)
77
85
  @store.clear!
78
86
  end
87
+
88
+ def test_clear_file
89
+ mock_file_hash
90
+ @store.type = :eager_loading
91
+ @store.save_report('app_path/dog.rb' => [0, 1, 1])
92
+ @store.type = Coverband::RUNTIME_TYPE
93
+ @store.save_report('app_path/dog.rb' => [1, 0, 1])
94
+ assert_equal [1, 1, 2], @store.get_coverage_report[:merged]['app_path/dog.rb']['data']
95
+ @store.clear_file!('app_path/dog.rb')
96
+ assert_nil @store.get_coverage_report[:merged]['app_path/dog.rb']
97
+ end
98
+
99
+ def test_size
100
+ mock_file_hash
101
+ @store.type = :eager_loading
102
+ @store.save_report('app_path/dog.rb' => [0, 1, 1])
103
+ assert @store.size > 1
104
+ end
105
+
106
+ def test_base_key
107
+ assert @store.send(:base_key).end_with?(Coverband::RUNTIME_TYPE.to_s)
108
+ end
79
109
  end
@@ -39,7 +39,7 @@ class CollectorsCoverageTest < Minitest::Test
39
39
 
40
40
  test 'Dog eager load coverage' do
41
41
  store = Coverband.configuration.store
42
- assert_nil store.type
42
+ assert_equal Coverband::RUNTIME_TYPE, store.type
43
43
  file = coverband.eager_loading do
44
44
  require_unique_file
45
45
  end
@@ -50,8 +50,17 @@ class CollectorsDeltaTest < Minitest::Test
50
50
  end
51
51
 
52
52
  if Coverband.configuration.one_shot_coverage_implemented_in_ruby_version?
53
- test 'one shot lines results' do
53
+ test 'oneshot coverage calls clear' do
54
+ Coverband.configuration.stubs(:use_oneshot_lines_coverage).returns(true)
55
+ current_coverage = {
56
+ 'car.rb' => [1, 5]
57
+ }
54
58
 
59
+ ::Coverage.expects(:result).with(clear: true, stop: false).returns(current_coverage)
60
+ results = Coverband::Collectors::Delta::RubyCoverage.results
61
+ end
62
+
63
+ test 'one shot lines results' do
55
64
  Coverband.configuration.stubs(:use_oneshot_lines_coverage).returns(true)
56
65
  current_coverage = {}
57
66
  results = Coverband::Collectors::Delta.results(mock_coverage(current_coverage))
@@ -23,10 +23,23 @@ class CoverbandTest < Minitest::Test
23
23
  ::Coverband.start
24
24
  end
25
25
 
26
+ test 'Coverband#configured? works' do
27
+ Coverband.configure
28
+ assert Coverband.configured?
29
+ end
30
+
31
+ test 'Eager load coverage block' do
32
+ Coverband.eager_loading_coverage {
33
+ #some code
34
+ 1 + 1
35
+ }
36
+ assert_equal :runtime, Coverband.configuration.store.type
37
+ end
38
+
26
39
  test 'Eager load coverage' do
27
40
  Coverband.eager_loading_coverage!
28
41
  assert_equal :eager_loading, Coverband.configuration.store.type
29
42
  Coverband.runtime_coverage!
30
- assert_nil Coverband.configuration.store.type
43
+ assert_equal :runtime, Coverband.configuration.store.type
31
44
  end
32
45
  end
@@ -13,7 +13,6 @@ class HTMLFormatterTest < Minitest::Test
13
13
  test 'generate dynamic content hosted html report' do
14
14
  Coverband.configure do |config|
15
15
  config.store = @store
16
- config.s3_bucket = nil
17
16
  config.ignore = ['notsomething.rb']
18
17
  end
19
18
  mock_file_hash
@@ -31,7 +30,6 @@ class HTMLFormatterTest < Minitest::Test
31
30
  test 'generate static HTML report file' do
32
31
  Coverband.configure do |config|
33
32
  config.store = @store
34
- config.s3_bucket = nil
35
33
  config.ignore = ['notsomething.rb']
36
34
  end
37
35
  mock_file_hash
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Dog<%=dog_number%>
4
+
5
+ def self.bark
6
+ new.bark
7
+ end
8
+
9
+ def bark
10
+ 'woof'
11
+ end
12
+ end
@@ -24,33 +24,34 @@ class RailsFullStackTest < Minitest::Test
24
24
  # We have to combine everything in one test
25
25
  # because we can only initialize rails once per test
26
26
  # run. Possibly fork test runs to avoid this problem in future?
27
- test 'this is how we do it' do
28
- visit '/dummy/show'
29
- Coverband.report_coverage
30
- assert_content('I am no dummy')
31
- visit '/coverage'
32
- within page.find('a', text: /dummy_controller.rb/).find(:xpath, '../..') do
33
- assert_selector('td', text: '100.0 %')
34
- end
27
+ unless ENV['COVERBAND_MEMORY_TEST']
28
+ test 'this is how we do it' do
29
+ visit '/dummy/show'
30
+ Coverband.report_coverage
31
+ assert_content('I am no dummy')
32
+ visit '/coverage'
33
+ within page.find('a', text: /dummy_controller.rb/).find(:xpath, '../..') do
34
+ assert_selector('td', text: '100.0 %')
35
+ end
35
36
 
36
- # Test gems are reporting coverage
37
- assert_content('Gems')
38
- assert page.html.match('rainbow/wrapper.rb')
37
+ # Test gems are reporting coverage
38
+ assert_content('Gems')
39
+ assert page.html.match('rainbow/wrapper.rb')
39
40
 
40
- # Test eager load data stored separately
41
- dummy_controller = "./test/rails#{Rails::VERSION::MAJOR}_dummy/app/controllers/dummy_controller.rb"
42
- store.type = :eager_loading
43
- eager_expected = [1, 1, 0, nil, nil]
44
- results = store.coverage[dummy_controller]['data']
45
- assert_equal(eager_expected, results)
41
+ # Test eager load data stored separately
42
+ dummy_controller = "./test/rails#{Rails::VERSION::MAJOR}_dummy/app/controllers/dummy_controller.rb"
43
+ store.type = :eager_loading
44
+ eager_expected = [1, 1, 0, nil, nil]
45
+ results = store.coverage[dummy_controller]['data']
46
+ assert_equal(eager_expected, results)
46
47
 
47
- store.type = nil
48
- runtime_expected = [0, 0, 1, nil, nil]
49
- results = store.coverage[dummy_controller]['data']
48
+ store.type = Coverband::RUNTIME_TYPE
49
+ runtime_expected = [0, 0, 1, nil, nil]
50
+ results = store.coverage[dummy_controller]['data']
51
+ end
50
52
  end
51
53
 
52
54
  ###
53
- # Please keep this test starting on line 22
54
55
  # as we run it in single test mode via the benchmarks.
55
56
  # Add new tests below this test
56
57
  ###
@@ -80,14 +81,23 @@ class RailsFullStackTest < Minitest::Test
80
81
  visit '/dummy/show'
81
82
  assert_content('I am no dummy')
82
83
  Coverband.report_coverage
83
- # this is expected to retain memory across requests
84
- # clear it to remove the false positive from test
85
- Coverband::Collectors::Coverage.instance.send(:add_previous_results, nil)
84
+ ###
85
+ # Set to nil not {} as it is easier to verify that no memory is retained when nil gets released
86
+ # don't use Coverband::Collectors::Delta.reset which sets to {}
87
+ #
88
+ # we clear this as this one variable is expected to retain memory and is a false positive
89
+ ###
90
+ Coverband::Collectors::Delta.class_variable_set(:@@previous_coverage, nil)
91
+ # needed to test older versions to discover when we had the regression
92
+ # Coverband::Collectors::Coverage.instance.send(:add_previous_results, nil)
86
93
  end
87
94
  end.pretty_print
88
95
  data = $stdout.string
89
96
  $stdout = previous_out
90
- raise 'leaking memory!!!' if data.match(/retained objects by gem(.*)retained objects by file/m)[0]&.match(/coverband/)
97
+ if data.match(/retained objects by gem(.*)retained objects by file/m)[0]&.match(/coverband/)
98
+ puts data
99
+ raise 'leaking memory!!!'
100
+ end
91
101
  ensure
92
102
  $stdout = previous_out
93
103
  end