Skip to content

Commit

Permalink
Adds coverage calculation by individual file feature.
Browse files Browse the repository at this point in the history
  • Loading branch information
Paul Tashman authored and xaviershay committed May 25, 2015
1 parent 18bb073 commit 84ef86a
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 2 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,14 @@ You can define the minimum coverage percentage expected. SimpleCov will return n
SimpleCov.minimum_coverage 90
```

### Minimum coverage by file

You can define the minimum coverage by file percentage expected. SimpleCov will return non-zero if unmet. This is useful to help ensure coverage is relatively consistent, rather than being skewed by particularly good or bad areas of the code.

```ruby
SimpleCov.minimum_coverage_by_file 80
```

### Maximum coverage drop

You can define the maximum coverage drop percentage at once. SimpleCov will return non-zero if exceeded.
Expand Down
11 changes: 11 additions & 0 deletions lib/simplecov/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,17 @@ def maximum_coverage_drop(coverage_drop = nil)
@maximum_coverage_drop ||= (coverage_drop || 100).to_f.round(2)
end

#
# Defines the minimum coverage per file required for the testsuite to pass.
# SimpleCov will return non-zero if the current coverage of the least covered file
# is below this threshold.
#
# Default is 0% (disabled)
#
def minimum_coverage_by_file(coverage = nil)
@minimum_coverage_by_file ||= (coverage || 0).to_f.round(2)
end

#
# Refuses any coverage drop. That is, coverage is only allowed to increase.
# SimpleCov will return non-zero if the coverage decreases.
Expand Down
4 changes: 4 additions & 0 deletions lib/simplecov/defaults.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,15 @@

if SimpleCov.result? # Result has been computed
covered_percent = SimpleCov.result.covered_percent.round(2)
covered_percentages = SimpleCov.result.covered_percentages.map { |p| p.round(2) }

if @exit_status == SimpleCov::ExitCodes::SUCCESS # No other errors
if covered_percent < SimpleCov.minimum_coverage # rubocop:disable Metrics/BlockNesting
$stderr.printf("Coverage (%.2f%%) is below the expected minimum coverage (%.2f%%).\n", covered_percent, SimpleCov.minimum_coverage)
@exit_status = SimpleCov::ExitCodes::MINIMUM_COVERAGE
elsif covered_percentages.any? { |p| p < SimpleCov.minimum_coverage_by_file } # rubocop:disable Metrics/BlockNesting
$stderr.printf("File (%.2f%%) is only (%.2f%%) covered. This is below the expected minimum coverage per file of (%.2f%%).\n", least_covered_file, covered_percentages.min, SimpleCov.minimum_coverage_by_file)
@exit_status = SimpleCov::ExitCodes::MINIMUM_COVERAGE
elsif (last_run = SimpleCov::LastRun.read) # rubocop:disable Metrics/BlockNesting
diff = last_run["result"]["covered_percent"] - covered_percent
if diff > SimpleCov.maximum_coverage_drop # rubocop:disable Metrics/BlockNesting
Expand Down
11 changes: 11 additions & 0 deletions lib/simplecov/file_list.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@ def skipped_lines
map { |f| f.skipped_lines.count }.inject(&:+)
end

# Computes the coverage based upon lines covered and lines missed for each file
# Returns an array with all coverage percentages
def covered_percentages
map(&:covered_percent)
end

# Finds the least covered file and returns that file's name
def least_covered_file
sort_by(&:covered_percent).first.filename
end

# Returns the overall amount of relevant lines of code across all files in this list
def lines_of_code
covered_lines + missed_lines
Expand Down
2 changes: 1 addition & 1 deletion lib/simplecov/result.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class Result
# Explicitly set the command name that was used for this coverage result. Defaults to SimpleCov.command_name
attr_writer :command_name

def_delegators :files, :covered_percent, :covered_strength, :covered_lines, :missed_lines
def_delegators :files, :covered_percent, :covered_percentages, :least_covered_file, :covered_strength, :covered_lines, :missed_lines
def_delegator :files, :lines_of_code, :total_lines

# Initialize a new SimpleCov::Result from given Coverage.result (a Hash of filenames each containing an array of
Expand Down
8 changes: 8 additions & 0 deletions spec/file_list_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@
expect(subject.covered_percent).to eq(78.57142857142857)
end

it "has the correct covered percentages" do
expect(subject.covered_percentages).to eq([50.0, 80.0, 100.0])
end

it "has the correct least covered file" do
expect(subject.least_covered_file).to match(/sample_controller.rb/)
end

it "has the correct covered strength" do
expect(subject.covered_strength).to eq(0.9285714285714286)
end
Expand Down
18 changes: 17 additions & 1 deletion spec/result_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,15 @@
expect(subject.covered_percent).to eq(86.66666666666667)
end

[:covered_percent, :covered_strength, :covered_lines, :missed_lines, :total_lines].each do |msg|
it "has accurate covered percentages" do
expect(subject.covered_percentages).to eq([80.0, 80.0, 100.0])
end

it "has accurate least covered file" do
expect(subject.least_covered_file).to match(/sample_controller.rb/)
end

[:covered_percent, :covered_percentages, :least_covered_file, :covered_strength, :covered_lines, :missed_lines, :total_lines].each do |msg|
it "responds to #{msg}" do
expect(subject).to respond_to(msg)
end
Expand All @@ -74,6 +82,10 @@
expect(dumped_result.covered_percent).to eq(subject.covered_percent)
end

it "has the same covered_percentages" do
expect(dumped_result.covered_percentages).to eq(subject.covered_percentages)
end

it "has the same timestamp" do
expect(dumped_result.created_at.to_i).to eq(subject.created_at.to_i)
end
Expand Down Expand Up @@ -101,6 +113,10 @@
it "has 80 covered percent" do
expect(SimpleCov::Result.new(original_result).covered_percent).to eq(80)
end

it "has [80.0, 80.0] covered percentages" do
expect(SimpleCov::Result.new(original_result).covered_percentages).to eq([80.0, 80.0])
end
end

context "with groups set up for all files" do
Expand Down

0 comments on commit 84ef86a

Please sign in to comment.