class Minitest::Heat::Source

Gets the most relevant lines of code surrounding the specified line of code

Constants

CONTEXTS

Attributes

context[RW]
filename[R]
line_number[RW]
max_line_count[RW]

Public Class Methods

new(filename, line_number:, max_line_count: 1, context: :around) click to toggle source
# File lib/minitest/heat/source.rb, line 13
def initialize(filename, line_number:, max_line_count: 1, context: :around)
  @filename = filename
  @line_number = Integer(line_number)
  @max_line_count = max_line_count
  @context = context
end

Public Instance Methods

file_lines() click to toggle source

Reads (and chomps) the lines of the target file

@return [type] [description]

# File lib/minitest/heat/source.rb, line 53
def file_lines
  @raw_lines ||= File.readlines(filename, chomp: true)
  @raw_lines.pop while @raw_lines.last.strip.empty?

  @raw_lines
rescue Errno::ENOENT
  # Occasionally, for a variety of reasons, a file can't be read. In those cases, it's best to
  # return no source code lines rather than have the test suite raise an error unrelated to
  # the code being tested becaues that gets confusing.
  []
end
line() click to toggle source

Looks up the line of code referenced

@return [String] the line of code at filename:line_number

# File lib/minitest/heat/source.rb, line 30
def line
  file_lines[line_number - 1]
end
line_numbers() click to toggle source

Line numbers for the returned lines

@return [Array<Integer>] the line numbers corresponding to the lines returned

# File lib/minitest/heat/source.rb, line 46
def line_numbers
  (first_line_number..last_line_number).to_a.uniq
end
lines() click to toggle source

Looks up the available lines of code around the referenced line number

@return [Array<String>] the range of lines of code around

# File lib/minitest/heat/source.rb, line 37
def lines
  return [line] if max_line_count == 1

  file_lines[(line_numbers.first - 1)..(line_numbers.last - 1)]
end
to_h() click to toggle source

Returns relevant lines as a hash with line numbers as the keys

@return [Hash] hash of relevant lines with line numbers as keys

# File lib/minitest/heat/source.rb, line 23
def to_h
  line_numbers.map(&:to_s).zip(lines).to_h
end

Private Instance Methods

first_line_number() click to toggle source

The number of the first line of code to return

@return [Integer] line number

# File lib/minitest/heat/source.rb, line 77
def first_line_number
  target = line_number - first_line_offset - leftover_trailing_lines_count

  # Can't go earlier than the first line
  target < 1 ? 1 : target
end
first_line_offset() click to toggle source

The target number of preceding lines to include

@return [Integer] number of preceding lines to include

# File lib/minitest/heat/source.rb, line 97
def first_line_offset
  case context
  when :before then other_lines_count
  when :around then preceding_lines_split_count
  when :after then 0
  end
end
last_line_number() click to toggle source

The number of the last line of code to return

@return [Integer] line number

# File lib/minitest/heat/source.rb, line 87
def last_line_number
  target = line_number + last_line_offset + leftover_preceding_lines_count

  # Can't go past the end of the file
  target > max_line_number ? max_line_number : target
end
last_line_offset() click to toggle source

The target number of trailing lines to include

@return [Integer] number of trailing lines to include

# File lib/minitest/heat/source.rb, line 108
def last_line_offset
  case context
  when :before then 0
  when :around then trailing_lines_split_count
  when :after then other_lines_count
  end
end
leftover_preceding_lines_count() click to toggle source

If the preceding lines offset takes_it past the beginning of the file, this provides the total number of lines that weren't used

@return [Integer] number of preceding lines that don't exist

# File lib/minitest/heat/source.rb, line 120
def leftover_preceding_lines_count
  target_line_number = line_number - first_line_offset

  target_line_number < 1 ? target_line_number.abs + 1 : 0
end
leftover_trailing_lines_count() click to toggle source

If the trailing lines offset takes_it past the end of the file, this provides the total number of lines that weren't used

@return [Integer] number of trailing lines that don't exist

# File lib/minitest/heat/source.rb, line 130
def leftover_trailing_lines_count
  target_line_number = line_number + last_line_offset

  target_line_number > max_line_number ? target_line_number - max_line_number : 0
end
max_line_number() click to toggle source

The largest possible value for line numbers

@return [Integer] the last line number of the file

# File lib/minitest/heat/source.rb, line 70
def max_line_number
  file_lines.length
end
other_lines_count() click to toggle source

The total number of lines to include in addition to the primary line

# File lib/minitest/heat/source.rb, line 137
def other_lines_count
  max_line_count - 1
end
preceding_lines_split_count() click to toggle source
# File lib/minitest/heat/source.rb, line 141
def preceding_lines_split_count
  # Round up preceding lines if it's uneven because preceding lines are more likely to be
  # helpful when debugging
  (other_lines_count / 2).round(0, half: :up)
end
trailing_lines_split_count() click to toggle source
# File lib/minitest/heat/source.rb, line 147
def trailing_lines_split_count
  # Round down preceding lines because they provide context in the file but don't contribute
  # in terms of the code that led to the error
  (other_lines_count / 2).round(0, half: :down)
end