Closed
Description
Trying to run rspec-rails test suite against Ruby 3.4, I encounter test failures such as:
8) be_a_new matcher #with right class and new record with composable matchers one attribute is a composable matcher fails
Failure/Error:
expect {
expect(record).to be_a_new(record.class).with(
foo: a_string_matching("bar"))
}.to raise_error("attribute {\"foo\"=>(a string matching \"bar\")} was not set on #{record.inspect}")
expected Exception with "attribute {\"foo\"=>(a string matching \"bar\")} was not set on #<#<Class:0x00007fe77b608208>:0x00007fe77b756c68 @attributes={foo: \"foo\", bar: \"bar\"}>", got #<RSpec::Expectations::ExpectationNotMetError: attribute {"foo" => (a string matching "bar")} was not set on #<#<Class:0x00007fe77b608208>:0x00007fe77b756c68 @attributes={foo: "foo", bar: "bar"}>> with backtrace:
# ./spec/rspec/rails/matchers/be_a_new_spec.rb:75:in 'block (7 levels) in <top (required)>'
# ./spec/rspec/rails/matchers/be_a_new_spec.rb:77:in 'block (6 levels) in <top (required)>'
# ./spec/spec_helper.rb:83:in 'block (3 levels) in <top (required)>'
# ./spec/spec_helper.rb:77:in 'block (2 levels) in <top (required)>'
# ./spec/rspec/rails/matchers/be_a_new_spec.rb:77:in 'block (6 levels) in <top (required)>'
# ./spec/spec_helper.rb:83:in 'block (3 levels) in <top (required)>'
# ./spec/spec_helper.rb:77:in 'block (2 levels) in <top (required)>'
The error message seems to be originating from here:
rspec-rails/lib/rspec/rails/matchers/be_a_new.rb
Lines 29 to 43 in 609bb83
Specifically the #{describe_unmatched_attributes.inspect}
. Here are some details from binding.irb
:
rom: /builddir/build/BUILD/rubygem-rspec-rails-7.1.0-build/rspec-rails-7.1.0/usr/share/gems/gems/rspec-rails-7.1.0/lib/rspec/rails/matchers/be_a_new.rb @ line 36 :
31: unless actual.is_a?(expected) && actual.new_record?
32: message << "expected #{actual.inspect} to be a new #{expected.inspect}"
33: end
34: unless attributes_match?(actual)
35: describe_unmatched_attributes = surface_descriptions_in(unmatched_attributes)
=> 36: binding.irb
37: if unmatched_attributes.size > 1
38: message << "attributes #{describe_unmatched_attributes.inspect} were not set on #{actual.inspect}"
39: else
40: message << "attribute #{describe_unmatched_attributes.inspect} was not set on #{actual.inspect}"
41: end
irb(#<RSpec::Rails::Matchers::BeA...):001> p unmatched_attributes
{"foo" => #<RSpec::Matchers::BuiltIn::Match:0x00007fa0e04f40b0 @expected="bar", @expected_captures=nil, @matcher_name=:a_string_matching>}
=> {"foo" => #<RSpec::Matchers::BuiltIn::Match:0x00007fa0e04f40b0 @expected="bar", @expected_captures=nil, @matcher_name=:a_string_matching>}
irb(#<RSpec::Rails::Matchers::BeA...):002> p surface_descriptions_in(unmatched_attributes)
{"foo" => (a string matching "bar")}
=> {"foo" => (a string matching "bar")}
irb(#<RSpec::Rails::Matchers::BeA...):003>
Obviously Ruby 3.4 changes the Hash formatting adding two spaces around hash rocket. The question is how to fix this. Several options:
- Only the test cases are adjusted
- Just add optional spaces
- Something more elaborated, with
Hash#inspect
- The backward compatibility of the output is kept, therefore tests stays but the error message is formatted differently
BTW I find the hash like formatting with the brackets a bit unfortunate.
Metadata
Metadata
Assignees
Labels
No labels