summaryrefslogtreecommitdiff
path: root/spec/ruby/core/array/concat_spec.rb
blob: 985c5d884a03189472e476108ce88b1826f21133 (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
130
131
132
require_relative '../../spec_helper'
require_relative 'fixtures/classes'

describe "Array#concat" do
  it "returns the array itself" do
    ary = [1,2,3]
    ary.concat([4,5,6]).equal?(ary).should be_true
  end

  it "appends the elements in the other array" do
    ary = [1, 2, 3]
    ary.concat([9, 10, 11]).should equal(ary)
    ary.should == [1, 2, 3, 9, 10, 11]
    ary.concat([])
    ary.should == [1, 2, 3, 9, 10, 11]
  end

  it "does not loop endlessly when argument is self" do
    ary = ["x", "y"]
    ary.concat(ary).should == ["x", "y", "x", "y"]
  end

  it "tries to convert the passed argument to an Array using #to_ary" do
    obj = mock('to_ary')
    obj.should_receive(:to_ary).and_return(["x", "y"])
    [4, 5, 6].concat(obj).should == [4, 5, 6, "x", "y"]
  end

  it "does not call #to_ary on Array subclasses" do
    obj = ArraySpecs::ToAryArray[5, 6, 7]
    obj.should_not_receive(:to_ary)
    [].concat(obj).should == [5, 6, 7]
  end

  it "raises a #{frozen_error_class} when Array is frozen and modification occurs" do
    lambda { ArraySpecs.frozen_array.concat [1] }.should raise_error(frozen_error_class)
  end

  # see [ruby-core:23666]
  it "raises a #{frozen_error_class} when Array is frozen and no modification occurs" do
    lambda { ArraySpecs.frozen_array.concat([]) }.should raise_error(frozen_error_class)
  end

  it "keeps tainted status" do
    ary = [1, 2]
    ary.taint
    ary.concat([3])
    ary.tainted?.should be_true
    ary.concat([])
    ary.tainted?.should be_true
  end

  it "is not infected by the other" do
    ary = [1,2]
    other = [3]; other.taint
    ary.tainted?.should be_false
    ary.concat(other)
    ary.tainted?.should be_false
  end

  it "keeps the tainted status of elements" do
    ary = [ Object.new, Object.new, Object.new ]
    ary.each {|x| x.taint }

    ary.concat([ Object.new ])
    ary[0].tainted?.should be_true
    ary[1].tainted?.should be_true
    ary[2].tainted?.should be_true
    ary[3].tainted?.should be_false
  end

  it "keeps untrusted status" do
    ary = [1, 2]
    ary.untrust
    ary.concat([3])
    ary.untrusted?.should be_true
    ary.concat([])
    ary.untrusted?.should be_true
  end

  it "is not infected untrustedness by the other" do
    ary = [1,2]
    other = [3]; other.untrust
    ary.untrusted?.should be_false
    ary.concat(other)
    ary.untrusted?.should be_false
  end

  it "keeps the untrusted status of elements" do
    ary = [ Object.new, Object.new, Object.new ]
    ary.each {|x| x.untrust }

    ary.concat([ Object.new ])
    ary[0].untrusted?.should be_true
    ary[1].untrusted?.should be_true
    ary[2].untrusted?.should be_true
    ary[3].untrusted?.should be_false
  end

  it "appends elements to an Array with enough capacity that has been shifted" do
    ary = [1, 2, 3, 4, 5]
    2.times { ary.shift }
    2.times { ary.pop }
    ary.concat([5, 6]).should == [3, 5, 6]
  end

  it "appends elements to an Array without enough capacity that has been shifted" do
    ary = [1, 2, 3, 4]
    3.times { ary.shift }
    ary.concat([5, 6]).should == [4, 5, 6]
  end

  ruby_version_is "2.4" do
    it "takes multiple arguments" do
      ary = [1, 2]
      ary.concat [3, 4]
      ary.should == [1, 2, 3, 4]
    end

    it "concatenates the initial value when given arguments contain 2 self" do
      ary = [1, 2]
      ary.concat ary, ary
      ary.should == [1, 2, 1, 2, 1, 2]
    end

    it "returns self when given no arguments" do
      ary = [1, 2]
      ary.concat.should equal(ary)
      ary.should == [1, 2]
    end
  end
end