coverband 4.2.0 → 4.2.2

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 (99) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +29 -9
  3. data/.travis.yml +10 -8
  4. data/CODE_OF_CONDUCT.md +76 -0
  5. data/Gemfile +3 -1
  6. data/Gemfile.rails4 +1 -0
  7. data/README.md +72 -43
  8. data/Rakefile +14 -3
  9. data/changes.md +66 -11
  10. data/coverband.gemspec +2 -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 +182 -0
  14. data/lib/coverband/adapters/redis_store.rb +33 -11
  15. data/lib/coverband/at_exit.rb +2 -11
  16. data/lib/coverband/collectors/coverage.rb +34 -40
  17. data/lib/coverband/collectors/delta.rb +34 -28
  18. data/lib/coverband/collectors/view_tracker.rb +124 -0
  19. data/lib/coverband/configuration.rb +96 -32
  20. data/lib/coverband/integrations/background.rb +9 -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 +21 -27
  28. data/lib/coverband/reporters/web.rb +19 -21
  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 +37 -8
  33. data/lib/coverband/utils/lines_classifier.rb +5 -0
  34. data/lib/coverband/utils/railtie.rb +20 -9
  35. data/lib/coverband/utils/relative_file_converter.rb +41 -0
  36. data/lib/coverband/utils/result.rb +1 -37
  37. data/lib/coverband/utils/results.rb +51 -0
  38. data/lib/coverband/utils/s3_report.rb +2 -2
  39. data/lib/coverband/utils/source_file.rb +31 -8
  40. data/lib/coverband/utils/tasks.rb +10 -10
  41. data/lib/coverband/version.rb +5 -1
  42. data/lib/coverband.rb +39 -22
  43. data/public/application.css +6 -6
  44. data/public/application.js +27 -0
  45. data/test/benchmarks/benchmark.rake +167 -73
  46. data/test/benchmarks/init_rails.rake +10 -0
  47. data/test/coverband/adapters/base_test.rb +73 -42
  48. data/test/coverband/adapters/file_store_test.rb +48 -37
  49. data/test/coverband/adapters/hash_redis_store_test.rb +190 -0
  50. data/test/coverband/adapters/redis_store_test.rb +92 -59
  51. data/test/coverband/at_exit_test.rb +0 -2
  52. data/test/coverband/collectors/coverage_test.rb +62 -10
  53. data/test/coverband/collectors/delta_test.rb +36 -6
  54. data/test/coverband/collectors/view_tracker_test.rb +77 -0
  55. data/test/coverband/configuration_test.rb +47 -7
  56. data/test/coverband/coverband_test.rb +14 -2
  57. data/test/coverband/integrations/background_middleware_test.rb +44 -0
  58. data/test/coverband/integrations/background_test.rb +1 -3
  59. data/test/coverband/integrations/report_middleware_test.rb +44 -0
  60. data/test/coverband/integrations/resque_worker_test.rb +6 -6
  61. data/test/coverband/integrations/test_resque_job.rb +3 -1
  62. data/test/coverband/reporters/base_test.rb +2 -79
  63. data/test/coverband/reporters/console_test.rb +2 -6
  64. data/test/coverband/reporters/html_test.rb +58 -19
  65. data/test/coverband/reporters/web_test.rb +0 -10
  66. data/test/coverband/utils/absolute_file_converter_test.rb +56 -0
  67. data/test/coverband/utils/file_groups_test.rb +11 -5
  68. data/test/coverband/utils/file_hasher_test.rb +29 -0
  69. data/test/coverband/utils/file_list_test.rb +5 -5
  70. data/test/coverband/utils/html_formatter_test.rb +43 -0
  71. data/test/coverband/utils/relative_file_converter_test.rb +39 -0
  72. data/test/coverband/utils/result_test.rb +6 -47
  73. data/test/coverband/utils/results_test.rb +54 -0
  74. data/test/coverband/utils/s3_report_test.rb +2 -0
  75. data/test/coverband/utils/source_file_test.rb +50 -0
  76. data/test/dog.rb.erb +12 -0
  77. data/test/forked/rails_full_stack_test.rb +106 -0
  78. data/test/forked/rails_rake_full_stack_test.rb +48 -0
  79. data/test/integration/full_stack_test.rb +17 -16
  80. data/test/rails4_dummy/Rakefile +6 -0
  81. data/test/rails4_dummy/config/application.rb +8 -9
  82. data/test/rails4_dummy/config/coverband.rb +5 -3
  83. data/test/rails5_dummy/Rakefile +6 -0
  84. data/test/rails5_dummy/config/application.rb +6 -10
  85. data/test/rails5_dummy/config/coverband.rb +4 -2
  86. data/test/rails_test_helper.rb +22 -5
  87. data/test/test_helper.rb +45 -8
  88. data/test/unique_files.rb +17 -9
  89. data/views/file_list.erb +2 -2
  90. data/views/gem_list.erb +10 -1
  91. data/views/layout.erb +6 -18
  92. data/views/nav.erb +35 -0
  93. data/views/source_file.erb +13 -4
  94. data/views/source_file_loader.erb +1 -1
  95. data/views/view_tracker.erb +37 -0
  96. metadata +59 -25
  97. data/lib/coverband/utils/file_path_helper.rb +0 -57
  98. data/test/coverband/integrations/middleware_test.rb +0 -96
  99. data/test/integration/rails_full_stack_test.rb +0 -95
@@ -1,57 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- ####
4
- # Helper functions for shared logic related to file path manipulation
5
- ####
6
- module Coverband
7
- module Utils
8
- module FilePathHelper
9
- ###
10
- # Takes a full path and converts to a relative path
11
- ###
12
- def full_path_to_relative(full_path)
13
- relative_filename = full_path
14
- Coverband.configuration.all_root_paths.each do |root|
15
- relative_filename = relative_filename.gsub(/^#{root}/, './')
16
- # once we have a relative path break out of the loop
17
- break if relative_filename.start_with? './'
18
- end
19
- relative_filename
20
- end
21
-
22
- ###
23
- # relative_path_to_full code takes:
24
- # relative_path: which is a full path the same as reported by Coverage
25
- # roots: if a collection of all possible full app paths
26
- # EX: [Coverband.configuration.root_paths, "#{current_root}/"]
27
- # The LAST item should be the current file system root
28
- # it expands that expands and adds a '/' as that isn't there from Dir.pwd
29
- #
30
- # NOTEs on configuration.root_paths usage
31
- # strings: matching is pretty simple for full string paths
32
- # regex: to get regex to work for changing deploy directories
33
- # the regex must be double escaped in double quotes
34
- # (if using \d for example)
35
- # or use single qoutes
36
- # example: '/box/apps/app_name/releases/\d+/'
37
- # example: '/var/local/company/company.d/[0-9]*/'
38
- ###
39
- def relative_path_to_full(relative_path, roots)
40
- relative_filename = relative_path
41
- local_filename = relative_filename
42
- roots.each do |root|
43
- relative_filename = relative_filename.gsub(/^#{root}/, './')
44
- end
45
- # the filename for our reports is expected to be a full path.
46
- # roots.last should be roots << current_root}/
47
- # a fully expanded path of config.root
48
- # filename = filename.gsub('./', roots.last)
49
- # above only works for app files
50
- # we need to rethink some of this logic
51
- # gems aren't at project root and can have multiple locations
52
- local_root = roots.find { |root| File.exist?(relative_filename.gsub('./', root)) }
53
- local_root ? relative_filename.gsub('./', local_root) : local_filename
54
- end
55
- end
56
- end
57
- end
@@ -1,96 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require File.expand_path('../../test_helper', File.dirname(__FILE__))
4
- require 'rack'
5
-
6
- class MiddlewareTest < Minitest::Test
7
- REDIS_STORAGE_FORMAT_VERSION = Coverband::Adapters::RedisStore::REDIS_STORAGE_FORMAT_VERSION
8
-
9
- def setup
10
- super
11
- Coverband.configure do |config|
12
- config.store = Coverband::Adapters::RedisStore.new(Redis.new)
13
- config.background_reporting_enabled = false
14
- end
15
- end
16
-
17
- test 'call app' do
18
- request = Rack::MockRequest.env_for('/anything.json')
19
- Coverband::Collectors::Coverage.instance.reset_instance
20
- middleware = Coverband::Middleware.new(fake_app)
21
- results = middleware.call(request)
22
- assert_equal '/anything.json', results.last
23
- end
24
-
25
- test 'pass all rack lint checks' do
26
- Coverband::Collectors::Coverage.instance.reset_instance
27
- app = Rack::Lint.new(Coverband::Middleware.new(fake_app))
28
- env = Rack::MockRequest.env_for('/hello')
29
- app.call(env)
30
- end
31
-
32
- test 'starts background reporter when configured' do
33
- request = Rack::MockRequest.env_for('/anything.json')
34
- Coverband.configuration.stubs(:background_reporting_enabled).returns(true)
35
- Coverband::Collectors::Coverage.instance.expects(:report_coverage).never
36
- Coverband::Background.expects(:start)
37
- middleware = Coverband::Middleware.new(fake_app)
38
- middleware.call(request)
39
- end
40
-
41
- test 'reports coverage when not set to background mode' do
42
- request = Rack::MockRequest.env_for('/anything.json')
43
- Coverband.configuration.stubs(:background_reporting_enabled).returns(false)
44
- Coverband::Collectors::Coverage.instance.expects(:report_coverage)
45
- Coverband::Background.expects(:start).never
46
- middleware = Coverband::Middleware.new(fake_app)
47
- middleware.call(request)
48
- end
49
-
50
- test 'never be report coverage with reporting_frequency of 0' do
51
- request = Rack::MockRequest.env_for('/anything.json')
52
- Coverband::Collectors::Coverage.instance.reset_instance
53
- collector = Coverband::Collectors::Coverage.instance
54
- collector.instance_variable_set('@reporting_frequency', 0.0)
55
- middleware = Coverband::Middleware.new(fake_app)
56
- store = Coverband::Collectors::Coverage.instance.instance_variable_get('@store')
57
- store.expects(:save_report).never
58
- middleware.call(request)
59
- end
60
-
61
- test 'always be enabled with sample percentage of 100' do
62
- request = Rack::MockRequest.env_for('/anything.json')
63
- Coverband::Collectors::Coverage.instance.reset_instance
64
- collector = Coverband::Collectors::Coverage.instance
65
- collector.report_coverage(true)
66
- collector.instance_variable_set('@reporting_frequency', 100.0)
67
- middleware = Coverband::Middleware.new(fake_app)
68
- store = Coverband::Collectors::Coverage.instance.instance_variable_get('@store')
69
- store.expects(:save_report).once
70
- middleware.call(request)
71
- end
72
-
73
- test 'reports coverage when an error is raised' do
74
- request = Rack::MockRequest.env_for('/anything.json')
75
- Coverband::Collectors::Coverage.instance.reset_instance
76
- Coverband::Collectors::Coverage.instance.expects(:report_coverage).once
77
- middleware = Coverband::Middleware.new(fake_app_raise_error)
78
- begin
79
- middleware.call(request)
80
- rescue StandardError
81
- nil
82
- end
83
- end
84
-
85
- private
86
-
87
- def fake_app
88
- @fake_app ||= lambda do |env|
89
- [200, { 'Content-Type' => 'text/plain' }, env['PATH_INFO']]
90
- end
91
- end
92
-
93
- def fake_app_raise_error
94
- @fake_app_raise_error ||= -> { raise 'hell' }
95
- end
96
- end
@@ -1,95 +0,0 @@
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::Collectors::Coverage.instance.report_coverage(true)
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
- test 'this is how we do it' do
28
- visit '/dummy/show'
29
- Coverband.report_coverage(true)
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
35
-
36
- #Test gems are reporting coverage
37
- assert_content('Gems')
38
- assert page.html.match('rainbow/wrapper.rb')
39
-
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)
46
-
47
- store.type = nil
48
- runtime_expected = [0, 0, 1, nil, nil]
49
- results = store.coverage[dummy_controller]['data']
50
- end
51
-
52
- ###
53
- # Please keep this test starting on line 22
54
- # as we run it in single test mode via the benchmarks.
55
- # Add new tests below this test
56
- ###
57
- test 'memory usage' do
58
- return unless ENV['COVERBAND_MEMORY_TEST']
59
- # we don't want this to run during our standard test suite
60
- # as the below profiler changes the runtime
61
- # and shold only be included for isolated processes
62
- begin
63
- require 'memory_profiler'
64
-
65
- # warmup
66
- 3.times do
67
- visit '/dummy/show'
68
- assert_content('I am no dummy')
69
- Coverband.report_coverage(true)
70
- end
71
-
72
- previous_out = $stdout
73
- capture = StringIO.new
74
- $stdout = capture
75
-
76
- MemoryProfiler.report do
77
- 15.times do
78
- visit '/dummy/show'
79
- assert_content('I am no dummy')
80
- Coverband.report_coverage(true)
81
- # this is expected to retain memory across requests
82
- # clear it to remove the false positive from test
83
- Coverband::Collectors::Coverage.instance.send(:add_previous_results, nil)
84
- end
85
- end.pretty_print
86
- data = $stdout.string
87
- $stdout = previous_out
88
- if data.match(/retained objects by gem(.*)retained objects by file/m)[0]&.match(/coverband/)
89
- raise 'leaking memory!!!'
90
- end
91
- ensure
92
- $stdout = previous_out
93
- end
94
- end
95
- end