Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

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...
commit 8ce0c12448ec432688933fd938d14dcc6e1d800b 1 parent 0f09860
Myron Marston myronmarston authored
21 lib/rspec/mocks/extensions/psych.rb
... ... @@ -0,0 +1,21 @@
  1 +module Psych
  2 + class << self
  3 + def dump_with_mocks(object, *args)
  4 + return dump_without_mocks(object, *args) unless object.instance_variable_defined?(:@mock_proxy)
  5 +
  6 + mp = object.instance_variable_get(:@mock_proxy)
  7 + return dump_without_mocks(object, *args) unless mp.is_a?(::RSpec::Mocks::Proxy)
  8 +
  9 + object.send(:remove_instance_variable, :@mock_proxy)
  10 +
  11 + begin
  12 + dump_without_mocks(object, *args)
  13 + ensure
  14 + object.instance_variable_set(:@mock_proxy,mp)
  15 + end
  16 + end
  17 +
  18 + alias_method :dump_without_mocks, :dump
  19 + alias_method :dump, :dump_with_mocks
  20 + end
  21 +end
8 lib/rspec/mocks/serialization.rb
... ... @@ -1,4 +1,5 @@
1 1 require 'rspec/mocks/extensions/marshal'
  2 +require 'rspec/mocks/extensions/psych' if defined?(::Psych)
2 3
3 4 module RSpec
4 5 module Mocks
@@ -8,14 +9,15 @@ def self.fix_for(object)
8 9 end
9 10
10 11 module YAML
11   - def to_yaml(*a)
12   - return super(*a) unless instance_variable_defined?(:@mock_proxy)
  12 + def to_yaml(options = {})
  13 + return nil if defined?(::Psych) && options.respond_to?(:[]) && options[:nodump]
  14 + return super(options) unless instance_variable_defined?(:@mock_proxy)
13 15
14 16 mp = @mock_proxy
15 17 remove_instance_variable(:@mock_proxy)
16 18
17 19 begin
18   - super(*a)
  20 + super(options)
19 21 ensure
20 22 @mock_proxy = mp
21 23 end
20 spec/rspec/mocks/serialization_spec.rb
@@ -53,7 +53,7 @@ def set_stub
53 53 subject.stub(:bazz => 5)
54 54 end
55 55
56   - with_yaml_loaded do
  56 + shared_examples_for 'normal YAML serialization' do
57 57 it 'serializes to yaml the same with and without stubbing, using #to_yaml' do
58 58 expect { set_stub }.to_not change { subject.to_yaml }
59 59 end
@@ -63,6 +63,24 @@ def set_stub
63 63 end
64 64 end
65 65
  66 + with_yaml_loaded do
  67 + compiled_with_psych = RbConfig::CONFIG['configure_args'] =~ /with-libyaml/
  68 +
  69 + if compiled_with_psych
  70 + context 'using Syck as the YAML engine' do
  71 + before(:each) { YAML::ENGINE.yamler = 'syck' }
  72 + it_behaves_like 'normal YAML serialization'
  73 + end
  74 +
  75 + context 'using Psych as the YAML engine' do
  76 + before(:each) { YAML::ENGINE.yamler = 'psych' }
  77 + it_behaves_like 'normal YAML serialization'
  78 + end
  79 + else
  80 + it_behaves_like 'normal YAML serialization'
  81 + end
  82 + end
  83 +
66 84 without_yaml_loaded do
67 85 it 'does not add #to_yaml to the stubbed object' do
68 86 subject.should_not respond_to(:to_yaml)

0 comments on commit 8ce0c12

Please sign in to comment.
Something went wrong with that request. Please try again.