coverband 6.1.4 → 6.1.6
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.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +16 -4
- data/.gitignore +3 -1
- data/.rubocop.yml +1 -1
- data/.standard.yml +1 -1
- data/Gemfile +1 -1
- data/{Gemfile.rails7 → Gemfile.rails7.2} +2 -2
- data/{Gemfile.rails6.0 → Gemfile.rails8.0} +2 -2
- data/README.md +38 -7
- data/Rakefile +1 -1
- data/changes.md +22 -3
- data/coverband.gemspec +2 -1
- data/lib/coverband/adapters/hash_redis_store.rb +1 -3
- data/lib/coverband/collectors/abstract_tracker.rb +1 -1
- data/lib/coverband/collectors/route_tracker.rb +2 -2
- data/lib/coverband/collectors/view_tracker.rb +1 -1
- data/lib/coverband/collectors/view_tracker_service.rb +1 -1
- data/lib/coverband/configuration.rb +0 -2
- data/lib/coverband/reporters/base.rb +1 -1
- data/lib/coverband/utils/dead_methods.rb +5 -1
- data/lib/coverband/utils/method_definition_scanner.rb +14 -2
- data/lib/coverband/utils/railtie.rb +1 -1
- data/lib/coverband/utils/tasks.rb +24 -6
- data/lib/coverband/version.rb +1 -1
- data/lib/coverband.rb +26 -0
- data/test/benchmarks/benchmark.rake +12 -18
- data/test/coverband/collectors/coverage_test.rb +3 -7
- data/test/coverband/collectors/route_tracker_test.rb +0 -1
- data/test/coverband/collectors/translation_tracker_test.rb +0 -1
- data/test/coverband/configuration_test.rb +0 -10
- data/test/coverband/integrations/rack_server_check_test.rb +6 -3
- data/test/coverband/track_key_test.rb +66 -0
- data/test/coverband/utils/dead_methods_test.rb +14 -2
- data/test/coverband/utils/method_definition_scanner_test.rb +1 -1
- data/test/dog.rb +5 -0
- data/test/forked/rails_full_stack_views_test.rb +1 -1
- data/test/rails7_dummy/config/coverband.rb +13 -1
- data/test/rails7_dummy/config/coverband_missing_redis.rb +12 -1
- data/test/rails8_dummy/config/coverband.rb +3 -0
- data/test/rails8_dummy/config/coverband_missing_redis.rb +3 -0
- data/test/rails8_dummy/tmp/local_secret.txt +1 -0
- data/test/test_helper.rb +1 -4
- data/test/unique_files.rb +6 -2
- metadata +37 -53
- data/Gemfile.rails6.1 +0 -10
- data/test/rails4_dummy/config/application.rb +0 -15
- data/test/rails4_dummy/config/coverband.rb +0 -3
- data/test/rails4_dummy/config/coverband_missing_redis.rb +0 -3
- data/test/rails5_dummy/Rakefile +0 -6
- data/test/rails5_dummy/app/controllers/dummy_controller.rb +0 -5
- data/test/rails5_dummy/app/controllers/dummy_view_controller.rb +0 -16
- data/test/rails5_dummy/app/views/dummy_view/show.html.erb +0 -5
- data/test/rails5_dummy/app/views/dummy_view/show_haml.html.haml +0 -4
- data/test/rails5_dummy/app/views/dummy_view/show_slim.html.slim +0 -4
- data/test/rails5_dummy/config/application.rb +0 -14
- data/test/rails5_dummy/config/coverband.rb +0 -15
- data/test/rails5_dummy/config/coverband_missing_redis.rb +0 -14
- data/test/rails5_dummy/config/environment.rb +0 -2
- data/test/rails5_dummy/config/routes.rb +0 -7
- data/test/rails5_dummy/config.ru +0 -3
- data/test/rails5_dummy/tmp/.keep +0 -0
- data/test/rails6_dummy/Rakefile +0 -6
- data/test/rails6_dummy/app/controllers/dummy_controller.rb +0 -5
- data/test/rails6_dummy/app/controllers/dummy_view_controller.rb +0 -16
- data/test/rails6_dummy/app/views/dummy_view/show.html.erb +0 -5
- data/test/rails6_dummy/app/views/dummy_view/show_haml.html.haml +0 -4
- data/test/rails6_dummy/app/views/dummy_view/show_slim.html.slim +0 -4
- data/test/rails6_dummy/config/boot.rb +0 -3
- data/test/rails6_dummy/config/coverband.rb +0 -3
- data/test/rails6_dummy/config/coverband_missing_redis.rb +0 -3
- data/test/rails6_dummy/config/environment.rb +0 -5
- data/test/rails6_dummy/config/routes.rb +0 -7
- data/test/rails6_dummy/config/secrets.yml +0 -3
- data/test/rails6_dummy/config.ru +0 -4
- data/test/rails6_dummy/tmp/.keep +0 -0
- /data/test/{rails4_dummy → rails8_dummy}/Rakefile +0 -0
- /data/test/{rails4_dummy → rails8_dummy}/app/controllers/dummy_controller.rb +0 -0
- /data/test/{rails4_dummy → rails8_dummy}/app/controllers/dummy_view_controller.rb +0 -0
- /data/test/{rails4_dummy → rails8_dummy}/app/views/dummy_view/show.html.erb +0 -0
- /data/test/{rails4_dummy → rails8_dummy}/app/views/dummy_view/show_haml.html.haml +0 -0
- /data/test/{rails4_dummy → rails8_dummy}/app/views/dummy_view/show_slim.html.slim +0 -0
- /data/test/{rails6_dummy → rails8_dummy}/config/application.rb +0 -0
- /data/test/{rails4_dummy → rails8_dummy}/config/boot.rb +0 -0
- /data/test/{rails4_dummy → rails8_dummy}/config/environment.rb +0 -0
- /data/test/{rails4_dummy → rails8_dummy}/config/routes.rb +0 -0
- /data/test/{rails4_dummy → rails8_dummy}/config/secrets.yml +0 -0
- /data/test/{rails4_dummy → rails8_dummy}/config.ru +0 -0
- /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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 032cf0d003aefa2d222472e12412e352f5059cfffc93645810692e60b3dc6602
|
|
4
|
+
data.tar.gz: b094364d6cc2dbfbc2527209f4bf03025c06199443a0b9fa0380851afe7a00ae
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 14ce46ede0f55f2162878529c8226a022518df0a0a22c83ad323d0856fad43b99a9f694b3b629171b86872bfd16626da9772388cae5a665a5e00e1493ef81b8b
|
|
7
|
+
data.tar.gz: c394482fdfddfa2d70dab2453517f2c490e66e1b9ef463a5a097413deb41540158a13a0626a2f3c4e62fc263de3052df6d99c7c7765ddb9ae867074b5b943e94
|
data/.github/workflows/main.yml
CHANGED
|
@@ -19,10 +19,14 @@ jobs:
|
|
|
19
19
|
# truffleruby,
|
|
20
20
|
# truffleruby-head,
|
|
21
21
|
# removing jruby again to flaky
|
|
22
|
-
gemfile: [ Gemfile.
|
|
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: ["
|
|
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
|
|
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
data/.rubocop.yml
CHANGED
data/.standard.yml
CHANGED
data/Gemfile
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
source
|
|
3
|
+
source 'https://rubygems.org'
|
|
4
4
|
|
|
5
5
|
# Specify your gem's dependencies in coverband.gemspec
|
|
6
6
|
gemspec
|
|
7
|
-
gem
|
|
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
|

|
|
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:
|
|
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
|
-
-
|
|
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.
|
|
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
data/changes.md
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
### Coverband 6.1.6
|
|
2
|
+
|
|
3
|
+
* Check for Rails::Engine - Stephen Wetzel
|
|
4
|
+
* Support views located in components directory, as well as sub-directories like packs/app/views - Derek Kniffin
|
|
5
|
+
|
|
6
|
+
### Coverband 6.1.5
|
|
7
|
+
|
|
8
|
+
* add testing for ruby-head
|
|
9
|
+
* drop support for older Ruby and Rails version as matching our policy
|
|
10
|
+
* remove ostruct as it is no longer in ruby-head
|
|
11
|
+
* fix issue requiring base64 to be added to folks gem files
|
|
12
|
+
* added support for track_key method allowing for code to specifically mark things tracked
|
|
13
|
+
* improvements to CI thanks ydah
|
|
14
|
+
* Update README to include functionality details for "Coverage first seen" and "Last activity recorded" thanks juanarevalo
|
|
15
|
+
* fixes for Rack 3 - thanks Aaron Pfeifer
|
|
16
|
+
* Do not mark single-line and empty methods as dead - fatkodima
|
|
17
|
+
* fix on clear_trackers rake task
|
|
18
|
+
* Consider eager loaded code too when detecting dead methods - fatkodima
|
|
19
|
+
|
|
1
20
|
### Coverband 6.1.4
|
|
2
21
|
|
|
3
22
|
* fix on ignoring to many view files thx @fatkodima
|
|
@@ -17,7 +36,7 @@
|
|
|
17
36
|
* improved documentation @jjb
|
|
18
37
|
* add back static output summary @bessey
|
|
19
38
|
|
|
20
|
-
other cleanup, small fixes, and updated mostly basic
|
|
39
|
+
other cleanup, small fixes, and updated mostly basic maintenance, by me.
|
|
21
40
|
|
|
22
41
|
### Coverband 6.1.2
|
|
23
42
|
|
|
@@ -29,7 +48,7 @@ other cleanup, small fixes, and updated mostly basic maintence, by me.
|
|
|
29
48
|
|
|
30
49
|
### Coverband 6.1.0
|
|
31
50
|
|
|
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
|
|
51
|
+
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
52
|
|
|
34
53
|
* Thanks to @FeLvi-zzz for the last time accessed support for the Hash Redis Store
|
|
35
54
|
* Thanks to @alpaca-tc for the improvements on the route tracker
|
|
@@ -42,7 +61,7 @@ This release has a number of smaller fixes and improvements. It includes a sizab
|
|
|
42
61
|
* This release addresses large projects and adds in paged reporting
|
|
43
62
|
* to ensure even on projects with 10K+ files it can load on heroku under the 30s timeout
|
|
44
63
|
* only supports HashRedis store
|
|
45
|
-
* faster UI for web UI in general which should be
|
|
64
|
+
* faster UI for web UI in general which should be noticeable on non paged reports
|
|
46
65
|
* reduce redis calls
|
|
47
66
|
|
|
48
67
|
### 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 = ">=
|
|
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
|
|
@@ -205,9 +205,7 @@ module Coverband
|
|
|
205
205
|
|
|
206
206
|
data = coverage_data_from_redis(data_from_redis)
|
|
207
207
|
timedata = coverage_time_data_from_redis(data_from_redis)
|
|
208
|
-
hash[file] = data_from_redis.
|
|
209
|
-
META_DATA_KEYS.include?(meta_data_key)
|
|
210
|
-
end.merge!("data" => data, "timedata" => timedata)
|
|
208
|
+
hash[file] = data_from_redis.slice(*META_DATA_KEYS).merge!("data" => data, "timedata" => timedata)
|
|
211
209
|
hash[file][LAST_UPDATED_KEY] =
|
|
212
210
|
(hash[file][LAST_UPDATED_KEY].nil? || hash[file][LAST_UPDATED_KEY] == "") ? nil : hash[file][LAST_UPDATED_KEY].to_i
|
|
213
211
|
hash[file].merge!(LAST_UPDATED_KEY => hash[file][LAST_UPDATED_KEY],
|
|
@@ -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
|
|
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)
|
|
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 >=
|
|
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)
|
|
@@ -108,7 +108,7 @@ module Coverband
|
|
|
108
108
|
|
|
109
109
|
def concrete_target
|
|
110
110
|
if defined?(Rails.application)
|
|
111
|
-
Dir.glob("#{@project_directory}
|
|
111
|
+
Dir.glob("#{@project_directory}/**/app/{views,components}/**/*.html.{erb,haml,slim}")
|
|
112
112
|
else
|
|
113
113
|
[]
|
|
114
114
|
end
|
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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 :
|
|
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
|
data/lib/coverband/version.rb
CHANGED
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&.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,11 +98,11 @@ 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
|
+
(line < non_nil_lines) ? rand(5) : nil
|
|
106
106
|
end
|
|
107
107
|
end
|
|
108
108
|
|
|
@@ -146,7 +146,7 @@ namespace :benchmarks do
|
|
|
146
146
|
x.report("store_reports_all") { store.save_report(report) }
|
|
147
147
|
end
|
|
148
148
|
keys_subset = report.keys.first(100)
|
|
149
|
-
report_subset = report.
|
|
149
|
+
report_subset = report.slice(*keys_subset)
|
|
150
150
|
Benchmark.ips do |x|
|
|
151
151
|
x.config(time: 20, warmup: 5)
|
|
152
152
|
x.report("store_reports_subset") { store.save_report(report_subset) }
|
|
@@ -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!
|
|
@@ -182,7 +183,7 @@ namespace :benchmarks do
|
|
|
182
183
|
|
|
183
184
|
def measure_memory_report_coverage
|
|
184
185
|
require "memory_profiler"
|
|
185
|
-
|
|
186
|
+
fake_report
|
|
186
187
|
store = benchmark_redis_store
|
|
187
188
|
store.clear!
|
|
188
189
|
mock_files(store)
|
|
@@ -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)
|
|
@@ -256,37 +258,29 @@ namespace :benchmarks do
|
|
|
256
258
|
# about 2mb
|
|
257
259
|
puts(ObjectSpace.memsize_of(data) / 2**20)
|
|
258
260
|
|
|
259
|
-
|
|
261
|
+
JSON.parse(data)
|
|
260
262
|
# this seems to just show the value of the pointer
|
|
261
263
|
# puts(ObjectSpace.memsize_of(json_data) / 2**20)
|
|
262
264
|
# implies json takes 10-12 mb
|
|
263
265
|
puts(ObjectSpace.memsize_of_all / 2**20)
|
|
264
|
-
|
|
265
|
-
json_data = nil
|
|
266
266
|
GC.start
|
|
267
|
-
|
|
267
|
+
JSON.parse(data)
|
|
268
268
|
# this seems to just show the value of the pointer
|
|
269
269
|
# puts(ObjectSpace.memsize_of(json_data) / 2**20)
|
|
270
270
|
# implies json takes 10-12 mb
|
|
271
271
|
puts(ObjectSpace.memsize_of_all / 2**20)
|
|
272
|
-
|
|
273
|
-
json_data = nil
|
|
274
272
|
GC.start
|
|
275
|
-
|
|
273
|
+
JSON.parse(data)
|
|
276
274
|
# this seems to just show the value of the pointer
|
|
277
275
|
# puts(ObjectSpace.memsize_of(json_data) / 2**20)
|
|
278
276
|
# implies json takes 10-12 mb
|
|
279
277
|
puts(ObjectSpace.memsize_of_all / 2**20)
|
|
280
|
-
|
|
281
|
-
json_data = nil
|
|
282
278
|
GC.start
|
|
283
|
-
|
|
279
|
+
JSON.parse(data)
|
|
284
280
|
# this seems to just show the value of the pointer
|
|
285
281
|
# puts(ObjectSpace.memsize_of(json_data) / 2**20)
|
|
286
282
|
# implies json takes 10-12 mb
|
|
287
283
|
puts(ObjectSpace.memsize_of_all / 2**20)
|
|
288
|
-
|
|
289
|
-
json_data = nil
|
|
290
284
|
GC.start
|
|
291
285
|
puts(ObjectSpace.memsize_of_all / 2**20)
|
|
292
286
|
|
|
@@ -316,7 +310,7 @@ namespace :benchmarks do
|
|
|
316
310
|
desc "runs memory leak check via Rails tests"
|
|
317
311
|
task memory_rails: [:setup] do
|
|
318
312
|
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`
|
|
313
|
+
puts `COVERBAND_MEMORY_TEST=true bundle exec ruby -I test test/forked/rails_full_stack_test.rb`
|
|
320
314
|
end
|
|
321
315
|
|
|
322
316
|
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
|