Skip to content

Commit

Permalink
Merge pull request #2 from viteinfinite/feature-temp-profdata
Browse files Browse the repository at this point in the history
Add JSON support to profdata format
  • Loading branch information
viteinfinite committed Jun 21, 2015
2 parents 1f58caa + 0c7877a commit 8558508
Show file tree
Hide file tree
Showing 21 changed files with 542 additions and 124 deletions.
13 changes: 13 additions & 0 deletions bin/slather
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ Clamp do
option ["--output-directory"], "OUTPUT_DIRECTORY", "The directory where your Cobertura XML report will be written to."
option ["--ignore", "-i"], "IGNORE", "ignore files conforming to a path", :multivalued => true

option ["--input-format"], "INPUT_FORMAT", "Input format (gcov, profdata)"
option ["--scheme"], "SCHEME", "The scheme for which the coverage was generated"

def execute
puts "Slathering..."

Expand All @@ -34,6 +37,8 @@ Clamp do
setup_source_directory
setup_output_directory
setup_coverage_service
setup_input_format
setup_scheme

post

Expand Down Expand Up @@ -93,6 +98,14 @@ Clamp do
end
end

def setup_input_format
project.input_format = input_format
end

def setup_scheme
project.scheme = scheme
end

end

subcommand "setup", "Configures an xcodeproj for test coverage generation" do
Expand Down
4 changes: 3 additions & 1 deletion lib/slather.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
require 'slather/version'
require 'slather/project'
require 'slather/coverage_info'
require 'slather/coverage_file'
require 'slather/coveralls_coverage_file'
require 'slather/coveralls_coverage'
require 'slather/profdata_coverage_file'
require 'slather/coverage_service/cobertura_xml_output'
require 'slather/coverage_service/coveralls'
require 'slather/coverage_service/hardcover'
Expand Down
127 changes: 35 additions & 92 deletions lib/slather/coverage_file.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
require 'slather/coverage_info'
require 'slather/coveralls_coverage'

module Slather
class CoverageFile

include CoverageInfo
include CoverallsCoverage

attr_accessor :project, :gcno_file_pathname

def initialize(project, gcno_file_pathname)
Expand All @@ -11,7 +17,6 @@ def initialize(project, gcno_file_pathname)
def source_file_pathname
@source_file_pathname ||= begin
base_filename = gcno_file_pathname.basename.sub_ext("")
# TODO: Handle Swift
path = nil
if project.source_directory
path = Dir["#{project.source_directory}/**/#{base_filename}.{#{supported_file_extensions.join(",")}}"].first
Expand All @@ -36,10 +41,6 @@ def source_data
source_file.read
end

def source_file_pathname_relative_to_repo_root
source_file_pathname.realpath.relative_path_from(Pathname("./").realpath)
end

def gcov_data
@gcov_data ||= begin
gcov_output = `gcov "#{source_file_pathname}" --object-directory "#{gcno_file_pathname.parent}" --branch-probabilities --branch-counts`
Expand All @@ -58,6 +59,24 @@ def gcov_data
end
end

def all_lines
unless cleaned_gcov_data.empty?
first_line_start = cleaned_gcov_data =~ /^\s+(-|#+|[0-9+]):\s+1:/
cleaned_gcov_data[first_line_start..-1].split("\n").map
else
[]
end
end

def cleaned_gcov_data
data = gcov_data.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '').gsub(/^function(.*) called [0-9]+ returned [0-9]+% blocks executed(.*)$\r?\n/, '')
data.gsub(/^branch(.*)$\r?\n/, '')
end

def raw_data
self.gcov_data
end

def line_coverage_data
unless cleaned_gcov_data.empty?
first_line_start = cleaned_gcov_data =~ /^\s+(-|#+|[0-9+]):\s+1:/
Expand All @@ -70,9 +89,8 @@ def line_coverage_data
end
end

def cleaned_gcov_data
data = gcov_data.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '').gsub(/^function(.*) called [0-9]+ returned [0-9]+% blocks executed(.*)$\r?\n/, '')
data.gsub(/^branch(.*)$\r?\n/, '')
def line_number_in_line(line)
line.split(':')[1].strip.to_i
end

def coverage_for_line(line)
Expand All @@ -89,104 +107,29 @@ def coverage_for_line(line)
end
end

def num_lines_tested
line_coverage_data.compact.select { |cd| cd > 0 }.count
end

def num_lines_testable
line_coverage_data.compact.count
end

def rate_lines_tested
if num_lines_testable > 0
(num_lines_tested / num_lines_testable.to_f)
else
0
end
end

def percentage_lines_tested
if num_lines_testable == 0
100
else
rate_lines_tested * 100
end
end

def branch_coverage_data
@branch_coverage_data ||= begin
branch_coverage_data = Hash.new

gcov_data.scan(/(^(\s+(-|#+|[0-9]+):\s+[1-9]+:(.*)$\r?\n)(^branch\s+[0-9]+\s+[a-zA-Z0-9]+\s+[a-zA-Z0-9]+$\r?\n)+)+/) do |data|
lines = data[0].split("\n")
line_number = lines[0].split(':')[1].strip.to_i
branch_coverage_data[line_number] = lines[1..-1].map do |line|
if line.split(' ')[2].strip == "never"
0
else
line.split(' ')[3].strip.to_i
end
gcov_data.scan(/(^(\s+(-|#+|[0-9]+):\s+[1-9]+:(.*)$\r?\n)(^branch\s+[0-9]+\s+[a-zA-Z0-9]+\s+[a-zA-Z0-9]+$\r?\n)+)+/) do |data|
lines = data[0].split("\n")
line_number = lines[0].split(':')[1].strip.to_i
branch_coverage_data[line_number] = lines[1..-1].map do |line|
if line.split(' ')[2].strip == "never"
0
else
line.split(' ')[3].strip.to_i
end
end
end
branch_coverage_data
end
end

def branch_coverage_data_for_statement_on_line(line_number)
branch_coverage_data[line_number] || []
end

def num_branches_for_statement_on_line(line_number)
branch_coverage_data_for_statement_on_line(line_number).length
end

def num_branch_hits_for_statement_on_line(line_number)
branch_coverage_data_for_statement_on_line(line_number).count { |hit_count| hit_count > 0 }
end

def rate_branch_coverage_for_statement_on_line(line_number)
branch_data = branch_coverage_data_for_statement_on_line(line_number)
if branch_data.empty?
0.0
else
(num_branch_hits_for_statement_on_line(line_number) / branch_data.length.to_f)
end
end

def percentage_branch_coverage_for_statement_on_line(line_number)
rate_branch_coverage_for_statement_on_line(line_number) * 100
end

def num_branches_testable
branch_coverage_data.keys.reduce(0) do |sum, line_number|
sum += num_branches_for_statement_on_line(line_number)
end
end

def num_branches_tested
branch_coverage_data.keys.reduce(0) do |sum, line_number|
sum += num_branch_hits_for_statement_on_line(line_number)
end
end

def rate_branches_tested
if (num_branches_testable > 0)
(num_branches_tested / num_branches_testable.to_f)
else
0.0
end
end

def source_file_basename
File.basename(source_file_pathname, '.m')
end

def ignored?
project.ignore_list.any? do |ignore|
File.fnmatch(ignore, source_file_pathname_relative_to_repo_root)
end
end

def supported_file_extensions
["cpp", "mm", "m"]
end
Expand Down
84 changes: 84 additions & 0 deletions lib/slather/coverage_info.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
module Slather
module CoverageInfo

def num_lines_tested
line_coverage_data.compact.select { |cd| cd > 0 }.count
end

def num_lines_testable
line_coverage_data.compact.count
end

def rate_lines_tested
if num_lines_testable > 0
(num_lines_tested / num_lines_testable.to_f)
else
0
end
end

def percentage_lines_tested
if num_lines_testable == 0
100
else
rate_lines_tested * 100
end
end

def branch_coverage_data_for_statement_on_line(line_number)
branch_coverage_data[line_number] || []
end

def num_branches_for_statement_on_line(line_number)
branch_coverage_data_for_statement_on_line(line_number).length
end

def num_branch_hits_for_statement_on_line(line_number)
branch_coverage_data_for_statement_on_line(line_number).count { |hit_count| hit_count > 0 }
end

def rate_branch_coverage_for_statement_on_line(line_number)
branch_data = branch_coverage_data_for_statement_on_line(line_number)
if branch_data.empty?
0.0
else
(num_branch_hits_for_statement_on_line(line_number) / branch_data.length.to_f)
end
end

def percentage_branch_coverage_for_statement_on_line(line_number)
rate_branch_coverage_for_statement_on_line(line_number) * 100
end

def num_branches_testable
branch_coverage_data.keys.reduce(0) do |sum, line_number|
sum += num_branches_for_statement_on_line(line_number)
end
end

def num_branches_tested
branch_coverage_data.keys.reduce(0) do |sum, line_number|
sum += num_branch_hits_for_statement_on_line(line_number)
end
end

def rate_branches_tested
if (num_branches_testable > 0)
(num_branches_tested / num_branches_testable.to_f)
else
0.0
end
end

def source_file_pathname_relative_to_repo_root
source_file_pathname.realpath.relative_path_from(Pathname("./").realpath)
end

def ignored?
project.ignore_list.any? do |ignore|
File.fnmatch(ignore, source_file_pathname_relative_to_repo_root)
end
end

end
end
12 changes: 8 additions & 4 deletions lib/slather/coverage_service/cobertura_xml_output.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ module CoverageService
module CoberturaXmlOutput

def coverage_file_class
Slather::CoverageFile
if input_format == "profdata"
Slather::ProfdataCoverageFile
else
Slather::CoverageFile
end
end
private :coverage_file_class

Expand All @@ -26,6 +30,7 @@ def store_report(report)
def grouped_coverage_files
groups = Hash.new
coverage_files.each do |coverage_file|
next if coverage_file == nil
path = File.dirname(coverage_file.source_file_pathname_relative_to_repo_root)
if groups[path] == nil
groups[path] = Array.new
Expand Down Expand Up @@ -127,8 +132,7 @@ def create_class_node(coverage_file)
lines_node = Nokogiri::XML::Node.new "lines", @doc
lines_node.parent = class_node

coverage_file.cleaned_gcov_data.split("\n").each do |line|
line_segments = line.split(':')
coverage_file.all_lines.each do |line|
if coverage_file.coverage_for_line(line)
line_node = create_line_node(line, coverage_file)
line_node.parent = lines_node
Expand All @@ -138,7 +142,7 @@ def create_class_node(coverage_file)
end

def create_line_node(line, coverage_file)
line_number = line.split(':')[1].strip.to_i
line_number = coverage_file.line_number_in_line(line)
line_node = Nokogiri::XML::Node.new "line", @doc
line_node['number'] = line_number
line_node['branch'] = "false"
Expand Down
6 changes: 5 additions & 1 deletion lib/slather/coverage_service/coveralls.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ module CoverageService
module Coveralls

def coverage_file_class
Slather::CoverallsCoverageFile
if input_format == "profdata"
Slather::ProfdataCoverageFile
else
Slather::CoverageFile
end
end
private :coverage_file_class

Expand Down
Loading

0 comments on commit 8558508

Please sign in to comment.