Skip to content

Commit

Permalink
Deprecate non-opt-in Marshal monkey-patch.
Browse files Browse the repository at this point in the history
  • Loading branch information
xaviershay committed Mar 8, 2014
1 parent c9afc79 commit 273f50b
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 0 deletions.
1 change: 1 addition & 0 deletions Changelog.md
Expand Up @@ -5,6 +5,7 @@ Deprecations:

* Deprecate `RSpec::Mocks::TestDouble.extend_onto`. (Myron Marston)
* Deprecate `RSpec::Mocks::ConstantStubber`. (Jon Rowe)
* Deprecate `Marshal.dump` monkey-patch without opt-in. (Xavier Shay)

### 2.99.0.beta2 / 2014-02-17
[full changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.0.beta1...v2.99.0.beta2)
Expand Down
9 changes: 9 additions & 0 deletions lib/rspec/mocks/configuration.rb
Expand Up @@ -6,6 +6,7 @@ class Configuration
def initialize
@yield_receiver_to_any_instance_implementation_blocks = false
@should_warn_about_any_instance_blocks = true
@marshal_patched = false
end

def yield_receiver_to_any_instance_implementation_blocks?
Expand Down Expand Up @@ -62,6 +63,14 @@ def syntax
syntaxes << :expect if Syntax.expect_enabled?
syntaxes
end

def patch_marshal_to_support_partial_doubles=(val)
@marshal_patched = val
end

def marshal_patched?
@marshal_patched
end
end

def self.configuration
Expand Down
15 changes: 15 additions & 0 deletions lib/rspec/mocks/extensions/marshal.rb
Expand Up @@ -6,6 +6,21 @@ def dump_with_mocks(object, *rest)
if ::RSpec::Mocks.space.nil? || !::RSpec::Mocks.space.registered?(object) || NilClass === object
dump_without_mocks(object, *rest)
else
unless ::RSpec::Mocks.configuration.marshal_patched?
RSpec.warn_deprecation(<<-EOS.gsub(/^\s+\|/, ''))
|Using Marshal.dump on stubbed objects relies on a monkey-patch
|that is being made opt-in in RSpec 3. To silence this warning
|please explicitly enable it:
|
|RSpec.configure do |rspec|
| rspec.mock_with :rspec do |mocks|
| mocks.patch_marshal_to_support_partial_doubles = true
| end
|end
|
|Called from #{RSpec::CallerFilter.first_non_rspec_line}."
EOS
end
dump_without_mocks(object.dup, *rest)
end
end
Expand Down
8 changes: 8 additions & 0 deletions spec/rspec/mocks/extensions/marshal_spec.rb
Expand Up @@ -31,13 +31,21 @@ def without_space
end

context 'when rspec-mocks has been fully initialized' do
include_context 'with isolated configuration'

it 'duplicates objects with stubbed or mocked implementations before serialization' do
RSpec::Mocks.configuration.patch_marshal_to_support_partial_doubles = true
obj = double(:foo => "bar")

serialized = Marshal.dump(obj)
expect(Marshal.load(serialized)).to be_an(obj.class)
end

it 'provides a deprecation warning' do
expect_warn_deprecation_with_call_site('marshal_spec.rb', __LINE__ + 1)
Marshal.dump double(:foo => "bar")
end

it 'does not duplicate other objects before serialization' do
obj = UndupableObject.new

Expand Down
2 changes: 2 additions & 0 deletions spec/rspec/mocks/serialization_spec.rb
Expand Up @@ -3,6 +3,7 @@
module RSpec
module Mocks
describe "Serialization of mocked objects" do
include_context 'with isolated configuration'

class SerializableObject < Struct.new(:foo, :bar); end

Expand Down Expand Up @@ -82,6 +83,7 @@ def set_stub
end

it 'marshals the same with and without stubbing' do
RSpec::Mocks.configuration.patch_marshal_to_support_partial_doubles = true
expect { set_stub }.to_not change { Marshal.dump(serializable_object) }
end
end
Expand Down

0 comments on commit 273f50b

Please sign in to comment.