Browse files

Revert "Revert "Fixed YAML serialization of a stubbed object.""

This reverts commit 7499777.
  • Loading branch information...
1 parent 8bb5142 commit d03d399eac2978b5e8e1c4507c58761f003d9274 @dchelimsky dchelimsky committed Oct 2, 2010
View
1 lib/rspec/mocks/framework.rb
@@ -14,3 +14,4 @@
require 'rspec/mocks/errors'
require 'rspec/mocks/error_generator'
require 'rspec/mocks/space'
+require 'rspec/mocks/serialization'
View
13 lib/rspec/mocks/methods.rb
@@ -73,10 +73,15 @@ def null_object?
private
def __mock_proxy
- if Mock === self
- @mock_proxy ||= Proxy.new(self, @name, @options)
- else
- @mock_proxy ||= Proxy.new(self)
+ @mock_proxy ||= begin
+ mp = if Mock === self
+ Proxy.new(self, @name, @options)
+ else
+ Proxy.new(self)
+ end
+
+ Serialization.fix_for(self)
+ mp
end
end
View
24 lib/rspec/mocks/serialization.rb
@@ -0,0 +1,24 @@
+module RSpec
+ module Mocks
+ module Serialization
+ def self.fix_for(object)
+ object.extend(YAML) if defined?(::YAML)
+ end
+
+ module YAML
+ def to_yaml(*a)
+ return super(*a) unless instance_variable_defined?(:@mock_proxy)
+
+ mp = @mock_proxy
+ remove_instance_variable(:@mock_proxy)
+
+ begin
+ super(*a)
+ ensure
+ @mock_proxy = mp
+ end
+ end
+ end
+ end
+ end
+end
View
69 spec/rspec/mocks/serialization_spec.rb
@@ -0,0 +1,69 @@
+require 'spec_helper'
+require 'yaml'
+
+module RSpec
+ module Mocks
+ class SerializableStruct < Struct.new(:foo, :bar); end
+
+ describe Serialization do
+ def self.with_yaml_loaded(&block)
+ context 'with YAML loaded' do
+ module_eval(&block)
+ end
+ end
+
+ def self.without_yaml_loaded(&block)
+ context 'without YAML loaded' do
+ before(:each) do
+ # We can't really unload yaml, but we can fake it here...
+ @orig_yaml_constant = Object.send(:remove_const, :YAML)
+ Struct.class_eval do
+ alias __old_to_yaml to_yaml
+ undef to_yaml
+ end
+ end
+
+ module_eval(&block)
+
+ after(:each) do
+ Object.const_set(:YAML, @orig_yaml_constant)
+ Struct.class_eval do
+ alias to_yaml __old_to_yaml
+ undef __old_to_yaml
+ end
+ end
+ end
+ end
+
+ subject { SerializableStruct.new(7, "something") }
+
+ def set_stub
+ subject.stub(:bazz => 5)
+ end
+
+ with_yaml_loaded do
+ it 'serializes to yaml the same with and without stubbing, using #to_yaml' do
+ expect { set_stub }.to_not change { subject.to_yaml }
+ end
+
+ it 'serializes to yaml the same with and without stubbing, using YAML.dump' do
+ expect { set_stub }.to_not change { YAML.dump(subject) }
+ end
+ end
+
+ without_yaml_loaded do
+ it 'does not add #to_yaml to the stubbed object' do
+ subject.should_not respond_to(:to_yaml)
+ set_stub
+ subject.should_not respond_to(:to_yaml)
+ end
+ end
+
+ it 'marshals the same with and without stubbing' do
+ pending("not sure how to fix this yet") do
+ expect { set_stub }.to_not change { Marshal.dump(subject) }
+ end
+ end
+ end
+ end
+end

0 comments on commit d03d399

Please sign in to comment.