-
-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix for NoMethodError: undefined method `supports_value_expectations?' #48
Conversation
With [this change](rspec/rspec-expectations#1139) in rspec-expectations, a call to `expect(my_object).to have(...)` is raising a `NoMethodError: undefined method `supports_value_expectations?' for <MyObject:0x000055a1b6e065c0>`. This is because ExpectationTarget calls `supports_value_expectation` here: https://github.com/rspec/rspec-expectations/blob/4e7011fe8ac68b74621336b07f894879c8da202d/lib/rspec/expectations/expectation_target.rb#L127 Which ends up being processed by `Have#method_missing` which sets `supports_value_expectations?` to @collection_name. Later in `Have#determine_collection` it tries to call `supports_value_expectations?` on my_object, which causes the NoMethodError. The fix is simple, just implement `Have#supports_value_expectations?`.
Your link cannot be the culprit, as:
So it would be useful to find out where a |
@JonRowe That puzzled me too, initially. But what happens is that Then the NoMethodError is raised here:
|
Can you please add a test case that is failing prior to the fix? |
hah lol the matcher thinks its an expectation |
Actually this will probably cause issues for other dynamic matchers, so I'm still wondering if this needs a fix upstream 🤔 |
Can you please add a test case that is failing prior to the fix? |
I still don't get what is going on 🤷 😄 |
I'm not sure if it need specific test for this. If you just run
and
After this patch, all tests pass. @JonRowe If by "dynamic matchers" you mean implement Anyway, I think the fix here is still pretty reasonable and practical. |
See rspec/rspec-collection_matchers#48 If a matcher supports dynamic arbitrary methods called on it, e.g. `have_at_least(100).bucks`, it would also consider a `supports_value_expectations?` call as a dynamic part. Instead of calling `supports_*?` methods on a matcher, explicitly check if it responds to it.
@guigs rspec/rspec-expectations#1294 should fix it for |
See rspec/rspec-collection_matchers#48 If a matcher supports dynamic arbitrary methods called on it, e.g. `have_at_least(100).bucks`, it would also consider a `supports_value_expectations?` call as a dynamic part. Instead of calling `supports_*?` methods on a matcher, explicitly check if it responds to it.
See rspec/rspec-collection_matchers#48 If a matcher supports dynamic arbitrary methods called on it, e.g. `have_at_least(100).bucks`, it would also consider a `supports_value_expectations?` call as a dynamic part. Instead of calling `supports_*?` methods on a matcher, explicitly check if it responds to it.
@pirj I confirm that rspec/rspec-expectations#1294 also fixes the issue for me. |
Great, thank you! |
See rspec/rspec-collection_matchers#48 If a matcher supports dynamic arbitrary methods called on it, e.g. `have_at_least(100).bucks`, it would also consider a `supports_value_expectations?` call as a dynamic part. Instead of calling `supports_*?` methods on a matcher, explicitly check if it responds to it. --- This commit was imported from rspec/rspec-expectations@c6475b5.
See rspec/rspec-collection_matchers#48 If a matcher supports dynamic arbitrary methods called on it, e.g. `have_at_least(100).bucks`, it would also consider a `supports_value_expectations?` call as a dynamic part. Instead of calling `supports_*?` methods on a matcher, explicitly check if it responds to it. --- This commit was imported from rspec/rspec-expectations@d8f272a.
In order to upgrade an application to Rails 6.1, it is necessary to use newer version of
rspec-rails
4.1.0.pre, which requires rspec-expectations 3.11.0.pre.Turns out that rspec-expectations 3.11.0.pre is incompatible with current rspec-collection_matchers, because of this change, a call to
expect(my_object).to have(...)
is raising aNoMethodError: undefined method 'supports_value_expectations?' for <MyObject:0x000055a1b6e065c0>
.This is because
Spec::Expectations::ExpectationTarget
callsmatcher.supports_value_expectation
here.Which ends up being processed by
Have#method_missing
which setssupports_value_expectations?
to@collection_name
. Then, later inHave#determine_collection
it tries to callsupports_value_expectations?
onmy_object
, which causes theNoMethodError
.The fix is simple, just implement
Have#supports_value_expectations?
.