Skip to content

Commit c7da38c

Browse files
committed
Add mutation testing with 100% coverage, enforce method coverage
* Add mutant-minitest and .mutant.yml targeting all HTMLFormatter methods * Add mutant CI workflow and rake task * Split tests into test_view_helpers.rb and test_formatter.rb * Enable method coverage enforcement when Ruby/SimpleCov support it * Fix warning: suppress method redefinition in test spies * Fix warning: use @_summary ivar instead of locals for ERB binding * Remove redundant respond_to? guard for method_coverage?
1 parent 2b49d91 commit c7da38c

File tree

17 files changed

+1444
-79
lines changed

17 files changed

+1444
-79
lines changed

.github/workflows/lint.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
name: lint
2+
3+
on: [push, pull_request]
4+
5+
jobs:
6+
rubocop:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- uses: actions/checkout@v6
10+
11+
- uses: ruby/setup-ruby@v1
12+
with:
13+
ruby-version: ruby
14+
bundler-cache: true
15+
16+
- run: bundle exec rubocop

.github/workflows/mutant.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
name: mutant
2+
3+
on: [push, pull_request]
4+
5+
jobs:
6+
mutant:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- uses: actions/checkout@v6
10+
11+
- uses: ruby/setup-ruby@v1
12+
with:
13+
ruby-version: ruby
14+
bundler-cache: true
15+
16+
- run: bundle exec mutant run

.github/workflows/test.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,5 @@ jobs:
3434
bundler-cache: true
3535
continue-on-error: ${{ (matrix.ruby-version == 'ruby-head') || (matrix.ruby-version == 'jruby-head') || (matrix.ruby-version == 'truffleruby') }}
3636

37-
- run: |
38-
bundle exec rake
37+
- run: bundle exec rake test
3938
continue-on-error: ${{ (matrix.ruby-version == 'ruby-head') || (matrix.ruby-version == 'jruby-head') || (matrix.ruby-version == 'truffleruby') }}

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,5 @@ coverage
2828
rdoc
2929
pkg
3030
.sass-cache
31+
/index.html
32+
/assets/[0-9]*

.mutant.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,4 @@ requires:
99
- simplecov-html
1010
matcher:
1111
subjects:
12-
- SimpleCov::Formatter::HTMLFormatter#coverage_css_class
13-
- SimpleCov::Formatter::HTMLFormatter#strength_css_class
12+
- SimpleCov::Formatter::HTMLFormatter*

.rubocop.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,3 @@ Style/TrailingCommaInHashLiteral:
6262

6363
Style/TrailingCommaInArrayLiteral:
6464
EnforcedStyleForMultiline: "comma"
65-
66-
Gemspec/RequireMFA:
67-
Enabled: false

Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ end
1616

1717
group :test do
1818
gem "minitest"
19+
gem "mutant-minitest"
1920
end
2021

2122
group :development do

Gemfile.lock

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,21 @@ GEM
1616
remote: https://rubygems.org/
1717
specs:
1818
ast (2.4.3)
19+
date (3.5.1)
20+
date (3.5.1-java)
21+
diff-lcs (2.0.0)
1922
docile (1.4.1)
2023
drb (2.2.3)
24+
erb (6.0.2)
25+
erb (6.0.2-java)
26+
io-console (0.8.2)
27+
io-console (0.8.2-java)
28+
irb (1.17.0)
29+
pp (>= 0.6.0)
30+
prism (>= 1.3.0)
31+
rdoc (>= 4.0.0)
32+
reline (>= 0.4.2)
33+
jar-dependencies (0.5.7)
2134
json (2.19.3)
2235
json (2.19.3-java)
2336
language_server-protocol (3.17.0.5)
@@ -26,6 +39,18 @@ GEM
2639
minitest (6.0.3)
2740
drb (~> 2.0)
2841
prism (~> 1.5)
42+
mutant (0.15.1)
43+
diff-lcs (>= 1.6, < 3)
44+
irb (~> 1.15)
45+
parser (~> 3.3.10)
46+
regexp_parser (~> 2.10)
47+
sorbet-runtime (~> 0.6.0)
48+
unparser (~> 0.8.2)
49+
mutant-minitest (0.15.1)
50+
minitest (>= 5.11, < 7)
51+
mutant (= 0.15.1)
52+
mutex_m (~> 0.2)
53+
mutex_m (0.3.0)
2954
nokogiri (1.19.2-arm64-darwin)
3055
racc (~> 1.4)
3156
nokogiri (1.19.2-java)
@@ -36,12 +61,27 @@ GEM
3661
parser (3.3.11.1)
3762
ast (~> 2.4.1)
3863
racc
64+
pp (0.6.3)
65+
prettyprint
66+
prettyprint (0.2.0)
3967
prism (1.9.0)
68+
psych (5.3.1)
69+
date
70+
stringio
71+
psych (5.3.1-java)
72+
date
73+
jar-dependencies (>= 0.1.7)
4074
racc (1.8.1)
4175
racc (1.8.1-java)
4276
rainbow (3.1.1)
4377
rake (13.3.1)
78+
rdoc (7.2.0)
79+
erb
80+
psych (>= 4.0.0)
81+
tsort
4482
regexp_parser (2.11.3)
83+
reline (0.6.3)
84+
io-console (~> 0.5)
4585
rubocop (1.86.0)
4686
json (~> 2.3)
4787
language_server-protocol (~> 3.17.0.2)
@@ -69,9 +109,16 @@ GEM
69109
rubocop (>= 1.72.1)
70110
ruby-progressbar (1.13.0)
71111
simplecov_json_formatter (0.1.4)
112+
sorbet-runtime (0.6.13073)
113+
stringio (3.2.0)
114+
tsort (0.2.0)
72115
unicode-display_width (3.2.0)
73116
unicode-emoji (~> 4.1)
74117
unicode-emoji (4.2.0)
118+
unparser (0.8.2)
119+
diff-lcs (>= 1.6, < 3)
120+
parser (>= 3.3.0)
121+
prism (>= 1.5.1)
75122

76123
PLATFORMS
77124
arm64-darwin-22
@@ -82,6 +129,7 @@ PLATFORMS
82129
DEPENDENCIES
83130
logger
84131
minitest
132+
mutant-minitest
85133
nokogiri
86134
rake (>= 11)
87135
rubocop

Rakefile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,12 @@ rescue LoadError
1919
end
2020
end
2121

22-
task default: %i[test rubocop]
22+
desc "Run mutation tests"
23+
task :mutant do
24+
sh "bundle exec mutant run"
25+
end
26+
27+
task default: %i[test rubocop mutant]
2328

2429
namespace :assets do
2530
desc "Compiles all assets using esbuild"

lib/simplecov-html.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class HTMLFormatter
2727

2828
def initialize(silent: false, inline_assets: false)
2929
@branch_coverage = SimpleCov.branch_coverage?
30-
@method_coverage = SimpleCov.respond_to?(:method_coverage?) && SimpleCov.method_coverage?
30+
@method_coverage = SimpleCov.method_coverage?
3131
@templates = {}
3232
@inline_assets = inline_assets || ENV.key?("SIMPLECOV_INLINE_ASSETS")
3333
@public_assets_dir = File.join(File.dirname(__FILE__), "../public/")
@@ -72,21 +72,21 @@ def output_path
7272
end
7373

7474
def asset_output_path
75-
@asset_output_path ||= File.join(output_path, "assets", SimpleCov::Formatter::HTMLFormatter::VERSION).tap do |path|
75+
@asset_output_path ||= File.join(output_path, "assets", VERSION).tap do |path|
7676
FileUtils.mkdir_p(path)
7777
end
7878
end
7979

8080
def assets_path(name)
8181
return asset_inline(name) if @inline_assets
8282

83-
File.join("./assets", SimpleCov::Formatter::HTMLFormatter::VERSION, name)
83+
File.join("./assets", VERSION, name)
8484
end
8585

8686
def asset_inline(name)
8787
path = File.join(@public_assets_dir, name)
8888
base64_content = [File.read(path)].pack("m0")
89-
"data:#{CONTENT_TYPES[File.extname(name)]};base64,#{base64_content}"
89+
"data:#{CONTENT_TYPES.fetch(File.extname(name))};base64,#{base64_content}"
9090
end
9191

9292
def formatted_source_file(source_file)

0 commit comments

Comments
 (0)