Class: Minitest::Heat::Hit

Inherits:
Object
  • Object
show all
Defined in:
lib/minitest/heat/hit.rb

Overview

Kind of like an issue, but instead of focusing on a failing test, it covers all issues for a

given file to build a heat map of the affected files and line numbers

Defined Under Namespace

Classes: Trace

Constant Summary collapse

WEIGHTS =

So we can sort hot spots by liklihood of being the most important spot to check out before

trying to fix something. These are ranked based on the possibility they represent ripple
effects where fixing one problem could potentially fix multiple other failures.

For example, if there's an exception in the file, start there. Broken code can't run. If a
test is broken (i.e. raising an exception), that's a special sort of failure that would be
misleading. It doesn't represent a proper failure, but rather a test that doesn't work.
{
  error: 5,    # exceptions from source code have the highest likelihood of a ripple effect
  broken: 4,   # broken tests won't have ripple effects but can't help if they can't run
  failure: 3,  # failures are kind of the whole point, and they could have ripple effects
  skipped: 2,  # skips aren't failures, but they shouldn't go ignored
  painful: 1,  # slow tests aren't failures, but they shouldn't be ignored
  slow: 0
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pathname) ⇒ self

Creates an instance of a Hit for the given pathname. It must be the full pathname to

uniquely identify the file or we could run into collisions that muddy the water and
obscure which files had which errors on which line numbers

Parameters:

  • pathname (Pathname, String)

    the full pathname to the file



36
37
38
39
40
# File 'lib/minitest/heat/hit.rb', line 36

def initialize(pathname)
  @pathname = Pathname(pathname)
  @issues = {}
  @lines = {}
end

Instance Attribute Details

#issuesObject (readonly)

Returns the value of attribute issues.



28
29
30
# File 'lib/minitest/heat/hit.rb', line 28

def issues
  @issues
end

#linesObject (readonly)

Returns the value of attribute lines.



28
29
30
# File 'lib/minitest/heat/hit.rb', line 28

def lines
  @lines
end

#pathnameObject (readonly)

Returns the value of attribute pathname.



28
29
30
# File 'lib/minitest/heat/hit.rb', line 28

def pathname
  @pathname
end

Instance Method Details

#countInteger

The total issue count for the file across all issue types. Includes duplicates if they exist

Returns:

  • (Integer)

    the sum of the counts for all line numbers for all issue types



76
77
78
79
80
81
82
# File 'lib/minitest/heat/hit.rb', line 76

def count
  count = 0
  issues.each_pair do |_type, values|
    count += values.size
  end
  count
end

#line_numbersArray<Integer>

The full set of unique line numbers across all issue types

Returns:

  • (Array<Integer>)

    the full set of unique offending line numbers for the hit



87
88
89
90
91
92
93
# File 'lib/minitest/heat/hit.rb', line 87

def line_numbers
  line_numbers = []
  issues.each_pair do |_type, values|
    line_numbers += values
  end
  line_numbers.uniq.sort
end

#log(type, line_number, backtrace: []) ⇒ void

This method returns an undefined value.

Adds a record of a given issue type for the line number

Parameters:

  • type (Symbol)

    one of Issue::TYPES

  • line_number (Integer, String)

    the line number to record the issue on

  • backtrace: (defaults to: [])

    nil [Array<Location>] the project locations from the backtrace



48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/minitest/heat/hit.rb', line 48

def log(type, line_number, backtrace: [])
  line_number = Integer(line_number)
  issue_type = type.to_sym

  # Store issues by issue type with an array of line numbers
  @issues[issue_type] ||= []
  @issues[issue_type] << line_number

  # Store issues by line number with an array of Traces
  @lines[line_number.to_s] ||= []
  @lines[line_number.to_s] << Trace.new(issue_type, line_number, backtrace)
end

#weightInteger

Calcuates an approximate weight to serve as a proxy for which files are most likely to be

the most problematic across the various issue types

Returns:

  • (Integer)

    the problem weight for the file



65
66
67
68
69
70
71
# File 'lib/minitest/heat/hit.rb', line 65

def weight
  weight = 0
  issues.each_pair do |type, values|
    weight += values.size * WEIGHTS.fetch(type, 0)
  end
  weight
end