Skip to content

Commit

Permalink
ensure null objects behave correctly with to_a and to_ary
Browse files Browse the repository at this point in the history
Conflicts:
	spec/rspec/mocks/mock_spec.rb
  • Loading branch information
JonRowe committed Jul 11, 2013
1 parent 778998b commit b2f3d4c
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 12 deletions.
12 changes: 8 additions & 4 deletions features/method_stubs/to_ary.feature
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@ Feature: double handling to_ary
"""ruby
describe "#to_ary" do
shared_examples "to_ary" do
it "raises a NoMethodError" do
expect { obj.to_ary }.to raise_error(NoMethodError)
end
it "can be overridden with a stub" do
obj.stub(:to_ary) { :non_nil_value }
obj.to_ary.should be(:non_nil_value)
Expand All @@ -35,11 +31,19 @@ Feature: double handling to_ary
context "sent to a double as_null_object" do
let(:obj) { double('obj').as_null_object }
include_examples "to_ary"
it "returns nil" do
expect( obj.to_ary ).to eq nil
end
end
context "sent to a double without as_null_object" do
let(:obj) { double('obj') }
include_examples "to_ary"
it "raises a NoMethodError" do
expect { obj.to_ary }.to raise_error(NoMethodError)
end
end
end
"""
Expand Down
7 changes: 5 additions & 2 deletions lib/rspec/mocks/test_double.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,16 @@ def __initialize_as_test_double(name=nil, stubs_and_options={})
end

def method_missing(message, *args, &block)
raise NoMethodError if message == :to_ary || message == :to_a
return 0 if message == :to_int && __mock_proxy.null_object?
if __mock_proxy.null_object?
return 0 if message == :to_int
return nil if [:to_a,:to_ary].include? message
end
__mock_proxy.record_message_received(message, *args, &block)

begin
__mock_proxy.null_object? ? self : super
rescue NameError
raise NoMethodError if message == :to_ary || message == :to_a
__mock_proxy.raise_unexpected_message_error(message, *args)
end
end
Expand Down
15 changes: 15 additions & 0 deletions spec/rspec/mocks/mock_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,21 @@ def @double.method_with_default_argument(arg={}); end
expect( Array(@double) ).to eq([@double])
end

it "is wrappable in an array when a null object" do
expect( Array(@double.as_null_object) ).to eq [@double]
end

%w[to_ary to_a].each do |method|
it "responds to #{method} as a null object" do
expect(@double.as_null_object.send method).to eq nil
end
end

it "passes proc to expectation block without an argument" do
@double.should_receive(:foo) { |&block| expect(block.call).to eq(:bar) }
@double.foo { :bar }
end

context "with Ruby > 1.8.6", :unless => RUBY_VERSION.to_s == '1.8.6' do
it "passes proc to expectation block without an argument" do
# We eval this because Ruby 1.8.6's syntax parser barfs on { |&block| ... }
Expand Down
14 changes: 8 additions & 6 deletions spec/rspec/mocks/to_ary_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,6 @@

describe "a double receiving to_ary" do
shared_examples "to_ary" do
it "returns nil" do
expect do
expect(obj.to_ary).to be_nil
end.to raise_error(NoMethodError)
end

it "doesn't respond" do
expect(obj).not_to respond_to(:to_ary)
end
Expand All @@ -31,10 +25,18 @@
context "double as_null_object" do
let(:obj) { double('obj').as_null_object }
include_examples "to_ary"

it "returns nil" do
expect(obj.to_ary).to eq nil
end
end

context "double without as_null_object" do
let(:obj) { double('obj') }
include_examples "to_ary"

it "raises NoMethodError" do
expect { obj.to_ary }.to raise_error(NoMethodError)
end
end
end

0 comments on commit b2f3d4c

Please sign in to comment.