Skip to content

Commit 1f17266

Browse files
authored
Fix error backtrace formatting on Ruby 3.4+ (#1771)
* 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
1 parent 328fd2b commit 1f17266

File tree

6 files changed

+36
-21
lines changed

6 files changed

+36
-21
lines changed

.github/workflows/test.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
fail-fast: false
1818
matrix:
1919
os: [ubuntu-latest, macos-latest, windows-latest]
20-
ruby: ['3.0', '3.1', '3.2', '3.3']
20+
ruby: ['3.0', '3.1', '3.2', '3.3', '3.4']
2121
include:
2222
- os: ubuntu-latest
2323
ruby: jruby-9.4

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ that need to rely on procedural loading / reloading of files should use method i
2323

2424
### Fixed
2525
- Fixed an issue where a change to one example in compatibility testing wasn't fully adhered to ([luke-hill](https://github.com/luke-hill))
26+
- 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))
2627

2728
### Removed
2829
- `StepDefinitionLight` associated methods. The class itself is present but deprecated

features/docs/extending_cucumber/custom_formatter.feature

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ Feature: Custom Formatter
4545
def initialize(config, options)
4646
@io = config.out_stream
4747
config.on_event :test_run_finished do |event|
48-
@io.print options.inspect
48+
@io.print options.to_json
4949
end
5050
end
5151
end
@@ -54,5 +54,5 @@ Feature: Custom Formatter
5454
When I run `cucumber features/f.feature --format MyCustom::Formatter,foo=bar,one=two --publish-quiet`
5555
Then it should pass with exactly:
5656
"""
57-
{"foo"=>"bar", "one"=>"two"}
57+
{"foo":"bar","one":"two"}
5858
"""

lib/cucumber/formatter/backtrace_filter.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,10 @@ def exception
4343

4444
if ::ENV['CUCUMBER_TRUNCATE_OUTPUT']
4545
# Strip off file locations
46+
regexp = RUBY_VERSION >= '3.4' ? /(.*):in '/ : /(.*):in `/
4647
filtered = filtered.map do |line|
47-
line =~ /(.*):in `/ ? Regexp.last_match(1) : line
48+
match = regexp.match(line)
49+
match ? match[1] : line
4850
end
4951
end
5052

lib/cucumber/glue/invoke_in_world.rb

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ def self.replace_instance_exec_invocation_line!(backtrace, instance_exec_invocat
1414
return unless instance_exec_pos
1515

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

1922
depth = backtrace.count { |line| line == instance_exec_invocation_line }
2023
end_pos = depth > 1 ? instance_exec_pos : -1
@@ -49,7 +52,13 @@ def self.cucumber_compatible_arity?(args, block)
4952
def self.cucumber_run_with_backtrace_filtering(pseudo_method)
5053
yield
5154
rescue Exception => e
52-
instance_exec_invocation_line = "#{__FILE__}:#{__LINE__ - 2}:in `cucumber_run_with_backtrace_filtering'"
55+
yield_line_number = __LINE__ - 2
56+
instance_exec_invocation_line =
57+
if RUBY_VERSION >= '3.4'
58+
"#{__FILE__}:#{yield_line_number}:in '#{name}.#{__method__}'"
59+
else
60+
"#{__FILE__}:#{yield_line_number}:in `#{__method__}'"
61+
end
5362
replace_instance_exec_invocation_line!((e.backtrace || []), instance_exec_invocation_line, pseudo_method)
5463
raise e
5564
end

spec/cucumber/glue/proto_world_spec.rb

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -68,36 +68,39 @@ module Glue
6868

6969
define_steps do
7070
When('an object is logged') do
71-
log(a: 1, b: 2, c: 3)
71+
object = Object.new
72+
def object.to_s
73+
'<test-object>'
74+
end
75+
log(object)
7276
end
7377
end
7478

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

8084
describe 'when logging multiple items on one call' do
8185
define_feature <<-FEATURE
82-
Feature: Banana party
86+
Feature: Logging multiple entries
8387
84-
Scenario: Monkey eats banana
85-
When monkey eats banana
88+
Scenario: Logging multiple entries
89+
When logging multiple entries
8690
FEATURE
8791

8892
define_steps do
89-
When('{word} {word} {word}') do |subject, verb, complement|
90-
log "subject: #{subject}", "verb: #{verb}", "complement: #{complement}", subject: subject, verb: verb, complement: complement
93+
When('logging multiple entries') do
94+
log 'entry one', 'entry two', 'entry three'
9195
end
9296
end
9397

94-
it 'logs each parameter independently' do
95-
expect(@out.string).to include [
96-
' subject: monkey',
97-
' verb: eats',
98-
' complement: banana',
99-
' {:subject=>"monkey", :verb=>"eats", :complement=>"banana"}'
100-
].join("\n")
98+
it 'logs each entry independently' do
99+
expect(@out.string).to include([
100+
' entry one',
101+
' entry two',
102+
' entry three'
103+
].join("\n"))
101104
end
102105
end
103106

0 commit comments

Comments
 (0)