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)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=src,line_number,coverage@skipped=false@src.encode!('UTF-8','UTF-8',:invalid=>:replace)if@src.respond_to?(:encode!)end# 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?end# Flags this line as skippeddefskipped!@skipped=trueend# Returns true if this line was skipped, false otherwise. Lines are skipped if they are wrapped with# # :nocov: comment lines.defskipped?!!skippedend# The status of this line - either covered, missed, skipped or never. Useful i.e. for direct use# as a css class in report generationdefstatusreturn'skipped'ifskipped?return'never'ifnever?return'missed'ifmissed?return'covered'ifcovered?endend# 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=filename,coverageFile.open(filename,"r:UTF-8"){|f|@src=f.readlines}end# Returns all source lines for this file as instances of SimpleCov::SourceFile::Line,# and thus including coverage data. Aliased as :source_linesdeflinesreturn@linesifdefined?@lines# 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])endprocess_skipped_lines!@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.countrelevant_lines=lines.count-never_lines.count-skipped_lines.countifrelevant_lines==00else(covered_lines.count)*100/relevant_lines.to_fendenddefcovered_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_fifeffective_lines_count==00elsestrength=lines_strength/effective_lines_countround_float(strength,1)endend# 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.countend# Will go through all source files and mark lines that are wrapped within # :nocov: comment blocks# as skipped.defprocess_skipped_lines!skipping=falselines.eachdo|line|ifline.src=~/^([\s]*)#([\s]*)(\:#{SimpleCov.nocov_token}\:)/skipping=!skippingelseline.skipped!ifskippingendendendprivate# ruby 1.9 could use Float#round(places) insteaddefround_float(float,places)factor=(10*places).to_f(float*factor).round/factorendendend