This gist tells the story: https://gist.github.com/2592376 including output. The minimal reproduction code is (copied from gist for convenience):
require 'rspec'
describe 'at_least(n).times' do
# Pass
it 'RSpec 2.9.0+ allows at_least(N).times when N > 0' do
mymock = mock
mymock.should_receive(:run).at_least(1).times
mymock.run
mymock.run
end
# Fail
it 'RSpec 2.9.0+ does *not* allow at_least(N).times when N = 0' do
mymock = mock
mymock.should_receive(:run).at_least(0).times
mymock.run
end
# Pass
it 'RSpec 2.10.0 allows at_least(N).times when N = 0 if .and_return is added' do
mymock = mock
mymock.should_receive(:run).at_least(0).times.and_return(true)
mymock.run.should be_true
end
end
Basically, in 2.9.0 (the last version I had tried this with), RSpec seemed to behave incorrectly if you passed in .at_least(0).times to a matcher. In 2.9.0 both specs with N=0 above will fail. 2.10.0 seems to fix the 3rd case when you have an .and_return clause, but that seems like a side-effect rather than an intentional fix. You still cannot do .at_least(0).times.
Oddly enough, my actual real world spec (see here) has a .and_return, and yet it worked in 2.9.0 but only started failing in 2.10.0, which completely contradicts the minimal case above. So something is going on behind the scenes here, but I assume if .at_least(0).times is fixed to work properly, the side effects will be solved as well.
edit: note that my gist runs the specs in ruby 1.9.3p125, but Travis shows the specs failing for all Rubies, in the real world code.
This gist tells the story: https://gist.github.com/2592376 including output. The minimal reproduction code is (copied from gist for convenience):
Basically, in 2.9.0 (the last version I had tried this with), RSpec seemed to behave incorrectly if you passed in
.at_least(0).timesto a matcher. In 2.9.0 both specs with N=0 above will fail. 2.10.0 seems to fix the 3rd case when you have an.and_returnclause, but that seems like a side-effect rather than an intentional fix. You still cannot do.at_least(0).times.Oddly enough, my actual real world spec (see here) has a
.and_return, and yet it worked in 2.9.0 but only started failing in 2.10.0, which completely contradicts the minimal case above. So something is going on behind the scenes here, but I assume if.at_least(0).timesis fixed to work properly, the side effects will be solved as well.edit: note that my gist runs the specs in ruby 1.9.3p125, but Travis shows the specs failing for all Rubies, in the real world code.