coverband 4.2.0 → 4.2.4

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.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +29 -10
  3. data/.travis.yml +16 -8
  4. data/CODE_OF_CONDUCT.md +76 -0
  5. data/Gemfile +3 -1
  6. data/Gemfile.rails4 +1 -0
  7. data/README.md +108 -59
  8. data/Rakefile +19 -3
  9. data/changes.md +85 -10
  10. data/coverband.gemspec +3 -5
  11. data/lib/coverband/adapters/base.rb +64 -45
  12. data/lib/coverband/adapters/file_store.rb +15 -9
  13. data/lib/coverband/adapters/hash_redis_store.rb +190 -0
  14. data/lib/coverband/adapters/redis_store.rb +35 -11
  15. data/lib/coverband/at_exit.rb +2 -11
  16. data/lib/coverband/collectors/coverage.rb +35 -41
  17. data/lib/coverband/collectors/delta.rb +34 -28
  18. data/lib/coverband/collectors/view_tracker.rb +157 -0
  19. data/lib/coverband/configuration.rb +115 -33
  20. data/lib/coverband/integrations/background.rb +12 -4
  21. data/lib/coverband/integrations/{middleware.rb → background_middleware.rb} +2 -6
  22. data/lib/coverband/integrations/bundler.rb +8 -0
  23. data/lib/coverband/integrations/report_middleware.rb +15 -0
  24. data/lib/coverband/integrations/resque.rb +3 -5
  25. data/lib/coverband/reporters/base.rb +40 -16
  26. data/lib/coverband/reporters/console_report.rb +1 -0
  27. data/lib/coverband/reporters/html_report.rb +31 -27
  28. data/lib/coverband/reporters/web.rb +63 -18
  29. data/lib/coverband/utils/absolute_file_converter.rb +47 -0
  30. data/lib/coverband/utils/file_hasher.rb +16 -0
  31. data/lib/coverband/utils/file_list.rb +16 -5
  32. data/lib/coverband/utils/html_formatter.rb +45 -8
  33. data/lib/coverband/utils/lines_classifier.rb +5 -0
  34. data/lib/coverband/utils/railtie.rb +28 -10
  35. data/lib/coverband/utils/relative_file_converter.rb +41 -0
  36. data/lib/coverband/utils/result.rb +6 -39
  37. data/lib/coverband/utils/results.rb +51 -0
  38. data/lib/coverband/utils/s3_report.rb +2 -3
  39. data/lib/coverband/utils/source_file.rb +34 -8
  40. data/lib/coverband/utils/tasks.rb +10 -10
  41. data/lib/coverband/version.rb +5 -1
  42. data/lib/coverband.rb +49 -27
  43. data/lua/install.sh +15 -0
  44. data/lua/lib/persist-coverage.lua +28 -0
  45. data/lua/test/bootstrap.lua +5 -0
  46. data/lua/test/harness.lua +19 -0
  47. data/lua/test/redis-call.lua +55 -0
  48. data/lua/test/test-persist-coverage.lua +132 -0
  49. data/public/application.css +14 -6
  50. data/public/application.js +27 -0
  51. data/test/benchmarks/benchmark.rake +167 -73
  52. data/test/benchmarks/init_rails.rake +10 -0
  53. data/test/coverband/adapters/base_test.rb +73 -42
  54. data/test/coverband/adapters/file_store_test.rb +48 -37
  55. data/test/coverband/adapters/hash_redis_store_test.rb +195 -0
  56. data/test/coverband/adapters/redis_store_test.rb +102 -59
  57. data/test/coverband/at_exit_test.rb +0 -2
  58. data/test/coverband/collectors/coverage_test.rb +71 -13
  59. data/test/coverband/collectors/delta_test.rb +36 -6
  60. data/test/coverband/collectors/view_tracker_test.rb +113 -0
  61. data/test/coverband/configuration_test.rb +47 -7
  62. data/test/coverband/coverband_test.rb +14 -2
  63. data/test/coverband/integrations/background_middleware_test.rb +44 -0
  64. data/test/coverband/integrations/background_test.rb +11 -3
  65. data/test/coverband/integrations/report_middleware_test.rb +44 -0
  66. data/test/coverband/integrations/resque_worker_test.rb +5 -6
  67. data/test/coverband/integrations/test_resque_job.rb +3 -1
  68. data/test/coverband/reporters/base_test.rb +5 -81
  69. data/test/coverband/reporters/console_test.rb +3 -10
  70. data/test/coverband/reporters/html_test.rb +71 -21
  71. data/test/coverband/reporters/web_test.rb +0 -10
  72. data/test/coverband/utils/absolute_file_converter_test.rb +56 -0
  73. data/test/coverband/utils/file_groups_test.rb +11 -5
  74. data/test/coverband/utils/file_hasher_test.rb +29 -0
  75. data/test/coverband/utils/file_list_test.rb +5 -5
  76. data/test/coverband/utils/html_formatter_test.rb +41 -0
  77. data/test/coverband/utils/relative_file_converter_test.rb +39 -0
  78. data/test/coverband/utils/result_test.rb +6 -47
  79. data/test/coverband/utils/results_test.rb +54 -0
  80. data/test/coverband/utils/s3_report_test.rb +2 -0
  81. data/test/coverband/utils/source_file_test.rb +54 -0
  82. data/test/dog.rb.erb +12 -0
  83. data/test/forked/rails_full_stack_test.rb +106 -0
  84. data/test/forked/rails_rake_full_stack_test.rb +58 -0
  85. data/test/integration/full_stack_test.rb +15 -16
  86. data/test/rails4_dummy/Rakefile +6 -0
  87. data/test/rails4_dummy/config/application.rb +8 -9
  88. data/test/rails4_dummy/config/coverband.rb +3 -11
  89. data/test/rails4_dummy/config/coverband_missing_redis.rb +3 -0
  90. data/test/rails5_dummy/Rakefile +6 -0
  91. data/test/rails5_dummy/config/application.rb +6 -10
  92. data/test/rails5_dummy/config/coverband.rb +7 -3
  93. data/test/rails5_dummy/config/coverband_missing_redis.rb +15 -0
  94. data/test/rails_test_helper.rb +22 -5
  95. data/test/test_helper.rb +52 -11
  96. data/test/unique_files.rb +17 -9
  97. data/views/data.erb +1 -0
  98. data/views/file_list.erb +13 -12
  99. data/views/gem_list.erb +10 -1
  100. data/views/layout.erb +6 -18
  101. data/views/nav.erb +36 -0
  102. data/views/source_file.erb +20 -4
  103. data/views/source_file_loader.erb +1 -1
  104. data/views/view_tracker.erb +52 -0
  105. metadata +71 -12
  106. data/lib/coverband/utils/file_path_helper.rb +0 -57
  107. data/test/coverband/integrations/middleware_test.rb +0 -96
  108. data/test/integration/rails_full_stack_test.rb +0 -95
@@ -62,6 +62,10 @@ describe Coverband::Utils::SourceFile do
62
62
  it 'has 80% covered_percent' do
63
63
  assert_equal 80.0, subject.covered_percent
64
64
  end
65
+
66
+ it 'working for nil last_updated_at' do
67
+ assert_equal "not available", subject.last_updated_at
68
+ end
65
69
  end
66
70
 
67
71
  describe 'simulating potential Ruby 1.9 defect -- see Issue #56' do
@@ -146,4 +150,54 @@ describe Coverband::Utils::SourceFile do
146
150
  assert_equal 0.0, subject.covered_percent
147
151
  end
148
152
  end
153
+
154
+ describe 'correctly identifies gems' do
155
+ COVERAGE_FOR_SKIPPED_AND_EXECUTED_RB = [nil, nil, 1, 1, 0, 1, 1, nil].freeze
156
+
157
+ describe 'the word gem in a path' do
158
+ subject do
159
+ Coverband::Utils::SourceFile.new('lib/rubocop/cop/gemspec/required_ruby_version.rb', COVERAGE_FOR_SKIPPED_AND_EXECUTED_RB)
160
+ end
161
+
162
+ it 'allows the word gem in path' do
163
+ assert_equal nil, subject.gem?
164
+ end
165
+ end
166
+
167
+ describe 'a folder gem in the path' do
168
+ subject do
169
+ Coverband::Utils::SourceFile.new('/var/gems/rubocop-0.67.0/lib/rubocop/cop/gemspec/required_ruby_version.rb', COVERAGE_FOR_SKIPPED_AND_EXECUTED_RB)
170
+ end
171
+
172
+ it 'allows the word gem in path' do
173
+ assert subject.gem?
174
+ end
175
+ end
176
+ end
177
+
178
+ describe 'correctly reports gem name' do
179
+ COVERAGE_FOR_SKIPPED_AND_EXECUTED_RB = [nil, nil, 1, 1, 0, 1, 1, nil].freeze
180
+
181
+ describe 'the word gem in a path' do
182
+ subject do
183
+ Coverband::Utils::SourceFile.new('lib/rubocop/cop/gemspec/required_ruby_version.rb', COVERAGE_FOR_SKIPPED_AND_EXECUTED_RB)
184
+ end
185
+
186
+ it 'allows the word gem in path' do
187
+ assert_equal nil, subject.gem_name
188
+ end
189
+ end
190
+
191
+ describe 'a folder gem in the path' do
192
+ subject do
193
+ Coverband::Utils::SourceFile.new('/var/gems/rubocop-0.67.0/lib/rubocop/cop/gemspec/required_ruby_version.rb', COVERAGE_FOR_SKIPPED_AND_EXECUTED_RB)
194
+ end
195
+
196
+ it 'allows the word gem in path' do
197
+ assert_equal 'rubocop-0.67.0', subject.gem_name
198
+ end
199
+ end
200
+ end
201
+
202
+
149
203
  end
data/test/dog.rb.erb ADDED
@@ -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
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path('../rails_test_helper', File.dirname(__FILE__))
4
+
5
+ class RailsFullStackTest < Minitest::Test
6
+ include Capybara::DSL
7
+ include Capybara::Minitest::Assertions
8
+
9
+ def setup
10
+ super
11
+ rails_setup
12
+ # preload first coverage hit
13
+ Coverband.report_coverage
14
+ require 'rainbow'
15
+ Rainbow('this text is red').red
16
+ end
17
+
18
+ def teardown
19
+ super
20
+ Capybara.reset_sessions!
21
+ Capybara.use_default_driver
22
+ end
23
+
24
+ # We have to combine everything in one test
25
+ # because we can only initialize rails once per test
26
+ # run. Possibly fork test runs to avoid this problem in future?
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
36
+
37
+ # Test gems are reporting coverage
38
+ assert_content('Gems')
39
+ assert page.html.match('rainbow/wrapper.rb')
40
+
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)
47
+
48
+ store.type = Coverband::RUNTIME_TYPE
49
+ runtime_expected = [0, 0, 1, nil, nil]
50
+ results = store.coverage[dummy_controller]['data']
51
+ end
52
+ end
53
+
54
+ ###
55
+ # as we run it in single test mode via the benchmarks.
56
+ # Add new tests below this test
57
+ ###
58
+ if ENV['COVERBAND_MEMORY_TEST']
59
+ test 'memory usage' do
60
+ return unless ENV['COVERBAND_MEMORY_TEST']
61
+
62
+ # we don't want this to run during our standard test suite
63
+ # as the below profiler changes the runtime
64
+ # and shold only be included for isolated processes
65
+ begin
66
+ require 'memory_profiler'
67
+
68
+ # warmup
69
+ 3.times do
70
+ visit '/dummy/show'
71
+ assert_content('I am no dummy')
72
+ Coverband.report_coverage
73
+ end
74
+
75
+ previous_out = $stdout
76
+ capture = StringIO.new
77
+ $stdout = capture
78
+
79
+ MemoryProfiler.report do
80
+ 15.times do
81
+ visit '/dummy/show'
82
+ assert_content('I am no dummy')
83
+ Coverband.report_coverage
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)
93
+ end
94
+ end.pretty_print
95
+ data = $stdout.string
96
+ $stdout = previous_out
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
101
+ ensure
102
+ $stdout = previous_out
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path('../rails_test_helper', File.dirname(__FILE__))
4
+ require 'rails'
5
+ require 'pundit'
6
+
7
+ class RailsRakeFullStackTest < Minitest::Test
8
+ def setup
9
+ super
10
+ Coverband.configuration.reset
11
+ Coverband.configure("./test/rails#{Rails::VERSION::MAJOR}_dummy/config/coverband.rb")
12
+ end
13
+
14
+ test 'rake tasks shows coverage properly within eager_loading' do
15
+ store.instance_variable_set(:@redis_namespace, 'coverband_test')
16
+ store.clear!
17
+ system("COVERBAND_CONFIG=./test/rails#{Rails::VERSION::MAJOR}_dummy/config/coverband.rb bundle exec rake -f test/rails#{Rails::VERSION::MAJOR}_dummy/Rakefile middleware")
18
+ store.instance_variable_set(:@redis_namespace, 'coverband_test')
19
+ store.type = :eager_loading
20
+ pundit_file = store.coverage.keys.grep(/pundit.rb/).first
21
+ refute_nil pundit_file
22
+ pundit_coverage = store.coverage[pundit_file]
23
+ refute_nil pundit_coverage
24
+ assert_includes pundit_coverage['data'], 1
25
+
26
+ store.type = Coverband::RUNTIME_TYPE
27
+ if ENV['SIMULATE_ONESHOT']
28
+ pundit_coverage = store.get_coverage_report[Coverband::RUNTIME_TYPE][pundit_file]
29
+ assert pundit_coverage['data'].compact.all? { |el| el == 0 }
30
+ else
31
+ pundit_coverage = store.coverage[pundit_file]
32
+ assert_nil pundit_coverage
33
+ end
34
+ end
35
+
36
+ test "ignored rake tasks don't add coverage" do
37
+ store.clear!
38
+ store.instance_variable_set(:@redis_namespace, 'coverband_test')
39
+ store.send(:save_report, basic_coverage_full_path)
40
+ output = `COVERBAND_CONFIG=./test/rails#{Rails::VERSION::MAJOR}_dummy/config/coverband.rb bundle exec rake -f test/rails#{Rails::VERSION::MAJOR}_dummy/Rakefile coverband:clear`
41
+ assert_nil output.match(/Coverband: Reported coverage via thread/)
42
+ coverage_report = store.get_coverage_report
43
+ empty_hash = {}
44
+ assert_equal empty_hash, coverage_report[Coverband::RUNTIME_TYPE]
45
+ assert_equal empty_hash, coverage_report[:eager_loading]
46
+ assert_equal empty_hash, coverage_report[:merged]
47
+ end
48
+
49
+ test "doesn't exit non-zero with error on missing redis" do
50
+ output = `COVERBAND_CONFIG=./test/rails#{Rails::VERSION::MAJOR}_dummy/config/coverband_missing_redis.rb bundle exec rake -f test/rails#{Rails::VERSION::MAJOR}_dummy/Rakefile -T`
51
+ assert_equal 0, $?.to_i
52
+ if ENV['COVERBAND_HASH_REDIS_STORE']
53
+ assert output.match(/Redis is not available/)
54
+ else
55
+ assert output.match(/coverage failed to store/)
56
+ end
57
+ end
58
+ end
@@ -6,52 +6,51 @@ require 'rack'
6
6
  class FullStackTest < Minitest::Test
7
7
  REDIS_STORAGE_FORMAT_VERSION = Coverband::Adapters::RedisStore::REDIS_STORAGE_FORMAT_VERSION
8
8
  TEST_RACK_APP = '../fake_app/basic_rack.rb'
9
- RELATIVE_FILE = './fake_app/basic_rack.rb'
10
9
 
11
10
  def setup
12
11
  super
13
12
  Coverband::Collectors::Coverage.instance.reset_instance
14
13
  Coverband.configure do |config|
15
- config.reporting_frequency = 100.0
16
- config.store = Coverband::Adapters::RedisStore.new(Redis.new)
17
14
  config.s3_bucket = nil
18
15
  config.background_reporting_enabled = false
19
- config.root_paths = ["#{File.expand_path('../', File.dirname(__FILE__))}/"]
20
16
  config.track_gems = true
21
17
  end
22
- Coverband.configuration.store.clear!
23
18
  Coverband.start
19
+ Coverband::Collectors::Coverage.instance.eager_loading!
20
+ @rack_file = require_unique_file 'fake_app/basic_rack.rb'
21
+ Coverband.report_coverage
24
22
  Coverband::Collectors::Coverage.instance.runtime!
25
- @rack_file = File.expand_path(TEST_RACK_APP, File.dirname(__FILE__))
26
- require @rack_file
27
- # preload first coverage hit
28
- Coverband::Collectors::Coverage.instance.report_coverage(true)
29
23
  end
30
24
 
31
25
  test 'call app' do
32
26
  request = Rack::MockRequest.env_for('/anything.json')
33
- middleware = Coverband::Middleware.new(fake_app_with_lines)
27
+ middleware = Coverband::BackgroundMiddleware.new(fake_app_with_lines)
34
28
  results = middleware.call(request)
35
29
  assert_equal 'Hello Rack!', results.last
36
- sleep(0.2)
30
+ Coverband.report_coverage
37
31
  expected = [nil, nil, 0, nil, 0, 0, 1, nil, nil]
38
- assert_equal expected, Coverband.configuration.store.coverage[RELATIVE_FILE]['data']
32
+ assert_equal expected, Coverband.configuration.store.coverage[@rack_file]['data']
39
33
 
40
34
  # additional calls increase count by 1
41
35
  middleware.call(request)
42
- sleep(0.2)
36
+ Coverband.report_coverage
43
37
  expected = [nil, nil, 0, nil, 0, 0, 2, nil, nil]
44
- assert_equal expected, Coverband.configuration.store.coverage[RELATIVE_FILE]['data']
38
+ assert_equal expected, Coverband.configuration.store.coverage[@rack_file]['data']
39
+
40
+ # class coverage
41
+ Coverband.eager_loading_coverage!
42
+ Coverband.configuration.store.coverage[@rack_file]['data']
43
+ expected = [nil, nil, 1, nil, 1, 1, 0, nil, nil]
45
44
  end
46
45
 
47
46
  test 'call app with gem tracking' do
48
47
  require 'rainbow'
49
48
  Rainbow('this text is red').red
50
49
  request = Rack::MockRequest.env_for('/anything.json')
51
- middleware = Coverband::Middleware.new(fake_app_with_lines)
50
+ middleware = Coverband::BackgroundMiddleware.new(fake_app_with_lines)
52
51
  results = middleware.call(request)
53
52
  assert_equal 'Hello Rack!', results.last
54
- sleep(0.1)
53
+ Coverband.report_coverage
55
54
  assert Coverband.configuration.store.coverage.keys.any? { |key| key.end_with?('rainbow/global.rb') }
56
55
  end
57
56
 
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require_relative 'config/application'
5
+
6
+ Rails.application.load_tasks
@@ -1,15 +1,14 @@
1
- require File.expand_path('../boot', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path('boot', __dir__)
4
+
5
+ require 'rails'
6
+ require 'action_controller/railtie'
7
+ require 'coverband'
8
+ Bundler.require(*Rails.groups)
2
9
 
3
- require "rails"
4
- require "action_controller/railtie"
5
10
  module Rails4Dummy
6
11
  class Application < Rails::Application
7
- # Coverband needs to be setup before any of the initializers to capture usage of them
8
- Coverband.configure(File.open("#{Rails.root}/config/coverband.rb"))
9
- config.middleware.use Coverband::Middleware
10
- config.before_initialize do
11
- Coverband.start
12
- end
13
12
  config.eager_load = true
14
13
  end
15
14
  end
@@ -1,11 +1,3 @@
1
- Coverband.configure do |config|
2
- config.root = Dir.pwd
3
- config.store = Coverband::Adapters::RedisStore.new(Redis.new(url: ENV['REDIS_URL'])) if defined? Redis
4
- config.ignore = %w[vendor .erb$ .slim$]
5
- config.root_paths = []
6
- config.logger = Rails.logger
7
- config.verbose = true
8
- config.background_reporting_enabled = false
9
- config.track_gems = true
10
- config.gem_details = true
11
- end
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../rails5_dummy/config/coverband'
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../rails5_dummy/config/coverband_missing_redis'
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require_relative 'config/application'
5
+
6
+ Rails.application.load_tasks
@@ -1,16 +1,12 @@
1
- require "rails"
2
- require "action_controller/railtie"
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails'
4
+ require 'action_controller/railtie'
3
5
  require 'coverband'
6
+ Bundler.require(*Rails.groups)
4
7
 
5
- module Dummy
8
+ module Rails5Dummy
6
9
  class Application < Rails::Application
7
- # Coverband needs to be setup before any of the initializers to capture usage of them
8
- Coverband.configure(File.open("#{Rails.root}/config/coverband.rb"))
9
- config.middleware.use Coverband::Middleware
10
- config.before_initialize do
11
- Coverband.start
12
- end
13
10
  config.eager_load = true
14
11
  end
15
12
  end
16
-
@@ -1,11 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  Coverband.configure do |config|
2
4
  config.root = Dir.pwd
3
- config.store = Coverband::Adapters::RedisStore.new(Redis.new(url: ENV['REDIS_URL'])) if defined? Redis
4
- config.ignore = %w[vendor .erb$ .slim$]
5
+ config.store = Coverband::Adapters::RedisStore.new(Redis.new(db: 2, url: ENV['REDIS_URL']), redis_namespace: 'coverband_test') if defined? Redis
6
+ config.ignore = %w[.erb$ .slim$]
5
7
  config.root_paths = []
6
8
  config.logger = Rails.logger
7
9
  config.verbose = true
8
- config.background_reporting_enabled = false
10
+ config.background_reporting_enabled = true
9
11
  config.track_gems = true
10
12
  config.gem_details = true
13
+ config.use_oneshot_lines_coverage = true if ENV['ONESHOT']
14
+ config.simulate_oneshot_lines_coverage = true if ENV['SIMULATE_ONESHOT']
11
15
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ Coverband.configure do |config|
4
+ config.root = Dir.pwd
5
+ config.store = Coverband::Adapters::RedisStore.new(Redis.new(db: 2, url: 'redis://127.0.0.1:123'), redis_namespace: 'coverband_test') if defined? Redis
6
+ config.ignore = %w[vendor .erb$ .slim$]
7
+ config.root_paths = []
8
+ config.logger = Rails.logger
9
+ config.verbose = true
10
+ config.background_reporting_enabled = true
11
+ config.track_gems = true
12
+ config.gem_details = true
13
+ config.use_oneshot_lines_coverage = true if ENV['ONESHOT']
14
+ config.simulate_oneshot_lines_coverage = true if ENV['SIMULATE_ONESHOT']
15
+ end
@@ -1,16 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minitest'
4
+ require 'minitest/fork_executor'
5
+
6
+ # Forked executor includes autorun which does not work with qrush/m
7
+ # https://github.com/qrush/m/issues/26
8
+ # https://github.com/seattlerb/minitest/blob/master/lib/minitest/autorun.rb
9
+ if defined?(M)
10
+ Minitest.class_eval do
11
+ def self.autorun
12
+ puts 'No autorunning'
13
+ end
14
+ end
15
+ end
16
+
17
+ Minitest.parallel_executor = Minitest::ForkExecutor.new
1
18
  require File.expand_path('./test_helper', File.dirname(__FILE__))
2
19
  require 'capybara'
3
20
  require 'capybara/minitest'
4
21
  def rails_setup
5
- ENV["RAILS_ENV"] = "test"
22
+ ENV['RAILS_ENV'] = 'test'
6
23
  require 'rails'
7
- #coverband must be required after rails
8
- load 'coverband/utils/railtie.rb'
24
+ # coverband must be required after rails
9
25
  Coverband.configure("./test/rails#{Rails::VERSION::MAJOR}_dummy/config/coverband.rb")
26
+ load 'coverband/utils/railtie.rb'
27
+
10
28
  require_relative "../test/rails#{Rails::VERSION::MAJOR}_dummy/config/environment"
11
29
  require 'capybara/rails'
12
- #Our coverage report is wrapped in display:none as of now
30
+ # Our coverage report is wrapped in display:none as of now
13
31
  Capybara.ignore_hidden_elements = false
14
32
  require 'mocha/minitest'
15
33
  end
16
-
data/test/test_helper.rb CHANGED
@@ -7,8 +7,8 @@ original_verbosity = $VERBOSE
7
7
  $VERBOSE = nil
8
8
  require 'rubygems'
9
9
  require 'aws-sdk-s3'
10
- require 'coveralls'
11
10
  require 'simplecov'
11
+ require 'coveralls'
12
12
  require 'minitest/autorun'
13
13
  require 'mocha/minitest'
14
14
  require 'ostruct'
@@ -19,18 +19,35 @@ require 'pry-byebug'
19
19
  require_relative 'unique_files'
20
20
  $VERBOSE = original_verbosity
21
21
 
22
- Coveralls.wear!
22
+ unless ENV['ONESHOT'] || ENV['SIMULATE_ONESHOT']
23
+ SimpleCov.formatter = Coveralls::SimpleCov::Formatter
24
+ SimpleCov.start do
25
+ add_filter 'test/forked'
26
+ end
27
+
28
+ Coveralls.wear!
29
+ end
23
30
 
24
31
  module Coverband
25
32
  module Test
33
+ TEST_DB = 2
34
+
35
+ def self.redis
36
+ @redis ||= Redis.new(db: TEST_DB)
37
+ end
38
+
26
39
  def self.reset
27
- [:eager_loading, nil].each do |type|
28
- Coverband.configuration.store.type = type
29
- Coverband.configuration.store.clear!
30
- end
40
+ Coverband.configuration.redis_namespace = 'coverband_test'
41
+ Coverband.configuration.store.instance_variable_set(:@redis_namespace, 'coverband_test')
42
+ Coverband.configuration.store.class.class_variable_set(:@@path_cache, {})
31
43
  Coverband.configuration.reset
32
44
  Coverband::Collectors::Coverage.instance.reset_instance
45
+ Coverband::Utils::RelativeFileConverter.reset
46
+ Coverband::Utils::AbsoluteFileConverter.reset
47
+ Coverband.configuration.redis_namespace = 'coverband_test'
33
48
  Coverband::Background.stop
49
+ Coverband.configuration.store.instance_variable_set(:@redis, redis)
50
+ redis.flushdb
34
51
  end
35
52
 
36
53
  def setup
@@ -60,6 +77,7 @@ def test(name, &block)
60
77
  false
61
78
  end
62
79
  raise "#{test_name} is already defined in #{self}" if defined
80
+
63
81
  if block_given?
64
82
  define_method(test_name, &block)
65
83
  else
@@ -69,10 +87,8 @@ def test(name, &block)
69
87
  end
70
88
  end
71
89
 
72
- def mock_file_hash
73
- mock_file = mock('mock_file')
74
- mock_file.expects(:hexdigest).at_least_once.returns('abcd')
75
- Digest::MD5.expects(:file).at_least_once.returns(mock_file)
90
+ def mock_file_hash(hash: 'abcd')
91
+ Coverband::Utils::FileHasher.expects(:hash).at_least_once.returns(hash)
76
92
  end
77
93
 
78
94
  def example_line
@@ -83,16 +99,41 @@ def basic_coverage
83
99
  { 'app_path/dog.rb' => example_line }
84
100
  end
85
101
 
102
+ def basic_coverage_full_path
103
+ { basic_coverage_file_full_path => example_line }
104
+ end
105
+
106
+ def basic_source_fixture_coverage
107
+ { source_fixture('sample.rb') => example_line }
108
+ end
109
+
110
+ def basic_coverage_file_full_path
111
+ "#{test_root}/dog.rb"
112
+ end
113
+
86
114
  def source_fixture(filename)
87
115
  File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', filename))
88
116
  end
89
117
 
118
+ def fixtures_root
119
+ File.expand_path(File.join(File.dirname(__FILE__), 'fixtures'))
120
+ end
121
+
90
122
  def test_root
91
123
  File.expand_path(File.join(File.dirname(__FILE__)))
92
124
  end
93
125
 
126
+ ###
127
+ # This handles an issue where the store is setup in tests prior to being able to set the namespace
128
+ ###
94
129
  def store
95
- Coverband.configuration.store
130
+ if Coverband.configuration.store.redis_namespace == 'coverband_test'
131
+ Coverband.configuration.store
132
+ else
133
+ Coverband.configuration.redis_namespace = 'coverband_test'
134
+ Coverband.configuration.instance_variable_set(:@store, nil)
135
+ Coverband.configuration.store
136
+ end
96
137
  end
97
138
 
98
139
  # Taken from http://stackoverflow.com/questions/4459330/how-do-i-temporarily-redirect-stderr-in-ruby
data/test/unique_files.rb CHANGED
@@ -2,22 +2,30 @@
2
2
 
3
3
  require 'securerandom'
4
4
  require 'fileutils'
5
+ require 'erb'
6
+ require 'ostruct'
5
7
 
6
- UNIQUE_FILES_DIR = "./test/unique_files"
8
+ UNIQUE_FILES_DIR = './test/unique_files'
7
9
 
8
- def require_unique_file(file = 'dog.rb')
9
- dir = "#{UNIQUE_FILES_DIR}/#{SecureRandom.uuid}"
10
- FileUtils.mkdir_p(dir)
11
- temp_file = "#{dir}/#{file}"
12
- File.open(temp_file, 'w'){ |w| w.write(File.read("./test/#{file}")) }
10
+ def require_unique_file(file = 'dog.rb', variables = {})
11
+ uuid = SecureRandom.uuid
12
+ dir = "#{UNIQUE_FILES_DIR}/#{uuid}"
13
+ file_name = file.sub('.erb', '')
14
+ temp_file = "#{dir}/#{file_name}"
15
+ FileUtils.mkdir_p(Pathname.new(temp_file).dirname.to_s)
16
+ file_contents = File.read("./test/#{file}")
17
+ file_contents = ERB.new(file_contents).result(OpenStruct.new(variables).instance_eval { binding }) if variables.any?
18
+ File.open(temp_file, 'w') { |w| w.write(file_contents) }
13
19
  require temp_file
14
- temp_file
20
+ Coverband::Utils::RelativeFileConverter.convert(File.expand_path(temp_file))
15
21
  end
16
22
 
17
23
  def remove_unique_files
18
24
  FileUtils.rm_r(UNIQUE_FILES_DIR) if File.exist?(UNIQUE_FILES_DIR)
19
25
  end
20
26
 
21
- Minitest.after_run do
22
- remove_unique_files
27
+ if defined?(Minitest)
28
+ Minitest.after_run do
29
+ remove_unique_files
30
+ end
23
31
  end
data/views/data.erb ADDED
@@ -0,0 +1 @@
1
+ <%= result.source_files.to_json %>