Module: Bulldogger::RSpec

Defined in:
lib/bulldogger/integrations/rspec.rb

Overview

Connects RSpec failures to evidence files. It does not control test execution, formatter behavior, or test results.

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.instanceObject

Dogfood can assign an isolated observer. The default preserves the normal integration API for applications that need one lifecycle.



16
17
18
# File 'lib/bulldogger/integrations/rspec.rb', line 16

def instance
  @instance || Bulldogger.default
end

Class Method Details

.annotate!(exception, path) ⇒ Object

Tags the exception's own #message, so the evidence line sits inside the same text RSpec's own formatter prints for this failure. This after(:each) hook runs synchronously inside Example#run, before RSpec's reporter notifies any formatter, so the rewrite is guaranteed to land before anything reads the message -- unlike Minitest's CompositeReporter, RSpec has no second observer that could print the failure first. A frozen exception can't take a singleton method; fall back to printing the line directly so a frozen exception never means a silently missing evidence line.



44
45
46
47
48
49
50
51
# File 'lib/bulldogger/integrations/rspec.rb', line 44

def self.annotate!(exception, path)
  original = exception.message
  lines = FailureOutput.lines(path)
  suffix = "\n#{lines.join("\n")}"
  exception.define_singleton_method(:message) { "#{original}#{suffix}" }
rescue FrozenError
  $stdout.puts lines
end

.test_for(example) ⇒ Object

RSpec has already scored the example's description and its file/line into metadata by the time after(:each) runs; test_for reads those off the Example instead of re-deriving them.



24
25
26
27
28
29
30
31
32
# File 'lib/bulldogger/integrations/rspec.rb', line 24

def self.test_for(example)
  {
    framework: "rspec",
    id: example.full_description,
    file: example.[:file_path],
    line: example.[:line_number],
    seed: ::RSpec.configuration.seed
  }
end