Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'doc/development/ruby3_gotchas.md')
-rw-r--r--doc/development/ruby3_gotchas.md37
1 files changed, 37 insertions, 0 deletions
diff --git a/doc/development/ruby3_gotchas.md b/doc/development/ruby3_gotchas.md
index dbe6fa13eee..db328b0b1a5 100644
--- a/doc/development/ruby3_gotchas.md
+++ b/doc/development/ruby3_gotchas.md
@@ -163,3 +163,40 @@ For Ruby 3 compliance, this should be changed to one of the following invocation
- `f(**{k: v})`
- `f(k: v)`
+
+## RSpec `with` argument matcher fails for shorthand Hash syntax
+
+Because keyword arguments ("kwargs") are a first-class concept in Ruby 3, keyword arguments are not
+converted into internal `Hash` instances anymore. This leads to RSpec method argument matchers failing
+when the receiver takes a positional options hash instead of kwargs:
+
+```ruby
+def m(options={}); end
+```
+
+```ruby
+expect(subject).to receive(:m).with(a: 42)
+```
+
+In Ruby 3 this expectations fails with the following error:
+
+```plaintext
+ Failure/Error:
+
+ #<subject> received :m with unexpected arguments
+ expected: ({:a=>42})
+ got: ({:a=>42})
+```
+
+This happens because RSpec uses a kwargs argument matcher here, but the method takes a hash.
+It works in Ruby 2, because `a: 42` is converted to a hash first and RSpec will use a hash argument matcher.
+
+A workaround is to not use the shorthand syntax and pass an actual `Hash` instead whenever we know a method
+to take an options hash:
+
+```ruby
+# Note the braces around the key-value pair.
+expect(subject).to receive(:m).with({ a: 42 })
+```
+
+For more information, see [the official issue report for RSpec](https://github.com/rspec/rspec-mocks/issues/1460).