Skip to content

Commit

Permalink
Fix yaml serialization when using Psych.
Browse files Browse the repository at this point in the history
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 rspec#36.
  • Loading branch information
myronmarston committed Feb 20, 2011
1 parent 0f09860 commit 8ce0c12
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 4 deletions.
21 changes: 21 additions & 0 deletions lib/rspec/mocks/extensions/psych.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
8 changes: 5 additions & 3 deletions lib/rspec/mocks/serialization.rb
@@ -1,4 +1,5 @@
require 'rspec/mocks/extensions/marshal'
require 'rspec/mocks/extensions/psych' if defined?(::Psych)

module RSpec
module Mocks
Expand All @@ -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
Expand Down
20 changes: 19 additions & 1 deletion spec/rspec/mocks/serialization_spec.rb
Expand Up @@ -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
Expand All @@ -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)
Expand Down

0 comments on commit 8ce0c12

Please sign in to comment.