Module: Evilution::Compare::Categorizer Private
- Defined in:
- lib/evilution/compare/categorizer.rb
This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.
Constant Summary collapse
- ALIVE =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
%i[survived].freeze
- DEAD =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
%i[killed timeout error].freeze
Class Method Summary collapse
- .bucket_single_sided(against_record, current_record, a_kind, c_kind, buckets) ⇒ Object private
-
.call(against, current) ⇒ Hash
private
Bucketed comparison result with keys: -
:alive_only_against=>Array<{record: Record, peer_status: Symbol|nil}>records that survived in against but not in current (or absent in current). -
.classify(against_record, current_record, buckets) ⇒ Object
private
Dispatches one fingerprint pair into buckets.
- .count_excluded(against_record, current_record, buckets) ⇒ Object private
- .index_by_fingerprint(records) ⇒ Object private
-
.kind_of(record) ⇒ Object
private
Returns :alive, :dead, :excluded, or nil (for nil records).
- .sort_buckets!(buckets) ⇒ Object private
- .sort_key(record) ⇒ Object private
Class Method Details
.bucket_single_sided(against_record, current_record, a_kind, c_kind, buckets) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
77 78 79 80 81 82 83 84 |
# File 'lib/evilution/compare/categorizer.rb', line 77 def bucket_single_sided(against_record, current_record, a_kind, c_kind, buckets) # peer_status is the peer record's status symbol, or nil if peer absent. # When the peer is excluded, its status symbol (e.g. :neutral) flows through. a_peer = current_record && current_record.status c_peer = against_record && against_record.status buckets[:alive_only_against] << { record: against_record, peer_status: a_peer } if a_kind == :alive buckets[:alive_only_current] << { record: current_record, peer_status: c_peer } if c_kind == :alive end |
.call(against, current) ⇒ Hash
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns bucketed comparison result with keys:
:alive_only_against=>Array<{record: Record, peer_status: Symbol|nil}>records that survived in against but not in current (or absent in current).peer_statusis the current-side record's status symbol, ornilwhen no current-side record exists for that fingerprint.:alive_only_current=>Array<{record: Record, peer_status: Symbol|nil}>mirror of the above from the current side.:shared_alive=>Array<{against: Record, current: Record}>mutations that survived in both runs.:shared_dead=>Array<{against: Record, current: Record}>mutations killed/timed-out/errored in both runs.:excluded_against=>Integercount of against records with non-actionable statuses (neutral, equivalent, unresolved, unparseable).:excluded_current=>Integermirror for the current side.
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/evilution/compare/categorizer.rb', line 31 def call(against, current) # Duplicate fingerprints within one side should not happen (Normalizer # invariant). If they do, last write wins — we do not dedupe proactively. against_by_fp = index_by_fingerprint(against) current_by_fp = index_by_fingerprint(current) buckets = { alive_only_against: [], alive_only_current: [], shared_alive: [], shared_dead: [], excluded_against: 0, excluded_current: 0 } (against_by_fp.keys | current_by_fp.keys).each do |fp| classify(against_by_fp[fp], current_by_fp[fp], buckets) end sort_buckets!(buckets) buckets end |
.classify(against_record, current_record, buckets) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Dispatches one fingerprint pair into buckets. Either record may be nil (fingerprint present on only one side).
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/evilution/compare/categorizer.rb', line 56 def classify(against_record, current_record, buckets) count_excluded(against_record, current_record, buckets) a_kind = kind_of(against_record) c_kind = kind_of(current_record) if a_kind == :alive && c_kind == :alive buckets[:shared_alive] << { against: against_record, current: current_record } elsif a_kind == :dead && c_kind == :dead buckets[:shared_dead] << { against: against_record, current: current_record } else bucket_single_sided(against_record, current_record, a_kind, c_kind, buckets) end # A dead-only fingerprint (dead on one side, absent on the other) is # intentionally not bucketed and not counted as excluded. end |
.count_excluded(against_record, current_record, buckets) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
72 73 74 75 |
# File 'lib/evilution/compare/categorizer.rb', line 72 def count_excluded(against_record, current_record, buckets) buckets[:excluded_against] += 1 if against_record && kind_of(against_record) == :excluded buckets[:excluded_current] += 1 if current_record && kind_of(current_record) == :excluded end |
.index_by_fingerprint(records) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
106 107 108 |
# File 'lib/evilution/compare/categorizer.rb', line 106 def index_by_fingerprint(records) records.to_h { |r| [r.fingerprint, r] } end |
.kind_of(record) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns :alive, :dead, :excluded, or nil (for nil records).
87 88 89 90 91 92 93 |
# File 'lib/evilution/compare/categorizer.rb', line 87 def kind_of(record) return nil if record.nil? return :alive if ALIVE.include?(record.status) return :dead if DEAD.include?(record.status) :excluded end |
.sort_buckets!(buckets) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
95 96 97 98 99 100 |
# File 'lib/evilution/compare/categorizer.rb', line 95 def sort_buckets!(buckets) buckets[:alive_only_against].sort_by! { |e| sort_key(e[:record]) } buckets[:alive_only_current].sort_by! { |e| sort_key(e[:record]) } buckets[:shared_alive].sort_by! { |e| sort_key(e[:against]) } buckets[:shared_dead].sort_by! { |e| sort_key(e[:against]) } end |
.sort_key(record) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
102 103 104 |
# File 'lib/evilution/compare/categorizer.rb', line 102 def sort_key(record) [record.file_path, record.line, record.fingerprint] end |