Class: ErrorToCommunicate::Heuristic::RSpecFailure

Inherits:
ErrorToCommunicate::Heuristic show all
Defined in:
lib/error_to_communicate/rspec_formatter.rb

Instance Attribute Summary collapse

Attributes inherited from ErrorToCommunicate::Heuristic

#einfo, #project

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from ErrorToCommunicate::Heuristic

#backtrace, #classname, #explanation, for?, #message, #semantic_backtrace, #semantic_explanation

Constructor Details

#initialize(attributes) ⇒ RSpecFailure

Returns a new instance of RSpecFailure.



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/error_to_communicate/rspec_formatter.rb', line 17

def initialize(attributes)
  self.failure_number = attributes.fetch :failure_number
  self.failure        = attributes.fetch :failure
  self.config         = attributes.fetch :config
  binding             = attributes.fetch :binding

  # initialize the heuristic
  ExceptionInfo.parse(failure.exception, binding).tap do |einfo|
    einfo.backtrace = ExceptionInfo.parse_backtrace failure.formatted_backtrace, binding
    super einfo: einfo, project: config.project
  end

  if assertion?
    # format it with our lib
    self.semantic_info =
      [:heuristic, [ # ":heuristic" is dumb, it's not a heuristic, it's an error message, Maybe we need a :section or something?
        [:message, self.class.fix_whitespace(message)],
        *backtrace.take(1).map { |loc|
          [:code, {location: loc, context: (-5..5), emphasis: :code}]
        }
      ]]

    self.semantic_summary =
      [:summary, [
        [:columns,
          [:classname, failure_number],        # TODO: not classname
          [:classname, failure.description]]]] # TODO: not classname
  else
    # wrap the heuristic that would otherwise be chosen
    heuristic             = config.heuristic_for einfo, binding
    self.semantic_info    = heuristic.semantic_info
    self.semantic_summary =
      [:summary, [
        [:columns,
          [:classname,   failure_number],      # TODO: not classname
          [:classname,   failure.description], # TODO: not classname
          [:classname,   heuristic.classname], # TODO: not classname
          [:explanation, heuristic.semantic_explanation]]]]
  end
end

Instance Attribute Details

#configObject

Returns the value of attribute config.



14
15
16
# File 'lib/error_to_communicate/rspec_formatter.rb', line 14

def config
  @config
end

#failureObject

Returns the value of attribute failure.



14
15
16
# File 'lib/error_to_communicate/rspec_formatter.rb', line 14

def failure
  @failure
end

#failure_numberObject

Returns the value of attribute failure_number.



14
15
16
# File 'lib/error_to_communicate/rspec_formatter.rb', line 14

def failure_number
  @failure_number
end

#semantic_infoObject

Returns the value of attribute semantic_info.



15
16
17
# File 'lib/error_to_communicate/rspec_formatter.rb', line 15

def semantic_info
  @semantic_info
end

#semantic_summaryObject

Returns the value of attribute semantic_summary.



15
16
17
# File 'lib/error_to_communicate/rspec_formatter.rb', line 15

def semantic_summary
  @semantic_summary
end

Class Method Details

.fix_whitespace(str) ⇒ Object



7
8
9
10
11
12
# File 'lib/error_to_communicate/rspec_formatter.rb', line 7

def self.fix_whitespace(str)
  str = str.dup
  str.sub! /\A\n*/, "" # remove leading newlines
  str.sub! /\n*\Z/, "" # remove trailing newlines
  str << "\n"          # one newline on the end
end

Instance Method Details

#assertion?Boolean

Returns:

  • (Boolean)


58
59
60
61
62
# File 'lib/error_to_communicate/rspec_formatter.rb', line 58

def assertion?
  # RSpec differentiates failures from assertions by whether RSpec is in the name:
  # https://github.com/JoshCheek/mrspec/blob/2761ba2180eb5f71a9262f6d59ce20d7cc8a47c3/lib/mrspec/minitest_assertion_for_rspec.rb
  classname =~ /RSpec/
end