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]
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]]
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)
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]
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)
28 [ 1, 2, [3, [4, 5] ] ].flatten(obj).should == [1, 2, 3, [4, 5]]
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)
37 it "does not call flatten on elements" do
39 obj.should_not_receive(:flatten)
40 [obj, obj].flatten.should == [obj, obj]
43 obj.should_not_receive(:flatten)
44 [obj, obj].flatten.should == [5, 4, 5, 4]
47 it "raises an ArgumentError on recursive arrays" do
50 lambda { x.flatten }.should raise_error(ArgumentError)
56 lambda { x.flatten }.should raise_error(ArgumentError)
59 it "flattens any element which responds to #to_ary, using the return value of said method" do
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]
65 y.should_receive(:to_ary).at_least(:once).and_return(ArraySpecs::MyArray[])
66 [y].flatten.should == []
69 z.should_receive(:to_ary).and_return([2, x, y, 5])
70 [1, z, 6].flatten.should == [1, 2, 3, 4, 5, 6]
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
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]
88 it "returns nil if no modifications took place" do
90 a.flatten!.should == nil
92 a.flatten!.should_not == nil
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]]
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)
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]
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)
115 [ 1, 2, [3, [4, 5] ] ].flatten!(obj).should == [1, 2, 3, [4, 5]]
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)
124 it "raises an ArgumentError on recursive arrays" do
127 lambda { x.flatten! }.should raise_error(ArgumentError)
133 lambda { x.flatten! }.should raise_error(ArgumentError)
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, []]
140 lambda { nested_ary.flatten! }.should raise_error(TypeError)
143 it "does not raise on frozen arrays when no modification would take place" do
144 ArraySpecs.frozen_array.flatten!.should be_nil