Closed Drenmi closed 3 years ago
Although the implementation of this is not trivial, as Ruby, despite now making a clear distinction between keyword arguments and hashes, does not expose the former as its own object.
Ruby doesn't tell you what a keyword hash is, but you can detect all of the circumstances when keywords can be used, because the method itself contains that information. We use this information in the method signature verifier, and we have some logic to detect when you are passing keyword arguments, its just not perfect in Ruby 3 world. Its also possible to detect keyword hashes when used with ruby2 keywords, which is the approach #1394 uses which I think would solve your use case.
Thanks, @JonRowe!
Based on the PR description, this is indeed what we were looking for. 🙏
Description
Since Ruby has now taken the stance that keyword arguments and hashes are not interchangeable, we're left with a class of errors that can be easily masked when stubbing a method call.
Consider this method definition, representing a common pattern for, let's say, API wrappers:
Now, in the test for another class,
Qux
, which uses this wrapper as a collaborator, we stub out the call:So far, so good. Now assume in
Qux
, we are doing this:Notice we have forgotten to use
**
to convert the options into keyword arguments. This will result in a warning in Ruby 2.7, and a runtime error in Ruby 3.However, our tests will pass. Effectively hiding this mistake.
We can try to add a constraint in our test:
... but to no avail. The tests still pass.
Possible solution
Of course the first solution that comes to mind is to add a new argument matcher here, e.g.
keyword_args
.Although the implementation of this is not trivial, as Ruby, despite now making a clear distinction between keyword arguments and hashes, does not expose the former as its own object.
Any solution of this sort would likely need to involve some runtime introspection using
Binding
, or similar.Your environment
Expected behavior
The test suite catches any runtime errors that might occur.
Actual behavior
The test suite passes.