Permalink
Browse files

Allow both instance and class doubles for unloaded classes.

Previously, if you used both fire_double("Foo") and fire_replaced_class_double("Foo"), and Foo was not defined, stubbing or mocking a method on the fire double would fail because ConstantStubber.original_value_for returned nil for "Foo" (since it was originally unloaded), but the constant lookup would succeed and it would try to verify the implementation against the class stub.

Now, ConstantStubber.find_original_value_for yields if the given class has been stubbed, and the value it yields can be nil if it was originally unloaded.  This allows us to support this edge case.
  • Loading branch information...
1 parent ee88a5d commit 02f315096375b3b21c179da4a7f125680996c69a @myronmarston myronmarston committed May 9, 2012
Showing with 31 additions and 5 deletions.
  1. +9 −5 lib/rspec/fire.rb
  2. +22 −0 spec/fire_double_spec.rb
View
@@ -135,9 +135,12 @@ def stub!(method_name)
end
def with_doubled_class
- if original_stubbed_const_value = ConstantStubber.original_value_for(@__doubled_class_name)
- yield original_stubbed_const_value
- elsif recursive_const_defined?(@__doubled_class_name)
+ ConstantStubber.find_original_value_for(@__doubled_class_name) do |value|
+ yield value if value
+ return
+ end
+
+ if recursive_const_defined?(@__doubled_class_name)
yield recursive_const_get(@__doubled_class_name)
end
end
@@ -390,9 +393,10 @@ def self.stubbers
@stubbers ||= []
end
- def self.original_value_for(constant_name)
+ def self.find_original_value_for(constant_name)
stubber = stubbers.find { |s| s.full_constant_name == constant_name }
- stubber.original_value if stubber
+ yield stubber.original_value if stubber
+ self
end
end
View
@@ -270,6 +270,28 @@ def use_doubles(class_double, instance_double)
double.should_receive(:foo).with("a").and_return(:bar)
A::B::C.foo("a").should eq(:bar)
end
+
+ def use_doubles(class_double, instance_double)
+ instance_double.should_receive(:undefined_method).and_return(3)
+ class_double.should_receive(:undefined_method).and_return(4)
+
+ instance_double.undefined_method.should eq(3)
+ class_double.undefined_method.should eq(4)
+ end
+
+ it 'can be used after a declared fire_double for the same class' do
+ instance_double = fire_double("A::B::C")
+ class_double = fire_replaced_class_double("A::B::C")
+
+ use_doubles class_double, instance_double
+ end
+
+ it 'can be used before a declared fire_double for the same class' do
+ class_double = fire_replaced_class_double("A::B::C")
+ instance_double = fire_double("A::B::C")
+
+ use_doubles class_double, instance_double
+ end
end
shared_examples_for "loaded constant stubbing" do |const_name|

0 comments on commit 02f3150

Please sign in to comment.