Skip to content

Commit d8be1a3

Browse files
sferikshetty-tejas
andcommitted
Add errors to JSON output for files below minimum coverage
Report per-file minimum coverage violations in the JSON formatter, supporting line, branch, and method coverage criteria. This makes the JSON self-contained for downstream consumers (e.g. CI reporters) that don't have access to the Ruby process to check exit codes. Co-Authored-By: Tejas <tejas.shetty@mailbox.org>
1 parent 8931869 commit d8be1a3

File tree

6 files changed

+82
-5
lines changed

6 files changed

+82
-5
lines changed

lib/simplecov/formatter/json_formatter/result_hash_formatter.rb

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ def format
1414
format_total
1515
format_files
1616
format_groups
17+
format_errors
1718

1819
formatted_result
1920
end
@@ -37,14 +38,31 @@ def format_groups
3738
end
3839
end
3940

41+
def format_errors
42+
SimpleCov.minimum_coverage_by_file.each do |criterion, expected_percent|
43+
@result.files.each do |file|
44+
actual = SimpleCov.round_coverage(file.coverage_statistics.fetch(criterion).percent)
45+
next unless actual < expected_percent
46+
47+
criterion_key = CRITERION_KEYS.fetch(criterion)
48+
errors = formatted_result[:errors][criterion_key] ||= {}
49+
errors[file.filename] = actual
50+
end
51+
end
52+
end
53+
54+
CRITERION_KEYS = {line: :lines, branch: :branches, method: :methods}.freeze
55+
private_constant :CRITERION_KEYS
56+
4057
def formatted_result
4158
@formatted_result ||= {
4259
meta: {
4360
simplecov_version: SimpleCov::VERSION
4461
},
4562
total: {},
4663
coverage: {},
47-
groups: {}
64+
groups: {},
65+
errors: {}
4866
}
4967
end
5068

spec/fixtures/json/sample.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,6 @@
4343
"lines_covered_percent": 90.0
4444
}
4545
},
46-
"groups": {}
46+
"groups": {},
47+
"errors": {}
4748
}

spec/fixtures/json/sample_groups.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,5 +53,6 @@
5353
"strength": 0.0
5454
}
5555
}
56-
}
56+
},
57+
"errors": {}
5758
}

spec/fixtures/json/sample_with_branch.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,5 +65,6 @@
6565
"branches_covered_percent": 50.0
6666
}
6767
},
68-
"groups": {}
68+
"groups": {},
69+
"errors": {}
6970
}

spec/fixtures/json/sample_with_method.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,5 +77,6 @@
7777
"methods_covered_percent": 100.0
7878
}
7979
},
80-
"groups": {}
80+
"groups": {},
81+
"errors": {}
8182
}

spec/json_formatter_spec.rb

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,61 @@
107107
end
108108
end
109109

110+
context "with minimum_coverage_by_file for lines" do
111+
before do
112+
allow(SimpleCov).to receive(:minimum_coverage_by_file).and_return(line: 95)
113+
end
114+
115+
it "reports files below the threshold in errors" do
116+
subject.format(result)
117+
errors = json_output.fetch("errors")
118+
expect(errors).to eq(
119+
"lines" => {source_fixture("json/sample.rb") => 90.0}
120+
)
121+
end
122+
end
123+
124+
context "with minimum_coverage_by_file for branches" do
125+
let(:result) do
126+
SimpleCov::Result.new({
127+
source_fixture("json/sample.rb") => {
128+
"lines" => [nil, 1, 1, 1, 1, nil, nil, 1, 1, nil, nil,
129+
1, 1, 0, nil, 1, nil, nil, nil, nil, 1, 0, nil, nil, nil],
130+
"branches" => {
131+
[:if, 0, 13, 4, 17, 7] => {
132+
[:then, 1, 14, 6, 14, 10] => 0,
133+
[:else, 2, 16, 6, 16, 10] => 1
134+
}
135+
}
136+
}
137+
})
138+
end
139+
140+
before do
141+
enable_branch_coverage
142+
allow(SimpleCov).to receive(:minimum_coverage_by_file).and_return(branch: 75)
143+
end
144+
145+
it "reports files below the threshold in errors" do
146+
subject.format(result)
147+
errors = json_output.fetch("errors")
148+
expect(errors).to eq(
149+
"branches" => {source_fixture("json/sample.rb") => 50.0}
150+
)
151+
end
152+
end
153+
154+
context "with minimum_coverage_by_file when all files pass" do
155+
before do
156+
allow(SimpleCov).to receive(:minimum_coverage_by_file).and_return(line: 80)
157+
end
158+
159+
it "returns empty errors" do
160+
subject.format(result)
161+
expect(json_output.fetch("errors")).to eq({})
162+
end
163+
end
164+
110165
context "with groups" do
111166
let(:line_stats) { SimpleCov::CoverageStatistics.new(covered: 8, missed: 2) }
112167

0 commit comments

Comments
 (0)