moduleSimpleCov## Representation of a source file including it's coverage data, source code,# source lines and featuring helpers to interpret that data.#classSourceFile# Representation of a single line in a source file including# this specific line's source code, line_number and code coverage,# with the coverage being either nil (coverage not applicable, e.g. comment# line), 0 (line not covered) or >1 (the amount of times the line was# executed)classLine# The source code for this line. Aliased as :sourceattr_reader:src# The line number in the source file. Aliased as :line, :numberattr_reader:line_number# The coverage data for this line: either nil (never), 0 (missed) or >=1 (times covered)attr_reader:coverage# Whether this line was skippedattr_reader:skipped# Lets grab some fancy aliases, shall we?alias_method:source,:srcalias_method:line,:line_numberalias_method:number,:line_numberdefinitialize(src,line_number,coverage,skipped=false)raiseArgumentError,"Only String accepted for source"unlesssrc.kind_of?(String)raiseArgumentError,"Only Fixnum accepted for line_number"unlessline_number.kind_of?(Fixnum)raiseArgumentError,"Only Fixnum and nil accepted for coverage"unlesscoverage.kind_of?(Fixnum)orcoverage.nil?@src,@line_number,@coverage,@skipped=src,line_number,coverage,skippedend# Returns true if this is a line that should have been covered, but was notdefmissed?notnever?andnotskipped?andcoverage==0end# Returns true if this is a line that has been covereddefcovered?notnever?andnotskipped?andcoverage>0end# Returns true if this line is not relevant for coveragedefnever?notskipped?andcoverage.nil?enddefskipped?@skippedendend# The full path to this source file (e.g. /User/colszowka/projects/simplecov/lib/simplecov/source_file.rb)attr_reader:filename# The array of coverage data received from the Coverage.resultattr_reader:coverage# The source code for this file. Aliased as :sourceattr_reader:srcalias_method:source,:srcdefinitialize(filename,coverage)@filename,@coverage,@src=filename,coverage,File.readlines(filename)@skipped_line_numbers=process_skipped_linesend# Returns all source lines for this file as instances of SimpleCov::SourceFile::Line,# and thus including coverage data. Aliased as :source_linesdeflinesreturn@linesunless@lines.nil?# Warning to identify condition from Issue #56ifcoverage.size>src.size$stderr.puts"Warning: coverage data provided by Coverage [#{coverage.size}] exceeds number of lines in #{filename} [#{src.size}]"end# Initialize lines@lines=[]src.each_with_indexdo|src,i|@lines<<SimpleCov::SourceFile::Line.new(src,i+1,coverage[i],@skipped_line_numbers.include?(i+1))end@linesendalias_method:source_lines,:lines# Access SimpleCov::SourceFile::Line source lines by line numberdefline(number)lines[number-1]end# The coverage for this file in percent. 0 if the file has no relevant linesdefcovered_percentreturn100.0iflines.length==0orlines.length==never_lines.count(covered_lines.count)*100/(lines.count-never_lines.count-skipped_lines.count).to_fend#defcovered_strengthreturn0iflines.length==0orlines.length==never_lines.countlines_strength=0lines.eachdo|c|lines_strength+=c.coverageifc.coverageendeffective_lines_count=(lines.count-never_lines.count-skipped_lines.count).to_fstrength=lines_strength/effective_lines_countround_float(strength,1)end# Returns all covered lines as SimpleCov::SourceFile::Linedefcovered_lines@covered_lines||=lines.select{|c|c.covered?}end# Returns all lines that should have been, but were not covered# as instances of SimpleCov::SourceFile::Linedefmissed_lines@missed_lines||=lines.select{|c|c.missed?}end# Returns all lines that are not relevant for coverage as# SimpleCov::SourceFile::Line instancesdefnever_lines@never_lines||=lines.select{|c|c.never?}end# Returns all lines that were skipped as SimpleCov::SourceFile::Line instancesdefskipped_lines@skipped_lines||=lines.select{|c|c.skipped?}end# Returns the number of relevant lines (covered + missed)deflines_of_codecovered_lines.count+missed_lines.countenddefprocess_skipped_linesskipped_line_numbers=[]skipping=false@src.each_with_indexdo|line,i|ifline=~/^\s*#\:nocov\:/skipping=!skippingelseskipped_line_numbers<<i+1ifskippingendendskipped_line_numbersendprivate# ruby 1.9 could use Float#round(places) insteaddefround_float(float,places)factor=(10*places).to_f(float*factor).round/factorendendend