spec/rspec/mocks/space_spec.rb in rspec-mocks-3.0.0.beta1 vs spec/rspec/mocks/space_spec.rb in rspec-mocks-3.0.0.beta2
- old
+ new
@@ -1,33 +1,244 @@
require 'spec_helper'
module RSpec::Mocks
describe Space do
+ let(:space) { Space.new }
+ let(:dbl_1) { Object.new }
+ let(:dbl_2) { Object.new }
- describe "#proxies_of(klass)" do
- let(:space) { Space.new }
+ describe "#verify_all" do
+ it "verifies all mocks within" do
+ verifies = []
+ space.proxy_for(dbl_1).stub(:verify) { verifies << :dbl_1 }
+ space.proxy_for(dbl_2).stub(:verify) { verifies << :dbl_2 }
+
+ space.verify_all
+
+ expect(verifies).to match_array([:dbl_1, :dbl_2])
+ end
+
+ def define_singleton_method_on_recorder_for(klass, name, &block)
+ recorder = space.any_instance_recorder_for(klass)
+ (class << recorder; self; end).send(:define_method, name, &block)
+ end
+
+ it 'verifies all any_instance recorders within' do
+ klass_1, klass_2 = Class.new, Class.new
+
+ verifies = []
+
+ # We can't `stub` a method on the recorder because it defines its own `stub`...
+ define_singleton_method_on_recorder_for(klass_1, :verify) { verifies << :klass_1 }
+ define_singleton_method_on_recorder_for(klass_2, :verify) { verifies << :klass_2 }
+
+ space.verify_all
+
+ expect(verifies).to match_array([:klass_1, :klass_2])
+ end
+ end
+
+ describe "#reset_all" do
+ it "resets all mocks within" do
+ resets = []
+
+ space.proxy_for(dbl_1).stub(:reset) { resets << :dbl_1 }
+ space.proxy_for(dbl_2).stub(:reset) { resets << :dbl_2 }
+
+ space.reset_all
+
+ expect(resets).to match_array([:dbl_1, :dbl_2])
+ end
+ end
+
+ describe "#proxies_of(klass)" do
it 'returns proxies' do
space.proxy_for("")
- expect(space.proxies_of(String).map(&:class)).to eq([PartialMockProxy])
+ expect(space.proxies_of(String).map(&:class)).to eq([PartialDoubleProxy])
end
- it 'returns only the proxies whose object is an instance of the given class' do
+ def create_generations
grandparent_class = Class.new
parent_class = Class.new(grandparent_class)
child_class = Class.new(parent_class)
grandparent = grandparent_class.new
parent = parent_class.new
child = child_class.new
+ return grandparent, parent, child
+ end
+
+ it 'returns only the proxies whose object is an instance of the given class' do
+ grandparent, parent, child = create_generations
+
space.proxy_for(grandparent)
- parent_proxy = space.proxy_for(parent)
- child_proxy = space.proxy_for(child)
+ parent_proxy = space.proxy_for(parent)
+ child_proxy = space.proxy_for(child)
- expect(space.proxies_of(parent_class)).to match_array([parent_proxy, child_proxy])
+ expect(space.proxies_of(parent.class)).to contain_exactly(parent_proxy, child_proxy)
end
+
+ it 'looks in the parent space for matching proxies' do
+ _, parent, child = create_generations
+
+ parent_proxy = space.proxy_for(parent)
+ subspace = space.new_scope
+ child_proxy = subspace.proxy_for(child)
+
+ expect(subspace.proxies_of(parent.class)).to contain_exactly(parent_proxy, child_proxy)
+ end
end
+ it 'tracks proxies in parent and child space separately' do
+ proxy1 = space.proxy_for(Object.new)
+ subspace = space.new_scope
+ proxy2 = subspace.proxy_for(Object.new)
+
+ expect(space.proxies.values).to include(proxy1)
+ expect(space.proxies.values).not_to include(proxy2)
+
+ expect(subspace.proxies.values).to include(proxy2)
+ expect(subspace.proxies.values).not_to include(proxy1)
+ end
+
+ it "only adds an instance once" do
+ m1 = double("mock1")
+
+ expect {
+ space.ensure_registered(m1)
+ }.to change { space.proxies }
+
+ expect {
+ space.ensure_registered(m1)
+ }.not_to change { space.proxies }
+ end
+
+ [:ensure_registered, :proxy_for].each do |method|
+ describe "##{method}" do
+ define_method :get_proxy do |space, object|
+ space.__send__(method, object)
+ end
+
+ it 'returns the proxy for the given object' do
+ obj1 = Object.new
+ obj2 = Object.new
+
+ expect(get_proxy(space, obj1)).to equal(get_proxy(space, obj1))
+ expect(get_proxy(space, obj2)).to equal(get_proxy(space, obj2))
+ expect(get_proxy(space, obj1)).not_to equal(get_proxy(space, obj2))
+ end
+
+ it 'can stil return a proxy from a parent context' do
+ proxy = get_proxy(space, Object)
+ subspace = space.new_scope
+
+ expect(get_proxy(subspace, Object)).to equal(proxy)
+ end
+
+ it "does not store a parent's proxy in the child space" do
+ get_proxy(space, Object)
+ subspace = space.new_scope
+
+ expect {
+ get_proxy(subspace, Object)
+ }.not_to change { subspace.proxies }.from({})
+ end
+ end
+ end
+
+ describe "#registered?" do
+ it 'returns true if registered in this space' do
+ space.ensure_registered(Object)
+ expect(space).to be_registered(Object)
+ end
+
+ it 'returns true if registered in a parent space' do
+ space.ensure_registered(Object)
+ expect(space.new_scope).to be_registered(Object)
+ end
+
+ it 'returns false if not registered in this or a parent space' do
+ expect(space.new_scope).not_to be_registered(Object)
+ end
+ end
+
+ describe "#constant_mutator_for" do
+ it 'returns the mutator for the given const name' do
+ space = RSpec::Mocks.space
+ stub_const("Foo", 3)
+ stub_const("Bar", 4)
+
+ expect(space.constant_mutator_for("Foo")).to equal(space.constant_mutator_for("Foo"))
+ expect(space.constant_mutator_for("Bar")).to equal(space.constant_mutator_for("Bar"))
+ expect(space.constant_mutator_for("Foo")).not_to equal(space.constant_mutator_for("Bar"))
+ end
+
+ it 'can stil return a mutator from a parent context' do
+ space = RSpec::Mocks.space
+
+ stub_const("Foo", 3)
+ mutator = space.constant_mutator_for("Foo")
+
+ in_new_space_scope do
+ subspace = RSpec::Mocks.space
+ expect(subspace.constant_mutator_for("Foo")).to equal(mutator)
+ end
+ end
+ end
+
+ describe "#any_instance_recorder_for" do
+ it 'returns the recorder for the given class' do
+ expect(space.any_instance_recorder_for(String)).to equal(space.any_instance_recorder_for(String))
+ expect(space.any_instance_recorder_for(Symbol)).to equal(space.any_instance_recorder_for(Symbol))
+ expect(space.any_instance_recorder_for(String)).not_to equal(space.any_instance_recorder_for(Symbol))
+ end
+
+ it 'can stil return a recorder from a parent context' do
+ recorder = space.any_instance_recorder_for(String)
+ subspace = space.new_scope
+
+ expect(subspace.any_instance_recorder_for(String)).to equal(recorder)
+ end
+
+ it "does not store a parent's proxy in the child space" do
+ space.any_instance_recorder_for(String)
+ subspace = space.new_scope
+
+ expect {
+ subspace.any_instance_recorder_for(String)
+ }.not_to change { subspace.any_instance_recorders }.from({})
+ end
+ end
+
+ it 'can be diffed in a failure when it has references to an error generator via a proxy' do
+ space1 = Space.new
+ space2 = Space.new
+
+ space1.proxy_for("")
+ space2.proxy_for("")
+
+ expect {
+ expect(space1).to eq(space2)
+ }.to raise_error(RSpec::Expectations::ExpectationNotMetError, /Diff/)
+ end
+
+ it 'removes an any_instance_recorder when requested' do
+ klass = Class.new
+
+ space.any_instance_recorder_for(klass)
+
+ expect {
+ space.remove_any_instance_recorder_for(klass)
+ }.to change { space.any_instance_recorders.size }.by(-1)
+ end
+
+ def in_new_space_scope
+ RSpec::Mocks.setup
+ yield
+ ensure
+ RSpec::Mocks.teardown
+ end
end
end