Updated RubySpec source to 55122684.
[rbx.git] / spec / frozen / 1.8 / core / array / flatten_spec.rb
blob0eb73af8b8214a0dbcb8593c9fff2a4622aa8ff0
1 require File.dirname(__FILE__) + '/../../spec_helper'
2 require File.dirname(__FILE__) + '/fixtures/classes'
4 describe "Array#flatten" do
5   it "returns a one-dimensional flattening recursively" do
6     [[[1, [2, 3]],[2, 3, [4, [4, [5, 5]], [1, 2, 3]]], [4]], []].flatten.should == [1, 2, 3, 2, 3, 4, 4, 5, 5, 1, 2, 3, 4]
7   end
8   
9   ruby_version_is "1.8.7" do
10     it "takes an optional argument that determines the level of recursion" do
11       [ 1, 2, [3, [4, 5] ] ].flatten(1).should == [1, 2, 3, [4, 5]]
12     end
13     
14     it "returns self when the level of recursion is 0" do
15       a = [ 1, 2, [3, [4, 5] ] ]
16       a.flatten(0).should equal(a)
17     end
18     
19     it "ignores negative levels" do
20       [ 1, 2, [ 3, 4, [5, 6] ] ].flatten(-1).should == [1, 2, 3, 4, 5, 6]
21       [ 1, 2, [ 3, 4, [5, 6] ] ].flatten(-10).should == [1, 2, 3, 4, 5, 6]
22     end
23     
24     it "tries to convert passed Objects to Integers using #to_int" do
25       obj = mock("Converted to Integer")
26       obj.should_receive(:to_int).and_return(1)
27       
28       [ 1, 2, [3, [4, 5] ] ].flatten(obj).should == [1, 2, 3, [4, 5]]
29     end
30     
31     it "raises a TypeError when the passed Object can't be converted to an Integer" do
32       obj = mock("Not converted")
33       lambda { [ 1, 2, [3, [4, 5] ] ].flatten(obj) }.should raise_error(TypeError)
34     end
35   end
37   it "does not call flatten on elements" do
38     obj = mock('[1,2]')
39     obj.should_not_receive(:flatten)
40     [obj, obj].flatten.should == [obj, obj]
42     obj = [5, 4]
43     obj.should_not_receive(:flatten)
44     [obj, obj].flatten.should == [5, 4, 5, 4]
45   end
46   
47   it "raises an ArgumentError on recursive arrays" do
48     x = []
49     x << x
50     lambda { x.flatten }.should raise_error(ArgumentError)
51   
52     x = []
53     y = []
54     x << y
55     y << x
56     lambda { x.flatten }.should raise_error(ArgumentError)
57   end
59   it "flattens any element which responds to #to_ary, using the return value of said method" do
60     x = mock("[3,4]")
61     x.should_receive(:to_ary).at_least(:once).and_return([3, 4])
62     [1, 2, x, 5].flatten.should == [1, 2, 3, 4, 5]
64     y = mock("MyArray[]")
65     y.should_receive(:to_ary).at_least(:once).and_return(ArraySpecs::MyArray[])
66     [y].flatten.should == []
68     z = mock("[2,x,y,5]")
69     z.should_receive(:to_ary).and_return([2, x, y, 5])
70     [1, z, 6].flatten.should == [1, 2, 3, 4, 5, 6]
71   end
72   
73   it "returns subclass instance for Array subclasses" do
74     ArraySpecs::MyArray[].flatten.class.should == ArraySpecs::MyArray
75     ArraySpecs::MyArray[1, 2, 3].flatten.class.should == ArraySpecs::MyArray
76     ArraySpecs::MyArray[1, [2], 3].flatten.class.should == ArraySpecs::MyArray
77     [ArraySpecs::MyArray[1, 2, 3]].flatten.class.should == Array
78   end
79 end  
81 describe "Array#flatten!" do
82   it "modifies array to produce a one-dimensional flattening recursively" do
83     a = [[[1, [2, 3]],[2, 3, [4, [4, [5, 5]], [1, 2, 3]]], [4]], []]
84     a.flatten!.should equal(a)
85     a.should == [1, 2, 3, 2, 3, 4, 4, 5, 5, 1, 2, 3, 4]
86   end
88   it "returns nil if no modifications took place" do
89     a = [1, 2, 3]
90     a.flatten!.should == nil
91     a = [1, [2, 3]]
92     a.flatten!.should_not == nil
93   end
95   ruby_version_is "1.8.7" do
96     it "takes an optional argument that determines the level of recursion" do
97       [ 1, 2, [3, [4, 5] ] ].flatten!(1).should == [1, 2, 3, [4, 5]]
98     end
99     
100     # NOTE: This is inconsistent behaviour, it should return nil
101     it "returns self when the level of recursion is 0" do
102       a = [ 1, 2, [3, [4, 5] ] ]
103       a.flatten!(0).should equal(a)
104     end
105     
106     it "ignores negative levels" do
107       [ 1, 2, [ 3, 4, [5, 6] ] ].flatten!(-1).should == [1, 2, 3, 4, 5, 6]
108       [ 1, 2, [ 3, 4, [5, 6] ] ].flatten!(-10).should == [1, 2, 3, 4, 5, 6]
109     end
110     
111     it "tries to convert passed Objects to Integers using #to_int" do
112       obj = mock("Converted to Integer")
113       obj.should_receive(:to_int).and_return(1)
114       
115       [ 1, 2, [3, [4, 5] ] ].flatten!(obj).should == [1, 2, 3, [4, 5]]
116     end
117     
118     it "raises a TypeError when the passed Object can't be converted to an Integer" do
119       obj = mock("Not converted")
120       lambda { [ 1, 2, [3, [4, 5] ] ].flatten!(obj) }.should raise_error(TypeError)
121     end
122   end
124   it "raises an ArgumentError on recursive arrays" do
125     x = []
126     x << x
127     lambda { x.flatten! }.should raise_error(ArgumentError)
128   
129     x = []
130     y = []
131     x << y
132     y << x
133     lambda { x.flatten! }.should raise_error(ArgumentError)
134   end
136   compliant_on :ruby, :jruby do
137     it "raises a TypeError on frozen arrays when modification would take place" do
138       nested_ary = [1, 2, []]
139       nested_ary.freeze
140       lambda { nested_ary.flatten! }.should raise_error(TypeError)
141     end
143     it "does not raise on frozen arrays when no modification would take place" do
144       ArraySpecs.frozen_array.flatten!.should be_nil
145     end
146   end