-
-
Notifications
You must be signed in to change notification settings - Fork 158
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
Expectation with never cardinality should display deprecation warning #681
base: main
Are you sure you want to change the base?
Expectation with never cardinality should display deprecation warning #681
Conversation
we found several failing tests, here's one
on mocha main branch, it only produces one print statement
i couldn't find the time to debug all the failing cases so there might be other issues - we are pretty busy with other work right now so responses might be delayed, but thanks a lot for diving into this! cc @zenspider |
I'm about to make some changes in this area and this will make it easier to see what's going on.
I'm planning to use this in a subsequent commit.
I'm planning to use this in a subsequent commit.
I'm planning to use this in a subsequent commit.
Currently when an invocation matches an expectation which does not allow invocations (i.e. `Expectation#never` has been called on it), but the invocation also matches another expectation which does allow invocations, then the test does not fail with an unexpected invocation error. In #679 I'm planning to change this behaviour so the test fails fast with an unexpected invocation error. This commit displays a deprecation warning instead to give users a chance to update their code before the actual change is made.
In the previous commit, the changes meant that a block provided to `Expectation#with` was being invoked three times instead of once. The original behaviour was not explicitly documented and there is code in the wild [1] that relies on `Expectation#with` only being called once per invocation. I'm not convinced that test code should be relying on this behaviour, but from a performance point-of-view, it probably makes sense to avoid calling the matching methods on `ExpectationList` multiple times unnecessarily. This commit changes the code in `Mock#handle_method_call` to avoid unnecessary calls to these methods. I've created #682 to suggest improving the docs for `Expectation#with` when it takes a block argument to address the ambiguity that has become apparent. [1]: #681 (comment)
094ea8f
to
065fe3d
Compare
In the previous commit, the changes meant that a block provided to `Expectation#with` was being invoked three times instead of once. The original behaviour was not explicitly documented and there is code in the wild [1] that relies on `Expectation#with` only being called once per invocation. I'm not convinced that test code should be relying on this behaviour, but from a performance point-of-view, it probably makes sense to avoid calling the matching methods on `ExpectationList` multiple times unnecessarily. This commit changes the code in `Mock#handle_method_call` to avoid unnecessary calls to these methods. I've created #682 to suggest improving the docs for `Expectation#with` when it takes a block argument to address the ambiguity that has become apparent. [1]: #681 (comment)
Thanks for running your test suite against the branch with the deprecation warnings. I assume that the "failure" in the the example test is because in reality you have tests relying on def test_stub_with
Klass.stubs(:foo).with { |_| p 'inside stub' }
Klass.foo
end If so, while this was never documented behaviour to be relied upon, I've changed the code to avoid multiple invocations of the matcher block. 😓 Could you try running your test suite against the updated branch when you have time? 🙏 |
hi, i tried the latest commit again - the above is the original issue we reported and the latest commit is failing it instead of giving a deprecation warning 😅 cc @zenspider |
Hmm. That's very odd. I have an acceptance test which is pretty much exactly that test and it is passing in the branch. To double-check, I just ran the test below and got the expected output, i.e. the test passed but a deprecation warning was reported. Can you double-check that you were using the correct branch? i.e. # klass_test.rb
require "bundler/inline"
gemfile do
source "https://rubygems.org"
gem "minitest"
gem "mocha", git: "https://github.com/freerange/mocha.git", branch: "expectation-with-never-cardinality-should-display-deprecation-warning"
end
require "minitest/autorun"
require "mocha/minitest"
class TestKlass < Minitest::Test
class Klass
def self.foo; end
end
def test_foo_never_called
Klass.stubs(:foo)
Klass.expects(:foo).never
Klass.foo
end
end
|
Currently when an invocation matches an expectation which does not allow invocations (i.e.
Expectation#never
has been called on it), but the invocation also matches another expectation which does allow invocations, then the test does not fail with an unexpected invocation error.In #679 I'm planning to change this behaviour so the test fails fast with an unexpected invocation error. This PR means we display a deprecation warning instead to give users a chance to update their code before the actual change is made.