class RuboCop::RSpec::ExpectOffense::AnnotatedSource

Parsed representation of code annotated with the ‘^^^ Message` style

def self.parse(annotated_source)

Returns:
  • (AnnotatedSource) -

Parameters:
  • annotated_source (String) -- string passed to the matchers
def self.parse(annotated_source)
  source      = []
  annotations = []
  annotated_source.each_line do |source_line|
    if ANNOTATION_PATTERN.match?(source_line)
      annotations << [source.size, source_line]
    else
      source << source_line
    end
  end
  annotations.each { |a| a[0] = 1 } if source.empty?
  new(source, annotations)
end

def ==(other)

def ==(other)
  other.is_a?(self.class) && other.lines == lines && match_annotations?(other)
end

def initialize(lines, annotations)

Other tags:
    Note: - annotations are sorted so that reconstructing the annotation

Parameters:
  • annotations (Array<(Integer, String)>) --
  • lines (Array) --
def initialize(lines, annotations)
  @lines       = lines.freeze
  @annotations = annotations.sort.freeze
end

def match_annotations?(other)

This way the diff is clean.
Dirty hack: expectations with [...] are rewritten when they match
def match_annotations?(other)
  annotations.zip(other.annotations) do |(_actual_line, actual_annotation),
                                         (_expected_line, expected_annotation)|
    if expected_annotation&.end_with?(ABBREV) &&
       actual_annotation.start_with?(expected_annotation[0...-ABBREV.length])
      expected_annotation.replace(actual_annotation)
    end
  end
  annotations == other.annotations
end

def plain_source

Returns:
  • (String) -
def plain_source
  lines.join
end

def to_s

Returns:
  • (String) -

Other tags:
    Example: standardization -
def to_s
  reconstructed = lines.dup
  annotations.reverse_each do |line_number, annotation|
    reconstructed.insert(line_number, annotation)
  end
  reconstructed.join
end

def with_offense_annotations(offenses)

Returns:
  • (self) -

Parameters:
  • offenses (Array) --
def with_offense_annotations(offenses)
  offense_annotations =
    offenses.map do |offense|
      indent     = ' ' * offense.column
      carets     = '^' * offense.column_length
      carets     = '^{}' if offense.column_length.zero?
      [offense.line, "#{indent}#{carets} #{offense.message}\n"]
    end
  self.class.new(lines, offense_annotations)
end