summaryrefslogtreecommitdiff
path: root/spec/ruby/core/kernel/shared/dup_clone.rb
blob: a52ccab359ed51c40676287cb1134f99074a6483 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
class ObjectSpecDup
  def initialize()
    @obj = :original
  end

  attr_accessor :obj
end

class ObjectSpecDupInitCopy
  def initialize()
    @obj = :original
  end

  attr_accessor :obj, :original

  def initialize_copy(original)
    @obj = :init_copy
    @original = original
  end

  private :initialize_copy
end

describe :kernel_dup_clone, shared: true do
  it "returns a new object duplicated from the original" do
    o = ObjectSpecDup.new
    o2 = ObjectSpecDup.new

    o.obj = 10

    o3 = o.send(@method)

    o3.obj.should == 10
    o2.obj.should == :original
  end

  it "produces a shallow copy, contained objects are not recursively dupped" do
    o = ObjectSpecDup.new
    array = [1, 2]
    o.obj = array

    o2 = o.send(@method)
    o2.obj.should equal(o.obj)
  end

  it "calls #initialize_copy on the NEW object if available, passing in original object" do
    o = ObjectSpecDupInitCopy.new
    o2 = o.send(@method)

    o.obj.should == :original
    o2.obj.should == :init_copy
    o2.original.should equal(o)
  end

  ruby_version_is ''...'2.7' do
    it "preserves tainted state from the original" do
      o = ObjectSpecDupInitCopy.new
      o2 = o.send(@method)
      o.taint
      o3 = o.send(@method)

      o2.tainted?.should == false
      o3.tainted?.should == true
    end
  end

  it "does not preserve the object_id" do
    o1 = ObjectSpecDupInitCopy.new
    old_object_id = o1.object_id
    o2 = o1.send(@method)
    o2.object_id.should_not == old_object_id
  end

  ruby_version_is ''...'2.7' do
    it "preserves untrusted state from the original" do
      o = ObjectSpecDupInitCopy.new
      o2 = o.send(@method)
      o.untrust
      o3 = o.send(@method)

      o2.untrusted?.should == false
      o3.untrusted?.should == true
    end
  end

  it "returns nil for NilClass" do
    nil.send(@method).should == nil
  end

  it "returns true for TrueClass" do
    true.send(@method).should == true
  end

  it "returns false for FalseClass" do
    false.send(@method).should == false
  end

  it "returns the same Integer for Integer" do
    1.send(@method).should == 1
  end

  it "returns the same Symbol for Symbol" do
    :my_symbol.send(@method).should == :my_symbol
  end

  ruby_version_is ''...'2.5' do
    it "raises a TypeError for Complex" do
      c = Complex(1.3, 3.1)
      -> { c.send(@method) }.should raise_error(TypeError)
    end

    it "raises a TypeError for Rational" do
      r = Rational(1, 3)
      -> { r.send(@method) }.should raise_error(TypeError)
    end
  end

  ruby_version_is '2.5' do
    it "returns self for Complex" do
      c = Complex(1.3, 3.1)
      c.send(@method).should equal c
    end

    it "returns self for Rational" do
      r = Rational(1, 3)
      r.send(@method).should equal r
    end
  end
end