Permalink
Browse files

Fix yaml serialization when using Psych.

Without these changes, I was getting SystemStackErrors when calling YAML.dump(stubbed_object) or stubbed_object.to_yaml.

To test this, you may need to reinstall ruby 1.9.2 with psych support.  On OSX with homebrew and rvm, this will do the trick:

brew install libyaml
rvm install ruby-1.9.2 --with-libyaml-dir=/usr/local

Closes #36.
  • Loading branch information...
1 parent 0f09860 commit 8ce0c12448ec432688933fd938d14dcc6e1d800b @myronmarston myronmarston committed Feb 8, 2011
Showing with 45 additions and 4 deletions.
  1. +21 −0 lib/rspec/mocks/extensions/psych.rb
  2. +5 −3 lib/rspec/mocks/serialization.rb
  3. +19 −1 spec/rspec/mocks/serialization_spec.rb
@@ -0,0 +1,21 @@
+module Psych
+ class << self
+ def dump_with_mocks(object, *args)
+ return dump_without_mocks(object, *args) unless object.instance_variable_defined?(:@mock_proxy)
+
+ mp = object.instance_variable_get(:@mock_proxy)
+ return dump_without_mocks(object, *args) unless mp.is_a?(::RSpec::Mocks::Proxy)
+
+ object.send(:remove_instance_variable, :@mock_proxy)
+
+ begin
+ dump_without_mocks(object, *args)
+ ensure
+ object.instance_variable_set(:@mock_proxy,mp)
+ end
+ end
+
+ alias_method :dump_without_mocks, :dump
+ alias_method :dump, :dump_with_mocks
+ end
+end
@@ -1,4 +1,5 @@
require 'rspec/mocks/extensions/marshal'
+require 'rspec/mocks/extensions/psych' if defined?(::Psych)
module RSpec
module Mocks
@@ -8,14 +9,15 @@ def self.fix_for(object)
end
module YAML
- def to_yaml(*a)
- return super(*a) unless instance_variable_defined?(:@mock_proxy)
+ def to_yaml(options = {})
+ return nil if defined?(::Psych) && options.respond_to?(:[]) && options[:nodump]
+ return super(options) unless instance_variable_defined?(:@mock_proxy)
mp = @mock_proxy
remove_instance_variable(:@mock_proxy)
begin
- super(*a)
+ super(options)
ensure
@mock_proxy = mp
end
@@ -53,7 +53,7 @@ def set_stub
subject.stub(:bazz => 5)
end
- with_yaml_loaded do
+ shared_examples_for 'normal YAML serialization' 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
@@ -63,6 +63,24 @@ def set_stub
end
end
+ with_yaml_loaded do
+ compiled_with_psych = RbConfig::CONFIG['configure_args'] =~ /with-libyaml/
+
+ if compiled_with_psych
+ context 'using Syck as the YAML engine' do
+ before(:each) { YAML::ENGINE.yamler = 'syck' }
+ it_behaves_like 'normal YAML serialization'
+ end
+
+ context 'using Psych as the YAML engine' do
+ before(:each) { YAML::ENGINE.yamler = 'psych' }
+ it_behaves_like 'normal YAML serialization'
+ end
+ else
+ it_behaves_like 'normal YAML serialization'
+ end
+ end
+
without_yaml_loaded do
it 'does not add #to_yaml to the stubbed object' do
subject.should_not respond_to(:to_yaml)

0 comments on commit 8ce0c12

Please sign in to comment.