Class: Covered::Coverage
- Inherits:
-
Object
- Object
- Covered::Coverage
- Includes:
- Ratio
- Defined in:
- lib/covered/coverage.rb
Overview
Stores line execution counts and source metadata for a single file.
Instance Attribute Summary collapse
-
#annotations ⇒ Object
readonly
Returns the value of attribute annotations.
-
#counts ⇒ Object
readonly
Returns the value of attribute counts.
- #Line annotations indexed by line number.(annotationsindexedbylinenumber.) ⇒ Object readonly
- #Line execution counts indexed by line number.(executioncountsindexedbylinenumber.) ⇒ Object readonly
-
#source ⇒ Object
Returns the value of attribute source.
- #The covered source metadata.(coveredsourcemetadata.) ⇒ Object readonly
Class Method Summary collapse
-
.deserialize(unpacker) ⇒ Object
Deserialize a coverage object from the given unpacker.
-
.for(path, **options) ⇒ Object
Build coverage for the given source path.
Instance Method Summary collapse
-
#[](line_number) ⇒ Object
The raw coverage count for the given line number.
-
#annotate(line_number, annotation) ⇒ Object
Add an annotation to the given line number.
-
#as_json ⇒ Object
A JSON-compatible representation of this coverage object.
-
#empty ⇒ Object
Create an empty coverage with the same source.
-
#executable_count ⇒ Object
The number of executable lines.
-
#executable_lines ⇒ Object
Counts for lines that are executable.
-
#executed_count ⇒ Object
The number of executable lines that were executed.
-
#executed_lines ⇒ Object
Counts for executable lines that were executed.
-
#for_lines(line_numbers) ⇒ Object
Construct a new coverage object for the given line numbers.
-
#freeze ⇒ Object
Freeze this coverage and its mutable collections.
-
#fresh? ⇒ Boolean
Whether the source file has not changed since this coverage was recorded.
-
#initialize(source, counts = [], annotations = {}) ⇒ Coverage
constructor
Initialize coverage with the given source, line counts and annotations.
-
#initialize_copy(other) ⇒ Object
Initialize a copy of this coverage object.
-
#mark(line_number, value = 1) ⇒ Object
Add the given execution count to one or more line numbers.
-
#merge!(other) ⇒ Object
Merge another coverage object into this coverage object.
-
#missing_count ⇒ Object
The number of executable lines that were not executed.
-
#path ⇒ Object
The covered source path.
-
#path=(value) ⇒ Object
Assign the covered source path.
-
#print(output) ⇒ Object
Print a human-readable coverage summary.
-
#read(&block) ⇒ Object
Read the covered source.
-
#serialize(packer) ⇒ Object
Serialize this coverage object with the given packer.
-
#to_a ⇒ Object
The raw coverage counts array.
-
#to_s ⇒ Object
A human-readable representation of this coverage object.
-
#total ⇒ Object
The total number of executions across all tracked lines.
-
#zero? ⇒ Boolean
Whether this coverage has no executions.
Methods included from Ratio
#complete?, #percentage, #ratio
Constructor Details
#initialize(source, counts = [], annotations = {}) ⇒ Coverage
Initialize coverage with the given source, line counts and annotations.
48 49 50 51 52 |
# File 'lib/covered/coverage.rb', line 48 def initialize(source, counts = [], annotations = {}) @source = source @counts = counts @annotations = annotations end |
Instance Attribute Details
#annotations ⇒ Object (readonly)
Returns the value of attribute annotations.
71 72 73 |
# File 'lib/covered/coverage.rb', line 71 def annotations @annotations end |
#counts ⇒ Object (readonly)
Returns the value of attribute counts.
68 69 70 |
# File 'lib/covered/coverage.rb', line 68 def counts @counts end |
#Line annotations indexed by line number.(annotationsindexedbylinenumber.) ⇒ Object (readonly)
71 |
# File 'lib/covered/coverage.rb', line 71 attr :annotations |
#Line execution counts indexed by line number.(executioncountsindexedbylinenumber.) ⇒ Object (readonly)
68 |
# File 'lib/covered/coverage.rb', line 68 attr :counts |
#source ⇒ Object
Returns the value of attribute source.
65 66 67 |
# File 'lib/covered/coverage.rb', line 65 def source @source end |
#The covered source metadata.(coveredsourcemetadata.) ⇒ Object (readonly)
65 |
# File 'lib/covered/coverage.rb', line 65 attr_accessor :source |
Class Method Details
.deserialize(unpacker) ⇒ Object
Deserialize a coverage object from the given unpacker.
273 274 275 276 277 278 279 |
# File 'lib/covered/coverage.rb', line 273 def self.deserialize(unpacker) source = unpacker.read counts = unpacker.read annotations = unpacker.read self.new(source, counts, annotations) end |
Instance Method Details
#[](line_number) ⇒ Object
The raw coverage count for the given line number.
205 206 207 |
# File 'lib/covered/coverage.rb', line 205 def [] line_number @counts[line_number] end |
#annotate(line_number, annotation) ⇒ Object
Add an annotation to the given line number.
88 89 90 91 |
# File 'lib/covered/coverage.rb', line 88 def annotate(line_number, annotation) @annotations[line_number] ||= [] @annotations[line_number] << annotation end |
#as_json ⇒ Object
A JSON-compatible representation of this coverage object.
253 254 255 256 257 258 259 260 |
# File 'lib/covered/coverage.rb', line 253 def as_json { counts: counts, executable_count: executable_count, executed_count: executed_count, percentage: percentage.to_f.round(2), } end |
#empty ⇒ Object
Create an empty coverage with the same source.
81 82 83 |
# File 'lib/covered/coverage.rb', line 81 def empty self.class.new(@source, [nil] * @counts.size) end |
#executable_count ⇒ Object
The number of executable lines.
217 218 219 |
# File 'lib/covered/coverage.rb', line 217 def executable_count executable_lines.count end |
#executable_lines ⇒ Object
Counts for lines that are executable.
211 212 213 |
# File 'lib/covered/coverage.rb', line 211 def executable_lines @counts.compact end |
#executed_count ⇒ Object
The number of executable lines that were executed.
229 230 231 |
# File 'lib/covered/coverage.rb', line 229 def executed_count executed_lines.count end |
#executed_lines ⇒ Object
Counts for executable lines that were executed.
223 224 225 |
# File 'lib/covered/coverage.rb', line 223 def executed_lines executable_lines.reject(&:zero?) end |
#for_lines(line_numbers) ⇒ Object
Construct a new coverage object for the given line numbers. Only the given line numbers will be considered for the purposes of computing coverage.
129 130 131 132 133 134 135 136 |
# File 'lib/covered/coverage.rb', line 129 def for_lines(line_numbers) counts = [nil] * @counts.size line_numbers.each do |line_number| counts[line_number] = @counts[line_number] end self.class.new(@source, counts, @annotations) end |
#freeze ⇒ Object
Freeze this coverage and its mutable collections.
181 182 183 184 185 186 187 188 |
# File 'lib/covered/coverage.rb', line 181 def freeze return self if frozen? @counts.freeze @annotations.freeze super end |
#fresh? ⇒ Boolean
Whether the source file has not changed since this coverage was recorded.
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/covered/coverage.rb', line 152 def fresh? if @source.modified_time.nil? # We don't know when the file was last modified, so we assume it is stale: return false end unless File.exist?(@source.path) # The file no longer exists, so we assume it is stale: return false end if @source.modified_time >= File.mtime(@source.path) # The file has not been modified since we last processed it, so we assume it is fresh: return true end return false end |
#initialize_copy(other) ⇒ Object
Initialize a copy of this coverage object.
56 57 58 59 60 61 62 |
# File 'lib/covered/coverage.rb', line 56 def initialize_copy(other) super @source = other.source.dup @counts = other.counts.dup @annotations = other.annotations.transform_values(&:dup) end |
#mark(line_number, value = 1) ⇒ Object
Add the given execution count to one or more line numbers.
96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/covered/coverage.rb', line 96 def mark(line_number, value = 1) Array(value).each_with_index do |value, index| offset = line_number + index next if offset < 1 if @counts[offset] @counts[offset] += value else @counts[offset] = value end end end |
#merge!(other) ⇒ Object
Merge another coverage object into this coverage object.
111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/covered/coverage.rb', line 111 def merge!(other) # If the counts are non-zero and don't match, that can indicate a problem. other.counts.each_with_index do |count, index| if count @counts[index] ||= 0 @counts[index] += count end end @annotations.merge!(other.annotations) do |line_number, a, b| Array(a) + Array(b) end end |
#missing_count ⇒ Object
The number of executable lines that were not executed.
235 236 237 |
# File 'lib/covered/coverage.rb', line 235 def missing_count executable_count - executed_count end |
#path ⇒ Object
The covered source path.
140 141 142 |
# File 'lib/covered/coverage.rb', line 140 def path @source.path end |
#path=(value) ⇒ Object
Assign the covered source path.
146 147 148 |
# File 'lib/covered/coverage.rb', line 146 def path= value @source.path = value end |
#print(output) ⇒ Object
Print a human-readable coverage summary.
241 242 243 |
# File 'lib/covered/coverage.rb', line 241 def print(output) output.puts "** #{executed_count}/#{executable_count} lines executed; #{percentage.to_f.round(2)}% covered." end |
#read(&block) ⇒ Object
Read the covered source.
175 176 177 |
# File 'lib/covered/coverage.rb', line 175 def read(&block) @source.read(&block) end |
#serialize(packer) ⇒ Object
Serialize this coverage object with the given packer.
264 265 266 267 268 |
# File 'lib/covered/coverage.rb', line 264 def serialize(packer) packer.write(@source) packer.write(@counts) packer.write(@annotations) end |
#to_a ⇒ Object
The raw coverage counts array.
192 193 194 |
# File 'lib/covered/coverage.rb', line 192 def to_a @counts end |
#to_s ⇒ Object
A human-readable representation of this coverage object.
247 248 249 |
# File 'lib/covered/coverage.rb', line 247 def to_s "\#<#{self.class} path=#{self.path} #{self.percentage.to_f.round(2)}% covered>" end |
#total ⇒ Object
The total number of executions across all tracked lines.
75 76 77 |
# File 'lib/covered/coverage.rb', line 75 def total counts.sum{|count| count || 0} end |
#zero? ⇒ Boolean
Whether this coverage has no executions.
198 199 200 |
# File 'lib/covered/coverage.rb', line 198 def zero? total.zero? end |