summaryrefslogtreecommitdiff
path: root/spec/ruby/core/array/multiply_spec.rb
blob: 23d5c99f3a849afd87becc0ac834a0b7934fed52 (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
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
require_relative 'shared/join'

describe "Array#*" do
  it "tries to convert the passed argument to a String using #to_str" do
    obj = mock('separator')
    obj.should_receive(:to_str).and_return('::')
    ([1, 2, 3, 4] * obj).should == '1::2::3::4'
  end

  it "tires to convert the passed argument to an Integer using #to_int" do
    obj = mock('count')
    obj.should_receive(:to_int).and_return(2)
    ([1, 2, 3, 4] * obj).should == [1, 2, 3, 4, 1, 2, 3, 4]
  end

  it "raises a TypeError if the argument can neither be converted to a string nor an integer" do
    obj = mock('not a string or integer')
    ->{ [1,2] * obj }.should raise_error(TypeError)
  end

  it "converts the passed argument to a String rather than an Integer" do
    obj = mock('2')
    def obj.to_int() 2 end
    def obj.to_str() "2" end
    ([:a, :b, :c] * obj).should == "a2b2c"
  end

  it "raises a TypeError is the passed argument is nil" do
    ->{ [1,2] * nil }.should raise_error(TypeError)
  end

  it "raises an ArgumentError when passed 2 or more arguments" do
    ->{ [1,2].send(:*, 1, 2) }.should raise_error(ArgumentError)
  end

  it "raises an ArgumentError when passed no arguments" do
    ->{ [1,2].send(:*) }.should raise_error(ArgumentError)
  end
end

describe "Array#* with an integer" do
  it "concatenates n copies of the array when passed an integer" do
    ([ 1, 2, 3 ] * 0).should == []
    ([ 1, 2, 3 ] * 1).should == [1, 2, 3]
    ([ 1, 2, 3 ] * 3).should == [1, 2, 3, 1, 2, 3, 1, 2, 3]
    ([] * 10).should == []
  end

  it "does not return self even if the passed integer is 1" do
    ary = [1, 2, 3]
    (ary * 1).should_not equal(ary)
  end

  it "properly handles recursive arrays" do
    empty = ArraySpecs.empty_recursive_array
    (empty * 0).should == []
    (empty * 1).should == empty
    (empty * 3).should == [empty, empty, empty]

    array = ArraySpecs.recursive_array
    (array * 0).should == []
    (array * 1).should == array
  end

  it "raises an ArgumentError when passed a negative integer" do
    -> { [ 1, 2, 3 ] * -1 }.should raise_error(ArgumentError)
    -> { [] * -1 }.should raise_error(ArgumentError)
  end

  describe "with a subclass of Array" do
    before :each do
      ScratchPad.clear

      @array = ArraySpecs::MyArray[1, 2, 3, 4, 5]
    end

    ruby_version_is ''...'3.0' do
      it "returns a subclass instance" do
        (@array * 0).should be_an_instance_of(ArraySpecs::MyArray)
        (@array * 1).should be_an_instance_of(ArraySpecs::MyArray)
        (@array * 2).should be_an_instance_of(ArraySpecs::MyArray)
      end
    end

    ruby_version_is '3.0' do
      it "returns an Array instance" do
        (@array * 0).should be_an_instance_of(Array)
        (@array * 1).should be_an_instance_of(Array)
        (@array * 2).should be_an_instance_of(Array)
      end
    end

    it "does not call #initialize on the subclass instance" do
      (@array * 2).should == [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
      ScratchPad.recorded.should be_nil
    end
  end
end

describe "Array#* with a string" do
  it_behaves_like :array_join_with_string_separator, :*
end