Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add method coverage support #110

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,12 @@ jobs:

matrix:
ruby-version:
- '2.5'
- '2.6'
- '2.7'
- '3.0'
- '3.1'
- ruby-head
- jruby
- jruby-9.3
- jruby-head

steps:
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,5 @@ coverage
rdoc
pkg
.sass-cache

.ruby-version
156 changes: 153 additions & 3 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ AllCops:
Bundler/DuplicatedGem:
Enabled: false

Gemspec/RequiredRubyVersion:
Enabled: false

Layout/AccessModifierIndentation:
EnforcedStyle: outdent

Expand Down Expand Up @@ -74,3 +71,156 @@ Style/TrailingCommaInHashLiteral:

Style/TrailingCommaInArrayLiteral:
EnforcedStyleForMultiline: "comma"

Gemspec/DateAssignment: # new in 1.10
Enabled: true

Layout/LineEndStringConcatenationIndentation: # new in 1.18
Enabled: true

Layout/SpaceBeforeBrackets: # new in 1.7
Enabled: true

Lint/AmbiguousAssignment: # new in 1.7
Enabled: true

Lint/AmbiguousOperatorPrecedence: # new in 1.21
Enabled: true

Lint/AmbiguousRange: # new in 1.19
Enabled: true

Lint/DeprecatedConstants: # new in 1.8
Enabled: true

Lint/DuplicateBranch: # new in 1.3
Enabled: true

Lint/DuplicateRegexpCharacterClassElement: # new in 1.1
Enabled: true

Lint/EmptyBlock: # new in 1.1
Enabled: true

Lint/EmptyClass: # new in 1.3
Enabled: true

Lint/EmptyInPattern: # new in 1.16
Enabled: true

Lint/IncompatibleIoSelectWithFiberScheduler: # new in 1.21
Enabled: true

Lint/LambdaWithoutLiteralBlock: # new in 1.8
Enabled: true

Lint/NoReturnInBeginEndBlocks: # new in 1.2
Enabled: true

Lint/NumberedParameterAssignment: # new in 1.9
Enabled: true

Lint/OrAssignmentToConstant: # new in 1.9
Enabled: true

Lint/RedundantDirGlobSort: # new in 1.8
Enabled: true

Lint/RequireRelativeSelfPath: # new in 1.22
Enabled: true

Lint/SymbolConversion: # new in 1.9
Enabled: true

Lint/ToEnumArguments: # new in 1.1
Enabled: true

Lint/TripleQuotes: # new in 1.9
Enabled: true

Lint/UnexpectedBlockArity: # new in 1.5
Enabled: true

Lint/UnmodifiedReduceAccumulator: # new in 1.1
Enabled: true

Lint/UselessRuby2Keywords: # new in 1.23
Enabled: true

Naming/BlockForwarding: # new in 1.24
Enabled: true

Security/IoMethods: # new in 1.22
Enabled: true

Style/ArgumentsForwarding: # new in 1.1
Enabled: true

Style/CollectionCompact: # new in 1.2
Enabled: true

Style/DocumentDynamicEvalDefinition: # new in 1.1
Enabled: true

Style/EndlessMethod: # new in 1.8
Enabled: true

Style/FileRead: # new in 1.24
Enabled: true

Style/FileWrite: # new in 1.24
Enabled: true

Style/HashConversion: # new in 1.10
Enabled: true

Style/HashExcept: # new in 1.7
Enabled: true

Style/IfWithBooleanLiteralBranches: # new in 1.9
Enabled: true

Style/InPatternThen: # new in 1.16
Enabled: true

Style/MapToHash: # new in 1.24
Enabled: true

Style/MultilineInPatternThen: # new in 1.16
Enabled: true

Style/NegatedIfElseCondition: # new in 1.2
Enabled: true

Style/NestedFileDirname: # new in 1.26
Enabled: true

Style/NilLambda: # new in 1.3
Enabled: true

Style/NumberedParameters: # new in 1.22
Enabled: true

Style/NumberedParametersLimit: # new in 1.22
Enabled: true

Style/OpenStructUse: # new in 1.23
Enabled: true

Style/QuotedSymbols: # new in 1.16
Enabled: true

Style/RedundantArgument: # new in 1.4
Enabled: true

Style/RedundantSelfAssignmentBranch: # new in 1.19
Enabled: true

Style/SelectByRegexp: # new in 1.22
Enabled: true

Style/StringChars: # new in 1.12
Enabled: true

Style/SwapValues: # new in 1.1
Enabled: true
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,4 @@ DEPENDENCIES
yui-compressor

BUNDLED WITH
2.3.10
2.4.3
2 changes: 1 addition & 1 deletion assets/stylesheets/application.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
//= require ./reset.css
//= require_directory ./plugins/
//= require ./screen.css
//= require ./screen.css
5 changes: 5 additions & 0 deletions assets/stylesheets/screen.css
Original file line number Diff line number Diff line change
Expand Up @@ -319,3 +319,8 @@ thead th {
.source_table .missed-branch:nth-child(even) {
background-color: #cc6e6e;
}

.t-missed-method-summary ul {
margin: 0;
padding-left: 2em;
}
48 changes: 37 additions & 11 deletions lib/simplecov-html.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@
major, minor, patch = SimpleCov::VERSION.scan(/\d+/).first(3).map(&:to_i)
if major < 0 || minor < 9 || patch < 0
raise "The version of SimpleCov you are using is too old. "\
"Please update with `gem install simplecov` or `bundle update simplecov`"
"Please update with `gem install simplecov` or `bundle update simplecov`"
end

module SimpleCov
module Formatter
class HTMLFormatter
class HTMLFormatter # rubocop:disable Metrics/ClassLength
def initialize
@branchable_result = SimpleCov.branch_coverage?
@branch_coverage = SimpleCov.branch_coverage?
@method_coverage = SimpleCov.method_coverage?
@templates = {}
@inline_assets = !ENV["SIMPLECOV_INLINE_ASSETS"].nil?
@public_assets_dir = File.join(File.dirname(__FILE__), "../public/")
Expand All @@ -38,20 +39,31 @@ def format(result)
end

def output_message(result)
str = "Coverage report generated for #{result.command_name} to #{output_path}. #{result.covered_lines} / #{result.total_lines} LOC (#{result.covered_percent.round(2)}%) covered."
str += " #{result.covered_branches} / #{result.total_branches} branches (#{result.coverage_statistics[:branch].percent.round(2)}%) covered." if branchable_result?
str
parts = []
parts << "Coverage report generated for #{result.command_name} to #{output_path}"
parts << "Line coverage: #{render_stats(result, :line)}"
parts << "Branch coverage: #{render_stats(result, :branch)}" if branch_coverage?
parts << "Method coverage: #{render_stats(result, :method)}" if method_coverage?

parts.join("\n")
end

def branch_coverage?
# cached in initialize because we truly look it up a whole bunch of times
# and it's easier to cache here then in SimpleCov because there we might
# still enable/disable branch coverage criterion
@branch_coverage
end

def branchable_result?
def method_coverage?
# cached in initialize because we truly look it up a whole bunch of times
# and it's easier to cache here then in SimpleCov because there we might
# still enable/disable branch coverage criterion
@branchable_result
@method_coverage
end

def line_status?(source_file, line)
if branchable_result? && source_file.line_with_missed_branch?(line.number)
if branch_coverage? && source_file.line_with_missed_branch?(line.number)
"missed-branch"
else
line.status
Expand Down Expand Up @@ -83,6 +95,10 @@ def assets_path(name)
File.join("./assets", SimpleCov::Formatter::HTMLFormatter::VERSION, name)
end

def to_id(value)
value.gsub(/^[^a-zA-Z]+/, "").gsub(/[^a-zA-Z0-9\-_]/, "")
end

def asset_inline(name)
path = File.join(@public_assets_dir, name)

Expand All @@ -94,7 +110,7 @@ def asset_inline(name)
".css" => "text/css",
}[File.extname(name)]

base64_content = Base64.strict_encode64 File.open(path).read
base64_content = Base64.strict_encode64 File.read(path)
"data:#{content_type};base64,#{base64_content}"
end

Expand All @@ -107,7 +123,6 @@ def formatted_source_file(source_file)

# Returns a table containing the given source files
def formatted_file_list(title, source_files)
title_id = title.gsub(/^[^a-zA-Z]+/, "").gsub(/[^a-zA-Z0-9\-_]/, "")
template("file_list").result(binding)
end

Expand Down Expand Up @@ -151,6 +166,17 @@ def shortened_filename(source_file)
def link_to_source_file(source_file)
%(<a href="##{id source_file}" class="src_link" title="#{shortened_filename source_file}">#{shortened_filename source_file}</a>)
end

def render_stats(result, criterion)
stats = result.coverage_statistics.fetch(criterion)

Kernel.format(
"%<covered>d / %<total>d (%<percent>.2f%%)",
covered: stats.covered,
total: stats.total,
percent: stats.percent
)
end
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion simplecov-html.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Gem::Specification.new do |gem|
gem.summary = gem.description
gem.license = "MIT"

gem.required_ruby_version = ">= 2.4"
gem.required_ruby_version = ">= 2.6"

gem.files = `git ls-files`.split("\n")
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
Expand Down
Loading
Loading