Skip to content

Commit

Permalink
Fix error backtrace formatting on Ruby 3.4+ (#1771)
Browse files Browse the repository at this point in the history
* Fix error backtrace formatting on Ruby 3.4+

Accomodate the new Ruby 3.4+ backtrace display format

* CI: add Ruby 3.4 to the test matrix

* Tests: support Ruby 3.4+ Hash#inspect

* Tests: use deterministic object logging

* Tests: avoid exercising Ruby’s Hash#inspect method

* Tests: avoid passing params unnecessarily
  • Loading branch information
orien authored Feb 25, 2025
1 parent 328fd2b commit 1f17266
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 21 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
ruby: ['3.0', '3.1', '3.2', '3.3']
ruby: ['3.0', '3.1', '3.2', '3.3', '3.4']
include:
- os: ubuntu-latest
ruby: jruby-9.4
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ that need to rely on procedural loading / reloading of files should use method i

### Fixed
- Fixed an issue where a change to one example in compatibility testing wasn't fully adhered to ([luke-hill](https://github.com/luke-hill))
- Fixed Ruby 3.4+ issue where error backtraces weren't being formatted. ([#1771](https://github.com/cucumber/cucumber-ruby/pull/1771) [orien](https://github.com/orien))

### Removed
- `StepDefinitionLight` associated methods. The class itself is present but deprecated
Expand Down
4 changes: 2 additions & 2 deletions features/docs/extending_cucumber/custom_formatter.feature
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Feature: Custom Formatter
def initialize(config, options)
@io = config.out_stream
config.on_event :test_run_finished do |event|
@io.print options.inspect
@io.print options.to_json
end
end
end
Expand All @@ -54,5 +54,5 @@ Feature: Custom Formatter
When I run `cucumber features/f.feature --format MyCustom::Formatter,foo=bar,one=two --publish-quiet`
Then it should pass with exactly:
"""
{"foo"=>"bar", "one"=>"two"}
{"foo":"bar","one":"two"}
"""
4 changes: 3 additions & 1 deletion lib/cucumber/formatter/backtrace_filter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,10 @@ def exception

if ::ENV['CUCUMBER_TRUNCATE_OUTPUT']
# Strip off file locations
regexp = RUBY_VERSION >= '3.4' ? /(.*):in '/ : /(.*):in `/
filtered = filtered.map do |line|
line =~ /(.*):in `/ ? Regexp.last_match(1) : line
match = regexp.match(line)
match ? match[1] : line
end
end

Expand Down
13 changes: 11 additions & 2 deletions lib/cucumber/glue/invoke_in_world.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ def self.replace_instance_exec_invocation_line!(backtrace, instance_exec_invocat
return unless instance_exec_pos

replacement_line = instance_exec_pos + INSTANCE_EXEC_OFFSET
backtrace[replacement_line].gsub!(/`.*'/, "`#{pseudo_method}'") if pseudo_method
if pseudo_method
pattern = RUBY_VERSION >= '3.4' ? /'.*'/ : /`.*'/
backtrace[replacement_line].gsub!(pattern, "`#{pseudo_method}'")
end

depth = backtrace.count { |line| line == instance_exec_invocation_line }
end_pos = depth > 1 ? instance_exec_pos : -1
Expand Down Expand Up @@ -49,7 +52,13 @@ def self.cucumber_compatible_arity?(args, block)
def self.cucumber_run_with_backtrace_filtering(pseudo_method)
yield
rescue Exception => e
instance_exec_invocation_line = "#{__FILE__}:#{__LINE__ - 2}:in `cucumber_run_with_backtrace_filtering'"
yield_line_number = __LINE__ - 2
instance_exec_invocation_line =
if RUBY_VERSION >= '3.4'
"#{__FILE__}:#{yield_line_number}:in '#{name}.#{__method__}'"
else
"#{__FILE__}:#{yield_line_number}:in `#{__method__}'"
end
replace_instance_exec_invocation_line!((e.backtrace || []), instance_exec_invocation_line, pseudo_method)
raise e
end
Expand Down
33 changes: 18 additions & 15 deletions spec/cucumber/glue/proto_world_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,36 +68,39 @@ module Glue

define_steps do
When('an object is logged') do
log(a: 1, b: 2, c: 3)
object = Object.new
def object.to_s
'<test-object>'
end
log(object)
end
end

it 'attached the styring version on the object' do
expect(@out.string).to include '{:a=>1, :b=>2, :c=>3}'
it 'prints the stringified version of the object as a log message' do
expect(@out.string).to include('<test-object>')
end
end

describe 'when logging multiple items on one call' do
define_feature <<-FEATURE
Feature: Banana party
Feature: Logging multiple entries
Scenario: Monkey eats banana
When monkey eats banana
Scenario: Logging multiple entries
When logging multiple entries
FEATURE

define_steps do
When('{word} {word} {word}') do |subject, verb, complement|
log "subject: #{subject}", "verb: #{verb}", "complement: #{complement}", subject: subject, verb: verb, complement: complement
When('logging multiple entries') do
log 'entry one', 'entry two', 'entry three'
end
end

it 'logs each parameter independently' do
expect(@out.string).to include [
' subject: monkey',
' verb: eats',
' complement: banana',
' {:subject=>"monkey", :verb=>"eats", :complement=>"banana"}'
].join("\n")
it 'logs each entry independently' do
expect(@out.string).to include([
' entry one',
' entry two',
' entry three'
].join("\n"))
end
end

Expand Down

0 comments on commit 1f17266

Please sign in to comment.