Skip to content
This repository has been archived by the owner on Nov 30, 2024. It is now read-only.

Commit

Permalink
Introduce full_cause_backtrace configuration
Browse files Browse the repository at this point in the history
By default, RSpec only prints the first line of a 'caused by' backtrace. This commit introduces a new 'full_cause_backtrace' config option which will enable printing the entire cause backtrace.
  • Loading branch information
davidtaylorhq authored and pirj committed Jan 25, 2024
1 parent 3bde989 commit f49f672
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 2 deletions.
7 changes: 7 additions & 0 deletions lib/rspec/core/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,12 @@ def shared_context_metadata_behavior=(value)
# return [Integer]
add_setting :max_displayed_failure_line_count

# @macro full_cause_backtrace
# Display the full backtrace of causing exceptions
# (default false).
# return [Boolean]
add_setting :full_cause_backtrace

# @macro add_setting
# Format the output for pending examples. Can be set to:
# - :full (default) - pending examples appear similarly to failures
Expand Down Expand Up @@ -571,6 +577,7 @@ def initialize
@derived_metadata_blocks = FilterableItemRepository::QueryOptimized.new(:any?)
@threadsafe = true
@max_displayed_failure_line_count = 10
@full_cause_backtrace = false
@world = World::Null
@shared_context_metadata_behavior = :trigger_inclusion
@pending_failure_output = :full
Expand Down
7 changes: 6 additions & 1 deletion lib/rspec/core/formatters/exception_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,12 @@ def formatted_cause(exception)
end

unless last_cause.backtrace.nil? || last_cause.backtrace.empty?
cause << (" #{backtrace_formatter.format_backtrace(last_cause.backtrace, example.metadata).first}")
lines = backtrace_formatter.format_backtrace(last_cause.backtrace, example.metadata)
lines = [lines[0]] unless RSpec.configuration.full_cause_backtrace # rubocop:disable Metrics/BlockNesting

lines.each do |line|
cause << (" #{line}")
end
end
end

Expand Down
28 changes: 27 additions & 1 deletion spec/rspec/core/formatters/exception_presenter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ def initialize(message, backtrace = [], cause = nil)
end

caused_by_line_num = __LINE__ + 1
let(:first_exception) { FakeException.new("Real\nculprit", ["#{__FILE__}:#{__LINE__}"]) }
let(:first_exception) { FakeException.new("Real\nculprit", ["#{__FILE__}:#{__LINE__}", "#{__FILE__}:#{__LINE__}"]) }

it 'includes the first exception that caused the failure', :if => RSpec::Support::RubyFeatures.supports_exception_cause? do
the_presenter = Formatters::ExceptionPresenter.new(the_exception, example)
Expand All @@ -202,6 +202,32 @@ def initialize(message, backtrace = [], cause = nil)
EOS
end

context 'with RSpec.configuration.full_cause_backtrace enabled' do
before do
RSpec.configuration.full_cause_backtrace = true
end

it 'prints full cause backtrace', :if => RSpec::Support::RubyFeatures.supports_exception_cause? do
the_presenter = Formatters::ExceptionPresenter.new(the_exception, example)

expect(the_presenter.fully_formatted(1)).to eq(<<-EOS.gsub(/^ +\|/, ''))
|
| 1) Example
| Failure/Error: # The failure happened here!#{ encoding_check }
|
| Boom
| Bam
| # ./spec/rspec/core/formatters/exception_presenter_spec.rb:#{line_num}
| # ------------------
| # --- Caused by: ---
| # Real
| # culprit
| # ./spec/rspec/core/formatters/exception_presenter_spec.rb:#{caused_by_line_num}
| # ./spec/rspec/core/formatters/exception_presenter_spec.rb:#{caused_by_line_num}
EOS
end
end

context "when the first exception doesn't have a backgrace" do
let(:first_exception) { FakeException.new("Real\nculprit", backtrace) }

Expand Down

0 comments on commit f49f672

Please sign in to comment.