Class: Mutineer::AggregateResult

Inherits:
Object
  • Object
show all
Defined in:
lib/mutineer/result.rb

Overview

Aggregates a flat list of Results into counts, the mutation score, and the surviving-mutant list. The score denominator is killed + survived ONLY (KTD-4): no-coverage, uncapturable, skipped (invalid), errored, timeout, and ignored (#10 equivalent-mutant suppression) are each excluded and surfaced separately — so suppressing every survivor reaches 100%. An empty denominator yields a nil score (rendered "N/A"), never 0.0 — distinguishing "no testable mutants" from "0% killed".

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(results) ⇒ AggregateResult

Returns a new instance of AggregateResult.



60
61
62
63
# File 'lib/mutineer/result.rb', line 60

def initialize(results)
  @results = results
  @by_status = results.group_by(&:status)
end

Instance Attribute Details

#resultsObject (readonly)

Returns the value of attribute results.



58
59
60
# File 'lib/mutineer/result.rb', line 58

def results
  @results
end

Instance Method Details

#by_sourceObject

#11: split into { source_file => AggregateResult } so the Reporter (per-source breakdown) and #13 (per-source roll-up / baseline diff) share one shape with all the score/count methods. After Runner.execute every result carries a subject, so the grouping is total; bare results (no subject, only in unit tests) are skipped so file keys stay sortable strings.



95
96
97
98
99
# File 'lib/mutineer/result.rb', line 95

def by_source
  @results.select { |r| r.subject }
          .group_by { |r| r.subject.file }
          .transform_values { |rs| AggregateResult.new(rs) }
end

#covered_countObject

The score denominator (also shown to the reader).



78
# File 'lib/mutineer/result.rb', line 78

def covered_count = killed_count + survived_count

#errored_countObject



70
# File 'lib/mutineer/result.rb', line 70

def errored_count         = count(:error)

#ignored_countObject



72
# File 'lib/mutineer/result.rb', line 72

def ignored_count         = count(:ignored)

#killed_countObject



65
# File 'lib/mutineer/result.rb', line 65

def killed_count          = count(:killed)

#mutation_scoreObject

killed / (killed + survived) as a rounded percentage, or nil when nothing was testable.



82
83
84
85
86
# File 'lib/mutineer/result.rb', line 82

def mutation_score
  return nil if covered_count.zero?

  (killed_count.to_f / covered_count * 100).round(1)
end

#no_coverage_countObject



67
# File 'lib/mutineer/result.rb', line 67

def no_coverage_count     = count(:no_coverage)

#skipped_invalid_countObject



69
# File 'lib/mutineer/result.rb', line 69

def skipped_invalid_count = count(:skipped)

#survived_countObject



66
# File 'lib/mutineer/result.rb', line 66

def survived_count        = count(:survived)

#surviving_mutantsObject



88
# File 'lib/mutineer/result.rb', line 88

def surviving_mutants = @results.select(&:survived?)

#timeout_countObject



71
# File 'lib/mutineer/result.rb', line 71

def timeout_count         = count(:timeout)

#totalObject

Every generated, classified mutation. NOT the score denominator.



75
# File 'lib/mutineer/result.rb', line 75

def total = @results.size

#uncapturable_countObject



68
# File 'lib/mutineer/result.rb', line 68

def uncapturable_count    = count(:uncapturable)