coverband 6.1.4 → 6.1.5

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 (85) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +16 -4
  3. data/.gitignore +3 -1
  4. data/.rubocop.yml +1 -1
  5. data/.standard.yml +1 -1
  6. data/Gemfile +1 -1
  7. data/{Gemfile.rails7 → Gemfile.rails7.2} +2 -2
  8. data/{Gemfile.rails6.0 → Gemfile.rails8.0} +2 -2
  9. data/README.md +38 -7
  10. data/Rakefile +1 -1
  11. data/changes.md +17 -3
  12. data/coverband.gemspec +2 -1
  13. data/lib/coverband/collectors/abstract_tracker.rb +1 -1
  14. data/lib/coverband/collectors/route_tracker.rb +2 -2
  15. data/lib/coverband/collectors/view_tracker_service.rb +1 -1
  16. data/lib/coverband/configuration.rb +0 -2
  17. data/lib/coverband/reporters/base.rb +1 -1
  18. data/lib/coverband/utils/dead_methods.rb +5 -1
  19. data/lib/coverband/utils/method_definition_scanner.rb +14 -2
  20. data/lib/coverband/utils/tasks.rb +24 -6
  21. data/lib/coverband/version.rb +1 -1
  22. data/lib/coverband.rb +26 -0
  23. data/test/benchmarks/benchmark.rake +5 -3
  24. data/test/coverband/collectors/coverage_test.rb +3 -7
  25. data/test/coverband/collectors/route_tracker_test.rb +0 -1
  26. data/test/coverband/collectors/translation_tracker_test.rb +0 -1
  27. data/test/coverband/configuration_test.rb +0 -10
  28. data/test/coverband/integrations/rack_server_check_test.rb +6 -3
  29. data/test/coverband/track_key_test.rb +66 -0
  30. data/test/coverband/utils/dead_methods_test.rb +14 -2
  31. data/test/coverband/utils/method_definition_scanner_test.rb +1 -1
  32. data/test/dog.rb +5 -0
  33. data/test/forked/rails_full_stack_views_test.rb +1 -1
  34. data/test/rails7_dummy/config/coverband.rb +13 -1
  35. data/test/rails7_dummy/config/coverband_missing_redis.rb +12 -1
  36. data/test/rails8_dummy/config/coverband.rb +3 -0
  37. data/test/rails8_dummy/config/coverband_missing_redis.rb +3 -0
  38. data/test/rails8_dummy/tmp/local_secret.txt +1 -0
  39. data/test/test_helper.rb +1 -4
  40. data/test/unique_files.rb +6 -2
  41. metadata +36 -49
  42. data/Gemfile.rails6.1 +0 -10
  43. data/test/rails4_dummy/config/application.rb +0 -15
  44. data/test/rails4_dummy/config/coverband.rb +0 -3
  45. data/test/rails4_dummy/config/coverband_missing_redis.rb +0 -3
  46. data/test/rails5_dummy/Rakefile +0 -6
  47. data/test/rails5_dummy/app/controllers/dummy_controller.rb +0 -5
  48. data/test/rails5_dummy/app/controllers/dummy_view_controller.rb +0 -16
  49. data/test/rails5_dummy/app/views/dummy_view/show.html.erb +0 -5
  50. data/test/rails5_dummy/app/views/dummy_view/show_haml.html.haml +0 -4
  51. data/test/rails5_dummy/app/views/dummy_view/show_slim.html.slim +0 -4
  52. data/test/rails5_dummy/config/application.rb +0 -14
  53. data/test/rails5_dummy/config/coverband.rb +0 -15
  54. data/test/rails5_dummy/config/coverband_missing_redis.rb +0 -14
  55. data/test/rails5_dummy/config/environment.rb +0 -2
  56. data/test/rails5_dummy/config/routes.rb +0 -7
  57. data/test/rails5_dummy/config.ru +0 -3
  58. data/test/rails5_dummy/tmp/.keep +0 -0
  59. data/test/rails6_dummy/Rakefile +0 -6
  60. data/test/rails6_dummy/app/controllers/dummy_controller.rb +0 -5
  61. data/test/rails6_dummy/app/controllers/dummy_view_controller.rb +0 -16
  62. data/test/rails6_dummy/app/views/dummy_view/show.html.erb +0 -5
  63. data/test/rails6_dummy/app/views/dummy_view/show_haml.html.haml +0 -4
  64. data/test/rails6_dummy/app/views/dummy_view/show_slim.html.slim +0 -4
  65. data/test/rails6_dummy/config/boot.rb +0 -3
  66. data/test/rails6_dummy/config/coverband.rb +0 -3
  67. data/test/rails6_dummy/config/coverband_missing_redis.rb +0 -3
  68. data/test/rails6_dummy/config/environment.rb +0 -5
  69. data/test/rails6_dummy/config/routes.rb +0 -7
  70. data/test/rails6_dummy/config/secrets.yml +0 -3
  71. data/test/rails6_dummy/config.ru +0 -4
  72. data/test/rails6_dummy/tmp/.keep +0 -0
  73. /data/test/{rails4_dummy → rails8_dummy}/Rakefile +0 -0
  74. /data/test/{rails4_dummy → rails8_dummy}/app/controllers/dummy_controller.rb +0 -0
  75. /data/test/{rails4_dummy → rails8_dummy}/app/controllers/dummy_view_controller.rb +0 -0
  76. /data/test/{rails4_dummy → rails8_dummy}/app/views/dummy_view/show.html.erb +0 -0
  77. /data/test/{rails4_dummy → rails8_dummy}/app/views/dummy_view/show_haml.html.haml +0 -0
  78. /data/test/{rails4_dummy → rails8_dummy}/app/views/dummy_view/show_slim.html.slim +0 -0
  79. /data/test/{rails6_dummy → rails8_dummy}/config/application.rb +0 -0
  80. /data/test/{rails4_dummy → rails8_dummy}/config/boot.rb +0 -0
  81. /data/test/{rails4_dummy → rails8_dummy}/config/environment.rb +0 -0
  82. /data/test/{rails4_dummy → rails8_dummy}/config/routes.rb +0 -0
  83. /data/test/{rails4_dummy → rails8_dummy}/config/secrets.yml +0 -0
  84. /data/test/{rails4_dummy → rails8_dummy}/config.ru +0 -0
  85. /data/test/{rails4_dummy → rails8_dummy}/tmp/.keep +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a3ffdf0c9a4cefbcbc728967f36ed20a90755074864a2fe858859b739e6912bb
4
- data.tar.gz: e853e687820d45bbf414f51efd3a51f996b05f5eff0dcecac95351b076b3300d
3
+ metadata.gz: 975365fa04dde3dda04ba2ce23934907d8282214dffac3772ce79516fdaaec12
4
+ data.tar.gz: 9bf44550712764df06f191f2c8d4cb99d01d1c1084d9ca730cf52fcd6e5103e3
5
5
  SHA512:
6
- metadata.gz: 3f2f69c9de574808771f002af9fc4903fed8ec9af0d52288457759ff21b1c8a3c0e42111a6ea59c8830893fc57acf05e300f8520903dda920a894419710ad386
7
- data.tar.gz: 20073041f076062cefeeeb8bcec74d703086d70c86c6f7b0b2511474f5c0cd2b9cb61510245cca49104dff53a8979249a2b4dae2bfad85b09682c9dd56ce5628
6
+ metadata.gz: e951529d4bf603e2ec218e2ad175a9288dcd0e18bca0d225ce569185d12f984f7c5d79dd78650d9b2c3dda60f720751387b712f06a2963280e9863ea1083114f
7
+ data.tar.gz: 500ae4d38825b881d38c3d1e23d520ec736f4773affe4bc8f7b309d088efaacc284a1b19e4035ec4ee37f4ac8f7d76030c63fbc29798cfb34082986eef8ee62d
@@ -19,10 +19,14 @@ jobs:
19
19
  # truffleruby,
20
20
  # truffleruby-head,
21
21
  # removing jruby again to flaky
22
- gemfile: [ Gemfile.rails6.0, Gemfile.rails6.1, Gemfile.rails7.0, Gemfile.rails7.1 ]
22
+ gemfile: [ Gemfile.rails7.0, Gemfile.rails7.1, Gemfile.rails7.2, Gemfile.rails8.0 ]
23
23
  # need to add support for multiple gemfiles
24
- ruby: ["2.7", "3.0", "3.1", "3.2", "3.3"]
24
+ ruby: ["3.1", "3.2", "3.3", "3.4", "ruby-head"]
25
25
  redis-version: [4, 5, 6, 7]
26
+ exclude:
27
+ # Rails 8 requires ruby 3.2+.
28
+ - gemfile: 'rails_8.0'
29
+ ruby: '3.1'
26
30
  runs-on: ${{ matrix.os }}-latest
27
31
  steps:
28
32
  - uses: actions/checkout@v4
@@ -33,6 +37,14 @@ jobs:
33
37
  with:
34
38
  ruby-version: ${{ matrix.ruby }}
35
39
  bundler-cache: true # runs 'bundle install' and caches installed gems automatically
36
- - run: bundle exec standardrb
37
- - run: bundle exec rake
40
+ - run: bundle exec rake test:all
38
41
  - run: "RUBYOPT='--enable=frozen-string-literal --debug=frozen-string-literal' bundle exec rake"
42
+ starndardrb:
43
+ runs-on: ubuntu-latest
44
+ steps:
45
+ - uses: actions/checkout@v4
46
+ - uses: ruby/setup-ruby@v1
47
+ with:
48
+ ruby-version: 3.1
49
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
50
+ - run: bundle exec standardrb --format github
data/.gitignore CHANGED
@@ -24,4 +24,6 @@ temp_results
24
24
  .env
25
25
  log/
26
26
  test/unique_files
27
- test/rails5_dummy/tmp
27
+ test/rails7_dummy/tmp
28
+ CLAUDE.md
29
+ .claude/
data/.rubocop.yml CHANGED
@@ -2,4 +2,4 @@ require: standard
2
2
 
3
3
  inherit_gem:
4
4
  standard:
5
- - config/ruby-2.7.yml
5
+ - config/ruby-3.1.yml
data/.standard.yml CHANGED
@@ -1,4 +1,4 @@
1
- ruby_version: 2.7
1
+ ruby_version: 3.1
2
2
  fix: false # default: false
3
3
  parallel: true # default: false
4
4
  format: progress # default: Standard::Formatter
data/Gemfile CHANGED
@@ -4,7 +4,7 @@ source "https://rubygems.org"
4
4
 
5
5
  # Specify your gem's dependencies in coverband.gemspec
6
6
  gemspec
7
- gem "rails", "~>7"
7
+ gem "rails" # latest
8
8
  gem "haml"
9
9
  gem "slim"
10
10
  gem "webrick"
@@ -4,7 +4,7 @@ source 'https://rubygems.org'
4
4
 
5
5
  # Specify your gem's dependencies in coverband.gemspec
6
6
  gemspec
7
- gem 'rails', '~>7'
7
+ gem 'rails', '~>7.2.0'
8
8
  gem "haml"
9
9
  gem "slim"
10
- gem "webrick"
10
+ gem "webrick"
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- source "https://rubygems.org"
3
+ source 'https://rubygems.org'
4
4
 
5
5
  # Specify your gem's dependencies in coverband.gemspec
6
6
  gemspec
7
- gem "rails", "~>6.0.0"
7
+ gem 'rails', '~>8.0.0'
8
8
  gem "haml"
9
9
  gem "slim"
10
10
  gem "webrick"
data/README.md CHANGED
@@ -116,6 +116,39 @@ The columns in the web UI are as follows:
116
116
  When viewing an individual file, a line of code such as a class or method definition may appear green because it is eager loaded by the application, but still not be hit at all in runtime by actual users.
117
117
 
118
118
  ![example of a file with lines not hit at runtime](https://user-images.githubusercontent.com/96786/63541229-aa98a580-c4eb-11e9-8eb8-c004fe1369db.png)
119
+ #### Coverage first seen and Last activity recorded
120
+ In the context of Coverband, a file is considered relevant for monitoring if it is located within certain specified project paths. Specifically, Coverband monitors all *.rb files located in the following paths:
121
+
122
+ - app/
123
+
124
+ - lib/
125
+
126
+ - config/
127
+
128
+ This applies as long as these files are not included in the list of exclusions defined in "config.ignore".
129
+
130
+ #### Coverage first seen
131
+ This attribute shows the exact date and time when Coverband first detected the file. This detection happens when:
132
+
133
+ - The file is loaded by Ruby (e.g., during application startup in Rails via autoload or require).
134
+
135
+ - The file becomes relevant for monitoring, even if no lines within it have been executed yet.
136
+
137
+ - By default, Coverband resets a file’s coverage data and updates its “Coverage first seen” timestamp whenever the file changes, ensuring the coverage reflects the file’s new state.
138
+
139
+ #### Last activity recorded
140
+ This attribute shows the most recent time when any line in the file was executed at runtime. It specifically reflects runtime execution and does not include the file’s load time.
141
+
142
+ - When any line in the file is executed at runtime (e.g., a method is called, a route is triggered, or a conditional is evaluated), Coverband updates the “Last activity recorded” timestamp.
143
+
144
+ - This only occurs when the file’s lines are actually executed. If a file is loaded but none of its lines are executed, the “Last activity recorded” timestamp will not be updated.
145
+
146
+ - It helps determine if a file is actively being used in the application. If a file has no recent activity, it may be a candidate for review or removal.
147
+
148
+ #### Example
149
+ - If a file has a “Coverage first seen” timestamp but no “Last activity recorded”, this indicates that the file is being loaded but no runtime activity is occurring (e.g., it contains unused methods or classes).
150
+
151
+ - If both attributes are populated and the “Last activity recorded” timestamp is recent, the file is actively used in the application.
119
152
 
120
153
  ### Mounting as a Rack App
121
154
 
@@ -305,12 +338,10 @@ Now that Coverband uses MD5 hashes there should be no reason to manually clear c
305
338
 
306
339
  `rake coverband:clear`
307
340
 
308
- This can also be done through the web if `config.web_enable_clear` is enabled.
309
-
310
- **NOTE**: The previous task does not clear the trackers data (views, routes, translations, etc).
311
- To clear trackers data, run
341
+ This will clear both the coverage and trackers data. It can also be done through the web if `config.web_enable_clear` is enabled.
312
342
 
313
- `rake coverband:clear_tracker`
343
+ To clear only coverage data, run `rake coverband:clear_coverage`.
344
+ To clear only trackers data, run `rake coverband:clear_tracker`.
314
345
 
315
346
  ### Adding Rake Tasks outside of Rails
316
347
 
@@ -399,14 +430,14 @@ Outputs:
399
430
 
400
431
  # Prerequisites
401
432
 
402
- - Coverband 3.0.X+ requires Ruby 2.3+
433
+ - Ruby 3.1+
403
434
  - Coverband currently requires Redis for production usage
404
435
 
405
436
  ### Ruby and Rails Version Support
406
437
 
407
438
  We will match Heroku & Ruby's support lifetime, supporting the last 3 major Ruby releases. For details see [supported runtimes](https://devcenter.heroku.com/articles/ruby-support#supported-runtimes).
408
439
 
409
- For Rails, we will follow the policy of the [Rails team maintenance policy](https://guides.rubyonrails.org/maintenance_policy.html). We officially support the last two major release versions, while providing minimal support (major bugs / security fixes) for an additional version. This means at the moment we primarily target Rails 6.x, 5.x, and will try to keep current functionality working for Rails 4.x but may release new features that do not work on that target.
440
+ For Rails, we will follow the policy of the [Rails team maintenance policy](https://guides.rubyonrails.org/maintenance_policy.html). We officially support the last two major release versions, while providing minimal support (major bugs / security fixes) for an additional version. At the moment we primarily target Rails 7.0+.
410
441
 
411
442
  ### JRuby Support
412
443
 
data/Rakefile CHANGED
@@ -8,7 +8,7 @@ RuboCop::RakeTask.new
8
8
 
9
9
  task default: %i[test]
10
10
 
11
- task "test:all": %i[rubocop test forked_tests benchmarks:memory benchmarks]
11
+ task "test:all": %i[test forked_tests benchmarks:memory benchmarks]
12
12
 
13
13
  task :test
14
14
  require "rake/testtask"
data/changes.md CHANGED
@@ -1,3 +1,17 @@
1
+ ### Coverband 6.1.5
2
+
3
+ * add testing for ruby-head
4
+ * drop support for older Ruby and Rails version as matching our policy
5
+ * remove ostruct as it is no longer in ruby-head
6
+ * fix issue requiring base64 to be added to folks gem files
7
+ * added support for track_key method allowing for code to specifically mark things tracked
8
+ * improvements to CI thanks ydah
9
+ * Update README to include functionality details for "Coverage first seen" and "Last activity recorded" thanks juanarevalo
10
+ * fixes for Rack 3 - thanks Aaron Pfeifer
11
+ * Do not mark single-line and empty methods as dead - fatkodima
12
+ * fix on clear_trackers rake task
13
+ * Consider eager loaded code too when detecting dead methods - fatkodima
14
+
1
15
  ### Coverband 6.1.4
2
16
 
3
17
  * fix on ignoring to many view files thx @fatkodima
@@ -17,7 +31,7 @@
17
31
  * improved documentation @jjb
18
32
  * add back static output summary @bessey
19
33
 
20
- other cleanup, small fixes, and updated mostly basic maintence, by me.
34
+ other cleanup, small fixes, and updated mostly basic maintenance, by me.
21
35
 
22
36
  ### Coverband 6.1.2
23
37
 
@@ -29,7 +43,7 @@ other cleanup, small fixes, and updated mostly basic maintence, by me.
29
43
 
30
44
  ### Coverband 6.1.0
31
45
 
32
- This release has a number of smaller fixes and improvements. It includes a sizable refactoring around the UI which should simplify improvements going forward. This release is mostly targetting large projects with 6K+ ruby files, use the new `config.paged_reporting = true` option with the HashRedisStore to enable paged reporting for large projects. The HashRedisStore now also includes the last time a line in a file was executed.
46
+ This release has a number of smaller fixes and improvements. It includes a sizable refactoring around the UI which should simplify improvements going forward. This release is mostly targeting large projects with 6K+ ruby files, use the new `config.paged_reporting = true` option with the HashRedisStore to enable paged reporting for large projects. The HashRedisStore now also includes the last time a line in a file was executed.
33
47
 
34
48
  * Thanks to @FeLvi-zzz for the last time accessed support for the Hash Redis Store
35
49
  * Thanks to @alpaca-tc for the improvements on the route tracker
@@ -42,7 +56,7 @@ This release has a number of smaller fixes and improvements. It includes a sizab
42
56
  * This release addresses large projects and adds in paged reporting
43
57
  * to ensure even on projects with 10K+ files it can load on heroku under the 30s timeout
44
58
  * only supports HashRedis store
45
- * faster UI for web UI in general which should be noticable on non paged reports
59
+ * faster UI for web UI in general which should be noticeable on non paged reports
46
60
  * reduce redis calls
47
61
 
48
62
  ### Coverband 6.0.2
data/coverband.gemspec CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
20
20
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
21
21
  spec.require_paths = %w[lib]
22
22
 
23
- spec.required_ruby_version = ">= 2.7"
23
+ spec.required_ruby_version = ">= 3.1"
24
24
 
25
25
  spec.metadata = {
26
26
  "homepage_uri" => "https://github.com/danmayer/coverband",
@@ -62,4 +62,5 @@ Gem::Specification.new do |spec|
62
62
  # quality adapter, I think this is more honest about requirements and reduces confusion
63
63
  # without this there was a race condition on calling coverband configure before redis was loaded
64
64
  spec.add_runtime_dependency "redis", ">= 3.0"
65
+ spec.add_runtime_dependency "base64"
65
66
  end
@@ -109,7 +109,7 @@ module Coverband
109
109
 
110
110
  # This is the basic rails version supported, if there is something more unique over ride in subclass
111
111
  def self.supported_version?
112
- defined?(Rails) && defined?(Rails::VERSION) && Rails::VERSION::STRING.split(".").first.to_i >= 5
112
+ defined?(Rails::VERSION) && Rails::VERSION::STRING.split(".").first.to_i >= 7
113
113
  end
114
114
 
115
115
  def route
@@ -13,7 +13,7 @@ module Coverband
13
13
  TITLE = "Routes"
14
14
 
15
15
  def initialize(options = {})
16
- if Rails&.respond_to?(:version) && Gem::Version.new(Rails.version) >= Gem::Version.new("6.0.0") && Gem::Version.new(Rails.version) < Gem::Version.new("7.1.0")
16
+ if Rails&.respond_to?(:version) && Gem::Version.new(Rails.version) < Gem::Version.new("7.1.0")
17
17
  require_relative "../utils/rails6_ext"
18
18
  end
19
19
 
@@ -52,7 +52,7 @@ module Coverband
52
52
  end
53
53
 
54
54
  def self.supported_version?
55
- defined?(Rails) && defined?(Rails::VERSION) && Rails::VERSION::STRING.split(".").first.to_i >= 6
55
+ defined?(Rails) && defined?(Rails::VERSION) && Rails::VERSION::STRING.split(".").first.to_i >= 7
56
56
  end
57
57
 
58
58
  def unused_keys(used_keys = nil)
@@ -24,7 +24,7 @@ module Coverband
24
24
  end
25
25
 
26
26
  def self.supported_version?
27
- defined?(Rails) && defined?(Rails::VERSION) && Rails::VERSION::STRING.split(".").first.to_i >= 4
27
+ defined?(Rails::VERSION) && Rails::VERSION::STRING.split(".").first.to_i >= 7
28
28
  end
29
29
 
30
30
  private
@@ -224,8 +224,6 @@ module Coverband
224
224
  def ignore=(ignored_array)
225
225
  ignored_array = ignored_array.map { |ignore_str| Regexp.new(ignore_str) }
226
226
  @ignore |= ignored_array
227
- rescue RegexpError
228
- logger.error "an invalid regular expression was passed in, ensure string are valid regex patterns #{ignored_array.join(",")}"
229
227
  end
230
228
 
231
229
  def current_root
@@ -85,7 +85,7 @@ module Coverband
85
85
  # why do we need to merge covered files data?
86
86
  # basically because paths on machines or deployed hosts could be different, so
87
87
  # two different keys could point to the same filename or `line_key`
88
- # this happens when deployment has a dynmaic path or the path change during deployment (hot code reload)
88
+ # this happens when deployment has a dynamic path or the path change during deployment (hot code reload)
89
89
  # TODO: think we are filtering based on ignore while sending to the store
90
90
  # and as we also pull it out here
91
91
  ###
@@ -37,7 +37,11 @@ module Coverband
37
37
  end
38
38
 
39
39
  def self.scan_all
40
- coverage = Coverband.configuration.store.coverage
40
+ # If the file was loaded during eager loading and then its code is never executed
41
+ # during runtime, then it will not have any runtime coverage. When reporting
42
+ # dead methods, we need to look at all the files discovered during the eager loading
43
+ # and runtime phases.
44
+ coverage = Coverband.configuration.store.get_coverage_report[Coverband::MERGED_TYPE]
41
45
  coverage.flat_map do |file_path, coverage|
42
46
  scan(file_path: file_path, coverage: coverage["data"])
43
47
  end
@@ -32,11 +32,23 @@ if defined?(RubyVM::AbstractSyntaxTree)
32
32
  private
33
33
 
34
34
  def first_line_number
35
- @method_definition.first_line_number + 1
35
+ if multiline?
36
+ @method_definition.first_line_number + 1
37
+ else
38
+ @method_definition.first_line_number
39
+ end
36
40
  end
37
41
 
38
42
  def last_line_number
39
- @method_definition.last_line_number - 1
43
+ if multiline?
44
+ @method_definition.last_line_number - 1
45
+ else
46
+ @method_definition.last_line_number
47
+ end
48
+ end
49
+
50
+ def multiline?
51
+ @method_definition.last_line_number - @method_definition.first_line_number > 1
40
52
  end
41
53
  end
42
54
 
@@ -12,7 +12,7 @@ namespace :coverband do
12
12
  FileUtils.cp(config_template, "./config/coverband.rb")
13
13
  end
14
14
 
15
- desc "console formated report of Coverband code coverage"
15
+ desc "console formatted report of Coverband code coverage"
16
16
  task :coverage do
17
17
  require "coverband/utils/html_formatter"
18
18
  require "coverband/utils/result"
@@ -23,7 +23,7 @@ namespace :coverband do
23
23
  Coverband::Reporters::ConsoleReport.report(Coverband.configuration.store)
24
24
  end
25
25
 
26
- desc "JSON formated report of Coverband code coverage"
26
+ desc "JSON formatted report of Coverband code coverage"
27
27
  task :coverage_json do
28
28
  require "coverband/utils/html_formatter"
29
29
  require "coverband/utils/result"
@@ -51,7 +51,7 @@ namespace :coverband do
51
51
  # gem "simplecov-html", require: false
52
52
  # the file is written to coverage/index.html
53
53
  ###
54
- desc "static HTML formated report of Coverband code coverage"
54
+ desc "static HTML formatted report of Coverband code coverage"
55
55
  task :coverage_html do
56
56
  require "coverband/utils/html_formatter"
57
57
  require "coverband/utils/result"
@@ -113,7 +113,16 @@ namespace :coverband do
113
113
  if Coverband.configuration.store.is_a?(Coverband::Adapters::FileStore)
114
114
  Coverband.configuration.store.merge_mode = true
115
115
  end
116
- Rack::Server.start app: Coverband::Reporters::Web.new,
116
+
117
+ begin
118
+ require "rackup/server"
119
+ server_class = Rackup::Server
120
+ rescue LoadError
121
+ require "rack/server"
122
+ server_class = Rack::Server
123
+ end
124
+
125
+ server_class.start app: Coverband::Reporters::Web.new,
117
126
  Port: ENV.fetch("COVERBAND_COVERAGE_PORT", 9022).to_i
118
127
  end
119
128
 
@@ -129,10 +138,16 @@ namespace :coverband do
129
138
  end
130
139
 
131
140
  ###
132
- # clear data helpful for development or after configuration issues
141
+ # clear all coverband data
142
+ ###
143
+ desc "reset Coverband coverage and trackers data, helpful for development, debugging, etc"
144
+ task clear: [:clear_coverage, :clear_tracker]
145
+
146
+ ###
147
+ # clear coverband coverage data
133
148
  ###
134
149
  desc "reset Coverband coverage data, helpful for development, debugging, etc"
135
- task :clear do
150
+ task :clear_coverage do
136
151
  Coverband.configuration.store.clear!
137
152
  end
138
153
 
@@ -141,6 +156,9 @@ namespace :coverband do
141
156
  ###
142
157
  desc "reset Coverband trackers data (view, routes, translations, etc), helpful for development, debugging, etc"
143
158
  task :clear_tracker do
159
+ # Load rails-related trackers, if the gem is used in a rails app.
160
+ Coverband.configuration.railtie! if defined?(Rails::Railtie)
161
+
144
162
  trackers = Coverband.configuration.trackers
145
163
  trackers.each(&:reset_recordings)
146
164
  end
@@ -5,5 +5,5 @@
5
5
  # use format "4.2.1.rc.1" ~> 4.2.1.rc to prerelease versions like v4.2.1.rc.2 and v4.2.1.rc.3
6
6
  ###
7
7
  module Coverband
8
- VERSION = "6.1.4"
8
+ VERSION = "6.1.5"
9
9
  end
data/lib/coverband.rb CHANGED
@@ -100,6 +100,32 @@ module Coverband
100
100
  coverage_instance.runtime!
101
101
  end
102
102
 
103
+ # Track a key with the specified tracker.
104
+ # @param tracker_type [Symbol] The type of tracker to use (e.g., :view_tracker, :translations_tracker, :routes_tracker)
105
+ # @param key [String] The key to track
106
+ # @return [Boolean] True if tracking was successful, false otherwise
107
+ # @raise [ArgumentError] If the tracker_type is not supported
108
+ def self.track_key(tracker_type, key)
109
+ return false unless key
110
+
111
+ supported_trackers = [:view_tracker, :translations_tracker, :routes_tracker]
112
+
113
+ unless supported_trackers.include?(tracker_type)
114
+ raise ArgumentError, "Unsupported tracker type: #{tracker_type}. Must be one of: #{supported_trackers.join(', ')}"
115
+ end
116
+
117
+ begin
118
+ tracker = configuration.send(tracker_type)
119
+ return false unless tracker && tracker.respond_to?(:track_key)
120
+
121
+ tracker.track_key(key)
122
+ true
123
+ rescue => e
124
+ configuration.logger.error "Coverband: Failed to track key '#{key}' with tracker '#{tracker_type}'. Error: #{e.message}"
125
+ false
126
+ end
127
+ end
128
+
103
129
  private_class_method def self.coverage_instance
104
130
  Coverband::Collectors::Coverage.instance
105
131
  end
@@ -98,9 +98,9 @@ namespace :benchmarks do
98
98
  Coverband::Collectors::Coverage.instance.reset_instance
99
99
  end
100
100
 
101
- lines = 45
102
- non_nil_lines = 18
103
101
  def fake_line_numbers
102
+ lines = 45
103
+ non_nil_lines = 18
104
104
  lines.times.map do |line|
105
105
  coverage = (line < non_nil_lines) ? rand(5) : nil
106
106
  end
@@ -155,6 +155,7 @@ namespace :benchmarks do
155
155
 
156
156
  def measure_memory
157
157
  require "memory_profiler"
158
+ require "stringio"
158
159
  report = fake_report
159
160
  store = benchmark_redis_store
160
161
  store.clear!
@@ -249,6 +250,7 @@ namespace :benchmarks do
249
250
 
250
251
  desc "checks memory of collector"
251
252
  task memory_check: [:setup] do
253
+ require "stringio"
252
254
  require "objspace"
253
255
  puts "memory load check"
254
256
  puts(ObjectSpace.memsize_of_all / 2**20)
@@ -316,7 +318,7 @@ namespace :benchmarks do
316
318
  desc "runs memory leak check via Rails tests"
317
319
  task memory_rails: [:setup] do
318
320
  puts "runs memory rails test to ensure we dont leak"
319
- puts `COVERBAND_MEMORY_TEST=true bundle exec test/forked/rails_full_stack_test.rb`
321
+ puts `COVERBAND_MEMORY_TEST=true bundle exec ruby -I test test/forked/rails_full_stack_test.rb`
320
322
  end
321
323
 
322
324
  desc "runs memory leak checks"
@@ -23,7 +23,7 @@ class CollectorsCoverageTest < Minitest::Test
23
23
  file = require_unique_file
24
24
  coverband.report_coverage
25
25
  coverage = Coverband.configuration.store.coverage
26
- assert_equal(coverage[file]["data"], [nil, nil, 1, 1, 0, nil, nil])
26
+ assert_equal(coverage[file]["data"], [nil, nil, 1, 1, 0, nil, nil, 1, nil, 1, nil, nil])
27
27
  end
28
28
 
29
29
  test "Dog method and class coverage" do
@@ -31,7 +31,7 @@ class CollectorsCoverageTest < Minitest::Test
31
31
  Dog.new.bark
32
32
  coverband.report_coverage
33
33
  coverage = Coverband.configuration.store.coverage
34
- assert_equal(coverage["./test/dog.rb"]["data"], [nil, nil, 1, 1, 1, nil, nil])
34
+ assert_equal(coverage["./test/dog.rb"]["data"], [nil, nil, 1, 1, 1, nil, nil, 1, nil, 1, nil, nil])
35
35
  end
36
36
 
37
37
  test "Dog eager load coverage" do
@@ -45,7 +45,7 @@ class CollectorsCoverageTest < Minitest::Test
45
45
  coverband.eager_loading!
46
46
  coverage = Coverband.configuration.store.coverage[file]
47
47
  refute_nil coverage, "Eager load coverage is present"
48
- assert_equal(coverage["data"], [nil, nil, 1, 1, 0, nil, nil])
48
+ assert_equal(coverage["data"], [nil, nil, 1, 1, 0, nil, nil, 1, nil, 1, nil, nil])
49
49
  end
50
50
 
51
51
  test "gets coverage instance" do
@@ -78,16 +78,12 @@ class CollectorsCoverageTest < Minitest::Test
78
78
  end
79
79
 
80
80
  test "using coverage state idle with ruby >= 3.1.0" do
81
- return unless Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.1.0")
82
-
83
81
  ::Coverage.expects(:state).returns(:idle)
84
82
  ::Coverage.expects(:start).with(oneshot_lines: false)
85
83
  Coverband::Collectors::Coverage.send(:new)
86
84
  end
87
85
 
88
86
  test "using coverage state suspended with ruby >= 3.1.0" do
89
- return unless Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.1.0")
90
-
91
87
  ::Coverage.expects(:state).returns(:suspended).at_least_once
92
88
  ::Coverage.expects(:resume)
93
89
  Coverband::Collectors::Coverage.send(:new)
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require File.expand_path("../../test_helper", File.dirname(__FILE__))
4
- require "ostruct"
5
4
 
6
5
  class RouterTrackerTest < Minitest::Test
7
6
  # NOTE: using struct vs open struct as open struct has a special keyword method that overshadows the method value on Ruby 2.x
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require File.expand_path("../../test_helper", File.dirname(__FILE__))
4
- require "ostruct"
5
4
 
6
5
  class TranslationTrackerTest < Minitest::Test
7
6
  # NOTE: using struct vs open struct as open struct has a special keyword method that overshadows the method value on Ruby 2.x
@@ -39,16 +39,6 @@ class BaseTest < Minitest::Test
39
39
  assert_equal expected, Coverband.configuration.ignore
40
40
  end
41
41
 
42
- test "ignore catches regex errors" do
43
- Coverband.configuration.logger.expects(:error).with("an invalid regular expression was passed in, ensure string are valid regex patterns *invalidRegex*")
44
- Coverband.configure do |config|
45
- config.ignore = ["*invalidRegex*"]
46
- end
47
- Coverband::Collectors::Coverage.instance.reset_instance
48
- expected = (Coverband::Configuration::IGNORE_DEFAULTS << "config/environments").map { |str| Regexp.new(str) }
49
- assert_equal expected, Coverband.configuration.ignore
50
- end
51
-
52
42
  test "ignore" do
53
43
  Coverband::Collectors::Coverage.instance.reset_instance
54
44
  assert !Coverband.configuration.ignore.first.nil?
@@ -3,20 +3,23 @@
3
3
  require File.expand_path("../../test_helper", File.dirname(__FILE__))
4
4
 
5
5
  class RackServerCheckTest < Minitest::Test
6
+ # Create a Struct for the caller location at the class level
7
+ LocationStruct = Struct.new(:path, :label)
8
+
6
9
  test "returns true when running in rack server" do
7
- caller_locations = ["blah/lib/rack/server.rb"].map { |path| OpenStruct.new(path: path, label: "foo") }
10
+ caller_locations = ["blah/lib/rack/server.rb"].map { |path| LocationStruct.new(path, "foo") }
8
11
  Kernel.expects(:caller_locations).returns(caller_locations)
9
12
  assert(Coverband::RackServerCheck.running?)
10
13
  end
11
14
 
12
15
  test "returns false when not running in rack server" do
13
- caller_locations = ["blah/lib/sidekiq/worker.rb"].map { |path| OpenStruct.new(path: path, label: "foo") }
16
+ caller_locations = ["blah/lib/sidekiq/worker.rb"].map { |path| LocationStruct.new(path, "foo") }
14
17
  Kernel.expects(:caller_locations).returns(caller_locations)
15
18
  refute(Coverband::RackServerCheck.running?)
16
19
  end
17
20
 
18
21
  test "returns true if running within a rails server" do
19
- caller_locations = [OpenStruct.new(path: "/lib/rails/commands/commands_tasks.rb", label: "server")]
22
+ caller_locations = [LocationStruct.new("/lib/rails/commands/commands_tasks.rb", "server")]
20
23
  Kernel.expects(:caller_locations).returns(caller_locations)
21
24
  assert(Coverband::RackServerCheck.running?)
22
25
  end