Module: RSpec::Retryable::Example

Defined in:
lib/rspec/retryable/example.rb

Instance Method Summary collapse

Instance Method Details

#fail_with_exceptionObject

https://github.com/rspec/rspec-core/blob/3-10-maintenance/lib/rspec/core/example.rb#L433-L441 Used internally to set an exception and fail without actually executing the example when an exception is raised in before(:context).



42
43
44
45
# File 'lib/rspec/retryable/example.rb', line 42

def fail_with_exception(...)
  @failed_in_context = true
  super
end

#failed_in_context?Boolean

Returns:

  • (Boolean)


47
48
49
# File 'lib/rspec/retryable/example.rb', line 47

def failed_in_context?
  !!@failed_in_context
end

#finish(reporter) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/rspec/retryable/example.rb', line 9

def finish(reporter)
  [:retryable] ||= Metadata.new

  if @exception
    state = :failed
    execution_result.exception = @exception
    record_finished :failed, reporter
  elsif execution_result.pending_message
    state = :pending
    record_finished :pending, reporter
  else
    state = :passed
    record_finished :passed, reporter
  end

  @payload = RSpec::Retryable::Payload.new(self, state)

  RSpec::Retryable.handlers.invoke(@payload)

  if @payload.retry
    # Replaced the final result by the retry result
    @payload.result = retry_example
  end

  # Notify reporter only if it's not handled by the handlers
  notify_reporter if @payload.notify

  @payload.result
end

#notify_reporterObject



82
83
84
85
86
87
88
89
90
91
# File 'lib/rspec/retryable/example.rb', line 82

def notify_reporter
  case @payload.state
  when :failed
    reporter.example_failed self
  when :pending
    reporter.example_pending self
  when :passed
    reporter.example_passed self
  end
end

#retry_exampleObject



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/rspec/retryable/example.rb', line 51

def retry_example
  [:retryable].failures << @exception
  [:retryable].attempts += 1
  # Every retry turns off the retry and notify flag, it's up to the handler to turn them back on or not.
  @payload.retry = false
  @payload.notify = false
  # Duplicate the example for re-run
  new_example = duplicate_with()
  # The shared_group_inclusion_backtrace was reserved from duplication, but we need to keep as-is for
  # reporter/formatter to show the correct backtrace.
  # https://github.com/rspec/rspec/blob/0ae9cc43163507458494e631ca8e473bf24cdb26/rspec-core/lib/rspec/core/metadata.rb#L341
  new_example.[:shared_group_inclusion_backtrace] = [:shared_group_inclusion_backtrace]
  new_example.instance_variable_set(:@id, id)
  # Taken from https://github.com/rspec/rspec-core/blob/main/lib/rspec/core/example_group.rb#L644-L646
  instance = new_example.example_group.new(new_example.inspect_output)
  new_example.example_group.set_ivars(instance, new_example.example_group.before_context_ivars)
  # Use same reporter from example instead of the one passing in to behave like
  # a fresh new example.

  result = new_example.run(instance, reporter)
  # Update the execution result status to the new state from retry
  execution_result.status = new_example.execution_result.status

  if execution_result.status == :failed
    # Sets exception when retry failed
    execution_result.exception = new_example.execution_result.exception
  end

  result
end