Skip to content

Commit

Permalink
verifying ordering of spies
Browse files Browse the repository at this point in the history
  • Loading branch information
JonRowe committed Oct 23, 2013
1 parent 65d9cfb commit 4be9d39
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 1 deletion.
2 changes: 1 addition & 1 deletion lib/rspec/mocks/matchers/have_received.rb
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def generate_failure_message

def expected_messages_received?
mock_proxy.replay_received_message_on @expectation, &@block
@expectation.expected_messages_received?
@expectation.expected_messages_received? && @expectation.expected_ordering_received?
end

def mock_proxy
Expand Down
4 changes: 4 additions & 0 deletions lib/rspec/mocks/message_expectation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,10 @@ def expected_messages_received?
ignoring_args? || matches_exact_count? || matches_at_least_count? || matches_at_most_count?
end

def expected_ordering_received?
!@ordered || @order_group.verify_invocation_order(self)
end

# @private
def ignoring_args?
@expected_received_count == :any
Expand Down
21 changes: 21 additions & 0 deletions lib/rspec/mocks/order_group.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ def handle_order_constraint(expectation)
expectation.raise_out_of_order_error
end

def verify_invocation_order(expectation)
expectation.raise_out_of_order_error unless expectations_invoked_in_order?
true
end

def clear
@index = 0
@invocation_order.clear
Expand All @@ -52,6 +57,22 @@ def first_ordered
(@expectations[@index..-1] || []).find { |expectation| expectation.ordered? }
end

def expectations_invoked_in_order?
invoked_expectations == expected_invocations
end

def invoked_expectations
@expectations.select { |e| e.ordered? && @invocation_order.include?([e.orig_object,e.message]) }
end

def expected_invocations
@invocation_order.map { |invocation| expectation_for(*invocation) }.compact
end

def expectation_for(object, message)
@expectations.find { |e| e.orig_object == object && e.message == message }
end

end
end
end
22 changes: 22 additions & 0 deletions spec/rspec/mocks/matchers/have_received_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,28 @@ module Mocks
end
end
end

context 'ordered' do
let(:dbl) { double :one => 1, :two => 2 }

it 'passes when the messages were received in order' do
dbl.one
dbl.two

expect(dbl).to have_received(:one).ordered
expect(dbl).to have_received(:two).ordered
end

it 'fails when the messages are received out of order' do
dbl.two
dbl.one

expect {
expect(dbl).to have_received(:one).ordered
expect(dbl).to have_received(:two).ordered
}.to raise_error(/received :two out of order/m)
end
end
end

describe "expect(...).not_to have_received" do
Expand Down

0 comments on commit 4be9d39

Please sign in to comment.