ruby--ruby/spec/ruby/core/kernel/clone_spec.rb

129 lines
2.8 KiB
Ruby

require_relative '../../spec_helper'
require_relative 'fixtures/classes'
require_relative 'shared/dup_clone'
describe "Kernel#clone" do
it_behaves_like :kernel_dup_clone, :clone
before :each do
ScratchPad.clear
@obj = KernelSpecs::Duplicate.new 1, :a
end
it "calls #initialize_copy on the new instance" do
clone = @obj.clone
ScratchPad.recorded.should_not == @obj.object_id
ScratchPad.recorded.should == clone.object_id
end
it "uses the internal allocator and does not call #allocate" do
klass = Class.new
instance = klass.new
def klass.allocate
raise "allocate should not be called"
end
clone = instance.clone
clone.class.should equal klass
end
it "copies frozen state from the original" do
o2 = @obj.clone
@obj.freeze
o3 = @obj.clone
o2.should_not.frozen?
o3.should.frozen?
end
ruby_version_is '2.8' do
it 'takes an freeze: true option to frozen copy' do
@obj.clone(freeze: true).should.frozen?
@obj.freeze
@obj.clone(freeze: true).should.frozen?
end
end
it 'takes an freeze: false option to not return frozen copy' do
@obj.clone(freeze: false).should_not.frozen?
@obj.freeze
@obj.clone(freeze: false).should_not.frozen?
end
it "copies instance variables" do
clone = @obj.clone
clone.one.should == 1
clone.two.should == :a
end
it "copies singleton methods" do
def @obj.special() :the_one end
clone = @obj.clone
clone.special.should == :the_one
end
it "copies modules included in the singleton class" do
class << @obj
include KernelSpecs::DuplicateM
end
clone = @obj.clone
clone.repr.should == "KernelSpecs::Duplicate"
end
it "copies constants defined in the singleton class" do
class << @obj
CLONE = :clone
end
clone = @obj.clone
class << clone
CLONE.should == :clone
end
end
it "replaces a singleton object's metaclass with a new copy with the same superclass" do
cls = Class.new do
def bar
['a']
end
end
object = cls.new
object.define_singleton_method(:bar) do
['b', *super()]
end
object.bar.should == ['b', 'a']
cloned = object.clone
cloned.singleton_methods.should == [:bar]
# bar should replace previous one
cloned.define_singleton_method(:bar) do
['c', *super()]
end
cloned.bar.should == ['c', 'a']
# bar should be removed and call through to superclass
cloned.singleton_class.class_eval do
remove_method :bar
end
cloned.bar.should == ['a']
end
it 'copies frozen?' do
o = ''.freeze.clone
o.frozen?.should be_true
end
ruby_version_is ''...'2.7' do
it 'copies tainted?' do
o = ''.taint.clone
o.tainted?.should be_true
end
end
end